1 /*
2     HOTKEYS - use keys on your multimedia keyboard to control your computer
3     Copyright (C) 2000,2001  Anthony Y P Wong <ypwong@ypwong.org>
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     $Id: conf.c,v 1.10 2002/11/27 19:30:08 ypwong Exp $
20 */
21 
22 #if HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25 #include "common.h"
26 
27 #include <stdio.h>
28 #include <db.h>
29 #include <string.h>
30 #include <sys/param.h>
31 
32 #include "conf.h"
33 
34 #define DB_VERSION (DB_VERSION_MAJOR*100000+DB_VERSION_MINOR*1000+DB_VERSION_PATCH)
35 
36 char* conf_keys[] = {
37 
38     /* KEY             DEFAULT VALUE           */
39 
40     /* Specify the default keyboard to use */
41     "Kbd",             "\0",
42 
43     /* CDROM device */
44     "CDROM",           "/dev/cdrom",
45 
46     /* general actions */
47     "PrevTrack",       "xmms --rew",
48     "Play",            "xmms --play-pause",
49     "Stop",            "xmms --stop",
50     "Pause",           "xmms --pause",
51     "NextTrack",       "xmms --fwd",
52 /*    "Rewind",          "\0",
53  */
54 
55     "WebBrowser",      "mozilla",
56     "Email",           "mozilla -mail",
57     "Calculator",      "xcalc",
58     "FileManager",     "gmc",
59     "MyComputer",      "gmc",
60     "MyDocuments",     "gmc",
61     "Favorites",       "gnome-moz-remote --remote=openBookmarks",
62     "Transfer",        "gftp",
63     "Record",          "grecord",
64     "Shell",           "xterm -rv",
65     "NewsReader",      "mozilla -news",
66     "ScreenSaver",     "xscreensaver-command -activate",
67     "Communities",     "mozilla -remote 'openURL(http://slashdot.org)'",
68     "Search",          "mozilla -remote 'openURL(http://google.com)'",
69     "Idea",            "mozilla -remote 'openURL(http://sourceforge.net)'",
70     "Shopping",        "mozilla -remote 'openURL(http://thinkgeek.com)'",
71     "Go",              "mozilla -remote 'openURL(http://linux.com)'",
72     "Print",           "lpr",
73     "Messenger",       "gaim",
74     "Webcam",          "\0",
75     "Media",           "xmms",
76 /*
77     "Screendump",      "xwd -root",
78 */
79     /* xosd stuffs */
80 //    "osd_font",        "-*-lucidatypewriter-bold-r-normal-*-*-250-*-*-*-*-*-*",
81     "osd_font",        "lucidasanstypewriter-bold-24",
82     "osd_color",       "LawnGreen",
83     "osd_shadow_color",	"Black",
84     "osd_shadow_offset",	"3",
85     "osd_timeout",     "3",
86     "osd_position",    "bottom",
87     "osd_align",	"center",
88     "osd_hoffset",      "25",
89     "osd_voffset",      "25",
90     "osd_bar_length",	"25",
91     NULL,              NULL
92 };
93 
94 DB *         dbp;
95 
96 /***====================================================================***/
97 
98 char*
getConfig(char * key)99 getConfig(char* key)
100 {
101     DBT     k, data;
102 
103     /* Clear the structures as per db2's documentation
104      * XXX: don't whether this is still needed in db3 */
105     memset( &k, 0, sizeof(k) );
106     memset( &data, 0, sizeof(data) );
107 
108     k.data = key;
109     k.size = strlen(key) + 1;
110 
111     if ( dbp->get(dbp, NULL, &k, &data, 0) == 0 )
112     {
113         return data.data;
114     }
115     else
116     {
117         return NULL;
118     }
119 }
120 
121 int
setConfig(char * key,char * value,u_int32_t flags)122 setConfig(char* key, char* value, u_int32_t flags)
123 {
124     DBT     k, data;
125 
126     /* Clear the structures as per db2's documentation */
127     memset( &k, 0, sizeof(k) );
128     memset( &data, 0, sizeof(data) );
129 
130     k.data = xstrdup(key);
131     k.size = strlen(key) + 1;
132     data.data = xstrdup(value);
133     data.size = strlen(value) + 1;
134 
135     return dbp->put(dbp, NULL, &k, &data, flags);
136 }
137 
138 static void
fillDefaults(void)139 fillDefaults(void)
140 {
141     char** key = conf_keys;
142     int     err;
143 
144     do {
145         err = setConfig(*key, *(key+1), DB_NOOVERWRITE);
146         if ( err != 0 && err != DB_KEYEXIST )
147         {
148             uError("db: put: %s", strerror(errno));
149             bailout();
150         }
151         key += 2;
152     } while ( *key != NULL );
153 }
154 
155 static int
getKey(FILE * fp,char * key)156 getKey(FILE* fp, char* key)
157 {
158     int     c;
159     int     idx=0;
160 
161     while ( (c=fgetc(fp)) != '=' )
162     {
163         if (c == EOF)
164             return -1;
165         else if ( idx == 0 )
166         {
167             if ( c == '#' )
168             {
169                 /* this line is a comment, so we read until the newline */
170                 while ( (c=fgetc(fp)) != '\n' )
171                 {
172                     if (c == EOF)
173                         return -1;
174                 }
175                 return 1;
176             }
177             else if ( c == '\n' || c == ' ' )   /* blank line or empty spaces */
178             {
179                 continue;
180             }
181         }
182         key[idx] = (char)c;
183         if ( ++idx == MAX_KEY_LEN-1 )
184             break;
185     }
186     key[idx] = '\0';
187     return 0;
188 }
189 
190 
191 static int
getValue(FILE * fp,char * value)192 getValue(FILE* fp, char* value)
193 {
194     int     c;
195     int     idx=0;
196 
197     while ( (c=fgetc(fp)) != '\n' )
198     {
199         if (c == EOF)
200             return -1;
201         else
202         {
203             value[idx] = (char)c;
204             if ( ++idx == MAX_VALUE_LEN-1 )
205                 break;
206         }
207     }
208     value[idx] = '\0';
209     return 0;
210 }
211 
212 
213 static void
parseConfigFile(char * filename)214 parseConfigFile(char* filename)
215 {
216     FILE*   fp;
217     char    key[MAX_KEY_LEN];
218     char    keyvalue[MAX_VALUE_LEN];
219     int     r;
220 
221     if ( (fp = fopen( filename, "r" )) != NULL )
222     {
223         while ( !feof(fp) )
224         {
225             r = getKey(fp, key);
226             if ( r == -1 )      /* EOF, etc */
227                 break;
228             else if ( r == 1 )  /* comment */
229                 continue;
230 
231             if ( getValue(fp, keyvalue) == -1 )
232                 break;
233 
234             if ( setConfig( key, keyvalue, 0 ) != 0 )
235             {
236                 uError("db: put: %s", strerror(errno));
237                 bailout();
238             }
239         }
240 
241         fclose(fp);
242     }
243 }
244 
245 
246 void
readConfigFile(void)247 readConfigFile(void)
248 {
249     DB_ENV* dbenv = NULL;
250     int ret;
251 
252     char*   h;
253     char    filename[MAXPATHLEN];
254 
255     dbp = NULL;
256 
257     /* Create the hash table */
258 #if DB_VERSION >= 300000
259     if ( (ret = db_create(&dbp, dbenv, 0)) != 0 )
260     {
261         uError("Failed in db_create: %d", ret);
262         bailout();
263     }
264 #endif
265 
266 #if DB_VERSION >= 401025
267     if ( (ret = dbp->open(dbp, NULL, NULL, NULL, DB_HASH, DB_CREATE, 0664)) != 0 )
268 #elif DB_VERSION >= 300000
269     if ( (ret = dbp->open(dbp, NULL, NULL, DB_HASH, DB_CREATE, 0664)) != 0 )
270 #else
271     if ( (ret = dbp->open(NULL, DB_HASH, DB_CREATE, 0644, NULL, NULL, &dbp)) != 0 )
272 #endif
273     {
274         uError("Can't create hash table: %d", ret);
275         bailout();
276     }
277 
278     fillDefaults();
279 
280     /* parse the global config first */
281     strncpy( filename, CONFDIR, MAXPATHLEN-strlen(CONFIG_NAME)-2 );
282     strcat( filename, "/" );
283     strcat( filename, CONFIG_NAME );
284     if ( testReadable(filename) )
285         parseConfigFile(filename);
286 
287     /* See whether the user has his own config file */
288     if ( (h = getenv("HOME")) != NULL )
289     {
290         strncpy( filename, h, MAXPATHLEN-2-strlen(PACKAGE)-1-strlen(CONFIG_NAME)-1 );
291         strcat( filename, "/." PACKAGE "/" );
292         strcat( filename, CONFIG_NAME );
293         if ( testReadable(filename) )
294             parseConfigFile(filename);
295     }
296 }
297