filter.c 2.3 KB

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