3 #include <limits.h> /* for PATH_MAX */
4 #define __USE_GNU /* for strndup */
5 #include <string.h> /* for strdup */
6 #include <stdlib.h> /* getenv */
8 #include "pnd_container.h"
10 #include "pnd_discovery.h"
11 #include "pnd_notify.h"
12 #include "pnd_dbusnotify.h"
13 #include "pnd_logger.h"
16 #include "mmcustom_cats.h"
18 mmcustom_cat_t mmcustom_complete [ MMCUSTOM_CATS_MAX ];
19 unsigned int mmcustom_count = 0;
21 pnd_conf_handle g_custom_h = 0;
23 char *mmcustom_determine_path ( void ) {
24 char *home = getenv ( "HOME" );
25 static char path [ PATH_MAX ];
26 bzero ( path, PATH_MAX );
28 snprintf ( path, PATH_MAX - 1, "%s/%s", home ? home : ".", MMCUSTOM_CATS_PREF_FILENAME );
33 static unsigned char loaded = 0;
34 unsigned char mmcustom_setup ( void ) {
40 char *path = mmcustom_determine_path();
42 g_custom_h = pnd_conf_fetch_by_path ( path );
45 pnd_log ( pndn_rem, "Custom category conf file %s not found; is okay.\n", path );
46 return ( 1 ); // file does not exist most likely
49 // find its head; if no head (empty file), bail
50 char *iter = pnd_box_get_head ( g_custom_h );
53 pnd_log ( pndn_rem, "Custom category conf file %s is empty. Fine.\n", path );
57 // walk the conf, plucking out the values
59 char *k = pnd_box_get_key ( iter );
61 // does this entry look like it is a custom category?
62 if ( strncmp ( k, MMCUSTOM_CATS_SECTION, strlen ( MMCUSTOM_CATS_SECTION ) ) == 0 ) {
63 // determine the actual category name part
64 k += ( strlen ( MMCUSTOM_CATS_SECTION ) + 1 );
66 mmcustom_complete [ mmcustom_count ].cat = strdup ( k );
67 if ( iter && strcmp ( iter, MMCUSTOM_CATS_NOCAT ) != 0 ) {
68 mmcustom_complete [ mmcustom_count ].parent_cat = strdup ( iter );
70 mmcustom_complete [ mmcustom_count ].parent_cat = NULL;
78 iter = pnd_box_get_next ( iter );
82 pnd_log ( pndn_rem, "Found %u custom categories.\n", mmcustom_count );
89 void mmcustom_shutdown ( void ) {
91 bzero ( mmcustom_complete, sizeof(mmcustom_cat_t) * MMCUSTOM_CATS_MAX );
98 unsigned char mmcustom_write ( char *fullpath /* if NULL, uses canonical location */ ) {
101 fullpath = mmcustom_determine_path();
104 FILE *f = fopen ( fullpath, "w" );
111 for ( i = 0; i < mmcustom_count; i++ ) {
112 if ( mmcustom_complete [ i ].cat ) {
113 fprintf ( f, "%s.%s\t%s\n", MMCUSTOM_CATS_SECTION, mmcustom_complete [ i ].cat, mmcustom_complete [ i ].parent_cat ? mmcustom_complete [ i ].parent_cat : MMCUSTOM_CATS_NOCAT );
122 mmcustom_cat_t *mmcustom_query ( char *name, char *parentcatname ) {
125 // search for the cat/parent combination
126 for ( i = 0; i < mmcustom_count; i++ ) {
127 mmcustom_cat_t *p = &(mmcustom_complete [ i ]);
129 if ( strcasecmp ( p -> cat, name ) == 0 ) {
131 if ( parentcatname == NULL && p -> parent_cat == NULL ) {
133 } else if ( parentcatname && p -> parent_cat && strcasecmp ( p -> parent_cat, parentcatname ) == 0 ) {
144 mmcustom_cat_t *mmcustom_register ( char *catname, char *parentcatname ) {
145 mmcustom_complete [ mmcustom_count ].cat = strdup ( catname );
146 if ( parentcatname ) {
147 mmcustom_complete [ mmcustom_count ].parent_cat = strdup ( parentcatname );
150 return ( &(mmcustom_complete [ mmcustom_count - 1 ]) );
153 unsigned int mmcustom_count_subcats ( char *catname ) {
155 unsigned int counter = 0;
157 for ( i = 0; i < mmcustom_count; i++ ) {
159 if ( mmcustom_complete [ i ].parent_cat && strcasecmp ( mmcustom_complete [ i ].parent_cat, catname ) == 0 ) {
168 void mmcustom_unregister ( char *catname, char *parentcatname ) {
170 int parent_index = -1;
172 if ( parentcatname ) {
173 pnd_log ( pndn_warning, "Goal: Remove subcat %s of %s\n", catname, parentcatname );
175 pnd_log ( pndn_warning, "Goal: Remove parent cat %s and descendants\n", catname );
178 for ( i = 0; i < mmcustom_count; i++ ) {
180 // killing a parent cat, or just a subcat?
181 if ( parentcatname ) {
183 // killing a subcat, so match cat+subcat to kill
184 if ( mmcustom_complete [ i ].cat && strcmp ( mmcustom_complete [ i ].cat, catname ) == 0 &&
185 mmcustom_complete [ i ].parent_cat && strcasecmp ( mmcustom_complete [ i ].parent_cat, parentcatname ) == 0 )
187 pnd_log ( pndn_warning, " Removing subcat: %s of %s\n", catname, parentcatname );
188 free ( mmcustom_complete [ i ].cat );
189 mmcustom_complete [ i ].cat = NULL;
195 // killing a parent cat, so kill it, and any children of it
196 if ( mmcustom_complete [ i ].parent_cat == NULL &&
197 mmcustom_complete [ i ].cat &&
198 strcmp ( mmcustom_complete [ i ].cat, catname ) == 0 )
200 // flag the prent for future death (we need its name for now, since the caller is using it)
203 else if ( mmcustom_complete [ i ].cat &&
204 mmcustom_complete [ i ].parent_cat &&
205 strcmp ( mmcustom_complete [ i ].parent_cat, catname ) == 0 )
207 // kill children of it
208 pnd_log ( pndn_warning, " Removing cascading subcat: %s of %s\n", mmcustom_complete [ i ].cat, mmcustom_complete [ i ].parent_cat );
209 free ( mmcustom_complete [ i ].cat );
210 mmcustom_complete [ i ].cat = NULL;
217 // kill the actual cat itself
219 pnd_log ( pndn_warning, " Removing cat: %s\n", catname );
220 free ( mmcustom_complete [ i ].cat );
221 mmcustom_complete [ i ].cat = NULL;