pndnotifyd: fix some crashes
[pandora-libraries.git] / lib / pnd_pathiter.h
1
2 #ifndef h_pnd_pathiter_h
3 #define h_pnd_pathiter_h
4
5 // man don'y you wish it was python, perl or c++ right about now?
6 // perl: foreach i ( split ( ':', path ) ) would be sauce right now
7
8 // for wordexp(); nice thign to have bundled into libc!
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <wordexp.h>
12 // for stat()
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16 #include <ctype.h> // for isdigit()
17
18 // this really should be replaced by a function pair .. one to
19 // start a new search and one to go to next, bailing when done. Maybe
20 // a state struct. Like we have time. OR perhaps just a single
21 // func with a callback. Whatever.
22
23
24 // will be set to 0xFFFF for no limit currently set, or a smaller number
25 // if that is the depth limit
26 unsigned int pathiter_depthlimit;
27
28
29 #if 1 // globbing is performed
30
31 // only iterates actual existing paths; if you want to return
32 // non-matching paths, see below
33
34 #define SEARCHPATH_PRE                            \
35   char *end, *colon;                              \
36   char *head = searchpath;                        \
37   char chunk [ FILENAME_MAX ];                    \
38   char *lt;                                       \
39                                                   \
40   /*fprintf ( stderr, "sp %s\n", searchpath );*/  \
41                                                   \
42   while ( 1 ) {                                   \
43     colon = strchr ( head, ':' );                 \
44     end = strchr ( head, '\0' );                  \
45                                                   \
46     if ( colon && colon < end ) {                 \
47       memset ( chunk, '\0', FILENAME_MAX );       \
48       strncpy ( chunk, head, colon - head );      \
49     } else {                                      \
50       strncpy ( chunk, head, FILENAME_MAX - 1 );  \
51     }                                             \
52                                                   \
53     pathiter_depthlimit = 0xFFFF;                 \
54                                                   \
55     if ( ( lt = strchr ( chunk, '<' ) ) ) {       \
56       if ( isdigit ( *(lt+1) ) ) {                \
57         pathiter_depthlimit = atoi ( lt + 1 );    \
58       }                                           \
59       *lt = '\0';                                 \
60     }                                             \
61                                                   \
62     /*fprintf ( stderr, "-> chunk %s limit %d\n", chunk, pathiter_depthlimit );*/ \
63                                                   \
64     struct stat statbuf;                          \
65     wordexp_t _p;                                 \
66     char **_w;                                    \
67     int _i;                                       \
68     char buffer [ FILENAME_MAX ];                 \
69                                                   \
70     if ( wordexp ( chunk, &_p, 0 ) != 0 ) {       \
71       /* ignore this chunk I guess.. */           \
72     } else {                                      \
73       _w = _p.we_wordv;                           \
74                                                   \
75       for ( _i=0; _i < _p.we_wordc; _i++ ) {      \
76         strcpy ( buffer, _w [ _i ] );             \
77         /*fprintf ( stderr, "glob %s\n", buffer );*/    \
78         if ( ( stat ( buffer, &statbuf ) == 0 )   \
79           && ( S_ISDIR(statbuf.st_mode) ) )       \
80         { /* user code */
81
82 #define SEARCHPATH_POST                           \
83         } /* user code */                         \
84       } /* for each glob result */                \
85       wordfree ( &_p );                           \
86     } /* if wordexp succeeds */                   \
87     /* next search path */                        \
88     if ( colon && colon < end ) {                 \
89       head = colon + 1;                           \
90     } else {                                      \
91       break; /* done! */                          \
92     }                                             \
93                                                   \
94   } // while
95
96
97 // the following will return even non-matching chunks, but is not doing wordexp() expansion on it
98
99 #define SEARCHCHUNK_PRE                           \
100   char *end, *colon;                              \
101   char *head = searchpath;                        \
102   char chunk [ FILENAME_MAX ];                    \
103                                                   \
104   /*fprintf ( stderr, "sp %s\n", searchpath );*/  \
105                                                   \
106   while ( 1 ) {                                   \
107     colon = strchr ( head, ':' );                 \
108     end = strchr ( head, '\0' );                  \
109                                                   \
110     if ( colon && colon < end ) {                 \
111       memset ( chunk, '\0', FILENAME_MAX );       \
112       strncpy ( chunk, head, colon - head );      \
113     } else {                                      \
114       strncpy ( chunk, head, FILENAME_MAX - 1 );  \
115     }                                             \
116                                                   \
117     /*fprintf ( stderr, "-> %s\n", chunk ); */    \
118                                                   \
119     char buffer [ FILENAME_MAX ];                 \
120                                                   \
121     strcpy ( buffer, chunk );                     \
122     /*fprintf ( stderr, "glob %s\n", buffer );*/  \
123     { /* user code */
124
125 #define SEARCHCHUNK_POST                          \
126     } /* user code */                             \
127     /* next search path */                        \
128     if ( colon && colon < end ) {                 \
129       head = colon + 1;                           \
130     } else {                                      \
131       break; /* done! */                          \
132     }                                             \
133                                                   \
134   } // while
135
136
137 #endif // globbing is done
138
139
140 #if 0 // deprecated simple (no globbing/expansion)
141
142 #define SEARCHPATH_PRE                            \
143   char *end, *colon;                              \
144   char *head = searchpath;                        \
145   char buffer [ FILENAME_MAX ];                   \
146                                                   \
147   while ( 1 ) {                                   \
148     colon = strchr ( head, ':' );                 \
149     end = strchr ( head, '\0' );                  \
150                                                   \
151     if ( colon && colon < end ) {                 \
152       memset ( buffer, '\0', FILENAME_MAX );      \
153       strncpy ( buffer, head, colon - head );     \
154     } else {                                      \
155       strncpy ( buffer, head, FILENAME_MAX - 1 ); \
156     }                                             \
157                                                   \
158     //printf ( "Path to search: '%s'\n", buffer );
159
160 #define SEARCHPATH_POST                           \
161     /* next search path */                        \
162     if ( colon && colon < end ) {                 \
163       head = colon + 1;                           \
164     } else {                                      \
165       break; /* done! */                          \
166     }                                             \
167                                                   \
168   } // while
169
170 #endif // deprecated simple
171
172
173 #endif // #ifndef