2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #include <string.h> /* for making ftw.h happy */
6 #define _XOPEN_SOURCE 500
7 #define __USE_XOPEN_EXTENDED
8 #include <ftw.h> /* for nftw, tree walker */
10 #include "pnd_container.h"
12 #include "pnd_discovery.h"
13 #include "pnd_pathiter.h"
16 #warning "PND/PNZ support is not included yet; scripts need writing"
17 #warning " /usr/pandora/bin/pnd_valid.sh"
18 #warning " /usr/pandora/bin/pnd_prepare.sh"
19 #warning " /usr/pandora/bin/pnd_unprepare.sh"
21 // need these 'globals' due to the way nftw and ftw work :/
22 static pnd_box_handle disco_box;
23 static char *disco_overrides = NULL;
25 void pnd_disco_destroy ( pnd_disco_t *p ) {
27 if ( p -> title_en ) {
28 free ( p -> title_en );
39 if ( p -> unique_id ) {
40 free ( p -> unique_id );
43 if ( p -> main_category ) {
44 free ( p -> main_category );
47 if ( p -> clockspeed ) {
48 free ( p -> clockspeed );
54 static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
55 int typeflag, struct FTW *ftwbuf )
57 unsigned char valid = 0; // 1 for plaintext PXML, 2 for PND...
59 // PXML.xml is a possible application candidate (and not a dir named PXML.xml :)
60 if ( typeflag & FTW_D ) {
61 return ( 0 ); // skip directories and other non-regular files
64 if ( strcasecmp ( fpath + ftwbuf -> base, PXML_FILENAME ) == 0 ) {
68 // PND file and others may be valid as well .. but lets leave that for now
70 // PND and PNZ and whatever
73 // if not a file of interest, just keep looking until we run out
78 // potentially a valid application
80 // Plaintext PXML file
81 //printf ( "disco callback encountered '%s'\n", fpath );
83 pnd_pxml_handle pxmlh;
85 // pick up the PXML if we can
87 pxmlh = pnd_pxml_fetch ( (char*) fpath );
90 return ( 0 ); // continue the scan
93 // look for any overrides, if requested
94 #warning pnd_pxml_merge_override removed by Cpasjuste ...
95 // pnd_pxml_merge_override ( pxmlh, disco_overrides );
97 // check for validity and add to resultset if it looks executable
98 if ( pnd_is_pxml_valid_app ( pxmlh ) ) {
101 p = pnd_box_allocinsert ( disco_box, (char*) fpath, sizeof(pnd_disco_t) );
102 p -> title_en = strdup ( pnd_pxml_get_app_name ( pxmlh ) );
103 p -> icon = strdup ( pnd_pxml_get_icon_path ( pxmlh ) );
104 p -> exec = strdup ( pnd_pxml_get_exec_path ( pxmlh ) );
105 p -> unique_id = strdup ( pnd_pxml_get_unique_id ( pxmlh ) );
106 p -> main_category = strdup ( pnd_pxml_get_primary_category ( pxmlh ) );
107 p -> clockspeed = strdup ( pnd_pxml_get_clockspeed ( pxmlh ) );
112 pnd_pxml_delete ( pxmlh );
115 } else if ( valid == 2 ) {
119 return ( 0 ); // continue the tree walk
122 pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ) {
124 //printf ( "Searchpath to discover: '%s'\n", searchpath );
126 // alloc a container for the result set
127 disco_box = pnd_box_new ( "discovery" );
128 disco_overrides = overridespath;
130 /* iterate across the paths within the searchpath, attempting to locate applications
136 // invoke the dir walking function; thankfully Linux includes a pretty good one
137 nftw ( buffer, // path to descend
138 pnd_disco_callback, // callback to do processing
139 10, // no more than X open fd's at once
140 FTW_PHYS ); // do not follow symlinks
145 // return whatever we found, or NULL if nada
146 if ( ! pnd_box_get_head ( disco_box ) ) {
147 pnd_box_delete ( disco_box );
151 return ( disco_box );
154 unsigned char pnd_emit_dotdesktop ( char *targetpath, pnd_disco_t *p ) {
155 char filename [ FILENAME_MAX ];
156 char buffer [ 1024 ];
160 // http://standards.freedesktop.org/desktop-entry-spec
164 if ( ! p -> unique_id ) {
174 sprintf ( filename, "%s/%s.desktop", targetpath, p -> unique_id );
178 f = fopen ( filename, "w" );
184 if ( p -> title_en ) {
185 snprintf ( buffer, 1020, "Name=%s\n", p -> title_en );
186 fprintf ( f, "%s", buffer );
189 fprintf ( f, "Type=Application\n" );
190 fprintf ( f, "Version=1.0\n" );
193 snprintf ( buffer, 1020, "Icon=%s\n", p -> icon );
194 fprintf ( f, "%s", buffer );
197 if ( p -> description_en ) {
198 snprintf ( buffer, 1020, "Comment=%s\n", p -> description_en );
199 fprintf ( f, "%s", buffer );
202 if ( p -> startdir ) {
203 snprintf ( buffer, 1020, "Path=%s\n", p -> startdir );
204 fprintf ( f, "%s", buffer );
206 fprintf ( f, "Path=%s\n", PND_DEFAULT_WORKDIR );
210 snprintf ( buffer, 1020, "Exec=%s\n", p -> exec );
211 fprintf ( f, "%s", buffer );