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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2448 by gregoa, Fri Jan 14 01:14:54 2011 UTC revision 2449 by gregoa, Fri Mar 18 11:13:50 2011 UTC
# Line 42  Line 42 
42  #include <oauth.h>  #include <oauth.h>
43  #include "bti.h"  #include "bti.h"
44    
45    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  void bti_parse_configfile(struct session *session)  void bti_parse_configfile(struct session *session)
325  {  {
326          FILE *config_file;          FILE *config_file;
327          char *line = NULL;          char *line = NULL;
328            char *key = NULL;
329            char *value = NULL;
330          size_t len = 0;          size_t len = 0;
331          char *account = NULL;          ssize_t n;
332          char *password = NULL;          char *c;
         char *consumer_key = NULL;  
         char *consumer_secret = NULL;  
         char *access_token_key = NULL;  
         char *access_token_secret = NULL;  
         char *host = NULL;  
         char *proxy = NULL;  
         char *logfile = NULL;  
         char *action = NULL;  
         char *user = NULL;  
         char *replyto = NULL;  
         char *retweet = NULL;  
         int shrink_urls = 0;  
333    
334          config_file = fopen(session->configfile, "r");          config_file = fopen(session->configfile, "r");
335    
# Line 69  void bti_parse_configfile(struct session Line 338  void bti_parse_configfile(struct session
338                  return;                  return;
339    
340          do {          do {
341                  ssize_t n = getline(&line, &len, config_file);                  n = getline(&line, &len, config_file);
342                  if (n < 0)                  if (n < 0)
343                          break;                          break;
344                  if (line[n - 1] == '\n')                  if (line[n - 1] == '\n')
345                          line[n - 1] = '\0';                          line[n - 1] = '\0';
346                  /* Parse file.  Format is the usual value pairs:  
347                     account=name                  /* '#' is comment markers, like bash style */
                    passwort=value  
                    # is a comment character  
                 */  
348                  *strchrnul(line, '#') = '\0';                  *strchrnul(line, '#') = '\0';
349                  char *c = line;                  c = line;
350                  while (isspace(*c))                  while (isspace(*c))
351                          c++;                          c++;
352                  /* Ignore blank lines.  */                  /* Ignore blank lines.  */
353                  if (c[0] == '\0')                  if (c[0] == '\0')
354                          continue;                          continue;
355    
356                  if (!strncasecmp(c, "account", 7) && (c[7] == '=')) {                  /* parse the line into a key and value pair */
357                          c += 8;                  get_key(session, c, &key, &value);
                         if (c[0] != '\0')  
                                 account = strdup(c);  
                 } else if (!strncasecmp(c, "password", 8) &&  
                            (c[8] == '=')) {  
                         c += 9;  
                         if (c[0] != '\0')  
                                 password = strdup(c);  
                 } else if (!strncasecmp(c, "consumer_key", 12) &&  
                            (c[12] == '=')) {  
                         c += 13;  
                         if (c[0] != '\0')  
                                 consumer_key = strdup(c);  
                 } else if (!strncasecmp(c, "consumer_secret", 15) &&  
                            (c[15] == '=')) {  
                         c += 16;  
                         if (c[0] != '\0')  
                                 consumer_secret = strdup(c);  
                 } else if (!strncasecmp(c, "access_token_key", 16) &&  
                            (c[16] == '=')) {  
                         c += 17;  
                         if (c[0] != '\0')  
                                 access_token_key = strdup(c);  
                 } else if (!strncasecmp(c, "access_token_secret", 19) &&  
                            (c[19] == '=')) {  
                         c += 20;  
                         if (c[0] != '\0')  
                                 access_token_secret = strdup(c);  
                 } else if (!strncasecmp(c, "host", 4) &&  
                            (c[4] == '=')) {  
                         c += 5;  
                         if (c[0] != '\0')  
                                 host = strdup(c);  
                 } else if (!strncasecmp(c, "proxy", 5) &&  
                            (c[5] == '=')) {  
                         c += 6;  
                         if (c[0] != '\0')  
                                 proxy = strdup(c);  
                 } else if (!strncasecmp(c, "logfile", 7) &&  
                            (c[7] == '=')) {  
                         c += 8;  
                         if (c[0] != '\0')  
                                 logfile = strdup(c);  
                 } else if (!strncasecmp(c, "replyto", 7) &&  
                            (c[7] == '=')) {  
                         c += 8;  
                         if (c[0] != '\0')  
                                 replyto = strdup(c);  
                 } else if (!strncasecmp(c, "action", 6) &&  
                            (c[6] == '=')) {  
                         c += 7;  
                         if (c[0] != '\0')  
                                 action = strdup(c);  
                 } else if (!strncasecmp(c, "user", 4) &&  
                                 (c[4] == '=')) {  
                         c += 5;  
                         if (c[0] != '\0')  
                                 user = strdup(c);  
                 } else if (!strncasecmp(c, "shrink-urls", 11) &&  
                                 (c[11] == '=')) {  
                         c += 12;  
                         if (!strncasecmp(c, "true", 4) ||  
                                         !strncasecmp(c, "yes", 3))  
                                 shrink_urls = 1;  
                 } else if (!strncasecmp(c, "verbose", 7) &&  
                                 (c[7] == '=')) {  
                         c += 8;  
                         if (!strncasecmp(c, "true", 4) ||  
                                         !strncasecmp(c, "yes", 3))  
                                 session->verbose = 1;  
                 } else if (!strncasecmp(c,"retweet", 7) &&  
                                 (c[7] == '=')) {  
                         c += 8;  
                         if (c[0] != '\0')  
                                 retweet = strdup(c);  
                 }  
         } while (!feof(config_file));  
358    
359          if (password)                  process_line(session, key, value);
360                  session->password = password;          } while (!feof(config_file));
         if (account)  
                 session->account = account;  
         if (consumer_key)  
                 session->consumer_key = consumer_key;  
         if (consumer_secret)  
                 session->consumer_secret = consumer_secret;  
         if (access_token_key)  
                 session->access_token_key = access_token_key;  
         if (access_token_secret)  
                 session->access_token_secret = access_token_secret;  
         if (host) {  
                 if (strcasecmp(host, "twitter") == 0) {  
                         session->host = HOST_TWITTER;  
                         session->hosturl = strdup(twitter_host);  
                         session->hostname = strdup(twitter_name);  
                 } else if (strcasecmp(host, "identica") == 0) {  
                         session->host = HOST_IDENTICA;  
                         session->hosturl = strdup(identica_host);  
                         session->hostname = strdup(identica_name);  
                 } else {  
                         session->host = HOST_CUSTOM;  
                         session->hosturl = strdup(host);  
                         session->hostname = strdup(host);  
                 }  
                 free(host);  
         }  
         if (proxy) {  
                 if (session->proxy)  
                         free(session->proxy);  
                 session->proxy = proxy;  
         }  
         if (logfile)  
                 session->logfile = logfile;  
         if (replyto)  
                 session->replyto = replyto;  
         if (retweet)  
                 session->retweet = retweet;  
         if (action) {  
                 if (strcasecmp(action, "update") == 0)  
                         session->action = ACTION_UPDATE;  
                 else if (strcasecmp(action, "friends") == 0)  
                         session->action = ACTION_FRIENDS;  
                 else if (strcasecmp(action, "user") == 0)  
                         session->action = ACTION_USER;  
                 else if (strcasecmp(action, "replies") == 0)  
                         session->action = ACTION_REPLIES;  
                 else if (strcasecmp(action, "public") == 0)  
                         session->action = ACTION_PUBLIC;  
                 else if (strcasecmp(action, "group") == 0)  
                         session->action = ACTION_GROUP;  
                 else  
                         session->action = ACTION_UNKNOWN;  
                 free(action);  
         }  
         if (user)  
                 session->user = user;  
         session->shrink_urls = shrink_urls;  
361    
362          /* Free buffer and close file.  */          /* Free buffer and close file.  */
363          free(line);          free(line);
364          fclose(config_file);          fclose(config_file);
365  }  }
366    
   

Legend:
Removed from v.2448  
changed lines
  Added in v.2449

  ViewVC Help
Powered by ViewVC 1.1.26