PageRenderTime 59ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/mboxgrep-0.7.9/src/main.c

#
C | 375 lines | 298 code | 40 blank | 37 comment | 57 complexity | 65ee55e7a72ee76ad08bd54e6b2ebc08 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* -*- C -*-
  2. mboxgrep - scan mailbox for messages matching a regular expression
  3. Copyright (C) 2000, 2001, 2002, 2003 Daniel Spiljar
  4. Mboxgrep is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. Mboxgrep is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with mboxgrep; if not, write to the Free Software Foundation,
  14. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. $Id: main.c,v 1.32 2003/08/24 19:23:50 dspiljar Exp $ */
  16. #include <config.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <regex.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24. #ifdef HAVE_LIBPCRE
  25. #include <pcre.h>
  26. #endif /* HAVE_LIBPCRE */
  27. #ifdef HAVE_LIBZ
  28. #include <zlib.h>
  29. #endif /* HAVE_LIBZ */
  30. #include "getopt.h"
  31. #include "mboxgrep.h"
  32. #include "misc.h"
  33. #include "info.h"
  34. #include "mbox.h"
  35. #include "mh.h"
  36. #include "scan.h"
  37. #include "wrap.h" /* xcalloc() et cetera */
  38. #ifdef HAVE_LIBDMALLOC
  39. #include <dmalloc.h>
  40. #endif /* HAVE_LIBDMALLOC */
  41. regex_t posix_pattern;
  42. #ifdef HAVE_LIBPCRE
  43. pcre *pcre_pattern;
  44. pcre_extra *hints;
  45. #endif /* HAVE_LIBPCRE */
  46. char *boxname, *outboxname, *pipecmd, *tmpfilename;
  47. int maildir_count = 0;
  48. int count = 0;
  49. void *tmpp;
  50. checksum_t *cs;
  51. int
  52. main (int argc, char **argv)
  53. /* {{{ */
  54. {
  55. int option_index = 0;
  56. int c;
  57. #ifdef HAVE_LIBPCRE
  58. int errptr;
  59. const char *error;
  60. #endif /* HAVE_LIBPCRE */
  61. int haveregex = 0, havemailbox = 0;
  62. static char *regex_s;
  63. int singlefile = 0;
  64. int errcode = 0;
  65. char errbuf[BUFSIZ];
  66. static struct option long_options[] =
  67. /* {{{ */
  68. {
  69. {"count", 0, 0, 'c'},
  70. {"delete", 0, 0, 'd'},
  71. /* {"date", 1, 0, 'D'}, */
  72. {"extended-regexp", 0, 0, 'E'},
  73. {"basic-regexp", 0, 0, 'G'},
  74. {"perl-regexp", 0, 0, 'P'},
  75. {"help", 0, 0, 'h'},
  76. {"ignore-case", 0, 0, 'i'},
  77. {"mailbox-format", 1, 0, 'm'},
  78. {"no", 1, 0, 'n' },
  79. {"pipe", 1, 0, 'p'},
  80. {"regexp", 1, 0, 'e'},
  81. {"invert-match", 0, 0, 'v'},
  82. {"version", 0, 0, 'V'},
  83. {"headers", 0, 0, 'H'},
  84. {"body", 0, 0, 'B'},
  85. {"no-messages", 0, 0, 's'},
  86. {"output", 1, 0, 'o'},
  87. {"no-duplicates", 0, 0, 200},
  88. {"no-file-lock", 0, 0, 201},
  89. {"file-lock", 1, 0, 'l'},
  90. {"recursive", 0, 0, 'r'},
  91. {0, 0, 0, 0}
  92. };
  93. /* }}} */
  94. config.perl = 0;
  95. config.extended = 1;
  96. config.invert = 0;
  97. config.headers = 0;
  98. config.body = 0;
  99. config.action = DISPLAY;
  100. config.dedup = 0;
  101. config.recursive = 0;
  102. config.ignorecase = 0;
  103. config.format = MBOX; /* default mailbox format */
  104. config.lock = FCNTL; /* default file locking method */
  105. config.merr = 1; /* report errors by default */
  106. while (1)
  107. {
  108. c = getopt_long (argc, argv, "BcdEe:GHhil:m:n:o:Pp:rsVv", long_options,
  109. &option_index);
  110. if (c == -1)
  111. break;
  112. switch (c)
  113. /* {{{ */
  114. {
  115. case '?':
  116. usage();
  117. case 'c':
  118. config.action = COUNT;
  119. break;
  120. case 'd':
  121. config.action = DELETE;
  122. break;
  123. case 'e':
  124. regex_s = xstrdup (optarg);
  125. haveregex = 1;
  126. break;
  127. case 'o':
  128. outboxname = xstrdup (optarg);
  129. config.action = WRITE;
  130. break;
  131. case 'E':
  132. config.extended = 1;
  133. break;
  134. case 'G':
  135. config.extended = 0;
  136. break;
  137. case 'P':
  138. #ifdef HAVE_LIBPCRE
  139. config.extended = 0;
  140. config.perl = 1;
  141. #else
  142. fprintf(stderr,
  143. "%s: Support for Perl regular expressions not "
  144. "compiled in\n");
  145. exit(2);
  146. #endif /* HAVE_LIBPCRE */
  147. break;
  148. case 'h':
  149. help ();
  150. break;
  151. case 'i':
  152. config.ignorecase = 1;
  153. break;
  154. case 'm':
  155. config.format = folder_format (optarg);
  156. break;
  157. case 'l':
  158. config.lock = lock_method (optarg);
  159. break;
  160. case 'p':
  161. config.action = PIPE;
  162. pipecmd = xstrdup (optarg);
  163. break;
  164. case 'V':
  165. version ();
  166. break;
  167. case 'v':
  168. config.invert = 1;
  169. break;
  170. case 'H':
  171. config.headers = 1;
  172. break;
  173. case 'B':
  174. config.body = 1;
  175. break;
  176. case 's':
  177. config.merr = 0;
  178. break;
  179. case 201:
  180. config.lock = 0;
  181. break;
  182. case 'r':
  183. config.recursive = 1;
  184. break;
  185. case 200:
  186. config.dedup = 1;
  187. break;
  188. case 'n':
  189. {
  190. switch (optarg[0])
  191. {
  192. case 'd':
  193. config.dedup = 1;
  194. break;
  195. case 'l':
  196. config.lock = 0;
  197. break;
  198. default:
  199. fprintf(stderr, "%s: invalid option -- n%c\n",
  200. APPNAME, optarg[0]);
  201. exit(2);
  202. }
  203. }
  204. } /* switch */
  205. /* }}} */
  206. } /* while */
  207. if ((config.body == 0) && (config.headers == 0))
  208. {
  209. config.body = 1;
  210. config.headers = 1;
  211. }
  212. if (config.format == MAILDIR && config.action == WRITE)
  213. {
  214. gethostname (config.hostname, HOST_NAME_SIZE);
  215. config.pid = (int) getpid ();
  216. }
  217. cs = (checksum_t *) xmalloc (sizeof (checksum_t));
  218. cs->md5 = (char **) xcalloc (1, sizeof (char **));
  219. cs->n = 0;
  220. if (optind < argc && ! haveregex)
  221. {
  222. regex_s = xstrdup (argv[optind]);
  223. haveregex = 1;
  224. ++optind;
  225. } /* if */
  226. if (haveregex)
  227. {
  228. #ifdef HAVE_LIBPCRE
  229. if (config.perl)
  230. /* {{{ */
  231. {
  232. pcre_pattern = pcre_compile (regex_s,
  233. (config.ignorecase ? PCRE_CASELESS : 0),
  234. &error, &errptr, NULL);
  235. if (pcre_pattern == NULL)
  236. {
  237. if (config.merr)
  238. fprintf (stderr, "%s: %s: %s\n", APPNAME, regex_s, error);
  239. exit(2);
  240. }
  241. }
  242. /* }}} */
  243. else
  244. #endif /* HAVE_LIBPCRE */
  245. /* {{{ */
  246. {
  247. int flag1 = 0, flag2 = 0;
  248. if (config.ignorecase)
  249. flag1 = REG_ICASE;
  250. if (config.extended)
  251. flag2 = REG_EXTENDED;
  252. errcode = regcomp (&posix_pattern, regex_s,
  253. (flag1 | flag2 | REG_NEWLINE ));
  254. if (0 != errcode)
  255. {
  256. if (config.merr)
  257. {
  258. regerror (errcode, &posix_pattern, errbuf, BUFSIZ);
  259. fprintf (stderr, "%s: %s: %s\n", APPNAME, regex_s, errbuf);
  260. }
  261. exit (2);
  262. } /* if */
  263. } /* if */
  264. /* }}} */
  265. } /* if */
  266. else
  267. usage ();
  268. if (optind == (argc - 1))
  269. singlefile = 1;
  270. while (optind < argc)
  271. /* {{{ */
  272. {
  273. if (config.action == DELETE) {
  274. tmpp = tmpfile_open (argv[optind]);
  275. /* If we're root, copy {owner, group, perms} of mailbox to the tmpfile
  276. * so rename() will thus retain the original's ownership & permissions.
  277. */
  278. if (geteuid() == 0) {
  279. struct stat s;
  280. if (stat(argv[optind], &s) != -1) {
  281. if (fchown(fileno(tmpp), s.st_uid, s.st_gid) == -1)
  282. if (config.merr) perror(tmpfilename);
  283. if (fchmod(fileno(tmpp), s.st_mode) == -1)
  284. if (config.merr) perror(tmpfilename);
  285. }
  286. else if (config.merr) perror(argv[optind]);
  287. }
  288. }
  289. boxname = xstrdup (argv[optind]);
  290. if (config.recursive)
  291. recursive_scan (argv[optind]);
  292. else
  293. scan_mailbox (argv[optind]);
  294. havemailbox = 1;
  295. if (config.action == COUNT)
  296. {
  297. if (singlefile)
  298. fprintf (stdout, "%i\n", count);
  299. else
  300. {
  301. if (0 == strcmp ("-", argv[optind]))
  302. fprintf (stdout, "(standard input):%i\n", count);
  303. else
  304. fprintf (stdout, "%s:%i\n", argv[optind], count);
  305. }
  306. }
  307. if (config.action == DELETE)
  308. {
  309. #ifdef HAVE_LIBZ
  310. if (config.format == ZMBOX)
  311. gzclose (tmpp);
  312. #endif /* HAVE_LIBZ */
  313. if (config.format == MBOX)
  314. fclose (tmpp);
  315. rename (tmpfilename, argv[optind]);
  316. }
  317. ++optind;
  318. } /* while */
  319. /* }}} */
  320. if (! havemailbox)
  321. /* {{{ */
  322. {
  323. config.format = MBOX;
  324. scan_mailbox ("-");
  325. if (config.action == COUNT)
  326. fprintf (stdout, "%i\n", count);
  327. }
  328. /* }}} */
  329. return 0;
  330. } /* main */
  331. /* }}} */