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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2449 - (show annotations)
Fri Mar 18 11:13:50 2011 UTC (9 years, 7 months ago) by gregoa
File MIME type: text/plain
File size: 8887 byte(s)
[svn-upgrade] new version bti (030)
1 /*
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 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)
325 {
326 FILE *config_file;
327 char *line = NULL;
328 char *key = NULL;
329 char *value = NULL;
330 size_t len = 0;
331 ssize_t n;
332 char *c;
333
334 config_file = fopen(session->configfile, "r");
335
336 /* No error if file does not exist or is unreadable. */
337 if (config_file == NULL)
338 return;
339
340 do {
341 n = getline(&line, &len, config_file);
342 if (n < 0)
343 break;
344 if (line[n - 1] == '\n')
345 line[n - 1] = '\0';
346
347 /* '#' is comment markers, like bash style */
348 *strchrnul(line, '#') = '\0';
349 c = line;
350 while (isspace(*c))
351 c++;
352 /* Ignore blank lines. */
353 if (c[0] == '\0')
354 continue;
355
356 /* parse the line into a key and value pair */
357 get_key(session, c, &key, &value);
358
359 process_line(session, key, value);
360 } while (!feof(config_file));
361
362 /* Free buffer and close file. */
363 free(line);
364 fclose(config_file);
365 }
366

  ViewVC Help
Powered by ViewVC 1.1.26