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