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>
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.
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.
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.
33 #include <sys/types.h>
35 #include <curl/curl.h>
36 #include <libxml/xmlmemory.h>
37 #include <libxml/parser.h>
38 #include <libxml/tree.h>
45 typedef int (*config_function_callback)(struct session *session, char *value);
47 struct config_function {
49 config_function_callback callback;
55 * Read a line from the config file and assign it a key and a value.
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...
62 static int get_key(struct session *session, char *line, char **key, char **value)
69 if (linepos == NULL || linepos[0] == '\0')
73 while (isspace(linepos[0]) || linepos[0] == ',')
75 if (linepos[0] == '\0')
82 if (linepos[0] == '\0')
84 if (isspace(linepos[0]))
86 if (linepos[0] == '=')
90 /* remember the end of the key */
93 /* skip whitespace after key */
94 while (isspace(linepos[0]))
96 if (linepos[0] == '\0')
99 /* make sure this is a = operation */
101 * udev likes to check for += and == and lots of other complex
102 * assignments that we don't care about.
104 if (linepos[0] == '=')
112 /* skip whitespace after opearator */
113 while (isspace(linepos[0]))
115 if (linepos[0] == '\0')
119 * if the value is quoted, then terminate on a ", otherwise space is
122 if (linepos[0] == '"') {
132 temp = strchr(linepos, terminator);
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
143 printf("%s = %s\n", *key, *value);
147 static int session_string(char **field, char *value)
151 string = strdup(value);
161 static int session_bool(int *field, char *value)
163 if ((strncasecmp(value, "true", 4) == 0) ||
164 strncasecmp(value, "yes", 3) == 0)
169 static int account_callback(struct session *session, char *value)
171 return session_string(&session->account, value);
174 static int password_callback(struct session *session, char *value)
176 return session_string(&session->password, value);
179 static int proxy_callback(struct session *session, char *value)
181 return session_string(&session->proxy, value);
184 static int user_callback(struct session *session, char *value)
186 return session_string(&session->user, value);
189 static int consumer_key_callback(struct session *session, char *value)
191 return session_string(&session->consumer_key, value);
194 static int consumer_secret_callback(struct session *session, char *value)
196 return session_string(&session->consumer_secret, value);
199 static int access_token_key_callback(struct session *session, char *value)
201 return session_string(&session->access_token_key, value);
204 static int access_token_secret_callback(struct session *session, char *value)
206 return session_string(&session->access_token_secret, value);
209 static int logfile_callback(struct session *session, char *value)
211 return session_string(&session->logfile, value);
214 static int replyto_callback(struct session *session, char *value)
216 return session_string(&session->replyto, value);
219 static int retweet_callback(struct session *session, char *value)
221 return session_string(&session->retweet, value);
224 static int host_callback(struct session *session, char *value)
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);
235 session->host = HOST_CUSTOM;
236 session->hosturl = strdup(value);
237 session->hostname = strdup(value);
242 static int action_callback(struct session *session, char *value)
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;
257 session->action= ACTION_UNKNOWN;
261 static int verbose_callback(struct session *session, char *value)
263 return session_bool(&session->verbose, value);
266 static int shrink_urls_callback(struct session *session, char *value)
268 return session_bool(&session->shrink_urls, value);
272 * List of all of the config file options.
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.
277 * Make sure the table is NULL terminated, otherwise bad things will happen.
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 },
298 void process_line(struct session *session, char *key, char *value)
300 struct config_function *item;
303 if (key == NULL || value == NULL)
306 item = &config_table[0];
308 if (item->key == NULL || item->callback == NULL)
311 if (strncasecmp(item->key, key, strlen(item->key)) == 0) {
312 printf("calling %p, for key = '%s' and value = '%s'\n", item->callback, key, value);
313 result = item->callback(session, value);
321 void bti_parse_configfile(struct session *session)
331 config_file = fopen(session->configfile, "r");
333 /* No error if file does not exist or is unreadable. */
334 if (config_file == NULL)
338 n = getline(&line, &len, config_file);
341 if (line[n - 1] == '\n')
344 /* '#' is comment markers, like bash style */
345 *strchrnul(line, '#') = '\0';
349 /* Ignore blank lines. */
353 /* parse the line into a key and value pair */
354 get_key(session, c, &key, &value);
356 process_line(session, key, value);
357 } while (!feof(config_file));
359 /* Free buffer and close file. */