33#include "log.h"
44#include "util.h"
55
6+ #include <ctype.h>
67#include <errno.h>
78#include <unistd.h>
89#include <sys/stat.h>
@@ -62,8 +63,21 @@ int main(int argc, char **argv)
6263 */
6364 for (int i = 1 ; i < argc ; i ++ ) {
6465 add_arg (& all_argv , & all_argc , argv [i ]);
65- if (!strcmp (argv [i ], "--config" )) {
66- config_path = strdup (argv [i + 1 ]);
66+ if (!strncmp (argv [i ], "--config=" , 9 )) {
67+ if (argv [i ][9 ] == '\0' ) {
68+ lprintf (fatal , "--config requires a path\n" );
69+ }
70+ FREE (config_path );
71+ config_path = STRDUP (argv [i ] + 9 );
72+ } else if (!strcmp (argv [i ], "--config" )) {
73+ if (i + 1 >= argc || argv [i + 1 ][0 ] == '\0'
74+ || argv [i + 1 ][0 ] == '-' ) {
75+ lprintf (fatal , "--config requires a path\n" );
76+ }
77+ FREE (config_path );
78+ config_path = STRDUP (argv [i + 1 ]);
79+ add_arg (& all_argv , & all_argc , argv [i + 1 ]);
80+ i ++ ;
6781 }
6882 }
6983
@@ -176,7 +190,7 @@ static char *get_XDG_CONFIG_HOME(void)
176190
177191 const char * xdg_config_home = getenv ("XDG_CONFIG_HOME" );
178192 if (xdg_config_home ) {
179- config_dir = strndup (xdg_config_home , MAX_PATH_LEN );
193+ config_dir = STRNDUP (xdg_config_home , MAX_PATH_LEN );
180194 } else {
181195 const char * user_home = getenv ("HOME" );
182196 if (user_home ) {
@@ -205,42 +219,54 @@ void parse_config_file(char ***argv, int *argc)
205219 full_path = config_path ;
206220 }
207221
208- /*
209- * The buffer has to be able to fit a URL
210- */
211- int buf_len = MAX_PATH_LEN ;
212- char buf [buf_len ];
222+ char * buf = NULL ;
223+ size_t buf_len = 0 ;
213224 FILE * config = fopen (full_path , "r" );
214- if (config ) {
215- while (fgets (buf , buf_len , config )) {
216- if (buf [0 ] == '-' ) {
217- (* argc )++ ;
218- buf [strnlen (buf , buf_len ) - 1 ] = '\0' ;
219- char * space ;
220- space = strchr (buf , ' ' );
225+ if (!config ) {
226+ if (config_path ) {
227+ lprintf (fatal , "Could not open config file %s: %s\n" , full_path ,
228+ strerror (errno ));
229+ }
230+ } else {
231+ while (getline (& buf , & buf_len , config ) != -1 ) {
232+ // Remove trailing whitespace
233+ size_t len = strlen (buf );
234+ while (len > 0 && isspace ((unsigned char )buf [len - 1 ])) {
235+ buf [-- len ] = '\0' ;
236+ }
237+
238+ char * line = buf ;
239+ while (* line && isspace ((unsigned char )* line )) {
240+ line ++ ;
241+ }
242+
243+ if (line [0 ] == '-' ) {
244+ char * space = strpbrk (line , " \t" );
221245 if (!space ) {
222- * argv = (char * * )realloc ((void * )* argv ,
223- * argc * sizeof (char * ));
224- (* argv )[* argc - 1 ] = strndup (buf , buf_len );
246+ add_arg (argv , argc , line );
225247 } else {
226- (* argc )++ ;
227- * argv = (char * * )realloc ((void * )* argv ,
228- * argc * sizeof (char * ));
248+ * space = '\0' ;
249+ add_arg (argv , argc , line );
229250 /*
230- * Only copy up to the space character
251+ * Starts copying after the space, skipping leading
252+ * whitespace
231253 */
232- (* argv )[* argc - 2 ] = strndup (buf , space - buf );
233- /*
234- * Starts copying after the space
235- */
236- (* argv )[* argc - 1 ]
237- = strndup (space + 1 , buf_len - (space + 1 - buf ));
254+ char * value = space + 1 ;
255+ while (* value && isspace ((unsigned char )* value )) {
256+ value ++ ;
257+ }
258+ if (* value != '\0' ) {
259+ add_arg (argv , argc , value );
260+ }
238261 }
239262 }
240263 }
264+ FREE (buf );
241265 fclose (config );
242266 }
243- FREE (full_path );
267+ if (full_path != config_path ) {
268+ FREE (full_path );
269+ }
244270}
245271
246272static int parse_arg_list (int argc , char * * argv , char * * * fuse_argv ,
@@ -313,24 +339,24 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
313339 add_arg (fuse_argv , fuse_argc , "-s" );
314340 break ;
315341 case 'u' :
316- CONFIG .http_username = strdup (optarg );
342+ CONFIG .http_username = STRDUP (optarg );
317343 break ;
318344 case 'p' :
319- CONFIG .http_password = strdup (optarg );
345+ CONFIG .http_password = STRDUP (optarg );
320346 break ;
321347 case 'P' :
322- CONFIG .proxy = strdup (optarg );
348+ CONFIG .proxy = STRDUP (optarg );
323349 break ;
324350 case 'L' :
325351 /*
326352 * Long options
327353 */
328354 switch (long_index ) {
329355 case 6 :
330- CONFIG .proxy_username = strdup (optarg );
356+ CONFIG .proxy_username = STRDUP (optarg );
331357 break ;
332358 case 7 :
333- CONFIG .proxy_password = strdup (optarg );
359+ CONFIG .proxy_password = STRDUP (optarg );
334360 break ;
335361 case 8 :
336362 CONFIG .cache_enabled = 1 ;
@@ -345,19 +371,19 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
345371 CONFIG .max_conns = (int )strtol (optarg , NULL , 10 );
346372 break ;
347373 case 12 :
348- CONFIG .user_agent = strdup (optarg );
374+ CONFIG .user_agent = STRDUP (optarg );
349375 break ;
350376 case 13 :
351377 CONFIG .http_wait_sec = (int )strtol (optarg , NULL , 10 );
352378 break ;
353379 case 14 :
354- CONFIG .cache_dir = strdup (optarg );
380+ CONFIG .cache_dir = STRDUP (optarg );
355381 break ;
356382 case 15 :
357- CONFIG .sonic_username = strdup (optarg );
383+ CONFIG .sonic_username = STRDUP (optarg );
358384 break ;
359385 case 16 :
360- CONFIG .sonic_password = strdup (optarg );
386+ CONFIG .sonic_password = STRDUP (optarg );
361387 break ;
362388 case 17 :
363389 CONFIG .sonic_id3 = 1 ;
@@ -380,10 +406,10 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
380406 CONFIG .mode = SINGLE ;
381407 break ;
382408 case 23 :
383- CONFIG .cafile = strdup (optarg );
409+ CONFIG .cafile = STRDUP (optarg );
384410 break ;
385411 case 24 :
386- CONFIG .proxy_cafile = strdup (optarg );
412+ CONFIG .proxy_cafile = STRDUP (optarg );
387413 break ;
388414 case 25 :
389415 CONFIG .refresh_timeout = (int )strtol (optarg , NULL , 10 );
@@ -420,11 +446,16 @@ static int parse_arg_list(int argc, char **argv, char ***fuse_argv,
420446 */
421447void add_arg (char * * * fuse_argv_ptr , int * fuse_argc , char * opt_string )
422448{
449+ char * * tmp = (char * * )realloc ((void * )* fuse_argv_ptr ,
450+ ((size_t )* fuse_argc + 1 ) * sizeof (char * ));
451+ if (!tmp ) {
452+ lprintf (fatal , "realloc failed: %s\n" , strerror (errno ));
453+ return ;
454+ }
455+ * fuse_argv_ptr = tmp ;
423456 (* fuse_argc )++ ;
424- * fuse_argv_ptr
425- = (char * * )realloc ((void * )* fuse_argv_ptr , * fuse_argc * sizeof (char * ));
426457 char * * fuse_argv = * fuse_argv_ptr ;
427- fuse_argv [* fuse_argc - 1 ] = strdup (opt_string );
458+ fuse_argv [* fuse_argc - 1 ] = STRDUP (opt_string );
428459}
429460
430461static void print_help (char * program_name , int long_help )
0 commit comments