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_is_ready ( void ) {
102 unsigned char mmcustom_write ( char *fullpath /* if NULL, uses canonical location */ ) {
105 fullpath = mmcustom_determine_path();
108 FILE *f = fopen ( fullpath, "w" );
115 for ( i = 0; i < mmcustom_count; i++ ) {
116 if ( mmcustom_complete [ i ].cat ) {
117 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 );
126 mmcustom_cat_t *mmcustom_query ( char *name, char *parentcatname ) {
129 // search for the cat/parent combination
130 for ( i = 0; i < mmcustom_count; i++ ) {
131 mmcustom_cat_t *p = &(mmcustom_complete [ i ]);
133 if ( strcasecmp ( p -> cat, name ) == 0 ) {
135 if ( parentcatname == NULL && p -> parent_cat == NULL ) {
137 } else if ( parentcatname && p -> parent_cat && strcasecmp ( p -> parent_cat, parentcatname ) == 0 ) {
148 mmcustom_cat_t *mmcustom_register ( char *catname, char *parentcatname ) {
149 mmcustom_complete [ mmcustom_count ].cat = strdup ( catname );
150 if ( parentcatname ) {
151 mmcustom_complete [ mmcustom_count ].parent_cat = strdup ( parentcatname );
154 return ( &(mmcustom_complete [ mmcustom_count - 1 ]) );
157 unsigned int mmcustom_count_subcats ( char *catname ) {
159 unsigned int counter = 0;
161 for ( i = 0; i < mmcustom_count; i++ ) {
163 if ( mmcustom_complete [ i ].parent_cat && strcasecmp ( mmcustom_complete [ i ].parent_cat, catname ) == 0 ) {
172 void mmcustom_unregister ( char *catname, char *parentcatname ) {
174 int parent_index = -1;
176 if ( parentcatname ) {
177 pnd_log ( pndn_warning, "Goal: Remove subcat %s of %s\n", catname, parentcatname );
179 pnd_log ( pndn_warning, "Goal: Remove parent cat %s and descendants\n", catname );
182 for ( i = 0; i < mmcustom_count; i++ ) {
184 // killing a parent cat, or just a subcat?
185 if ( parentcatname ) {
187 // killing a subcat, so match cat+subcat to kill
188 if ( mmcustom_complete [ i ].cat && strcmp ( mmcustom_complete [ i ].cat, catname ) == 0 &&
189 mmcustom_complete [ i ].parent_cat && strcasecmp ( mmcustom_complete [ i ].parent_cat, parentcatname ) == 0 )
191 pnd_log ( pndn_warning, " Removing subcat: %s of %s\n", catname, parentcatname );
192 free ( mmcustom_complete [ i ].cat );
193 mmcustom_complete [ i ].cat = NULL;
199 // killing a parent cat, so kill it, and any children of it
200 if ( mmcustom_complete [ i ].parent_cat == NULL &&
201 mmcustom_complete [ i ].cat &&
202 strcmp ( mmcustom_complete [ i ].cat, catname ) == 0 )
204 // flag the prent for future death (we need its name for now, since the caller is using it)
207 else if ( mmcustom_complete [ i ].cat &&
208 mmcustom_complete [ i ].parent_cat &&
209 strcmp ( mmcustom_complete [ i ].parent_cat, catname ) == 0 )
211 // kill children of it
212 pnd_log ( pndn_warning, " Removing cascading subcat: %s of %s\n", mmcustom_complete [ i ].cat, mmcustom_complete [ i ].parent_cat );
213 free ( mmcustom_complete [ i ].cat );
214 mmcustom_complete [ i ].cat = NULL;
221 // kill the actual cat itself
223 pnd_log ( pndn_warning, " Removing cat: %s\n", catname );
224 free ( mmcustom_complete [ i ].cat );
225 mmcustom_complete [ i ].cat = NULL;