4 * by JH <jheinonen@users.sourceforge.net>
6 * Copyright (C) Jaakko Heinonen
18 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
33 static void init_abook();
34 static void quit_abook_sig(int i);
35 static void set_filenames();
36 static void parse_command_line(int argc, char **argv);
37 static void show_usage();
38 static void mutt_query(char *str);
39 static void init_mutt_query();
40 static void convert(char *srcformat, char *srcfile,
41 char *dstformat, char *dstfile);
42 static void add_email(int);
44 char *datafile = NULL;
47 int alternative_datafile = FALSE;
48 int alternative_rcfile = FALSE;
55 assert(datafile != NULL);
57 if( (f = fopen(datafile, "a")) == NULL)
71 signal(SIGKILL, quit_abook_sig);
72 signal(SIGTERM, quit_abook_sig);
79 if(!datafile_writeable()) {
80 char *s = mkstr("File %s is not writeable", datafile);
84 if(load_database(datafile) || !statusline_ask_boolean(
85 "If you continue all changes will "
86 "be lost. Do you want to continue?", FALSE)) {
93 load_database(datafile);
101 if( options_get_int("autosave") )
103 else if( statusline_ask_boolean("Save database", TRUE) )
115 quit_abook_sig(int i)
121 main(int argc, char **argv)
123 #if defined(HAVE_SETLOCALE) && defined(HAVE_LOCALE_H)
124 setlocale(LC_ALL, "" );
127 parse_command_line(argc, argv);
151 if( (stat(getenv("HOME"), &s)) == -1 || ! S_ISDIR(s.st_mode) ) {
152 fprintf(stderr,"%s is not a valid HOME directory\n", getenv("HOME") );
157 datafile = strconcat(getenv("HOME"), "/" DATAFILE, NULL);
160 rcfile = strconcat(getenv("HOME"), "/" RCFILE, NULL);
162 atexit(free_filenames);
172 MODE_ADD_EMAIL_QUIET,
178 change_mode(int *current, int mode)
180 if(*current != MODE_CONT) {
181 fprintf(stderr, "Cannot combine options --mutt-query, "
183 "--add-email or --add-email-quiet\n");
191 set_filename(char **var, char *path)
196 assert(*var == NULL); /* or else we probably leak memory */
197 assert(path != NULL);
206 *var = strconcat(cwd, path, NULL);
211 #define set_convert_var(X) do { if(mode != MODE_CONVERT) {\
212 fprintf(stderr, "please use option --%s after --convert option\n",\
213 long_options[option_index].name);\
220 parse_command_line(int argc, char **argv)
222 int mode = MODE_CONT;
223 char *query_string = NULL;
224 char *informat = "abook",
231 int option_index = 0;
243 static struct option long_options[] = {
244 { "help", 0, 0, 'h' },
245 { "add-email", 0, 0, OPT_ADD_EMAIL },
246 { "add-email-quiet", 0, 0, OPT_ADD_EMAIL_QUIET },
247 { "datafile", 1, 0, 'f' },
248 { "mutt-query", 1, 0, OPT_MUTT_QUERY },
249 { "config", 1, 0, 'C' },
250 { "convert", 0, 0, OPT_CONVERT },
251 { "informat", 1, 0, OPT_INFORMAT },
252 { "outformat", 1, 0, OPT_OUTFORMAT },
253 { "infile", 1, 0, OPT_INFILE },
254 { "outfile", 1, 0, OPT_OUTFILE },
255 { "formats", 0, 0, OPT_FORMATS },
259 c = getopt_long(argc, argv, "hC:",
260 long_options, &option_index);
270 change_mode(&mode, MODE_ADD_EMAIL);
272 case OPT_ADD_EMAIL_QUIET:
273 change_mode(&mode, MODE_ADD_EMAIL_QUIET);
276 set_filename(&datafile, optarg);
277 alternative_datafile = TRUE;
280 query_string = optarg;
281 change_mode(&mode, MODE_QUERY);
284 set_filename(&rcfile, optarg);
285 alternative_rcfile = TRUE;
288 change_mode(&mode, MODE_CONVERT);
291 set_convert_var(informat);
294 set_convert_var(outformat);
297 set_convert_var(infile);
300 set_convert_var(outfile);
311 fprintf(stderr, "%s: unrecognized arguments on command line\n",
319 case MODE_ADD_EMAIL_QUIET:
322 mutt_query(query_string);
324 convert(informat, infile, outformat, outfile);
332 puts (PACKAGE " v " VERSION "\n");
333 puts (" -h --help show usage");
334 puts (" -C --config <file> use an alternative configuration file");
335 puts (" --datafile <file> use an alternative addressbook file");
336 puts (" --mutt-query <string> make a query for mutt");
337 puts (" --add-email "
338 "read an e-mail message from stdin and\n"
340 "add the sender to the addressbook");
341 puts (" --add-email-quiet "
342 "same as --add-email but doesn't\n"
345 puts (" --convert convert address book files");
346 puts (" options to use with --convert:");
347 puts (" --informat <format> format for input file");
348 puts (" (default: abook)");
349 puts (" --infile <file> source file");
350 puts (" (default: stdin)");
351 puts (" --outformat <format> format for output file");
352 puts (" (default: text)");
353 puts (" --outfile <file> destination file");
354 puts (" (default: stdout)");
355 puts (" --formats list available formats");
362 extern list_item *database;
365 quit_mutt_query(int status)
374 muttq_print_item(FILE *file, int item)
376 char emails[MAX_EMAILS][MAX_EMAIL_LEN];
379 split_emailstr(item, emails);
381 for(i = 0; i < (options_get_int("mutt_return_all_emails") ?
382 MAX_EMAILS : 1) ; i++)
384 fprintf(file, "%s\t%s\t%s\n", emails[i],
385 database[item][NAME],
386 database[item][NOTES] == NULL ? " " :
387 database[item][NOTES]
392 mutt_query(char *str)
396 if( str == NULL || !strcasecmp(str, "all") ) {
397 struct db_enumerator e = init_db_enumerator(ENUM_ALL);
398 printf("All items\n");
399 db_enumerate_items(e)
400 muttq_print_item(stdout, e.item);
402 int search_fields[] = {NAME, EMAIL, NICK, -1};
404 if( (i = find_item(str, 0, search_fields)) < 0 ) {
405 printf("Not found\n");
410 muttq_print_item(stdout, i);
411 i = find_item(str, i+1, search_fields);
424 if( load_database(datafile) ) {
425 printf("Cannot open database\n");
433 make_mailstr(int item)
435 char email[MAX_EMAIL_LEN];
437 char *name = mkstr("\"%s\"", database[item][NAME]);
439 get_first_email(email, item);
441 ret = *database[item][EMAIL] ?
442 mkstr("%s <%s>", name, email) :
451 print_stderr(int item)
453 fprintf (stderr, "%c", '\n');
455 if( is_valid_item(item) )
456 muttq_print_item(stderr, item);
458 struct db_enumerator e = init_db_enumerator(ENUM_SELECTED);
459 db_enumerate_items(e) {
460 muttq_print_item(stderr, e.item);
467 launch_mutt(int item)
469 char *cmd = NULL, *mailstr = NULL;
470 char *mutt_command = options_get_str("mutt_command");
472 if(mutt_command == NULL || !*mutt_command)
475 if( is_valid_item(item) )
476 mailstr = make_mailstr(item);
478 struct db_enumerator e = init_db_enumerator(ENUM_SELECTED);
480 db_enumerate_items(e) {
483 strconcat(tmp, ",", make_mailstr(e.item), NULL):
484 strconcat(make_mailstr(e.item), NULL);
489 cmd = strconcat(mutt_command, " \'", mailstr,
493 fprintf(stderr, "cmd: %s\n", cmd);
499 * we need to make sure that curses settings are correct
505 launch_wwwbrowser(int item)
509 if( !is_valid_item(item) )
512 if( database[item][URL] )
513 cmd = mkstr("%s '%s'",
514 options_get_str("www_command"),
515 safe_str(database[item][URL]));
525 * we need to make sure that curses settings are correct
531 abook_malloc(size_t size)
535 if ( (ptr = malloc(size)) == NULL ) {
536 if( is_ui_initialized() )
538 perror("malloc() failed");
546 abook_realloc(void *ptr, size_t size)
548 ptr = realloc(ptr, size);
554 if( is_ui_initialized() )
556 perror("realloc() failed");
564 abook_fopen (const char *path, const char *mode)
568 if( ! strchr(mode, 'r') )
569 return fopen(path, mode);
571 if ( (stat(path, &s)) == -1 )
574 return S_ISREG(s.st_mode) ? fopen(path, mode) : NULL;
580 convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile)
584 if( !srcformat || !srcfile || !dstformat || !dstfile ) {
585 fprintf(stderr, "too few argumets to make conversion\n");
586 fprintf(stderr, "try --help\n");
590 if( !strcasecmp(srcformat, dstformat) ) {
591 printf( "input and output formats are the same\n"
600 switch( import_file(srcformat, srcfile) ) {
603 "input format %s not supported\n", srcformat);
607 fprintf(stderr, "cannot read file %s\n", srcfile);
613 switch( export_file(dstformat, dstfile) ) {
616 "output format %s not supported\n",
622 "cannot write file %s\n", dstfile);
633 * --add-email handling
636 static int add_email_count = 0;
641 if(add_email_count > 0) {
642 if(save_database() < 0) {
643 fprintf(stderr, "cannot open %s\n", datafile);
646 printf("%d item(s) added to %s\n", add_email_count, datafile);
648 puts("Valid sender address not found");
655 quit_add_email_sig(int signal)
664 atexit(free_filenames);
666 atexit(close_config);
669 * we don't actually care if loading fails or not
671 load_database(datafile);
673 atexit(close_database);
675 signal(SIGINT, quit_add_email_sig);
679 add_email_add_item(int quiet, char *name, char *email)
684 FILE *in = fopen("/dev/tty", "r");
687 fprintf(stderr, "cannot open /dev/tty\n"
688 "you may want to use --add-email-quiet\n");
691 printf("Add ``%s <%s>'' to %s ? (y/n)\n",
698 if(c == 'n' || c == 'N') {
702 } while(c != 'y' && c != 'Y');
706 memset(item, 0, sizeof(item));
707 item[NAME] = strdup(name);
708 item[EMAIL] = strdup(email);
709 add_item2database(item);
718 char *name = NULL, *email = NULL;
723 line = getaline(stdin);
724 if(line && !strncasecmp("From:", line, 5) ) {
725 getname(line, &name, &email);
726 add_email_count += add_email_add_item(quiet,
732 } while( !feof(stdin) );
738 * end of --add-email handling