File: | build/../abook.c |
Location: | line 659, column 7 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | |||
2 | * $Id$ | |||
3 | * | |||
4 | * by JH <jheinonen@users.sourceforge.net> | |||
5 | * | |||
6 | * Copyright (C) Jaakko Heinonen | |||
7 | */ | |||
8 | ||||
9 | #include <errno(*__errno_location ()).h> | |||
10 | #include <fcntl.h> | |||
11 | #include <ctype.h> | |||
12 | #include <signal.h> | |||
13 | #include <stdio.h> | |||
14 | #include <stdlib.h> | |||
15 | #include <string.h> | |||
16 | #include <unistd.h> | |||
17 | #include <sys/stat.h> | |||
18 | #ifdef HAVE_CONFIG_H1 | |||
19 | # include "config.h" | |||
20 | #endif | |||
21 | #if defined(HAVE_LOCALE_H1) && defined(HAVE_SETLOCALE1) | |||
22 | # include <locale.h> | |||
23 | #endif | |||
24 | #include <assert.h> | |||
25 | #include "abook.h" | |||
26 | #include "gettext.h" | |||
27 | #include "ui.h" | |||
28 | #include "database.h" | |||
29 | #include "list.h" | |||
30 | #include "filter.h" | |||
31 | #include "edit.h" | |||
32 | #include "misc.h" | |||
33 | #include "options.h" | |||
34 | #include "getname.h" | |||
35 | #include "getopt.h" | |||
36 | #include "views.h" | |||
37 | #include "xmalloc.h" | |||
38 | ||||
39 | static void init_abook(); | |||
40 | static void quit_abook_sig(int i); | |||
41 | static void set_filenames(); | |||
42 | static void parse_command_line(int argc, char **argv); | |||
43 | static void show_usage(); | |||
44 | static void mutt_query(char *str); | |||
45 | static void init_mutt_query(); | |||
46 | static void convert(char *srcformat, char *srcfile, | |||
47 | char *dstformat, char *dstfile); | |||
48 | static void add_email(int); | |||
49 | ||||
50 | char *datafile = NULL((void*)0); | |||
51 | static char *rcfile = NULL((void*)0); | |||
52 | ||||
53 | // custom formatting | |||
54 | char custom_format[FORMAT_STRING_LEN128] = "{nick} ({name}): {mobile}"; | |||
55 | char *parsed_custom_format = NULL((void*)0); | |||
56 | enum field_types *custom_format_fields = 0; | |||
57 | struct abook_output_item_filter selected_item_filter; | |||
58 | ||||
59 | bool_Bool alternative_datafile = FALSE0; | |||
60 | bool_Bool alternative_rcfile = FALSE0; | |||
61 | ||||
62 | ||||
63 | static int | |||
64 | datafile_writeable() | |||
65 | { | |||
66 | FILE *f; | |||
67 | ||||
68 | assert(datafile != NULL)((datafile != ((void*)0)) ? (void) (0) : __assert_fail ("datafile != ((void*)0)" , "../abook.c", 68, __PRETTY_FUNCTION__)); | |||
69 | ||||
70 | if( (f = fopen(datafile, "a")) == NULL((void*)0)) | |||
71 | return FALSE0; | |||
72 | ||||
73 | fclose(f); | |||
74 | ||||
75 | return TRUE1; | |||
76 | } | |||
77 | ||||
78 | static void | |||
79 | check_abook_directory() | |||
80 | { | |||
81 | struct stat s; | |||
82 | char *dir; | |||
83 | ||||
84 | assert(!is_ui_initialized())((!is_ui_initialized()) ? (void) (0) : __assert_fail ("!is_ui_initialized()" , "../abook.c", 84, __PRETTY_FUNCTION__)); | |||
85 | ||||
86 | if(alternative_datafile) | |||
87 | return; | |||
88 | ||||
89 | dir = strconcat(getenv("HOME"), "/" DIR_IN_HOME".abook", NULL((void*)0)); | |||
90 | assert(dir != NULL)((dir != ((void*)0)) ? (void) (0) : __assert_fail ("dir != ((void*)0)" , "../abook.c", 90, __PRETTY_FUNCTION__)); | |||
91 | ||||
92 | if(stat(dir, &s) == -1) { | |||
93 | if(errno(*__errno_location ()) != ENOENT2) { | |||
94 | perror(dir); | |||
95 | free(dir); | |||
96 | exit(EXIT_FAILURE1); | |||
97 | } | |||
98 | if(mkdir(dir, 0700) == -1) { | |||
99 | printf(_("Cannot create directory %s\n")((const char *) ("Cannot create directory %s\n")), dir); | |||
100 | perror(dir); | |||
101 | free(dir); | |||
102 | exit(EXIT_FAILURE1); | |||
103 | } | |||
104 | } else if(!S_ISDIR(s.st_mode)((((s.st_mode)) & 0170000) == (0040000))) { | |||
105 | printf(_("%s is not a directory\n")((const char *) ("%s is not a directory\n")), dir); | |||
106 | free(dir); | |||
107 | exit(EXIT_FAILURE1); | |||
108 | } | |||
109 | ||||
110 | free(dir); | |||
111 | } | |||
112 | ||||
113 | static void | |||
114 | xmalloc_error_handler(int err) | |||
115 | { | |||
116 | /* | |||
117 | * We don't try to save addressbook here because we don't know | |||
118 | * if it's fully loaded to memory. | |||
119 | */ | |||
120 | if(is_ui_initialized()) | |||
121 | close_ui(); | |||
122 | ||||
123 | fprintf(stderrstderr, _("Memory allocation failure: %s\n")((const char *) ("Memory allocation failure: %s\n")), strerror(err)); | |||
124 | exit(EXIT_FAILURE1); | |||
125 | } | |||
126 | ||||
127 | static void | |||
128 | init_abook() | |||
129 | { | |||
130 | set_filenames(); | |||
131 | check_abook_directory(); | |||
132 | init_opts(); | |||
133 | if(load_opts(rcfile) > 0) { | |||
134 | printf(_("Press enter to continue...\n")((const char *) ("Press enter to continue...\n"))); | |||
135 | fgetc(stdinstdin); | |||
136 | } | |||
137 | init_default_views(); | |||
138 | ||||
139 | signal(SIGTERM15, quit_abook_sig); | |||
140 | ||||
141 | init_index(); | |||
142 | ||||
143 | if(init_ui()) | |||
144 | exit(EXIT_FAILURE1); | |||
145 | ||||
146 | umask(DEFAULT_UMASK066); | |||
147 | ||||
148 | if(!datafile_writeable()) { | |||
149 | char *s = strdup_printf(_("File %s is not writeable")((const char *) ("File %s is not writeable")), datafile); | |||
150 | refresh_screen(); | |||
151 | statusline_msg(s); | |||
152 | free(s); | |||
153 | if(load_database(datafile) || !statusline_ask_boolean( | |||
154 | _("If you continue all changes will "((const char *) ("If you continue all changes will " "be lost. Do you want to continue?" )) | |||
155 | "be lost. Do you want to continue?")((const char *) ("If you continue all changes will " "be lost. Do you want to continue?" )), FALSE0)) { | |||
156 | free_opts(); | |||
157 | /*close_database();*/ | |||
158 | close_ui(); | |||
159 | exit(EXIT_FAILURE1); | |||
160 | } | |||
161 | } else | |||
162 | load_database(datafile); | |||
163 | ||||
164 | refresh_screen(); | |||
165 | } | |||
166 | ||||
167 | void | |||
168 | quit_abook(int save_db) | |||
169 | { | |||
170 | if(save_db) { | |||
171 | if(opt_get_bool(BOOL_AUTOSAVE)) | |||
172 | save_database(); | |||
173 | else if(statusline_ask_boolean(_("Save database")((const char *) ("Save database")), TRUE1)) | |||
174 | save_database(); | |||
175 | } else if(!statusline_ask_boolean(_("Quit without saving")((const char *) ("Quit without saving")), FALSE0)) | |||
176 | return; | |||
177 | ||||
178 | free_opts(); | |||
179 | close_database(); | |||
180 | ||||
181 | close_ui(); | |||
182 | ||||
183 | exit(EXIT_SUCCESS0); | |||
184 | } | |||
185 | ||||
186 | static void | |||
187 | quit_abook_sig(int i) | |||
188 | { | |||
189 | quit_abook(QUIT_SAVE1); | |||
190 | } | |||
191 | ||||
192 | int | |||
193 | main(int argc, char **argv) | |||
194 | { | |||
195 | #if defined(HAVE_SETLOCALE1) && defined(HAVE_LOCALE_H1) | |||
196 | setlocale(LC_MESSAGES5, ""); | |||
197 | setlocale(LC_TIME2, ""); | |||
198 | setlocale(LC_CTYPE0, ""); | |||
199 | setlocale(LC_COLLATE3, ""); | |||
200 | #endif | |||
201 | bindtextdomain(PACKAGE, LOCALEDIR)do {} while(0); | |||
202 | textdomain(PACKAGE)do {} while(0); | |||
203 | ||||
204 | xmalloc_set_error_handler(xmalloc_error_handler); | |||
205 | ||||
206 | prepare_database_internals(); | |||
207 | ||||
208 | parse_command_line(argc, argv); | |||
209 | ||||
210 | init_abook(); | |||
211 | ||||
212 | get_commands(); | |||
213 | ||||
214 | quit_abook(QUIT_SAVE1); | |||
215 | ||||
216 | return 0; | |||
217 | } | |||
218 | ||||
219 | static void | |||
220 | free_filenames() | |||
221 | { | |||
222 | xfree(rcfile)do { free(rcfile); rcfile = ((void*)0); } while(0); | |||
223 | xfree(datafile)do { free(datafile); datafile = ((void*)0); } while(0); | |||
224 | } | |||
225 | ||||
226 | ||||
227 | static void | |||
228 | set_filenames() | |||
229 | { | |||
230 | struct stat s; | |||
231 | ||||
232 | if( (stat(getenv("HOME"), &s)) == -1 || ! S_ISDIR(s.st_mode)((((s.st_mode)) & 0170000) == (0040000)) ) { | |||
233 | fprintf(stderrstderr,_("%s is not a valid HOME directory\n")((const char *) ("%s is not a valid HOME directory\n")), getenv("HOME") ); | |||
234 | exit(EXIT_FAILURE1); | |||
235 | } | |||
236 | ||||
237 | if(!datafile) | |||
238 | datafile = strconcat(getenv("HOME"), "/" DIR_IN_HOME".abook" "/" | |||
239 | DATAFILE"addressbook", NULL((void*)0)); | |||
240 | ||||
241 | if(!rcfile) | |||
242 | rcfile = strconcat(getenv("HOME"), "/" DIR_IN_HOME".abook" "/" | |||
243 | RCFILE"abookrc", NULL((void*)0)); | |||
244 | ||||
245 | atexit(free_filenames); | |||
246 | } | |||
247 | ||||
248 | /* | |||
249 | * CLI | |||
250 | */ | |||
251 | ||||
252 | enum { | |||
253 | MODE_CONT, | |||
254 | MODE_ADD_EMAIL, | |||
255 | MODE_ADD_EMAIL_QUIET, | |||
256 | MODE_QUERY, | |||
257 | MODE_CONVERT | |||
258 | }; | |||
259 | ||||
260 | static void | |||
261 | change_mode(int *current, int mode) | |||
262 | { | |||
263 | if(*current != MODE_CONT) { | |||
264 | fprintf(stderrstderr, _("Cannot combine options --mutt-query, "((const char *) ("Cannot combine options --mutt-query, " "--convert, " "--add-email or --add-email-quiet\n")) | |||
265 | "--convert, "((const char *) ("Cannot combine options --mutt-query, " "--convert, " "--add-email or --add-email-quiet\n")) | |||
266 | "--add-email or --add-email-quiet\n")((const char *) ("Cannot combine options --mutt-query, " "--convert, " "--add-email or --add-email-quiet\n"))); | |||
267 | exit(EXIT_FAILURE1); | |||
268 | } | |||
269 | ||||
270 | *current = mode; | |||
271 | } | |||
272 | ||||
273 | void | |||
274 | set_filename(char **var, char *path) | |||
275 | { | |||
276 | char *cwd; | |||
277 | ||||
278 | assert(var != NULL)((var != ((void*)0)) ? (void) (0) : __assert_fail ("var != ((void*)0)" , "../abook.c", 278, __PRETTY_FUNCTION__)); | |||
279 | assert(*var == NULL)((*var == ((void*)0)) ? (void) (0) : __assert_fail ("*var == ((void*)0)" , "../abook.c", 279, __PRETTY_FUNCTION__)); /* or else we probably leak memory */ | |||
280 | assert(path != NULL)((path != ((void*)0)) ? (void) (0) : __assert_fail ("path != ((void*)0)" , "../abook.c", 280, __PRETTY_FUNCTION__)); | |||
281 | ||||
282 | if(*path == '/') { | |||
283 | *var = xstrdup(path); | |||
284 | return; | |||
285 | } | |||
286 | ||||
287 | cwd = my_getcwd(); | |||
288 | ||||
289 | *var = strconcat(cwd, "/", path, NULL((void*)0)); | |||
290 | ||||
291 | free(cwd); | |||
292 | } | |||
293 | ||||
294 | #define set_convert_var(X)do { if(mode != MODE_CONVERT) { fprintf(stderr, ((const char * ) ("please use option --%s after --convert option\n")), long_options [option_index].name); exit(1); } else X = optarg; } while(0) do { if(mode != MODE_CONVERT) {\ | |||
295 | fprintf(stderrstderr, _("please use option --%s after --convert option\n")((const char *) ("please use option --%s after --convert option\n" )),\ | |||
296 | long_options[option_index].name);\ | |||
297 | exit(EXIT_FAILURE1);\ | |||
298 | } else\ | |||
299 | X = optarg;\ | |||
300 | } while(0) | |||
301 | ||||
302 | static void | |||
303 | parse_command_line(int argc, char **argv) | |||
304 | { | |||
305 | int mode = MODE_CONT; | |||
306 | char *query_string = NULL((void*)0); | |||
307 | char *informat = "abook", | |||
308 | *outformat = "text", | |||
309 | *infile = "-", | |||
310 | *outfile = "-"; | |||
311 | int c; | |||
312 | selected_item_filter = select_output_item_filter("muttq"); | |||
313 | ||||
314 | for(;;) { | |||
315 | int option_index = 0; | |||
316 | enum { | |||
317 | OPT_ADD_EMAIL, | |||
318 | OPT_ADD_EMAIL_QUIET, | |||
319 | OPT_MUTT_QUERY, | |||
320 | OPT_CONVERT, | |||
321 | OPT_INFORMAT, | |||
322 | OPT_OUTFORMAT, | |||
323 | OPT_OUTFORMAT_STR, | |||
324 | OPT_INFILE, | |||
325 | OPT_OUTFILE, | |||
326 | OPT_FORMATS | |||
327 | }; | |||
328 | static struct option long_options[] = { | |||
329 | { "help", 0, 0, 'h' }, | |||
330 | { "add-email", 0, 0, OPT_ADD_EMAIL }, | |||
331 | { "add-email-quiet", 0, 0, OPT_ADD_EMAIL_QUIET }, | |||
332 | { "datafile", 1, 0, 'f' }, | |||
333 | { "mutt-query", 1, 0, OPT_MUTT_QUERY }, | |||
334 | { "config", 1, 0, 'C' }, | |||
335 | { "convert", 0, 0, OPT_CONVERT }, | |||
336 | { "informat", 1, 0, OPT_INFORMAT }, | |||
337 | { "outformat", 1, 0, OPT_OUTFORMAT }, | |||
338 | { "outformatstr", 1, 0, OPT_OUTFORMAT_STR }, | |||
339 | { "infile", 1, 0, OPT_INFILE }, | |||
340 | { "outfile", 1, 0, OPT_OUTFILE }, | |||
341 | { "formats", 0, 0, OPT_FORMATS }, | |||
342 | { 0, 0, 0, 0 } | |||
343 | }; | |||
344 | ||||
345 | c = getopt_long(argc, argv, "hC:", | |||
346 | long_options, &option_index); | |||
347 | ||||
348 | if(c == -1) | |||
349 | break; | |||
350 | ||||
351 | switch(c) { | |||
352 | case 'h': | |||
353 | show_usage(); | |||
354 | exit(EXIT_SUCCESS0); | |||
355 | case OPT_ADD_EMAIL: | |||
356 | change_mode(&mode, MODE_ADD_EMAIL); | |||
357 | break; | |||
358 | case OPT_ADD_EMAIL_QUIET: | |||
359 | change_mode(&mode, MODE_ADD_EMAIL_QUIET); | |||
360 | break; | |||
361 | case 'f': | |||
362 | set_filename(&datafile, optarg); | |||
363 | alternative_datafile = TRUE1; | |||
364 | break; | |||
365 | case OPT_MUTT_QUERY: | |||
366 | query_string = optarg; | |||
367 | change_mode(&mode, MODE_QUERY); | |||
368 | break; | |||
369 | case 'C': | |||
370 | set_filename(&rcfile, optarg); | |||
371 | alternative_rcfile = TRUE1; | |||
372 | break; | |||
373 | case OPT_CONVERT: | |||
374 | change_mode(&mode, MODE_CONVERT); | |||
375 | break; | |||
376 | case OPT_INFORMAT: | |||
377 | set_convert_var(informat)do { if(mode != MODE_CONVERT) { fprintf(stderr, ((const char * ) ("please use option --%s after --convert option\n")), long_options [option_index].name); exit(1); } else informat = optarg; } while (0); | |||
378 | break; | |||
379 | case OPT_OUTFORMAT: | |||
380 | if(mode != MODE_CONVERT && mode != MODE_QUERY) { | |||
381 | fprintf(stderrstderr, | |||
382 | _("please use option --outformat after --convert or --mutt-query option\n")((const char *) ("please use option --outformat after --convert or --mutt-query option\n" ))); | |||
383 | exit(EXIT_FAILURE1); | |||
384 | } | |||
385 | // ascii-name is stored, it's used to traverse | |||
386 | // e_filters[] in MODE_CONVERT (see export_file()) | |||
387 | outformat = optarg; | |||
388 | // but in case a query-compatible filter is requested | |||
389 | // try to guess right now which one it is, from u_filters[] | |||
390 | selected_item_filter = select_output_item_filter(outformat); | |||
391 | break; | |||
392 | case OPT_OUTFORMAT_STR: | |||
393 | strncpy(custom_format, optarg, FORMAT_STRING_LEN)__builtin_strncpy (custom_format, optarg, 128); | |||
394 | custom_format[FORMAT_STRING_LEN128 - 1] = 0; | |||
395 | break; | |||
396 | case OPT_INFILE: | |||
397 | set_convert_var(infile)do { if(mode != MODE_CONVERT) { fprintf(stderr, ((const char * ) ("please use option --%s after --convert option\n")), long_options [option_index].name); exit(1); } else infile = optarg; } while (0); | |||
398 | break; | |||
399 | case OPT_OUTFILE: | |||
400 | set_convert_var(outfile)do { if(mode != MODE_CONVERT) { fprintf(stderr, ((const char * ) ("please use option --%s after --convert option\n")), long_options [option_index].name); exit(1); } else outfile = optarg; } while (0); | |||
401 | break; | |||
402 | case OPT_FORMATS: | |||
403 | print_filters(); | |||
404 | exit(EXIT_SUCCESS0); | |||
405 | default: | |||
406 | exit(EXIT_FAILURE1); | |||
407 | } | |||
408 | } | |||
409 | ||||
410 | // if the output format requested does not allow filtered querying | |||
411 | // (not in u_filter[]) and --convert has not been specified; bailout | |||
412 | if(! selected_item_filter.func && mode != MODE_CONVERT) { | |||
413 | printf("output format %s not supported or incompatible with --mutt-query\n", outformat); | |||
414 | exit(EXIT_FAILURE1); | |||
415 | } | |||
416 | if(! selected_item_filter.func) | |||
417 | selected_item_filter = select_output_item_filter("muttq"); | |||
418 | else if (! strcmp(outformat, "custom")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (outformat) && __builtin_constant_p ("custom") && (__s1_len = strlen (outformat), __s2_len = strlen ("custom") , (!((size_t)(const void *)((outformat) + 1) - (size_t)(const void *)(outformat) == 1) || __s1_len >= 4) && (!( (size_t)(const void *)(("custom") + 1) - (size_t)(const void * )("custom") == 1) || __s2_len >= 4)) ? __builtin_strcmp (outformat , "custom") : (__builtin_constant_p (outformat) && (( size_t)(const void *)((outformat) + 1) - (size_t)(const void * )(outformat) == 1) && (__s1_len = strlen (outformat), __s1_len < 4) ? (__builtin_constant_p ("custom") && ((size_t)(const void *)(("custom") + 1) - (size_t)(const void *)("custom") == 1) ? __builtin_strcmp (outformat, "custom") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("custom"); int __result = (((const unsigned char *) (const char *) (outformat))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (outformat))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (outformat))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (outformat))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p ("custom") && ((size_t )(const void *)(("custom") + 1) - (size_t)(const void *)("custom" ) == 1) && (__s2_len = strlen ("custom"), __s2_len < 4) ? (__builtin_constant_p (outformat) && ((size_t)( const void *)((outformat) + 1) - (size_t)(const void *)(outformat ) == 1) ? __builtin_strcmp (outformat, "custom") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (outformat); int __result = (((const unsigned char * ) (const char *) ("custom"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("custom"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("custom"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("custom"))[3] - __s2[3]); } } __result; } )))) : __builtin_strcmp (outformat, "custom")))); })) { | |||
419 | if(! *custom_format) { | |||
420 | fprintf(stderrstderr, _("Invalid custom format string\n")((const char *) ("Invalid custom format string\n"))); | |||
421 | exit(EXIT_FAILURE1); | |||
422 | } | |||
423 | parsed_custom_format = (char *)malloc(FORMAT_STRING_LEN128 * sizeof(char*)); | |||
424 | custom_format_fields = (enum field_types *)malloc(FORMAT_STRING_MAX_FIELDS16 * sizeof(enum field_types *)); | |||
425 | parse_custom_format(custom_format, parsed_custom_format, custom_format_fields); | |||
426 | } | |||
427 | if(optind < argc) { | |||
428 | fprintf(stderrstderr, _("%s: unrecognized arguments on command line\n")((const char *) ("%s: unrecognized arguments on command line\n" )), | |||
429 | argv[0]); | |||
430 | exit(EXIT_FAILURE1); | |||
431 | } | |||
432 | ||||
433 | switch(mode) { | |||
434 | case MODE_ADD_EMAIL: | |||
435 | add_email(0); | |||
436 | case MODE_ADD_EMAIL_QUIET: | |||
437 | add_email(1); | |||
438 | case MODE_QUERY: | |||
439 | mutt_query(query_string); | |||
440 | case MODE_CONVERT: | |||
441 | convert(informat, infile, outformat, outfile); | |||
442 | } | |||
443 | } | |||
444 | ||||
445 | ||||
446 | static void | |||
447 | show_usage() | |||
448 | { | |||
449 | puts (PACKAGE"abook" " v " VERSION"0.6.0pre2" "\n"); | |||
450 | puts (_(" -h --help show usage")((const char *) (" -h --help show usage"))); | |||
451 | puts (_(" -C --config <file> use an alternative configuration file")((const char *) (" -C --config <file> use an alternative configuration file" ))); | |||
452 | puts (_(" --datafile <file> use an alternative addressbook file")((const char *) (" --datafile <file> use an alternative addressbook file" ))); | |||
453 | puts (_(" --mutt-query <string> make a query for mutt")((const char *) (" --mutt-query <string> make a query for mutt" ))); | |||
454 | puts (_(" --add-email "((const char *) (" --add-email " "read an e-mail message from stdin and\n" " " "add the sender to the addressbook")) | |||
455 | "read an e-mail message from stdin and\n"((const char *) (" --add-email " "read an e-mail message from stdin and\n" " " "add the sender to the addressbook")) | |||
456 | " "((const char *) (" --add-email " "read an e-mail message from stdin and\n" " " "add the sender to the addressbook")) | |||
457 | "add the sender to the addressbook")((const char *) (" --add-email " "read an e-mail message from stdin and\n" " " "add the sender to the addressbook"))); | |||
458 | puts (_(" --add-email-quiet "((const char *) (" --add-email-quiet " "same as --add-email but doesn't\n" " require to confirm adding")) | |||
459 | "same as --add-email but doesn't\n"((const char *) (" --add-email-quiet " "same as --add-email but doesn't\n" " require to confirm adding")) | |||
460 | " require to confirm adding")((const char *) (" --add-email-quiet " "same as --add-email but doesn't\n" " require to confirm adding"))); | |||
461 | putchar('\n'); | |||
462 | puts (_(" --convert convert address book files")((const char *) (" --convert convert address book files"))); | |||
463 | puts (_(" options to use with --convert:")((const char *) (" options to use with --convert:"))); | |||
464 | puts (_(" --informat <format> format for input file")((const char *) (" --informat <format> format for input file" ))); | |||
465 | puts (_(" (default: abook)")((const char *) (" (default: abook)"))); | |||
466 | puts (_(" --infile <file> source file")((const char *) (" --infile <file> source file"))); | |||
467 | puts (_(" (default: stdin)")((const char *) (" (default: stdin)"))); | |||
468 | puts (_(" --outformat <format> format for output file")((const char *) (" --outformat <format> format for output file" ))); | |||
469 | puts (_(" (default: text)")((const char *) (" (default: text)"))); | |||
470 | puts (_(" --outfile <file> destination file")((const char *) (" --outfile <file> destination file") )); | |||
471 | puts (_(" (default: stdout)")((const char *) (" (default: stdout)"))); | |||
472 | puts (_(" --outformatstr <str> format to use for \"custom\" --outformat")((const char *) (" --outformatstr <str> format to use for \"custom\" --outformat" ))); | |||
473 | puts (_(" (default: \"{nick} ({name}): {mobile}\")")((const char *) (" (default: \"{nick} ({name}): {mobile}\")" ))); | |||
474 | puts (_(" --formats list available formats")((const char *) (" --formats list available formats"))); | |||
475 | } | |||
476 | ||||
477 | /* | |||
478 | * end of CLI | |||
479 | */ | |||
480 | ||||
481 | ||||
482 | static void | |||
483 | quit_mutt_query(int status) | |||
484 | { | |||
485 | close_database(); | |||
486 | free_opts(); | |||
487 | ||||
488 | exit(status); | |||
489 | } | |||
490 | ||||
491 | static void | |||
492 | mutt_query(char *str) | |||
493 | { | |||
494 | init_mutt_query(); | |||
495 | ||||
496 | if( str == NULL((void*)0) || !strcasecmp(str, "all") ) { | |||
497 | export_file("muttq", "-"); | |||
498 | } else { | |||
499 | int search_fields[] = {NAME, EMAIL, NICK, -1}; | |||
500 | int i; | |||
501 | if( (i = find_item(str, 0, search_fields)) < 0 ) { | |||
502 | printf("Not found\n"); | |||
503 | quit_mutt_query(EXIT_FAILURE1); | |||
504 | } | |||
505 | // mutt expects a leading line containing | |||
506 | // a message about the query. | |||
507 | // Others output filter supporting query (vcard, custom) | |||
508 | // don't needs this. | |||
509 | if(!strcmp(selected_item_filter.filtname, "muttq")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (selected_item_filter.filtname) && __builtin_constant_p ("muttq") && (__s1_len = strlen (selected_item_filter .filtname), __s2_len = strlen ("muttq"), (!((size_t)(const void *)((selected_item_filter.filtname) + 1) - (size_t)(const void *)(selected_item_filter.filtname) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("muttq") + 1) - (size_t )(const void *)("muttq") == 1) || __s2_len >= 4)) ? __builtin_strcmp (selected_item_filter.filtname, "muttq") : (__builtin_constant_p (selected_item_filter.filtname) && ((size_t)(const void *)((selected_item_filter.filtname) + 1) - (size_t)(const void *)(selected_item_filter.filtname) == 1) && (__s1_len = strlen (selected_item_filter.filtname), __s1_len < 4) ? (__builtin_constant_p ("muttq") && ((size_t)(const void *)(("muttq") + 1) - (size_t)(const void *)("muttq") == 1) ? __builtin_strcmp (selected_item_filter.filtname, "muttq") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("muttq"); int __result = (((const unsigned char *) (const char *) (selected_item_filter.filtname))[0] - __s2[0]); if ( __s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (selected_item_filter.filtname ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (selected_item_filter .filtname))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (selected_item_filter .filtname))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("muttq") && ((size_t)(const void *)(("muttq") + 1) - (size_t)(const void *)("muttq") == 1) && (__s2_len = strlen ("muttq"), __s2_len < 4) ? (__builtin_constant_p ( selected_item_filter.filtname) && ((size_t)(const void *)((selected_item_filter.filtname) + 1) - (size_t)(const void *)(selected_item_filter.filtname) == 1) ? __builtin_strcmp ( selected_item_filter.filtname, "muttq") : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (selected_item_filter.filtname); int __result = (((const unsigned char *) (const char *) ("muttq"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("muttq"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("muttq"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("muttq"))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (selected_item_filter.filtname, "muttq" )))); })) | |||
510 | putchar('\n'); | |||
511 | while(i >= 0) { | |||
512 | e_write_item(stdoutstdout, i, selected_item_filter.func); | |||
513 | i = find_item(str, i + 1, search_fields); | |||
514 | } | |||
515 | } | |||
516 | ||||
517 | quit_mutt_query(EXIT_SUCCESS0); | |||
518 | } | |||
519 | ||||
520 | static void | |||
521 | init_mutt_query() | |||
522 | { | |||
523 | set_filenames(); | |||
524 | init_opts(); | |||
525 | load_opts(rcfile); | |||
526 | ||||
527 | if( load_database(datafile) ) { | |||
528 | printf(_("Cannot open database\n")((const char *) ("Cannot open database\n"))); | |||
529 | quit_mutt_query(EXIT_FAILURE1); | |||
530 | exit(EXIT_FAILURE1); | |||
531 | } | |||
532 | } | |||
533 | ||||
534 | ||||
535 | static char * | |||
536 | make_mailstr(int item) | |||
537 | { | |||
538 | char email[MAX_EMAIL_LEN80]; | |||
539 | char *ret; | |||
540 | char *name = strdup_printf("\"%s\"", db_name_get(item)real_db_field_get(item, NAME, 1)); | |||
541 | ||||
542 | get_first_email(email, item); | |||
543 | ||||
544 | ret = *email ? | |||
545 | strdup_printf("%s <%s>", name, email) : | |||
546 | xstrdup(name); | |||
547 | ||||
548 | free(name); | |||
549 | ||||
550 | return ret; | |||
551 | } | |||
552 | ||||
553 | void | |||
554 | print_stderr(int item) | |||
555 | { | |||
556 | fprintf (stderrstderr, "%c", '\n'); | |||
557 | ||||
558 | if( is_valid_item(item) ) | |||
559 | muttq_print_item(stderrstderr, item); | |||
560 | else { | |||
561 | struct db_enumerator e = init_db_enumerator(ENUM_SELECTED); | |||
562 | db_enumerate_items(e)while( -1 != (e.item = real_db_enumerate_items(e))) { | |||
563 | muttq_print_item(stderrstderr, e.item); | |||
564 | } | |||
565 | } | |||
566 | ||||
567 | } | |||
568 | ||||
569 | void | |||
570 | launch_mutt(int item) | |||
571 | { | |||
572 | char *cmd = NULL((void*)0), *mailstr = NULL((void*)0); | |||
573 | char *mutt_command = opt_get_str(STR_MUTT_COMMAND); | |||
574 | ||||
575 | if(mutt_command == NULL((void*)0) || !*mutt_command) | |||
576 | return; | |||
577 | ||||
578 | if( is_valid_item(item) ) | |||
579 | mailstr = make_mailstr(item); | |||
580 | else { | |||
581 | struct db_enumerator e = init_db_enumerator(ENUM_SELECTED); | |||
582 | char *tmp = NULL((void*)0); | |||
583 | db_enumerate_items(e)while( -1 != (e.item = real_db_enumerate_items(e))) { | |||
584 | tmp = mailstr; | |||
585 | mailstr = tmp ? | |||
586 | strconcat(tmp, ",", make_mailstr(e.item), NULL((void*)0)): | |||
587 | strconcat(make_mailstr(e.item), NULL((void*)0)); | |||
588 | free(tmp); | |||
589 | } | |||
590 | } | |||
591 | ||||
592 | cmd = strconcat(mutt_command, " \'", mailstr, "\'", NULL((void*)0)); | |||
593 | free(mailstr); | |||
594 | #ifdef DEBUG | |||
595 | fprintf(stderrstderr, "cmd: %s\n", cmd); | |||
596 | #endif | |||
597 | system(cmd); | |||
598 | free(cmd); | |||
599 | ||||
600 | /* | |||
601 | * we need to make sure that curses settings are correct | |||
602 | */ | |||
603 | ui_init_curses(); | |||
604 | } | |||
605 | ||||
606 | void | |||
607 | launch_wwwbrowser(int item) | |||
608 | { | |||
609 | char *cmd = NULL((void*)0); | |||
610 | ||||
611 | if( !is_valid_item(item) ) | |||
612 | return; | |||
613 | ||||
614 | if(db_fget(item, URL)real_db_field_get(item, URL, 1)) | |||
615 | cmd = strdup_printf("%s '%s'", | |||
616 | opt_get_str(STR_WWW_COMMAND), | |||
617 | safe_str(db_fget(item, URL))((real_db_field_get(item, URL, 1) == ((void*)0)) ? "" : real_db_field_get (item, URL, 1))); | |||
618 | else | |||
619 | return; | |||
620 | ||||
621 | if ( cmd ) | |||
622 | system(cmd); | |||
623 | ||||
624 | free(cmd); | |||
625 | ||||
626 | /* | |||
627 | * we need to make sure that curses settings are correct | |||
628 | */ | |||
629 | ui_init_curses(); | |||
630 | } | |||
631 | ||||
632 | FILE * | |||
633 | abook_fopen (const char *path, const char *mode) | |||
634 | { | |||
635 | struct stat s; | |||
636 | bool_Bool stat_ok; | |||
637 | ||||
638 | stat_ok = (stat(path, &s) != -1); | |||
639 | ||||
640 | if(strchr(mode, 'r')(__extension__ (__builtin_constant_p ('r') && !__builtin_constant_p (mode) && ('r') == '\0' ? (char *) __rawmemchr (mode , 'r') : __builtin_strchr (mode, 'r')))) | |||
641 | return (stat_ok && S_ISREG(s.st_mode)((((s.st_mode)) & 0170000) == (0100000))) ? | |||
642 | fopen(path, mode) : NULL((void*)0); | |||
643 | else | |||
644 | return (stat_ok && S_ISDIR(s.st_mode)((((s.st_mode)) & 0170000) == (0040000))) ? | |||
645 | NULL((void*)0) : fopen(path, mode); | |||
646 | } | |||
647 | ||||
648 | static void | |||
649 | convert(char *srcformat, char *srcfile, char *dstformat, char *dstfile) | |||
650 | { | |||
651 | int ret=0; | |||
652 | ||||
653 | if( !srcformat || !srcfile || !dstformat || !dstfile ) { | |||
| ||||
654 | fprintf(stderrstderr, _("too few arguments to make conversion\n")((const char *) ("too few arguments to make conversion\n"))); | |||
655 | fprintf(stderrstderr, _("try --help\n")((const char *) ("try --help\n"))); | |||
656 | } | |||
657 | ||||
658 | #ifndef DEBUG | |||
659 | if( !strcasecmp(srcformat, dstformat) ) { | |||
| ||||
660 | printf( _("input and output formats are the same\n"((const char *) ("input and output formats are the same\n" "exiting...\n" )) | |||
661 | "exiting...\n")((const char *) ("input and output formats are the same\n" "exiting...\n" ))); | |||
662 | exit(EXIT_FAILURE1); | |||
663 | } | |||
664 | #endif | |||
665 | ||||
666 | set_filenames(); | |||
667 | init_opts(); | |||
668 | load_opts(rcfile); | |||
669 | init_standard_fields(); | |||
670 | ||||
671 | switch(import_file(srcformat, srcfile)) { | |||
672 | case -1: | |||
673 | fprintf(stderrstderr, | |||
674 | _("input format %s not supported\n")((const char *) ("input format %s not supported\n")), srcformat); | |||
675 | ret = 1; | |||
676 | break; | |||
677 | case 1: | |||
678 | fprintf(stderrstderr, _("cannot read file %s\n")((const char *) ("cannot read file %s\n")), srcfile); | |||
679 | ret = 1; | |||
680 | break; | |||
681 | } | |||
682 | ||||
683 | if(!ret) | |||
684 | switch(export_file(dstformat, dstfile)) { | |||
685 | case -1: | |||
686 | fprintf(stderrstderr, | |||
687 | _("output format %s not supported\n")((const char *) ("output format %s not supported\n")), | |||
688 | dstformat); | |||
689 | ret = 1; | |||
690 | break; | |||
691 | case 1: | |||
692 | fprintf(stderrstderr, | |||
693 | _("cannot write file %s\n")((const char *) ("cannot write file %s\n")), dstfile); | |||
694 | ret = 1; | |||
695 | break; | |||
696 | } | |||
697 | ||||
698 | close_database(); | |||
699 | free_opts(); | |||
700 | exit(ret); | |||
701 | } | |||
702 | ||||
703 | /* | |||
704 | * --add-email handling | |||
705 | */ | |||
706 | ||||
707 | static int add_email_count = 0, add_email_found = 0; | |||
708 | ||||
709 | static void | |||
710 | quit_add_email() | |||
711 | { | |||
712 | if(add_email_count > 0) { | |||
713 | if(save_database() < 0) { | |||
714 | fprintf(stderrstderr, _("cannot open %s\n")((const char *) ("cannot open %s\n")), datafile); | |||
715 | exit(EXIT_FAILURE1); | |||
716 | } | |||
717 | printf(_("%d item(s) added to %s\n")((const char *) ("%d item(s) added to %s\n")), add_email_count, datafile); | |||
718 | } else if (add_email_found == 0) { | |||
719 | puts(_("Valid sender address not found")((const char *) ("Valid sender address not found"))); | |||
720 | } | |||
721 | ||||
722 | exit(EXIT_SUCCESS0); | |||
723 | } | |||
724 | ||||
725 | static void | |||
726 | quit_add_email_sig(int signal) | |||
727 | { | |||
728 | quit_add_email(); | |||
729 | } | |||
730 | ||||
731 | static void | |||
732 | init_add_email() | |||
733 | { | |||
734 | set_filenames(); | |||
735 | check_abook_directory(); | |||
736 | init_opts(); | |||
737 | load_opts(rcfile); | |||
738 | init_standard_fields(); | |||
739 | atexit(free_opts); | |||
740 | ||||
741 | /* | |||
742 | * we don't actually care if loading fails or not | |||
743 | */ | |||
744 | load_database(datafile); | |||
745 | ||||
746 | atexit(close_database); | |||
747 | ||||
748 | signal(SIGINT2, quit_add_email_sig); | |||
749 | } | |||
750 | ||||
751 | static int | |||
752 | add_email_add_item(int quiet, char *name, char *email) | |||
753 | { | |||
754 | list_item item; | |||
755 | ||||
756 | if(opt_get_bool(BOOL_ADD_EMAIL_PREVENT_DUPLICATES)) { | |||
757 | int search_fields[] = { EMAIL, -1 }; | |||
758 | if(find_item(email, 0, search_fields) >= 0) { | |||
759 | if(!quiet) | |||
760 | printf(_("Address %s already in addressbook\n")((const char *) ("Address %s already in addressbook\n")), | |||
761 | email); | |||
762 | return 0; | |||
763 | } | |||
764 | } | |||
765 | ||||
766 | if(!quiet) { | |||
767 | FILE *in = fopen("/dev/tty", "r"); | |||
768 | char c; | |||
769 | if(!in) { | |||
770 | fprintf(stderrstderr, _("cannot open /dev/tty\n"((const char *) ("cannot open /dev/tty\n" "you may want to use --add-email-quiet\n" )) | |||
771 | "you may want to use --add-email-quiet\n")((const char *) ("cannot open /dev/tty\n" "you may want to use --add-email-quiet\n" ))); | |||
772 | exit(EXIT_FAILURE1); | |||
773 | } | |||
774 | ||||
775 | do { | |||
776 | printf(_("Add \"%s <%s>\" to %s? (%c/%c)\n")((const char *) ("Add \"%s <%s>\" to %s? (%c/%c)\n")), | |||
777 | name, | |||
778 | email, | |||
779 | datafile, | |||
780 | *S_("keybinding for yes|y")sgettext ("keybinding for yes|y"), | |||
781 | *S_("keybinding for no|n")sgettext ("keybinding for no|n")); | |||
782 | c = tolower(getc(in))(__extension__ ({ int __res; if (sizeof (_IO_getc (in)) > 1 ) { if (__builtin_constant_p (_IO_getc (in))) { int __c = (_IO_getc (in)); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower (_IO_getc (in)); } else __res = (*__ctype_tolower_loc ())[(int) (_IO_getc (in))]; __res; } )); | |||
783 | if(c == *S_("keybinding for no|n")sgettext ("keybinding for no|n")) { | |||
784 | fclose(in); | |||
785 | return 0; | |||
786 | } | |||
787 | } while(c != *S_("keybinding for yes|y")sgettext ("keybinding for yes|y")); | |||
788 | fclose(in); | |||
789 | } | |||
790 | ||||
791 | item = item_create(); | |||
792 | item_fput(item, NAME, xstrdup(name)); | |||
793 | item_fput(item, EMAIL, xstrdup(email)); | |||
794 | add_item2database(item); | |||
795 | item_free(&item); | |||
796 | ||||
797 | return 1; | |||
798 | } | |||
799 | ||||
800 | static void | |||
801 | add_email(int quiet) | |||
802 | { | |||
803 | char *line; | |||
804 | char *name = NULL((void*)0), *email = NULL((void*)0); | |||
805 | struct stat s; | |||
806 | ||||
807 | if( (fstat(fileno(stdinstdin), &s)) == -1 || S_ISDIR(s.st_mode)((((s.st_mode)) & 0170000) == (0040000)) ) { | |||
808 | fprintf(stderrstderr, _("stdin is a directory or cannot stat stdin\n")((const char *) ("stdin is a directory or cannot stat stdin\n" ))); | |||
809 | exit(EXIT_FAILURE1); | |||
810 | } | |||
811 | ||||
812 | init_add_email(); | |||
813 | ||||
814 | do { | |||
815 | line = getaline(stdinstdin); | |||
816 | if(line && !strncasecmp("From:", line, 5) ) { | |||
817 | add_email_found++; | |||
818 | getname(line, &name, &email); | |||
819 | add_email_count += add_email_add_item(quiet, | |||
820 | name, email); | |||
821 | xfree(name)do { free(name); name = ((void*)0); } while(0); | |||
822 | xfree(email)do { free(email); email = ((void*)0); } while(0); | |||
823 | } | |||
824 | xfree(line)do { free(line); line = ((void*)0); } while(0); | |||
825 | } while( !feof(stdinstdin) ); | |||
826 | ||||
827 | quit_add_email(); | |||
828 | } | |||
829 | ||||
830 | /* | |||
831 | * end of --add-email handling | |||
832 | */ |