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