63f14509c36a86a3bb5edbe56059945984fc56cf
[pandora-libraries.git] / lib / pnd_apps.c
1
2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #include <string.h> /* for memset */
5 #include <unistd.h> /* for fork/exec */
6
7 #include <sys/types.h> /* for wait */
8 #include <sys/wait.h> /* for wait */
9
10 #include "pnd_container.h"
11 #include "pnd_pxml.h"
12 #include "pnd_apps.h"
13
14 unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
15                               char *rel_exec, char *rel_startdir,
16                               unsigned int clockspeed, unsigned int options )
17 {
18   char *argv [ 60 ];
19   char s_clockspeed [ 100 ];
20   int f;
21
22   //printf ( "Entering pnd_apps_exec\n" );
23
24   if ( ! pndrun ) {
25     return ( 0 );
26   }
27
28   if ( ! fullpath ) {
29     return ( 0 );
30   }
31
32   if ( ! unique_id ) {
33     return ( 0 );
34   }
35
36   if ( ! rel_exec ) {
37     return ( 0 );
38   }
39
40 #if 0
41   printf ( "  runscript: %s\n", pndrun );
42   printf ( "  path: %s\n", fullpath );
43   printf ( "  id: %s\n", unique_id );
44   printf ( "  exec: %s\n", rel_exec );
45   printf ( "  cwd: %s\n", rel_startdir );
46   printf ( "  clock: %u\n", clockspeed );
47 #endif
48
49   memset ( argv, '\0', sizeof(char*) * 20 );
50
51   f = 0;
52   argv [ f++ ] = pndrun;
53   argv [ f++ ] = "-p";
54   argv [ f++ ] = fullpath;
55   argv [ f++ ] = "-e";
56   argv [ f++ ] = rel_exec;
57   if ( rel_startdir ) {
58     argv [ f++ ] = "-s";
59     argv [ f++ ] = rel_startdir;
60   }
61   argv [ f++ ] = "-b";
62   argv [ f++ ] = unique_id;
63   if ( clockspeed ) {
64     argv [ f++ ] = "-c";
65     snprintf ( s_clockspeed, 100, "%u", clockspeed );
66     argv [ f++ ] = s_clockspeed;
67   }
68
69   // skip -a (arguments) for now
70
71   if ( options & PND_EXEC_OPTION_NOUNION ) {
72     argv [ f++ ] = "-n"; // no union for now
73   }
74
75   if ( options & PND_EXEC_OPTION_NOX11 ) {
76     argv [ f++ ] = "-x"; // no union for now
77   }
78
79   // finish
80   argv [ f++ ] = NULL; // for execv
81
82   // debug
83 #if 0
84   int i;
85   for ( i = 0; i < f; i++ ) {
86     printf ( "exec's argv %u [ %s ]\n", i, argv [ i ] );
87   }
88 #endif
89
90   // invoke it!
91
92   if ( ( f = fork() ) < 0 ) {
93     // error forking
94   } else if ( f > 0 ) {
95     // parent
96   } else {
97     // child, do it
98     execv ( pndrun, argv );
99   } 
100
101   // by definition, either error occurred or we are the original application.
102
103   // do we wish to wait until the child process completes? (we don't
104   // care if it crashed, was killed, was suspended, whatever.)
105   if ( options & PND_EXEC_OPTION_BLOCK ) {
106     int status = 0;
107     //waitpid ( f, &status. 0 /* no options */ );
108     wait ( &status );
109   }
110
111   // printf ( "Exiting pnd_apps_exec\n" );
112
113   return ( 1 );
114 }
115
116 void pnd_get_ro_mountpoint ( char *fullpath, char *unique_id, char *r_mountpoint, unsigned int mountpoint_len ) {
117
118   if ( ! r_mountpoint ) {
119     return; // sillyness
120   }
121
122   snprintf ( r_mountpoint, mountpoint_len, "%s/%s/", PND_MOUNT_PATH, unique_id );
123
124   return;
125 }
126
127 unsigned char pnd_get_appdata_path ( char *fullpath, char *unique_id, char *r_path, unsigned int path_len ) {
128   // you know, determining the 'mount point' used is sort of a pain in the rear
129   // use df <file>, skip header line, grab first token. Cheap and should work.
130   // (Rather than just assume first two path chunks in path, say, which would be pretty darned
131   // accurate, but whose to say they're not using NFS or crazy mountpoints?)
132   FILE *df;
133   char cmdbuf [ 1024 ];
134
135   snprintf ( cmdbuf, 1023, "/bin/df %s", fullpath );
136
137   df = popen ( cmdbuf, "r" );
138
139   if ( ! df ) {
140     return ( 0 ); // tunefs: you can tune a filesystem but you can't tune a fish
141   }
142
143   // fetch and discard header
144   if ( ! fgets ( cmdbuf, 1023, df ) ) {
145     pclose ( df );
146     return ( 0 );
147   }
148
149   // grab df result line
150   if ( ! fgets ( cmdbuf, 1023, df ) ) {
151     pclose ( df );
152     return ( 0 );
153   }
154
155   pclose ( df );
156
157   // parse
158   char *ws = strchr ( cmdbuf, ' ' );
159
160   if ( ! ws ) {
161     return ( 0 );
162   }
163
164   *ws = '\0';
165
166   if ( r_path && path_len ) {
167     snprintf ( r_path, path_len, "%s/appdata/%s/", cmdbuf, unique_id );
168   }
169
170   return ( 1 );
171 }