Fix; introduced a core-dump that will occur when SD is not in place.
[pandora-libraries.git] / apps / pnd_run.c
1
2 #include <stdio.h> /* for printf, NULL */
3 #include <stdlib.h> /* for free */
4 #include <string.h> /* for strdup */
5
6 #include "pnd_conf.h"
7 #include "pnd_container.h"
8 #include "pnd_apps.h"
9 #include "pnd_discovery.h"
10 #include "pnd_locate.h"
11 #include "pnd_pndfiles.h"
12 #include "pnd_pxml.h"
13
14 static void usage ( char *argv[] ) {
15   printf ( "%s [-r runscript] [-n] path-to-pndfile\n", argv [ 0 ] );
16   printf ( "-r\tOptional. If not specified, will attempt to suss from configs.\n" );
17   printf ( "-n\tOptional. If present, instruct runscript to kill/restart X11 around app.\n" );
18   printf ( "pndfile\tRequired. Full path to the pnd-file to execute.\n" );
19   return;
20 }
21
22 int main ( int argc, char *argv[] ) {
23   char *pnd_run = NULL;
24   char *pndfile = NULL;
25   unsigned char no_x11 = 0;
26   unsigned char i;
27
28   for ( i = 1; i < argc; i++ ) {
29
30     if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'r' ) {
31       pnd_run = argv [ i + 1 ];
32       i++;
33       if ( ! pnd_run ) {
34         printf ( "-r specified, but no argument provided.\n" );
35         exit ( 0 );
36       }
37     } else if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'n' ) {
38       no_x11 = 1;
39     } else {
40
41       if ( argv [ i ][ 0 ] == '-' ) {
42         usage ( argv );
43         exit ( 0 );
44       } else if ( pndfile ) {
45         printf ( "Only one pndfile may be specified.\n" );
46       } else {
47         pndfile = argv [ i ];
48       }
49
50     }
51
52   } // for args
53
54   // if runscript was not specified on cmdline, attempt to pick it up from config
55   // ---> cribbed right out of discotest :/ copypaste ftw!
56   if ( ! pnd_run ) {
57     char *configpath;
58     char *overridespath;
59
60     // attempt to fetch a sensible default searchpath for configs
61     configpath = pnd_conf_query_searchpath();
62
63     // attempt to fetch the apps config. since it finds us the runscript
64     pnd_conf_handle apph;
65
66     apph = pnd_conf_fetch_by_id ( pnd_conf_apps, configpath );
67
68     if ( apph ) {
69
70       overridespath = pnd_conf_get_as_char ( apph, PND_PXML_OVERRIDE_KEY );
71
72       if ( ! overridespath ) {
73         overridespath = PND_PXML_OVERRIDE_SEARCHPATH;
74       }
75
76     } else {
77       // couldn't find a useful app search path so use the default
78       overridespath = PND_PXML_OVERRIDE_SEARCHPATH;
79     }
80
81     // given app-config, try to locate a runscript
82     char *run_searchpath;
83     char *run_script;
84     char *pndrun;
85
86     if ( apph ) {
87       run_searchpath = pnd_conf_get_as_char ( apph, PND_PNDRUN_SEARCHPATH_KEY );
88       run_script = pnd_conf_get_as_char ( apph, PND_PNDRUN_KEY );
89       pndrun = NULL;
90
91       if ( ! run_searchpath ) {
92         run_searchpath = PND_APPS_SEARCHPATH;
93         run_script = PND_PNDRUN_FILENAME;
94       }
95
96     } else {
97       run_searchpath = NULL;
98       run_script = NULL;
99       pndrun = PND_PNDRUN_DEFAULT;
100     }
101
102     if ( ! pndrun ) {
103       pndrun = pnd_locate_filename ( run_searchpath, run_script );
104     }
105
106     // hand back to main proggy
107     pnd_run = pndrun; // lame, fix this
108
109   } // try to locate runscript
110
111   if ( ! pnd_run ) {
112     printf ( "Runscript could not be determined. Fail.\n" );
113     exit ( 0 );
114   }
115
116   if ( ! pndfile ) {
117     usage ( argv );
118     exit ( 0 );
119   }
120
121   // summary
122   printf ( "Runscript\t%s\n", pnd_run );
123   printf ( "Pndfile\t%s\n", pndfile );
124   printf ( "Kill X11\t%s\n", no_x11 ? "true" : "false" );
125
126   // sadly, to launch a pnd-file we need to know what the executable is in there
127   unsigned int pxmlbuflen = 96 * 1024; // lame, need to calculate it
128   char *pxmlbuf = malloc ( pxmlbuflen );
129   if ( ! pxmlbuf ) {
130     printf ( "ERROR: RAM exhausted!\n" );
131     exit ( 0 );
132   }
133   memset ( pxmlbuf, '\0', pxmlbuflen );
134
135   FILE *f = fopen ( pndfile, "r" );
136   if ( ! f ) {
137     printf ( "ERROR: Couldn't open pndfile %s!\n", pndfile );
138     exit ( 0 );
139   }
140
141   pnd_pxml_handle h = NULL;
142   if ( pnd_pnd_seek_pxml ( f ) ) {
143     if ( pnd_pnd_accrue_pxml ( f, pxmlbuf, pxmlbuflen ) ) {
144       h = pnd_pxml_fetch_buffer ( "pnd_run", pxmlbuf );
145     }
146   }
147
148   fclose ( f );
149
150   if ( ! h ) {
151     printf ( "ERROR: Couldn't pull PXML.xml from the pndfile.\n" );
152     exit ( 0 );
153   }
154
155   // attempt to invoke
156   unsigned int options = 0;
157   if ( no_x11 ) {
158     options |= PND_EXEC_OPTION_NOX11;
159   }
160
161   unsigned int clock = 200;
162   if ( pnd_pxml_get_clockspeed ( h ) ) {
163     clock = atoi ( pnd_pxml_get_clockspeed ( h ) );
164   }
165
166   if ( ! pnd_apps_exec ( pnd_run, pndfile,
167                          pnd_pxml_get_unique_id ( h ),
168                          pnd_pxml_get_exec ( h ),
169                          pnd_pxml_get_startdir ( h ),
170                          clock,
171                          options )
172        )
173   {
174     printf ( "ERROR: PXML.xml data is bad\n" );
175   }
176
177   return ( 0 );
178 } // main