Initial commit of libpnd 0.0.5 so we cna restart with GIT
[pandora-libraries.git] / lib / pnd_discovery.c
1
2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #include <string.h> /* for making ftw.h happy */
5
6 #define _XOPEN_SOURCE 500
7 #define __USE_XOPEN_EXTENDED
8 #include <ftw.h> /* for nftw, tree walker */
9
10 #include "pnd_container.h"
11 #include "pnd_pxml.h"
12 #include "pnd_discovery.h"
13 #include "pnd_pathiter.h"
14
15 #warning "PND/PNZ support is not included yet; scripts need writing"
16 #warning "  /usr/pandora/bin/pnd_valid.sh"
17 #warning "  /usr/pandora/bin/pnd_prepare.sh"
18 #warning "  /usr/pandora/bin/pnd_unprepare.sh"
19
20 // need these 'globals' due to the way nftw and ftw work :/
21 static pnd_box_handle disco_box;
22 static char *disco_overrides = NULL;
23
24 void pnd_disco_destroy ( pnd_disco_t *p ) {
25
26   if ( p -> title_en ) {
27     free ( p -> title_en );
28   }
29
30   if ( p -> icon ) {
31     free ( p -> icon );
32   }
33
34   if ( p -> exec ) {
35     free ( p -> exec );
36   }
37
38   if ( p -> unique_id ) {
39     free ( p -> unique_id );
40   }
41
42   if ( p -> main_category ) {
43     free ( p -> main_category );
44   }
45
46   if ( p -> clockspeed ) {
47     free ( p -> clockspeed );
48   }
49
50   return;
51 }
52
53 static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
54                                 int typeflag, struct FTW *ftwbuf )
55 {
56   unsigned char valid = 0; // 1 for plaintext PXML, 2 for PND...
57
58   // PXML.xml is a possible application candidate (and not a dir named PXML.xml :)
59   if ( typeflag & FTW_D ) {
60     return ( 0 ); // skip directories and other non-regular files
61   }
62
63   if ( strcasecmp ( fpath + ftwbuf -> base, PXML_FILENAME ) == 0 ) {
64     valid = 1;
65   }
66
67   // PND file and others may be valid as well .. but lets leave that for now
68   //
69   // PND and PNZ and whatever
70   //
71
72   // if not a file of interest, just keep looking until we run out
73   if ( ! valid ) {
74     return ( 0 );
75   }
76
77   // potentially a valid application
78   if ( valid == 1 ) {
79     // Plaintext PXML file
80     //printf ( "disco callback encountered '%s'\n", fpath );
81
82     pnd_pxml_handle pxmlh;
83
84     // pick up the PXML if we can
85
86     pxmlh = pnd_pxml_fetch ( (char*) fpath );
87
88     if ( ! pxmlh ) {
89       return ( 0 ); // continue the scan
90     }
91
92     // look for any overrides, if requested
93 #warning pnd_pxml_merge_override removed by Cpasjuste ...
94   //  pnd_pxml_merge_override ( pxmlh, disco_overrides );
95
96     // check for validity and add to resultset if it looks executable
97     if ( pnd_is_pxml_valid_app ( pxmlh ) ) {
98       pnd_disco_t *p;
99
100       p = pnd_box_allocinsert ( disco_box, (char*) fpath, sizeof(pnd_disco_t) );
101       p -> title_en = strdup ( pnd_pxml_get_app_name ( pxmlh ) );
102       p -> icon = strdup ( pnd_pxml_get_icon_path ( pxmlh ) );
103       p -> exec = strdup ( pnd_pxml_get_exec_path ( pxmlh ) );
104       p -> unique_id = strdup ( pnd_pxml_get_unique_id ( pxmlh ) );
105       p -> main_category = strdup ( pnd_pxml_get_primary_category ( pxmlh ) );
106       p -> clockspeed = strdup ( pnd_pxml_get_clockspeed ( pxmlh ) ); 
107
108     }
109
110     // ditch pxml
111         pnd_pxml_delete ( pxmlh );
112
113         return 0;
114   } else if ( valid == 2 ) {
115     // PND ... ??
116   }
117
118   return ( 0 ); // continue the tree walk
119 }
120
121 pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ) {
122
123   //printf ( "Searchpath to discover: '%s'\n", searchpath );
124
125   // alloc a container for the result set
126   disco_box = pnd_box_new ( "discovery" );
127   disco_overrides = overridespath;
128
129   /* iterate across the paths within the searchpath, attempting to locate applications
130    */
131
132   SEARCHPATH_PRE
133   {
134
135     // invoke the dir walking function; thankfully Linux includes a pretty good one
136     nftw ( buffer,               // path to descend
137            pnd_disco_callback,   // callback to do processing
138            10,                   // no more than X open fd's at once
139            FTW_PHYS );           // do not follow symlinks
140
141   }
142   SEARCHPATH_POST
143
144   // return whatever we found, or NULL if nada
145   if ( ! pnd_box_get_head ( disco_box ) ) {
146     pnd_box_delete ( disco_box );
147     disco_box = NULL;
148   }
149
150   return ( disco_box );
151 }