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