ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/FreeBSDAdmin/Mail/SpamUpdate.c
(Generate patch)

Comparing FreeBSDAdmin/Mail/SpamUpdate.c (file contents):
Revision 816 by douglas, 2006-07-03T19:12:17-07:00 vs.
Revision 822 by douglas, 2006-07-04T16:57:34-07:00

# Line 6 | Line 6
6  
7   #include <assert.h>
8   #include <sys/types.h>
9 #include <regex.h>
9   #include <setjmp.h>
10 + #include <signal.h>
11   #include <stdbool.h>
12   #include <stdio.h>
13   #include <sys/wait.h>
# Line 28 | Line 28
28   static jmp_buf environment;
29   static char *error = NULL;
30   static bool debug = false;
31 + static sigset_t set;
32   static MAILSTREAM *streams[2];
33 + static uint8_t critical = 0;
34   static unsigned long *messages[] = { NULL, NULL };
35   static size_t counts[] = { 0, 0 };
36  
# Line 68 | Line 70 | static void *mcheck(void *value, jmp_buf
70          return value;
71   }
72  
71 /*static*/ int regcheck(int value, const regex_t *regex, jmp_buf environment)
72 {
73        if (value && value != REG_NOMATCH)
74        {
75                char exception[regerror(value, regex, NULL, 0)];
76
77                regerror(value, regex, exception, sizeof (exception));
78                longjmp(environment, (int)exception);
79        }
80
81        return value;
82 }
83
73   static void learn()
74   {
75          typedef struct { const char *verb, *args, *mailbox; } Job;
# Line 95 | Line 84 | static void learn()
84                  
85                  mail_search_full(streams[job - jobs], NIL, &search, SE_UID);
86  
87 <                /*unsigned long *messages_ = messages[job - jobs];
88 <                size_t count = counts[job - jobs];
87 >                const unsigned long *messages_ = messages[job - jobs];
88 >                const size_t count = counts[job - jobs];
89                  char files[count][sizeof (TEMP) / sizeof (char)];
90  
91                  for (size_t index = 0; index != count; ++index)
# Line 116 | Line 105 | static void learn()
105                          check(close(file), environment);
106                  }
107  
108 <                int pipe_[2];
108 >                int between[2];
109  
110 <                check(pipe(pipe_), environment);
110 >                check(pipe(between), environment);
111  
112                  pid_t assassin;
113  
114                  if (!(assassin = check(fork(), environment)))
115                  {
116 <                        check(dup2(pipe_[1], 1), environment);
117 <                        check(close(pipe_[0]), environment);
116 >                        check(dup2(between[1], 1), environment);
117 >                        check(close(between[0]), environment);
118  
119                          const char *args[count ? count + 3 : 5];
120                          
# Line 146 | Line 135 | static void learn()
135                          check(execv(ASSASSIN, (char *const *)args), environment);
136                  }
137  
138 <                check(close(pipe_[1]), environment);
138 >                check(close(between[1]), environment);
139 >
140 >                int in[2];
141 >
142 >                check(pipe(in), environment);
143  
144                  pid_t sed;
145  
146                  if (!(sed = check(fork(), environment)))
147                  {
148 <                        check(dup2(pipe_[0], 0), environment);
148 >                        check(dup2(between[0], 0), environment);
149 >                        check(dup2(in[1], 1), environment);
150 >                        check(close(in[0]), environment);
151                          check(execl(SED, "sed", "-e", INDENT, "-e", PERIOD, NULL), environment);
152                  }
153  
154 <                check(close(pipe_[0]), environment);
154 >                check(close(between[0]), environment);
155 >                check(close(in[1]), environment);
156 >
157 >                FILE *sed_ = fdopen(in[0], "r");
158 >                size_t size;
159 >
160 >                do
161 >                {
162 >                        char *line = fcheck(fgetln(sed_, &size), sed_, environment);
163 >
164 >                        fwrite(line, size, sizeof (char), stdout);
165 >                }
166 >                while (size != 0);
167 >
168 >                if (fclose(sed_))
169 >                        longjmp(environment, 1);
170  
171                  int status;
172  
# Line 164 | Line 174 | static void learn()
174                  check(waitpid(sed, &status, 0), environment);
175  
176                  for (size_t index = 0; index != count; ++index)
177 <                        check(unlink(files[index]), environment);*/
177 >                        check(unlink(files[index]), environment);
178          }
179   }
180  
# Line 172 | Line 182 | static void deliver()
182   {
183          printf("\nDelivering messages from the " POSITIVE " mailbox:\n");
184  
185 <        unsigned long *messages_ = messages[1];
186 <        size_t count = counts[1];
185 >        const unsigned long *messages_ = messages[1];
186 >        const size_t count = counts[1];
187 >
188          streams[0] = mcheck(mail_open(streams[0], "INBOX", (debug ? OP_DEBUG : 0) | OP_SHORTCACHE), environment);
189  
190          for (int index = 0; index != count; ++index)
# Line 228 | Line 239 | static void deliver()
239                          {
240                                  if (size_ == 1)
241                                  {
242 +                                        assert(*line == '\n');
243 +
244                                          header_ = false;
245  
246                                          goto crlf;
# Line 265 | Line 278 | crlf:                          assert(message);
278          printf("    %u message(s) delivered.\n", count);
279   }
280  
281 + void delete()
282 + {
283 +        char *mailboxes[] = { NEGATIVE, POSITIVE };
284 +
285 +        for (char **mailbox = mailboxes; mailbox != mailboxes + sizeof (mailboxes) / sizeof (*mailboxes); ++mailbox)
286 +        {
287 +                printf("\nDeleting messages from the %s mailbox:\n", *mailbox);
288 +
289 +                const unsigned long *messages_ = messages[mailbox - mailboxes];
290 +                const size_t count = counts[mailbox - mailboxes];
291 +                char *sequence = calloc(1, sizeof (char));
292 +                size_t size = 1;
293 +
294 +                for (size_t index = 0; index != count; ++index)
295 +                {
296 +                        char *message;
297 +
298 +                        asprintf(&message, "%lu%s", messages_[index], index + 1 != count ? "," : "");
299 +
300 +                        sequence = realloc(sequence, (size += strlen(message)) * sizeof (char));
301 +
302 +                        strlcat(sequence, message, size);
303 +                        free(message);
304 +                }
305 +
306 +                mail_setflag_full(streams[mailbox - mailboxes], sequence, "\\Deleted", ST_UID | ST_SILENT);
307 +                free(sequence);
308 +                printf("    %u message(s) marked deleted.\n", count);
309 +        }
310 + }
311 +
312   int main(int argc, char *argv[])
313   {
314          int exception;
# Line 294 | Line 338 | int main(int argc, char *argv[])
338                  else
339                          return printf("Usage: %s [-debug]\n", argv[0]), 1;
340  
341 <        printf("Information:\n    If you receive Spam in your Inbox mailbox, copy it to the " NEGATIVE " mailbox.\n\n    If you receive mail that is not Spam in your Assassin mailbox, copy it to the " POSITIVE " mailbox.\n");
341 >        printf("Information:\n    If you receive spam in your Inbox mailbox, copy it to the " NEGATIVE " mailbox.\n\n    If you receive mail that is not spam in your Spam/Assassin mailbox, copy it to the " POSITIVE " mailbox.\n");
342 >
343 >        check(sigemptyset(&set), environment);
344 >        check(sigaddset(&set, SIGHUP), environment);
345 >        check(sigaddset(&set, SIGINT), environment);
346  
347   #       include <c-client/linkage.c>
348  
# Line 303 | Line 351 | int main(int argc, char *argv[])
351  
352          learn();
353          deliver();
354 +        delete();
355          mail_close(streams[0]);
356          mail_close(streams[1]);
357          free(messages[0]);
# Line 324 | Line 373 | void mm_searched(MAILSTREAM *stream, uns
373                          assert(messages[index]);
374  
375                          messages[index][counts[index] - 1] = number;
376 +
377 +                        break;
378                  }
379   }
380  
# Line 348 | Line 399 | void mm_login(NETMBX *mb, char *user, ch
399  
400   void mm_critical(MAILSTREAM *stream)
401   {
402 <        fprintf(stderr, "critical\n");
402 >        if (!critical++)
403 >                check(sigprocmask(SIG_BLOCK, &set, NULL), environment);
404   }
405  
406   void mm_nocritical(MAILSTREAM *stream)
407   {
408 <        fprintf(stderr, "nocritical\n");
408 >        if (!--critical)
409 >                check(sigprocmask(SIG_UNBLOCK, &set, NULL), environment);
410   }
411  
412   long mm_diskerror(MAILSTREAM *stream, long errcode, long serious)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines