a0452ab3c4843b18d319bb78654660848eadca8d
[pandora-libraries.git] / lib / pnd_utility.c
1
2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #define __USE_GNU /* for strcasestr */
5 #include <string.h> /* for making ftw.h happy */
6 #include <unistd.h> /* for fork exec */
7
8 #include "pnd_pxml.h"
9 #include "pnd_container.h"
10 #include "pnd_utility.h"
11 #include "pnd_pndfiles.h"
12 #include "pnd_discovery.h"
13
14 // a generalized variable-substitution routine might be nice; for now we need a quick tilde one,
15 // so here goes. Brute force ftw!
16 char *pnd_expand_tilde ( char *freeable_buffer ) {
17   char *p;
18   char *s = freeable_buffer;
19   char *home = getenv ( "HOME" );
20
21   if ( ! home ) {
22     return ( s ); // can't succeed
23   }
24
25   while ( ( p = strchr ( s, '~' ) ) ) {
26     char *temp = malloc ( strlen ( s ) + strlen ( home ) + 1 );
27     memset ( temp, '\0', strlen ( s ) + strlen ( home ) + 1 );
28     // copy in stuff prior to ~
29     strncpy ( temp, s, p - s );
30     // copy tilde in
31     strcat ( temp, home );
32     // copy stuff after tilde in
33     strcat ( temp, p + 1 );
34     // swap ptrs
35     free ( s );
36     s = temp;
37   } // while finding matches
38
39   return ( s );
40 }
41
42 void pnd_exec_no_wait_1 ( char *fullpath, char *arg1 ) {
43   int i;
44
45   if ( ( i = fork() ) < 0 ) {
46     printf ( "ERROR: Couldn't fork()\n" );
47     return;
48   }
49
50   if ( i ) {
51     return; // parent process, don't care
52   }
53
54   // child process, do something
55   if ( arg1 ) {
56     execl ( fullpath, fullpath, arg1, (char*) NULL );
57   } else {
58     execl ( fullpath, fullpath, (char*) NULL );
59   }
60
61   // getting here is an error
62   //printf ( "Error attempting to run %s\n", fullpath );
63
64   return;
65 }
66
67 pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) {
68   unsigned char valid = pnd_object_type_unknown;
69   pnd_pxml_handle pxmlh = 0;
70
71   // WARN: this is way too close to callback in pnd_disco .. should be refactored!
72
73   if ( strcasestr ( fullpath, PXML_FILENAME ) ) {
74     valid = pnd_object_type_directory;
75   } else if ( strcasestr ( fullpath, PND_PACKAGE_FILEEXT "\0" ) ) {
76     valid = pnd_object_type_pnd;
77   }
78
79   // if not a file of interest, just keep looking until we run out
80   if ( ! valid ) {
81     return ( 0 );
82   }
83
84   // potentially a valid application
85   if ( valid == pnd_object_type_directory ) {
86     pxmlh = pnd_pxml_fetch ( (char*) fullpath );
87
88   } else if ( valid == pnd_object_type_pnd ) {
89     FILE *f;
90     char pxmlbuf [ 32 * 1024 ]; // TBD: assuming 32k pxml accrual buffer is a little lame
91
92     // open it up..
93     f = fopen ( fullpath, "r" );
94
95     // try to locate the PXML portion
96     if ( ! pnd_pnd_seek_pxml ( f ) ) {
97       fclose ( f );
98       return ( 0 ); // pnd or not, but not to spec. Pwn'd the pnd?
99     }
100
101     // accrue it into a buffer
102     if ( ! pnd_pnd_accrue_pxml ( f, pxmlbuf, 32 * 1024 ) ) {
103       fclose ( f );
104       return ( 0 );
105     }
106
107     // by now, we have <PXML> .. </PXML>, try to parse..
108     pxmlh = pnd_pxml_fetch_buffer ( (char*) fullpath, pxmlbuf );
109
110     // done with file
111     fclose ( f );
112
113   }
114
115   // ..
116
117   return ( pxmlh );
118 }