alex.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 901 行 · 第 1/2 页
C
901 行
/**************************************************************//* FILE: alex.c *//* AUTHOR: Peter Walburn @ DEC (EUEG) Reading, England. *//* DATE: February 28, 1990 *//* CONTENTS: Address Extraction Utility *//**************************************************************/static char rcsid[] = "$Id: alex.c,v 1.14 90/11/25 19:04:05 sharpe Exp $";#include "../h/mh.h"#include "../h/addrsbr.h"#include "../h/aliasbr.h"#include "../h/dropsbr.h"#include <stdio.h>#include "../zotnet/mts.h"#include <ctype.h>#include <errno.h>#include <setjmp.h>#include <sys/types.h>#include <signal.h>#include <sys/file.h>#include <limits.h>#define MAKESTR(X) (char *)malloc(strlen(X) + 1)#define MAKESTRUCT(X) (struct X *)malloc(sizeof(struct X))#define MAKEARGV(X) (char **)malloc(sizeof(char *) * X)#define NULLFILE (FILE *)NULLstatic struct swit switches[] = { /* switches is a structure storing */#define ADDRSW 0 /* all the options for 'alex'. */ "address string", 0, /* It is used for parsing the */ /* command line and also for */#define ALIASW 1 /* displaying all the options when */ "alias name", 0, /* the -help option is used. */#define COMPSW 2 "compress", 0,#define NCOMPSW 3 "nocompress", 0,#define FIELDSW 4 "field name{/name}", 0,#define NFIELDSW 5 "nofield name{/name}", 0,#define GLOBSW 6 "global", 0,#define NGLOBSW 7 "noglobal", 0,#define NAMESW 8 "name name", 0,#define QUERYSW 9 "query", 0,#define NQUERYSW 10 "noquery", 0,#define REPLSW 11 "replace", 0,#define NREPLSW 12 "noreplace", 0,#define WIDTHSW 13 "width n", 0,#define HELPSW 14 "help", 0, NULL, NULL};/* */struct fields { /* Structure for storing which fields to search */ char **priorities; struct fields *next;}; struct entry { /* Structure for storing aliases */ char *words; char **address_list; struct entry *next;};struct entry *get_alias ();struct entry *read_alias_file ();struct fields *add_field ();static void del_field (), del_all_fields (), output_aliases (), add_alias_entry (), compress_alias ();/* ARGSUSED */main (argc, argv)int argc;char *argv[];{ char *cp, **argp, **ap, *folder = NULL, /* Stores the mail folder to be used. */ *maildir, /* Stores full path name for mail folder. */ *alias_file = NULL, /* Stores name of alias file to be used. */ *alias_name = NULL, /* Stores name to be used for alias. */ *msgs[MAXARGS], /* Stores the messages to be searched. */ buf[BUFSIZ], /* General purpose buffer. */ *msg = NULL, /* Holds path of message being searched. */ name[NAMESZ], /* Field name being looked at in message. */ *arguments[MAXARGS], *address = NULL, /* Stores address specified on command line. */ *addr1; /* Stores full address from field. */ int msgp = 0, compnum, count = 0, /* General purpose index variable. */ replace = 0, /* flag which is set if -replace option given. */ compress = 0, /* flag set if -compress option given. */ query = 0, /* flag set if -query option given. */ width = 72, /* used for specifying maximum width of alias line; */ /* 72 is default. Can be changed with -width option. */ global = 0, /* Used for specifying if all occurrences of an alias */ /* in alias file should be updated. */ alias_num = 0, /* Counts the number of occurrences of an alias. */ low_msg, /* Set to the lowest message in specified sequence. */ hgh_msg, /* Set to highest message in specified sequence. */ found, /* Flag set if header field is found. */ do_default = 1,/* If no field values given, then use default. */ msgnum, state; /* state is used in searching mail messages; it */ /* corresponds to a header field or the body of a */ /* mail message. */ static struct fields *ref; static struct msgs *mp = NULL; /* Holds info about current , highest */ /* and lowest message, etc. */ static struct mailname *mail_name; /* Holds all info about a mail address */ FILE *in, *out; static struct fields *field_vals = NULL; /* Holds header fields to search */ static struct entry *alias_lists = NULL; /* Holds alias file info */ static struct entry *new_alias = NULL; /* Holds new alias info */ invo_name = r1bindex (argv[0], '/'); if ((cp = m_find (invo_name)) != NULL) { ap = brkstring (cp = getcpy (cp), " ", "\n"); ap = copyip (ap, arguments); } else ap = arguments; (void) copyip (argv + 1, ap); argp = arguments; while (cp = *argp++) { if (*cp == '-') switch (smatch (++cp, switches)) { case AMBIGSW: ambigsw (cp, switches); done (1); case UNKWNSW: adios (NULLCP, "-%s unknown", cp); case HELPSW: (void) sprintf (buf, "%s [+folder] [switches]", invo_name); help (buf, switches); done (1); case ADDRSW: if (!(address = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); address = trimcpy (address); /* Remove white spaces */ continue; case ALIASW: /* Argument following -alias can be a string or */ /* can be "-", to output on stdout. */ if (!(cp = *argp++)) adios (NULLCP, "missing argument to %s", argp[-2]); if (*cp == '-') { if (*++cp) adios (NULLCP, "missing argument to %s", argp[-2]); alias_file = NULL; } else alias_file = cp; continue; case GLOBSW: global++; continue; case NGLOBSW: global = 0; continue; case COMPSW: compress++; continue; case NCOMPSW: compress = 0; continue; case FIELDSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); field_vals = add_field (field_vals,cp); do_default = 0; continue; case NFIELDSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if (uleq (cp, "all")) del_all_fields (field_vals); else del_field (field_vals, cp); continue; case NAMESW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); alias_name = cp; continue; case QUERYSW: query++; continue; case NQUERYSW: query = 0; continue; case REPLSW: replace++; continue; case NREPLSW: replace = 0; continue; case WIDTHSW: if (!(cp = *argp++) || *cp == '-') adios (NULLCP, "missing argument to %s", argp[-2]); if ((width = atoi (cp)) < 1) adios (NULLCP, "bad argument %s %s", argp[-2], cp); continue; } if (*cp == '+' || *cp == '@') { if (folder) adios (NULLCP, "only one folder at a time!"); else folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); } else msgs[msgp++] = cp; }/* If no field values specified then use default : */ if (do_default) field_vals = add_field (field_vals,"reply-to/sender/from/to");/* If there is no command-line alias file name, then see if there is a default * one provided in the 'Aliasfile: ' profile entry... */ if (alias_file == NULL || *alias_file == '\0') alias_file = m_find ("Aliasfile");/* Ensure that any relative aliasfile is found in the MAIL directory. */ if (alias_file && *alias_file) alias_file = m_mailpath (alias_file);/* Read in the alias file and store all the lines in alias_lists. */ if (alias_file && *alias_file && alias_name && *alias_name) alias_lists = read_alias_file (alias_lists, alias_file); if (!msgp) msgs[msgp++] = "cur"; if (!folder) folder = m_getfolder (); maildir = m_maildir (folder); if (chdir (maildir) == NOTOK) adios (maildir, "unable to change directory to"); if (!(mp = m_gmsg (folder))) adios (NULLCP, "unable to read folder %s", folder); if (mp -> hghmsg == 0) adios (NULLCP, "no messages in %s", folder); for (msgnum = 0; msgnum < msgp; msgnum++) if (!m_convert (mp, msgs[msgnum])) done (1); m_setseq (mp); low_msg = mp -> lowsel; hgh_msg = mp -> hghsel;/* new_alias is where the new addresses are going to be stored; *//* If the alias already exists, new_alias points to structure holding all *//* that alias information. */ new_alias = get_alias (alias_lists, (alias_name) ? alias_name : "", replace, global, alias_num); do {/* Repeat this for each message in the sequence given on the command line. */ for (msgnum =low_msg; msgnum <= hgh_msg; msgnum++) { if (mp -> msgstats[msgnum] & SELECTED) mp -> lowsel = msgnum; if (mp -> lowsel != mp -> curmsg) m_setcur (mp, mp -> lowsel); m_sync (mp); m_update (); msg = getcpy (m_name (mp -> lowsel));/* If addresses are to be taken from header fields, then search through each *//* specified message for each field in turn. */ if (!address && (mp -> lowsel == msgnum)) { if ((in = fopen (msg, "r")) == NULLFILE) adios (msg, "unable to open"); ref = field_vals; while (ref != (struct fields *)NULL) { if (ref -> priorities[count] == NULLCP) { ref = ref -> next; count = 0; } else { found = 0; for (compnum = 1, state = FLD;;) { switch (state = m_getfld (state, name, buf, sizeof buf, in)) { case FLD: case FLDEOF: case FLDPLUS: compnum++; cp = add (buf, NULLCP); while (state == FLDPLUS) { state = m_getfld (state, name, buf, sizeof buf, in); cp = add (buf, cp); }/* Compare the current header field to that being sought. The comparison *//* is case insensitive. */ if (ref != (struct fields *)NULL && uleq (name, ref -> priorities[count])) { cp = trimcpy (cp); /* Remove spaces *//* This next bit strips off unnecessary parts of the address, eg. the *//* signature part. mail_name is a structure which holds the whole */ /* address, mail_name -> m_mbox holds the actual address. */ if (global || !alias_num) { while (addr1 = getname(cp)) { if ((mail_name = getm (addr1, NULLCP, 0, AD_HOST, NULLCP)) == NULL) adios(NULLCP,"bad address"); add_alias_entry (new_alias, mail_name -> m_mbox, query); mnfree (mail_name); } } found = 1; } free (cp); if (state != FLDEOF) continue; break; case BODY: case BODYEOF: case FILEEOF: break; case LENERR: case FMTERR: adios (NULLCP, "message format error in component #%d", compnum); default: adios(NULLCP,"getfld() returned %d",state); } /* end of switch */ break; } /* end of for compnum */ if (found) { ref = ref -> next; count = 0; } else count++; (void) fseek (in, 0L, 0); /* Go back to beginning of */ } /* mail message to search for next */ /* header field. */ } (void) fclose (in); } } if (address) /* Take address */ add_alias_entry (new_alias, address, query); /* from string. */ if (compress) compress_alias (new_alias); /* compress the aliases if required. */ if (!alias_file || !alias_name) output_aliases (new_alias, stdout, width, alias_name); if (alias_name && *alias_name) { new_alias = new_alias -> next; alias_num++; if (new_alias != (struct entry *)NULL) new_alias = get_alias (new_alias, alias_name, replace, 1, alias_num); } else new_alias = (struct entry *)NULL; } while (new_alias != (struct entry *)NULL); for (msgnum = low_msg; msgnum <= hgh_msg; msgnum++) /* We've looked at */ mp -> msgstats[msgnum] &= ~SELECTED; /* these msgs, so */ /* unset selected */ /* flag. */ if (alias_file && *alias_file && alias_name && *alias_name) { (void) strcpy (buf, m_backup (alias_file)); /* Make a backup of the */ if (rename (alias_file, buf) == NOTOK) /* alias file. */ adios (buf, "unable to backup %s to", alias_file);/* Output aliases to alias file. */ if ((out = fopen (alias_file, "w")) == NULLFILE) adios (NULLCP, "unable to fopen %s", alias_file); output_aliases (alias_lists, out, width, alias_name); (void) fclose (out); } if ((alias_num > 1) && alias_file && *alias_file) { (void) fprintf (stderr, "Warning: there are %d aliases with name %s in alias file\n", alias_num, alias_name); if (!global) (void) fprintf (stderr, " only the first occurrence was changed.\n"); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?