filter.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "common.h"
  2. #include "send.h"
  3. Biobuf bin;
  4. int rmail, tflg;
  5. char *subjectarg;
  6. char *findbody(char*);
  7. void
  8. main(int argc, char *argv[])
  9. {
  10. message *mp;
  11. dest *dp;
  12. Reprog *p;
  13. Resub match[10];
  14. char file[MAXPATHLEN];
  15. Biobuf *fp;
  16. char *rcvr, *cp;
  17. Mlock *l;
  18. String *tmp;
  19. int i;
  20. int header, body;
  21. header = body = 0;
  22. ARGBEGIN {
  23. case 'h':
  24. header = 1;
  25. break;
  26. case 'b':
  27. header = 1;
  28. body = 1;
  29. break;
  30. } ARGEND
  31. Binit(&bin, 0, OREAD);
  32. if(argc < 2){
  33. fprint(2, "usage: filter rcvr mailfile [regexp mailfile ...]\n");
  34. exits("usage");
  35. }
  36. mp = m_read(&bin, 1, 0);
  37. /* get rid of local system name */
  38. cp = strchr(s_to_c(mp->sender), '!');
  39. if(cp){
  40. cp++;
  41. mp->sender = s_copy(cp);
  42. }
  43. dp = d_new(s_copy(argv[0]));
  44. strecpy(file, file+sizeof file, argv[1]);
  45. cp = findbody(s_to_c(mp->body));
  46. for(i = 2; i < argc; i += 2){
  47. p = regcomp(argv[i]);
  48. if(p == 0)
  49. continue;
  50. if(regexec(p, s_to_c(mp->sender), match, 10)){
  51. regsub(argv[i+1], file, sizeof(file), match, 10);
  52. break;
  53. }
  54. if(header == 0 && body == 0)
  55. continue;
  56. if(regexec(p, s_to_c(mp->body), match, 10)){
  57. if(body == 0 && match[0].sp >= cp)
  58. continue;
  59. regsub(argv[i+1], file, sizeof(file), match, 10);
  60. break;
  61. }
  62. }
  63. /*
  64. * always lock the normal mail file to avoid too many lock files
  65. * lying about. This isn't right but it's what the majority prefers.
  66. */
  67. l = syslock(argv[1]);
  68. if(l == 0){
  69. fprint(2, "can't lock mail file %s\n", argv[1]);
  70. exit(1);
  71. }
  72. /*
  73. * open the destination mail file
  74. */
  75. fp = sysopen(file, "ca", MBOXMODE);
  76. if (fp == 0){
  77. tmp = s_append(0, file);
  78. s_append(tmp, ".tmp");
  79. fp = sysopen(s_to_c(tmp), "cal", MBOXMODE);
  80. if(fp == 0){
  81. sysunlock(l);
  82. fprint(2, "can't open mail file %s\n", file);
  83. exit(1);
  84. }
  85. syslog(0, "mail", "error: used %s", s_to_c(tmp));
  86. s_free(tmp);
  87. }
  88. Bseek(fp, 0, 2);
  89. if(m_print(mp, fp, (char *)0, 1) < 0
  90. || Bprint(fp, "\n") < 0
  91. || Bflush(fp) < 0){
  92. sysclose(fp);
  93. sysunlock(l);
  94. fprint(2, "can't write mail file %s\n", file);
  95. exit(1);
  96. }
  97. sysclose(fp);
  98. sysunlock(l);
  99. rcvr = argv[0];
  100. if(cp = strrchr(rcvr, '!'))
  101. rcvr = cp+1;
  102. logdelivery(dp, rcvr, mp);
  103. exit(0);
  104. }
  105. char*
  106. findbody(char *p)
  107. {
  108. if(*p == '\n')
  109. return p;
  110. while(*p){
  111. if(*p == '\n' && *(p+1) == '\n')
  112. return p+1;
  113. p++;
  114. }
  115. return p;
  116. }