/[debian]/bti/branches/upstream/current/config.c
ViewVC logotype

Annotation of /bti/branches/upstream/current/config.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2707 - (hide annotations)
Fri Dec 2 23:53:57 2011 UTC (9 years, 9 months ago) by gregoa
File MIME type: text/plain
File size: 9402 byte(s)
[svn-upgrade] new version bti (032)
1 gregoa 2336 /*
2     * Copyright (C) 2008-2011 Greg Kroah-Hartman <greg@kroah.com>
3     * Copyright (C) 2009 Bart Trojanowski <bart@jukie.net>
4     * Copyright (C) 2009-2010 Amir Mohammad Saied <amirsaied@gmail.com>
5     *
6     * This program is free software; you can redistribute it and/or modify it
7     * under the terms of the GNU General Public License as published by the
8     * Free Software Foundation version 2 of the License.
9     *
10     * This program is distributed in the hope that it will be useful, but
11     * WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     * General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License along
16     * with this program; if not, write to the Free Software Foundation, Inc.,
17     * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18     */
19    
20     #define _GNU_SOURCE
21    
22     #include <stdio.h>
23     #include <stdlib.h>
24     #include <stddef.h>
25     #include <string.h>
26     #include <getopt.h>
27     #include <errno.h>
28     #include <ctype.h>
29     #include <fcntl.h>
30     #include <unistd.h>
31     #include <time.h>
32     #include <sys/stat.h>
33     #include <sys/types.h>
34     #include <sys/wait.h>
35     #include <curl/curl.h>
36     #include <libxml/xmlmemory.h>
37     #include <libxml/parser.h>
38     #include <libxml/tree.h>
39     #include <pcre.h>
40     #include <termios.h>
41     #include <dlfcn.h>
42     #include <oauth.h>
43     #include "bti.h"
44    
45 gregoa 2449 typedef int (*config_function_callback)(struct session *session, char *value);
46    
47     struct config_function {
48     const char *key;
49     config_function_callback callback;
50     };
51    
52     /*
53     * get_key function
54     *
55     * Read a line from the config file and assign it a key and a value.
56     *
57     * This logic taken almost identically from taken from udev's rule file parsing
58     * logic in the file udev-rules.c, written by Kay Sievers and licensed under
59     * the GPLv2+. I hate writing parsers, so it makes sense to borrow working
60     * logic from those smarter than I...
61     */
62     static int get_key(struct session *session, char *line, char **key, char **value)
63     {
64     char *linepos;
65     char *temp;
66     char terminator;
67    
68     linepos = line;
69     if (linepos == NULL || linepos[0] == '\0')
70     return -1;
71    
72     /* skip whitespace */
73     while (isspace(linepos[0]) || linepos[0] == ',')
74     linepos++;
75     if (linepos[0] == '\0')
76     return -1;
77    
78     *key = linepos;
79    
80     for (;;) {
81     linepos++;
82     if (linepos[0] == '\0')
83     return -1;
84     if (isspace(linepos[0]))
85     break;
86     if (linepos[0] == '=')
87     break;
88     }
89    
90     /* remember the end of the key */
91     temp = linepos;
92    
93     /* skip whitespace after key */
94     while (isspace(linepos[0]))
95     linepos++;
96     if (linepos[0] == '\0')
97     return -1;
98    
99     /* make sure this is a = operation */
100     /*
101     * udev likes to check for += and == and lots of other complex
102     * assignments that we don't care about.
103     */
104     if (linepos[0] == '=')
105     linepos++;
106     else
107     return -1;
108    
109     /* terminate key */
110     temp[0] = '\0';
111    
112     /* skip whitespace after opearator */
113     while (isspace(linepos[0]))
114     linepos++;
115     if (linepos[0] == '\0')
116     return -1;
117    
118     /*
119     * if the value is quoted, then terminate on a ", otherwise space is
120     * the terminator.
121     * */
122     if (linepos[0] == '"') {
123     terminator = '"';
124     linepos++;
125     } else
126     terminator = ' ';
127    
128     /* get the value */
129     *value = linepos;
130    
131     /* terminate */
132     temp = strchr(linepos, terminator);
133     if (temp) {
134     temp[0] = '\0';
135     temp++;
136     } else {
137     /*
138     * perhaps we just hit the end of the line, so there would not
139     * be a terminator, so just use the whole rest of the string as
140     * the value.
141     */
142     }
143     /* printf("%s = %s\n", *key, *value); */
144     return 0;
145     }
146    
147     static int session_string(char **field, char *value)
148     {
149     char *string;
150    
151     string = strdup(value);
152     if (string) {
153     if (*field)
154     free(*field);
155     *field = string;
156     return 0;
157     }
158     return -1;
159     }
160    
161     static int session_bool(int *field, char *value)
162     {
163     if ((strncasecmp(value, "true", 4) == 0) ||
164     strncasecmp(value, "yes", 3) == 0)
165     *field = 1;
166     return 0;
167     }
168    
169     static int account_callback(struct session *session, char *value)
170     {
171     return session_string(&session->account, value);
172     }
173    
174     static int password_callback(struct session *session, char *value)
175     {
176     return session_string(&session->password, value);
177     }
178    
179     static int proxy_callback(struct session *session, char *value)
180     {
181     return session_string(&session->proxy, value);
182     }
183    
184     static int user_callback(struct session *session, char *value)
185     {
186     return session_string(&session->user, value);
187     }
188    
189     static int consumer_key_callback(struct session *session, char *value)
190     {
191     return session_string(&session->consumer_key, value);
192     }
193    
194     static int consumer_secret_callback(struct session *session, char *value)
195     {
196     return session_string(&session->consumer_secret, value);
197     }
198    
199     static int access_token_key_callback(struct session *session, char *value)
200     {
201     return session_string(&session->access_token_key, value);
202     }
203    
204     static int access_token_secret_callback(struct session *session, char *value)
205     {
206     return session_string(&session->access_token_secret, value);
207     }
208    
209     static int logfile_callback(struct session *session, char *value)
210     {
211     return session_string(&session->logfile, value);
212     }
213    
214     static int replyto_callback(struct session *session, char *value)
215     {
216     return session_string(&session->replyto, value);
217     }
218    
219     static int retweet_callback(struct session *session, char *value)
220     {
221     return session_string(&session->retweet, value);
222     }
223    
224     static int host_callback(struct session *session, char *value)
225     {
226     if (strcasecmp(value, "twitter") == 0) {
227     session->host = HOST_TWITTER;
228     session->hosturl = strdup(twitter_host);
229     session->hostname = strdup(twitter_name);
230     } else if (strcasecmp(value, "identica") == 0) {
231     session->host = HOST_IDENTICA;
232     session->hosturl = strdup(identica_host);
233     session->hostname = strdup(identica_name);
234     } else {
235     session->host = HOST_CUSTOM;
236     session->hosturl = strdup(value);
237     session->hostname = strdup(value);
238     }
239     return 0;
240     }
241    
242     static int action_callback(struct session *session, char *value)
243     {
244     if (strcasecmp(value, "update") == 0)
245     session->action = ACTION_UPDATE;
246     else if (strcasecmp(value, "friends") == 0)
247     session->action = ACTION_FRIENDS;
248     else if (strcasecmp(value, "user") == 0)
249     session->action = ACTION_USER;
250     else if (strcasecmp(value, "replies") == 0)
251     session->action = ACTION_REPLIES;
252     else if (strcasecmp(value, "public") == 0)
253     session->action = ACTION_PUBLIC;
254     else if (strcasecmp(value, "group") == 0)
255     session->action = ACTION_GROUP;
256     else
257     session->action= ACTION_UNKNOWN;
258     return 0;
259     }
260    
261     static int verbose_callback(struct session *session, char *value)
262     {
263     return session_bool(&session->verbose, value);
264     }
265    
266     static int shrink_urls_callback(struct session *session, char *value)
267     {
268     return session_bool(&session->shrink_urls, value);
269     }
270    
271     /*
272     * List of all of the config file options.
273     *
274     * To add a new option, just add a string for the key name, and the callback
275     * function that will be called with the value read from the config file.
276     *
277     * Make sure the table is NULL terminated, otherwise bad things will happen.
278     */
279     static struct config_function config_table[] = {
280     { "account", account_callback },
281     { "password", password_callback },
282     { "proxy", proxy_callback },
283     { "user", user_callback },
284     { "consumer_key", consumer_key_callback },
285     { "consumer_secret", consumer_secret_callback },
286     { "access_token_key", access_token_key_callback },
287     { "access_token_secret", access_token_secret_callback },
288     { "logfile", logfile_callback },
289     { "replyto", replyto_callback },
290     { "retweet", retweet_callback },
291     { "host", host_callback },
292     { "action", action_callback },
293     { "verbose", verbose_callback },
294     { "shrink-urls", shrink_urls_callback },
295     { NULL, NULL }
296     };
297    
298     static void process_line(struct session *session, char *key, char *value)
299     {
300     struct config_function *item;
301     int result;
302    
303     if (key == NULL || value == NULL)
304     return;
305    
306     item = &config_table[0];
307     for (;;) {
308     if (item->key == NULL || item->callback == NULL)
309     break;
310    
311     if (strncasecmp(item->key, key, strlen(item->key)) == 0) {
312     /*
313     * printf("calling %p, for key = '%s' and value = * '%s'\n",
314     * item->callback, key, value);
315     */
316     result = item->callback(session, value);
317     if (!result)
318     return;
319     }
320     item++;
321     }
322     }
323    
324 gregoa 2336 void bti_parse_configfile(struct session *session)
325     {
326     FILE *config_file;
327     char *line = NULL;
328 gregoa 2449 char *key = NULL;
329     char *value = NULL;
330 gregoa 2455 char *hashmarker;
331 gregoa 2336 size_t len = 0;
332 gregoa 2449 ssize_t n;
333     char *c;
334 gregoa 2336
335     config_file = fopen(session->configfile, "r");
336    
337     /* No error if file does not exist or is unreadable. */
338     if (config_file == NULL)
339     return;
340    
341     do {
342 gregoa 2449 n = getline(&line, &len, config_file);
343 gregoa 2336 if (n < 0)
344     break;
345     if (line[n - 1] == '\n')
346     line[n - 1] = '\0';
347 gregoa 2449
348 gregoa 2455 /*
349     * '#' is comment markers, like bash style but it is a valid
350     * character in some fields, so only treat it as a comment
351     * marker if it occurs at the beginning of the line, or after
352     * whitespace
353     */
354 gregoa 2707 hashmarker = strchr(line, '#');
355 gregoa 2455 if (line == hashmarker)
356     line[0] = '\0';
357     else {
358 gregoa 2707 while (hashmarker != NULL) {
359 gregoa 2455 --hashmarker;
360 gregoa 2707 if (isblank(hashmarker[0])) {
361 gregoa 2455 hashmarker[0] = '\0';
362 gregoa 2707 break;
363     } else {
364 gregoa 2455 /*
365     * false positive; '#' occured
366     * within a string
367     */
368 gregoa 2707 hashmarker = strchr(hashmarker+2, '#');
369 gregoa 2455 }
370     }
371     }
372 gregoa 2449 c = line;
373 gregoa 2336 while (isspace(*c))
374     c++;
375     /* Ignore blank lines. */
376     if (c[0] == '\0')
377     continue;
378    
379 gregoa 2449 /* parse the line into a key and value pair */
380     get_key(session, c, &key, &value);
381    
382     process_line(session, key, value);
383 gregoa 2336 } while (!feof(config_file));
384    
385     /* Free buffer and close file. */
386     free(line);
387     fclose(config_file);
388     }
389    

  ViewVC Help
Powered by ViewVC 1.1.26