📄 sms.c
字号:
#include <ctype.h>#include <stdarg.h>#include <stdlib.h>#include "main.h"#include "regex.h"#include "sms.h"#include "config.h"#define BYTEWIDTH 8extern int exitcode;/* This is a list with all available keywords/instructions */typedef enum { KEYWORD_NONE, /* must be the first one */ KEYWORD_ABORT, KEYWORD_BEGIN, KEYWORD_BREAK, KEYWORD_CONFIG, KEYWORD_CREATE, KEYWORD_DELETE, KEYWORD_ELSE, KEYWORD_END, KEYWORD_ENDIF, KEYWORD_FILTER, KEYWORD_IF, KEYWORD_INCLUDE, KEYWORD_LOG, KEYWORD_LOGFILE, KEYWORD_MAXPARTS, KEYWORD_MULTIPART, KEYWORD_NOT, KEYWORD_OPTIONS, KEYWORD_OUTPUT, KEYWORD_OUTSIZE, KEYWORD_PATH, KEYWORD_PHONE, KEYWORD_PORT, KEYWORD_PROGARGS, KEYWORD_PROGRAM, KEYWORD_REPLACE, KEYWORD_RUN, KEYWORD_SEARCH, KEYWORD_SERVER, KEYWORD_SHOWLOG, KEYWORD_SYSTEM, KEYWORD_UNBREAK, KEYWORD_WHEN, KEYWORD_WHENNOT, KEYWORD_EXIT, KEYWORD_LAST /* must be the last one */} KeyId;/* This is a node in the linked list with NOT-expressions that may be appended to a normal RE */struct Notre { struct re_pattern_buffer buf; char fastmap[(1 << BYTEWIDTH)]; char *search; char *log; /* log text to output when this is used (the first time) */ char *file; /* where this was found */ int lineno; /* line number */ struct Notre *next;};/* This is a node in the linked list with expressions that should be evaluated when the associated IF-expression matches */struct if_action { KeyId instruction; /* what instruction is this? */ char *param; /* parameter(s) to this instruction */ char *log; /* malloc()ed text to log when this is performed */ struct if_action *next; /* linked to the next if_action node */};struct RE { struct re_registers regs; /* search registers */ struct re_pattern_buffer buf; char fastmap[(1 << BYTEWIDTH)]; char *search; char *replace; char *log; /* log text to output when this is used (the first time) */ int prio; /* priority of this regex */ /* from where the search/replace pair comes from */ char *file; int lineno; int checker; /* used to prevent multiple loggins on the same line and "area" */ int replaceline; /* set to line number it has been used in */ int looper; /* used to prevent infinite looping */ struct RE *sublist; /* if this expression matches, this list should be appended to the main list */ long flags; #define RE_LOOP (1<<0) /* this check will be repeated on each line */#define RE_NOCASE (1<<1) /* no case significance */#define RE_SUBJECT (1<<2) /* only replace in subject */#define RE_FROM (1<<3) /* only replace in from */#define RE_FROM_ADDRESS (1<<16) /* only replace in from-email address */#define RE_ADDRESS RE_FROM_ADDRESS /* to make the old define still work */#define RE_TO (1<<17) /* only work in to */#define RE_TO_ADDRESS (1<<18) /* only work in to-email address */#define RE_BODY (1<<4) /* only replace in body */#define RE_ONCE (1<<5) /* once in a whole session */#define RE_FULLBODY (1<<6) /* replace on huge bite of a no-newlines buffer */#define RE_HEADER (1<<7) /* replace in header */#define RE_ABORT (1<<8) /* abort on match */#define RE_CONDITIONAL (1<<9) /* conditional search/replace */#define RE_REVERSED (1<<10) /* reversed action, i.e if it doesn't match */#define RE_DELETE (1<<11) /* delete named file */ char *delete;#define RE_CREATE (1<<12) /* create named file */ char *create;#define RE_SYSTEM (1<<13) /* run specified shell command line */ char *system;#define RE_DONE (1<<14) /* mark an IF-expression as done */#define RE_CONFIG (1<<15) /* read specified config file! */ char *config; struct Notre *not; /* list of non-matches */ struct if_action *action; /* list of attached actions */ struct RE *next;};typedef enum { COND_FALSE, /* must be first and zero */ COND_TRUE, COND_UNDEFINED, /* default in all cases, if 'begin' is found it acts as if TRUE */ COND_LAST} Condition;static int replaceregex(struct RE *re, unsigned char **line, struct re_registers *regs);char output[512]="F: $from S: $subject B: $body";char multipart[512]="[$index/$numparts]";char phone[256]=""; /* no default phone number */char smsserver[256]=""; /* no default server */unsigned short smsserverport=6793; /* default port according to sms server sources *//* no default ones for these: */char program[256]="";char run[256]="";char progargs[256]="";int prio_min = PRIO_DEFAULT;int prio_max = PRIO_DEFAULT;int maxdisplay = MAX_DISPLAY;int maxparts = MAX_PARTS; /* the maximum number parts to generate, each is max MAX_DISPLAY bytes big */FILE *logfile=NULL; /* write logs to this file pointer, NULL makes stderr */char forced_logfile = FALSE; /* override the logfile keyword *//* maximum number of directories supported in the path: */#define MAX_INCLUDE_PATH 25char *includepath[MAX_INCLUDE_PATH];int includeno=0;/* this is a bitpattern with all set active filters */long active_filter=0;long filter_lines=0; /* number of lines to cut off, or zero */#define FILTER_IGNORE (1<<0)#define FILTER_HTML (1<<1)extern int viewlog;#if 0FILE *testfp=stdin;#endif/* Log the specified data: */void logf(LogfType type, char *fmt, ...){ static char *prefix[]={ "", /* info */ "BREAK: ", "ERROR: ", "DEBUG: ", "REGEX: ", "WARNING: ", "ABORT: ", "IF: ", "SEARCH: ", "NOT: ", "DELETE: ", "CREATE: ", "SYSTEM: ", "CONFIG: ", "ACTION: ", "EXIT: ", }; char *s="=== %Y-%m-%d %T mail2sms " VERSION" started ===\n"; char e[2560]; time_t now; va_list ap; struct tm *tms; static char init=0; FILE *stream; if(!(viewlog & (1 << type))) { return; } stream=logfile?logfile:stderr; if(!init) { init = TRUE; now=time(NULL); tms = localtime(&now); strftime(e, sizeof(e), s, tms); fputs(e, stream); } va_start(ap, fmt); vsprintf(e, fmt, ap); va_end(ap); if( type < LOGF_LAST) fputs(prefix[type], stream); else fputs("BAD: ", stream); fputs(e, stream);}void ShowLog(char *toggle){ static char *logwords[]={ "INFO", /* info */ "BREAK", "ERROR", "DEBUG", "REGEX", "WARNING", "ABORT", "IF", "SEARCH", "NOT", "DELETE", "CREATE", "SYSTEM", "CONFIG", "ACTION", "EXIT", }; char *p; int i; char add=TRUE; p = strtok(toggle, " \t,"); while(p) { switch(*p) { case '+': add= TRUE; p++; break; case '-': add = FALSE; p++; break; } if(!strcasecmp("all", p)) { if(add) viewlog = 0xffffff; else viewlog = 0; } else { for(i=0; i< sizeof(logwords)/sizeof(logwords[0]); i++) { if(!strcasecmp(p, logwords[i])) { if(add) viewlog |= (1 << i); else viewlog &= ~(1 << i); i=0; break; } } if(i) { logf(LOGF_WARN, "unknown showlog keyword: %s\n", p); } } p = strtok(NULL, " \t,"); }}void AddPath(char *dir){ if(includeno < MAX_INCLUDE_PATH) { includepath[ includeno++ ] = strdup(dir); } else logf(LOGF_WARN, "max number of path entries (%d) already reached\n", MAX_INCLUDE_PATH);}/* The follow function is a plain rip-off from Hypermail (even though * I wrote it all) and I'll try to create the structs and defines to * leave it exactly as in hypermail to enable future updates when the * hypermail one develops */#define NONAME ""#define NOEMAIL ""/*** Push byte onto a buffer realloc the buffer if needed.**** Returns the (new) buffer pointer.*/char *PushByte(struct Push *push, char byte) /* byte to append */{#define PUSH_DEFAULT 32 /* default strings are this big */ if(!push) return NULL; /* this is a sever error */ if(!push->string) { push->string = (char *)malloc(PUSH_DEFAULT); if(!push->string) return NULL; /* error again */ push->alloc = PUSH_DEFAULT; push->len = 0;#ifdef DEBUG_PUSH fprintf(stderr, "PUSH: INIT at index 0 alloc %d\n", PUSH_DEFAULT);#endif } else if((push->len+2) >= push->alloc) { char *newptr; newptr = (char *)realloc(push->string, push->alloc*2); /* double the size */ if(!newptr) { return push->string; /* live on the old one! */ } push->alloc *= 2; /* enlarge the alloc size */ push->string = newptr; /* use the new buffer */#ifdef DEBUG_PUSH fprintf(stderr, "PUSH: REALLOC at index %d to alloc %d\n", push->len, push->alloc);#endif }#ifdef DEBUG_PUSH fprintf(stderr, "PUSH: WRITE '%c' at index %d\n", byte, push->len); #endif push->string[push->len++]=byte; push->string[push->len]=0; /* zero terminate */ return push->string; /* current buffer */}/*** Push a string onto a buffer, and realloc the buffer if needed.**** Returns the (new) buffer pointer.*/char *PushString(struct Push *push, char *append) /* string to append */{ char *string=NULL; while(append && *append) { /* continue until zero termination */ string = PushByte(push, *append); append++; /* get next character */ } return string; /* this is the new buffer */}/*** Push a limited string onto a buffer, and realloc the buffer if needed.**** Returns the (new) buffer pointer.*/char *PushNString(struct Push *push, char *append, /* string to append */ int size) /* maximum number of bytes to copy */{ char *string=NULL; while(append && *append && size--) { /* continue until zero termination */ string = PushByte(push, *append); append++; /* get next character */ } return string; /* this is the new buffer */}/*** Grabs the name and email address from a From: header.** This could get tricky; I've tried to keep it simple.** Should be able to handle all the addresses below:**** From: user [no @]** From: kent (Kent Landfield) [no @ - with comment]** From: <user@node.domain> [no text name, use email as text name]** From: Kent Landfield <kent> [text name but no @]** From: (kent) [comment - no email address]** From: "" <kent> [email address but null comment]** From: [blank From: line]** From: uu.net!kent [uucp addresses - no comment]** From: uu.net!kent (kent) [uucp addresses - with comment]** From: "(Joe Bloggs)" <joe@anorg.com> ** From: "Roy T. Fielding" <fielding@kiwi.ics.uci.edu>** From: kent@localhost** From: kent@uu.net (Kent Landfield)** From: (George Burgyan) <gburgyan@cybercon.com>** From: <gburgyan@cybercon.com> (George Burgyan) ** From: Kent B. Landfield <kent@landfield.com>** From: IN%"fekete+reply@c2.net" 26-JAN-1997 13:28:55.36** From: IN%"vicric@panix.com" "Vicki Richman" 13-AUG-1996 10:54:33.38** From: US2RMC::"lwv26@cas.org" "Larry W. Virden, x2487" 22-OCT-1994 09:44:21.44** From: Mail Delivery Subsystem <postmaster@igc.apc.org>** From: Self <ehasbrouck>** From: adam@eden.apana.org.au (Adam Frey)** From: faqserv@penguin-lust.mit.edu** From: nc0548@freebsd.netcom.com (Mark Hittinger)** From: "- Pam Greene, one of the *.answers moderators" <pgreene@MIT.EDU>** From: "Felan shena Thoron'edras" <felan@netcom.com>** From: David Muir Sharnoff <muir@idiom.com>** From: A.J.Doherty@reading.ac.uk (Andy Doherty)** From: Jordan Hubbard <jkh@vector.eikon.e-technik.tu-muenchen.de>** From: ZXPAN%SLACVM.BITNET@MITVMA.MIT.EDU** From: afs!piz!alf@uu5.psi.com (Alf the Poet)** From: answers@cp.tn.tudelft.nl ("Moderator *.answers")** From: mdw%merengue@merengue.oit.unc.edu (Matt Welsh)** From: bgoffe@whale.st.usm.edu (William L. Goffe)** * This is an interesting new one (1998-11-26):* From: <name.hidden@era.ericsson.se>汵ame.Hidden@era.ericsson.se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -