]> git.deb.at Git - pkg/abook.git/blob - abook.c
quit and print command added
[pkg/abook.git] / abook.c
1 /*
2  * $Id$
3  *
4  * by JH <jheinonen@users.sourceforge.net>
5  *
6  * Copyright (C) Jaakko Heinonen
7  */
8
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <sys/stat.h>
13 #include <signal.h>
14 #include <fcntl.h>
15 #ifdef HAVE_CONFIG_H
16 #       include "config.h"
17 #endif
18 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
19 #       include <locale.h>
20 #endif
21 #include "abook.h"
22 #include "ui.h"
23 #include "database.h"
24 #include "list.h"
25 #include "filter.h"
26 #include "edit.h"
27 #include "misc.h"
28 #include "options.h"
29
30 static void             init_abook();
31 static void             set_filenames();
32 static void             free_filenames();
33 static void             parse_command_line(int argc, char **argv);
34 static void             show_usage();
35 static void             mutt_query(char *str);
36 static void             init_mutt_query();
37 static void             quit_mutt_query();
38 static void             convert(char *srcformat, char *srcfile,
39                                 char *dstformat, char *dstfile);
40
41 char *datafile = NULL;
42 char *rcfile = NULL;
43
44 static void
45 init_abook()
46 {
47         set_filenames();
48         init_options();
49
50         signal(SIGKILL, quit_abook);
51         signal(SIGTERM, quit_abook);
52         
53         if( init_ui() )
54                 exit(1);
55         
56         umask(DEFAULT_UMASK);
57
58         /*
59          * this is very ugly for now
60          */
61         /*if( options_get_int("datafile", "autosave") )*/
62
63         if( load_database(datafile) == 2 ) {
64                 char *tmp = strconcat(getenv("HOME"),
65                                 "/" DATAFILE, NULL);
66
67                 if( safe_strcmp(tmp, datafile) ) {
68                         refresh_screen();
69                         statusline_msg("Sorry, the specified file does "
70                                 "not appear to be a valid abook addressbook");
71                         statusline_msg("Will open default addressbook...");
72                         free(datafile);
73                         datafile = tmp;
74                         load_database(datafile);
75                 } else
76                         free(tmp);
77         }
78
79         refresh_screen();
80 }
81
82 void
83 quit_abook()
84 {
85         if( options_get_int("autosave") )
86                 save_database();
87         else if( statusline_ask_boolean("Save database", TRUE) )
88                 save_database();
89
90         close_config();
91         close_database();
92
93         close_ui();
94         
95         exit(0);
96 }
97
98 int
99 main(int argc, char **argv)
100 {
101 #if defined(HAVE_SETLOCALE) && defined(HAVE_LOCALE_H)
102         setlocale(LC_ALL, "" );
103 #endif
104                 
105         parse_command_line(argc, argv);
106         
107         init_abook();
108
109         get_commands(); 
110         
111         quit_abook();
112
113         return 0;
114 }
115
116 static void
117 set_filenames()
118 {
119         struct stat s;
120
121         if( (stat(getenv("HOME"), &s)) == -1 || ! S_ISDIR(s.st_mode) ) {
122                 fprintf(stderr,"%s is not a valid HOME directory\n", getenv("HOME") );
123                 exit(1);
124         }
125
126         if (!datafile)
127                 datafile = strconcat(getenv("HOME"), "/" DATAFILE, NULL);
128
129         rcfile = strconcat(getenv("HOME"), "/" RCFILE, NULL);
130
131         atexit(free_filenames);
132 }
133
134 static void
135 free_filenames()
136 {
137         my_free(rcfile);
138         my_free(datafile);
139 }
140
141 static void
142 parse_command_line(int argc, char **argv)
143 {
144         int i;
145
146         for( i = 1; i < argc; i++ ) {
147                 if( !strcmp(argv[i], "--help") ) {
148                         show_usage();
149                         exit(1);
150                 } else
151                 if( !strcmp(argv[i], "--mutt-query") )
152                         mutt_query(argv[i + 1]);
153                 else
154                 if( !strcmp(argv[i], "--datafile") ) {
155                         if (argv[i+1]) {
156                                 if (argv[i+1][0] != '/') {
157                                         char *cwd = my_getcwd();
158                                         datafile = strconcat(cwd, "/", argv[i+1], NULL);
159                                         free(cwd);
160                                 } else {
161                                         datafile = strdup(argv[i+1]);
162                                 }
163                                 i++;
164                         } else {
165                                 show_usage();
166                                 exit(1);
167                         }
168                 } else
169                 if( !strcmp(argv[i], "--convert") ) {
170                         if( argc < 5 || argc > 6 ) {
171                                 fprintf(stderr, "incorrect number of argumets to make conversion\n");
172                                 fprintf(stderr, "try %s --help\n", argv[0]);
173                                 exit(1);
174                         }
175                         if( argv[i+4] )
176                                 convert(argv[i+1], argv[i+2],
177                                         argv[i+3], argv[i+4]);
178                         else
179                                 convert(argv[i+1], argv[i+2], argv[i+3], "-");
180                 } else {
181                         printf("option %s not recognized\n", argv[i]);
182                         printf("try %s --help\n", argv[0]);
183                         exit(1);
184                 }
185         }
186 }
187
188
189 static void
190 show_usage()
191 {
192         puts    (PACKAGE " v " VERSION "\n");
193         puts    ("      --help                          show usage");
194         puts    ("      --datafile      <filename>      use an alternative addressbook file");
195         puts    ("      --mutt-query    <string>        make a query for mutt");
196         puts    ("      --convert       <inputformat> <inputfile> "
197                  "<outputformat> <outputfile>");
198         putchar('\n');
199         puts    ("available formats for --convert option:");
200         print_filters();
201 #ifdef DEBUG
202         puts    ("\nWarning: this version compiled with DEBUG flag ON");
203 #endif
204 }
205
206 extern list_item *database;
207
208 static void
209 muttq_print_item(int item)
210 {
211         char emails[MAX_EMAILS][MAX_EMAIL_LEN];
212         int i;
213
214         split_emailstr(item, emails);
215         
216         for(i = 0; i < (options_get_int("mutt_return_all_emails") ?
217                         MAX_EMAILS : 1) ; i++)
218                 if( *emails[i] )
219                         printf("%s\t%s\t%s\n", emails[i],
220                                 database[item][NAME],
221                                 database[item][NOTES] == NULL ? " " :
222                                         database[item][NOTES]
223                                 );
224 }
225
226 static void
227 mutt_query(char *str)
228 {
229         init_mutt_query();
230
231         if( str == NULL || !strcasecmp(str, "all") ) {
232                 struct db_enumerator e = init_db_enumerator(ENUM_ALL);
233                 printf("All items\n");
234                 db_enumerate_items(e)
235                         muttq_print_item(e.item);
236         } else {
237                 int search_fields[] = {NAME, EMAIL, NICK, -1};
238                 int i;
239                 if( (i = find_item(str, 0, search_fields)) < 0 ) {
240                         printf("Not found\n");
241                         quit_mutt_query(1);
242                 }
243                 putchar('\n');
244                 while(i >= 0) {
245                         muttq_print_item(i);
246                         i = find_item(str, i+1, search_fields);
247                 }
248         }
249
250         quit_mutt_query(0);
251 }
252
253 static void
254 init_mutt_query()
255 {
256         set_filenames();
257         init_options();
258         
259         if( load_database(datafile) ) {
260                 printf("Cannot open database\n");
261                 quit_mutt_query(1);
262                 exit(1);
263         }
264 }
265
266 static void
267 quit_mutt_query(int status)
268 {
269         close_database();
270         close_config();
271
272         exit(status);
273 }
274
275
276 static char *
277 make_mailstr(int item)
278 {
279         char email[MAX_EMAIL_LEN];
280         char *ret;
281         char *name = mkstr("\"%s\"", database[item][NAME]);
282
283         get_first_email(email, item);
284
285         ret = *database[item][EMAIL] ?
286                 mkstr("%s <%s>", name, email) :
287                 strdup(name);
288
289         free(name);
290         
291         return ret;
292 }
293
294 void
295 print_stderr(int item)
296 {
297         char *mailstr = NULL;
298
299         if( is_valid_item(item) )
300                 mailstr = make_mailstr(item);
301         else {
302                 struct db_enumerator e = init_db_enumerator(ENUM_SELECTED);
303                 char *tmp = NULL;
304                 db_enumerate_items(e) {
305                         tmp = mailstr;
306                         mailstr = tmp ?
307                                 strconcat(tmp, ",", make_mailstr(e.item), NULL):
308                                 strconcat(make_mailstr(e.item), NULL);
309                         free(tmp);
310                 }
311         }
312
313     fprintf(stderr, "%s", mailstr);
314
315 #ifdef DEBUG
316         fprintf(stderr, "mailstr: %s\n", mailstr);
317 #endif
318
319         free(mailstr);
320
321 }
322
323 void
324 launch_mutt(int item)
325 {
326         char *cmd = NULL, *mailstr = NULL;
327         char *mutt_command = options_get_str("mutt_command");
328
329         if(mutt_command == NULL || !*mutt_command)
330                 return;
331
332         if( is_valid_item(item) )
333                 mailstr = make_mailstr(item);
334         else {
335                 struct db_enumerator e = init_db_enumerator(ENUM_SELECTED);
336                 char *tmp = NULL;
337                 db_enumerate_items(e) {
338                         tmp = mailstr;
339                         mailstr = tmp ?
340                                 strconcat(tmp, ",", make_mailstr(e.item), NULL):
341                                 strconcat(make_mailstr(e.item), NULL);
342                         free(tmp);
343                 }
344         }
345
346         cmd = strconcat(mutt_command, " \'", mailstr,
347                                 "\'", NULL);
348         free(mailstr);
349 #ifdef DEBUG
350         fprintf(stderr, "cmd: %s\n", cmd);
351 #endif
352         system(cmd);    
353         free(cmd);
354         
355         /*
356          * we need to make sure that curses settings are correct
357          */
358         ui_init_curses();
359 }
360
361 void
362 launch_wwwbrowser(int item)
363 {
364         char *cmd = NULL;
365
366         if( !is_valid_item(item) )
367                 return;
368
369         if( database[item][URL] )
370                 cmd = mkstr("%s '%s'",
371                                 options_get_str("www_command"),
372                                 safe_str(database[item][URL]));
373         else
374                 return;
375
376         if ( cmd )
377                 system(cmd);
378
379         free(cmd);
380
381         /*
382          * we need to make sure that curses settings are correct
383          */
384         ui_init_curses();
385 }
386
387 void *
388 abook_malloc(size_t size)
389 {
390         void *ptr;
391
392         if ( (ptr = malloc(size)) == NULL ) {
393                 if( is_ui_initialized() )
394                         quit_abook();
395                 perror("malloc() failed");
396                 exit(1);
397         }
398
399         return ptr;
400 }
401
402 void *
403 abook_realloc(void *ptr, size_t size)
404 {
405         ptr = realloc(ptr, size);
406
407         if( size == 0 )
408                 return NULL;
409
410         if( ptr == NULL ) {
411                 if( is_ui_initialized() )
412                         quit_abook();
413                 perror("realloc() failed");
414                 exit(1);
415         }
416
417         return ptr;
418 }
419
420 FILE *
421 abook_fopen (const char *path, const char *mode)
422 {       
423         struct stat s;
424         
425         if( ! strchr(mode, 'r') )
426                 return fopen(path, mode);
427         
428         if ( (stat(path, &s)) == -1 )
429                 return NULL;
430         
431         return S_ISREG(s.st_mode) ? fopen(path, mode) : NULL;
432 }
433
434
435
436 static void
437 convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile)
438 {
439         int ret=0;
440
441         if( !srcformat || !srcfile || !dstformat || !dstfile ) {
442                 fprintf(stderr, "too few argumets to make conversion\n");
443                 fprintf(stderr, "try --help\n");
444         }
445
446         strlower(srcformat);
447         strlower(dstformat);
448
449 #ifndef DEBUG
450         if( !strcmp(srcformat, dstformat) ) {
451                 printf( "input and output formats are the same\n"
452                         "exiting...\n");
453                 exit(1);
454         }
455 #endif
456
457         set_filenames();
458         init_options();
459
460         switch( import(srcformat, srcfile) ) {
461                 case -1:
462                         printf("input format %s not supported\n", srcformat);
463                         ret = 1;
464                 case 1:
465                         printf("cannot read file %s\n", srcfile);
466                         ret = 1;
467         }
468
469         if(!ret)
470                 switch( export(dstformat, dstfile) ) {
471                         case -1:
472                                 printf("output format %s not supported\n",
473                                                 dstformat);
474                                 ret = 1;
475                                 break;
476                         case 1:
477                                 printf("cannot write file %s\n", dstfile);
478                                 ret = 1;
479                                 break;
480                 }
481
482         close_database();
483         close_config();
484         exit(ret);
485 }
486
487