+#ifdef NOTIFY
+ else if (parse_identifier(filter,CUS "notify"))
+ {
+ /*
+ notify-command = "notify" { notify-options } ";"
+ notify-options = [":method" string]
+ [":priority" string]
+ [":message" string]
+ */
+
+ int m;
+ struct String method;
+ struct String priority;
+ struct String message;
+ struct Notification *already;
+ string_item *recipient;
+ struct String body;
+ uschar *envelope_from,*envelope_to;
+
+ if (!filter->require_notify)
+ {
+ filter->errmsg=CUS "missing previous require \"notify\";";
+ return -1;
+ }
+ method.character=(uschar*)0;
+ method.length=-1;
+ priority.character=(uschar*)0;
+ priority.length=-1;
+ message.character=(uschar*)0;
+ message.length=-1;
+ recipient=NULL;
+ body.length=-1;
+ body.character=(uschar*)0;
+ envelope_from=expand_string("$sender_address");
+ envelope_to=expand_string("$local_part_prefix$local_part$local_part_suffix@$domain");
+ for (;;)
+ {
+ if (parse_white(filter)==-1) return -1;
+ if (parse_identifier(filter,CUS ":method")==1)
+ {
+ if (parse_white(filter)==-1) return -1;
+ if ((m=parse_string(filter,&method))!=1)
+ {
+ if (m==0) filter->errmsg=CUS "method string expected";
+ return -1;
+ }
+ if (method.length>7 && strncmp(method.character,"mailto:",7)==0)
+ {
+ if (parse_mailto_uri(filter,method.character+7,&recipient,&body)==-1) return -1;
+ }
+ }
+ else if (parse_identifier(filter,CUS ":priority")==1)
+ {
+ if (parse_white(filter)==-1) return -1;
+ if ((m=parse_string(filter,&priority))!=1)
+ {
+ if (m==0) filter->errmsg=CUS "priority string expected";
+ return -1;
+ }
+ }
+ else if (parse_identifier(filter,CUS ":message")==1)
+ {
+ if (parse_white(filter)==-1) return -1;
+ if ((m=parse_string(filter,&message))!=1)
+ {
+ if (m==0) filter->errmsg=CUS "message string expected";
+ return -1;
+ }
+ }
+ else break;
+ }
+ if (parse_semicolon(filter)==-1) return -1;
+
+ if (method.length==-1)
+ {
+ if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
+ {
+ debug_printf("Ignoring method-less notification.\n");
+ }
+ }
+ else
+ {
+ for (already=filter->notified; already; already=already->next)
+ {
+ if (already->method.length==method.length
+ && (method.length==-1 || strcmp(already->method.character,method.character)==0)
+ && already->priority.length==priority.length
+ && (priority.length==-1 || strcmp(already->priority.character,priority.character)==0)
+ && already->message.length==message.length
+ && (message.length==-1 || strcmp(already->message.character,message.character)==0))
+ break;
+ }
+ if (already==(struct Notification*)0)
+ /* New notification, process it */
+ {
+ struct Notification *sent;
+ sent=store_get(sizeof(struct Notification));
+ sent->method=method;
+ sent->priority=priority;
+ sent->message=message;
+ sent->next=filter->notified;
+ filter->notified=sent;
+ if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
+ {
+ debug_printf("Notification to `%s'.\n",method.character);
+ }
+#ifndef COMPILE_SYNTAX_CHECKER
+ if (exec)
+ {
+ string_item *p;
+ header_line *h;
+ int pid,fd;
+
+ if ((pid = child_open_exim2(&fd,envelope_to,envelope_to))>=1)
+ {
+ FILE *f;
+
+ f = fdopen(fd, "wb");
+ fprintf(f,"From: %s\n",envelope_to);
+ for (p=recipient; p; p=p->next) fprintf(f,"To: %s\n",p->text);
+ for (h = header_list; h != NULL; h = h->next)
+ if (h->type == htype_received) fprintf(f,"%s",h->text);
+ fprintf(f,"Subject: %s\n",message.length==-1 ? CUS "notification" : message.character);
+ fprintf(f,"\n");
+ if (body.length>0) fprintf(f,"%s\n",body.character);
+ fflush(f);
+ (void)fclose(f);
+ (void)child_close(pid, 0);
+ }
+ }
+#endif
+ }
+ else
+ {
+ if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
+ {
+ debug_printf("Repeated notification to `%s' ignored.\n",method.character);
+ }
+ }
+ }
+ }
+#endif