diff options
author | Pav Lucistnik <pav@FreeBSD.org> | 2004-07-25 11:45:43 +0000 |
---|---|---|
committer | Pav Lucistnik <pav@FreeBSD.org> | 2004-07-25 11:45:43 +0000 |
commit | b2c122033361ea44c81be713f7d8b1c8f7638e46 (patch) | |
tree | a50f89bebed9fbb0e4e709cb66b83715c8004be3 /news | |
parent | Add a knob WITHOUT_PERL_64BITINT. This is primarily intended for those (diff) |
- Add lock outgoing files with flock, XPAT command, ability to handle
supersedes and cancel control messages.
PR: ports/69551
Submitted by: Andrey Slusar <vasallia@ukr.net> (maintainer)
Notes
Notes:
svn path=/head/; revision=114646
Diffstat (limited to 'news')
-rw-r--r-- | news/s-news/Makefile | 1 | ||||
-rw-r--r-- | news/s-news/files/patch-active | 5 | ||||
-rw-r--r-- | news/s-news/files/patch-config.h.in | 12 | ||||
-rw-r--r-- | news/s-news/files/patch-configure | 11 | ||||
-rw-r--r-- | news/s-news/files/patch-newfeed.in | 10 | ||||
-rw-r--r-- | news/s-news/files/patch-nntpd.c | 247 | ||||
-rw-r--r-- | news/s-news/files/patch-qnews.c | 95 | ||||
-rw-r--r-- | news/s-news/files/patch-rnews.c | 453 |
8 files changed, 831 insertions, 3 deletions
diff --git a/news/s-news/Makefile b/news/s-news/Makefile index bfe4285247c5..6e2043b7db0c 100644 --- a/news/s-news/Makefile +++ b/news/s-news/Makefile @@ -7,6 +7,7 @@ PORTNAME= s-news PORTVERSION= 0.1.11 +PORTREVISION= 1 CATEGORIES= news MASTER_SITES= http://www.lost.org.uk/ diff --git a/news/s-news/files/patch-active b/news/s-news/files/patch-active new file mode 100644 index 000000000000..75fe5f3955a3 --- /dev/null +++ b/news/s-news/files/patch-active @@ -0,0 +1,5 @@ +--- data/active 1998-09-06 14:11:15.000000000 +0100 ++++ data/active 2002-09-08 12:51:26.000000000 +0100 +@@ -1 +1,2 @@ + junk 0 1 y ++control.cancel 0 1 y diff --git a/news/s-news/files/patch-config.h.in b/news/s-news/files/patch-config.h.in new file mode 100644 index 000000000000..088da1f6fedd --- /dev/null +++ b/news/s-news/files/patch-config.h.in @@ -0,0 +1,12 @@ +--- config.h.in 2002-05-18 20:22:50.000000000 +0100 ++++ config.h.in 2002-10-12 19:23:12.000000000 +0100 +@@ -55,6 +55,9 @@ + /* Define if you have the <malloc.h> header file. */ + #undef HAVE_MALLOC_H + ++/* Define if you have the <sys/file.h> header file. */ ++#undef HAVE_SYS_FILE_H ++ + /* Define if you have the <memory.h> header file. */ + #undef HAVE_MEMORY_H + diff --git a/news/s-news/files/patch-configure b/news/s-news/files/patch-configure new file mode 100644 index 000000000000..90df458ec725 --- /dev/null +++ b/news/s-news/files/patch-configure @@ -0,0 +1,11 @@ +--- configure 2002-05-18 20:25:00.000000000 +0100 ++++ configure 2002-10-12 19:23:12.000000000 +0100 +@@ -2370,7 +2370,7 @@ + + fi + +-for ac_header in fcntl.h limits.h malloc.h syslog.h unistd.h ++for ac_header in fcntl.h limits.h malloc.h syslog.h unistd.h sys/file.h + do + as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` + echo "$as_me:2376: checking for $ac_header" >&5 diff --git a/news/s-news/files/patch-newfeed.in b/news/s-news/files/patch-newfeed.in index 6c6a80bec0f7..afae71c81e85 100644 --- a/news/s-news/files/patch-newfeed.in +++ b/news/s-news/files/patch-newfeed.in @@ -1,6 +1,6 @@ ---- newfeed.in.old Thu Jul 15 16:31:44 2004 -+++ newfeed.in Thu Jul 15 16:33:15 2004 -@@ -52,7 +52,7 @@ +--- newfeed.in.orig Sat Jun 29 21:29:49 2002 ++++ newfeed.in Sun Jul 25 04:40:59 2004 +@@ -52,9 +52,11 @@ umask $UMASK fi @@ -8,4 +8,8 @@ +if mkdir -p $SUCKDIR/$host then echo junk >$SUCKDIR/$host/active-ignore ++ # Uncomment the following line if you don't want cancel messages to propagate ++ #echo control.cancel >>$SUCKDIR/$host/active-ignore mkdir $SUCKDIR/$host/incoming + + for opt in $options diff --git a/news/s-news/files/patch-nntpd.c b/news/s-news/files/patch-nntpd.c new file mode 100644 index 000000000000..fad8f1c7b773 --- /dev/null +++ b/news/s-news/files/patch-nntpd.c @@ -0,0 +1,247 @@ +--- nntpd.c Sat May 18 20:21:56 2002 ++++ nntpd.c Wed Aug 21 22:09:46 2002 +@@ -2,6 +2,7 @@ + * S-News version 0.1.9 - A Simple News Server + * Copyright (C) 1998 Christopher John Purnell + * cjp@lost.org.uk ++ * XPAT support added in 2002 by Tony Houghton <tony@realh.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -106,6 +107,7 @@ + static void do_listgroup(char *); + static void do_xover(char *); + static void do_xhdr(char *); ++static void do_xpat(char *); + static void do_xpath(char *); + static void do_ihave(char *); + static void do_post(char *); +@@ -239,6 +241,10 @@ + { + do_xhdr(arg); + } ++ else if (!strcasecmp(line,"xpat")) ++ { ++ do_xpat(arg); ++ } + else if (!strcasecmp(line,"xover")) + { + do_xover(arg); +@@ -811,10 +817,11 @@ + printf(".\r\n"); + } + ++static char *xhdr_h[7] = { "Subject","From","Date","Message-ID", ++ "References","Bytes","Lines" }; ++ + static void do_xhdr(char *arg) + { +- static char *h[7] = { "Subject","From","Date","Message-ID", +- "References","Bytes","Lines" }; + char *fmt,*cp; + unsigned char c; + int i; +@@ -835,7 +842,7 @@ + i = -1; fmt = "%u \r\n"; + for (u=0; u<7; ++u) + { +- if (!strcasecmp(arg,h[u])) ++ if (!strcasecmp(arg,xhdr_h[u])) + { + fmt = ((i=u) < 5) ? "%u %s\r\n" : "%u %u\r\n"; + } +@@ -1118,6 +1125,7 @@ + printf("ARTICLE HEAD BODY STAT\r\n"); + printf("GROUP LIST NEXT LAST\r\n"); + printf("LISTGROUP XHDR XOVER XPATH\r\n"); ++ printf("XPAT "); + } + if (canpost) + { +@@ -1127,7 +1135,7 @@ + { + printf("IHAVE "); + } +- printf("HELP QUIT\r\n.\r\n"); ++ printf("\r\nHELP QUIT\r\n.\r\n"); + } + + static int match_pat(char *pat,char *str) +@@ -1533,3 +1541,177 @@ + + return str; + } ++ ++static int match_pattern(const char *pat,const char *str) ++{ ++ char c; ++ ++ while ((c = *(pat++))) ++ { ++ switch (c) ++ { ++ case '*': ++ if (!*pat) ++ return (1); ++ while (*str) ++ { ++ if (match_pattern(pat,str)) ++ return (1); ++ ++str; ++ } ++ break; ++ case '?': ++ if (!*str) ++ return (0); ++ break; ++ case '[': ++ if (*str) ++ { ++ unsigned char rev,mat=0,l=0,h,u=*str; ++ ++ if ((rev = (*pat=='^'?1:0))) ++ pat++; ++ if ((c=*pat)) do ++ { ++ pat++; ++ if (c=='-' && l && (h=*pat) && h!=']') ++ { ++ pat++; ++ if (u>=l && u<=h) mat=1; ++ l = 0; ++ } ++ else ++ { ++ if (u==c) mat=1; ++ l = c; ++ } ++ } ++ while ((c=*pat) && c!=']'); ++ if (c) ++ ++pat; ++ if (mat==rev) ++ return (0); ++ } ++ else ++ return (0); ++ break; ++ default: ++ if (*str!=c) ++ return (0); ++ break; ++ } ++ ++str; ++ } ++ ++ return (!*str); ++} ++ ++static void do_xpat(char *arg) ++{ ++ char *cp; ++ unsigned char c; ++ int i; ++ unsigned u,l; ++ char const **patterns = NULL; ++ size_t pat_size = 0; ++ size_t npats = 0; ++ ++ if (check_read()) return; ++ ++ if (!grp) ++ { ++ printf("412 no newsgroup has been selected\r\n"); ++ return; ++ } ++ ++ cp = arg; ++ while ((c=*(cp)) && !isspace(c)) cp++; ++ if (*cp) *(cp++) = '\0'; ++ ++ i = -1; ++ for (u=0; u<7; ++u) ++ { ++ if (!strcasecmp(arg,xhdr_h[u])) ++ { ++ // fmt = ((i=u) < 5) ? "%u %s\r\n" : "%u %u\r\n"; ++ i = u; ++ } ++ } ++ if (i == -1) ++ { ++ printf("501 header not in index\r\n"); ++ return; ++ } ++ ++ while ((c=*(cp)) && isspace(c)) cp++; ++ if (*cp) ++ { ++ u = strtoul(cp,&cp,10); ++ if (*cp == '-') ++ { ++ if (*(++cp)) l = strtoul(cp,&cp,10); ++ else l = grp->last; ++ } ++ else l = u; ++ } ++ else u = l = art; ++ ++ if (!u) ++ { ++ printf("420 no article has been selected\r\n"); ++ return; ++ } ++ ++ patterns = malloc(sizeof(char const *)); ++ pat_size = 1; ++ do ++ { ++ while (*cp && isspace(*cp)) ++cp; ++ if (*cp) ++ { ++ if (npats + 1 > pat_size) ++ { ++ patterns = realloc(patterns, (pat_size *= 2) * ++ sizeof(const char *)); ++ } ++ patterns[npats++] = cp; ++ while (*cp && !isspace(*cp)) ++cp; ++ if (*cp) *(cp++) = 0; ++ } ++ } while (*cp); ++ if (!npats) ++ { ++ free(patterns); ++ printf("501 command syntax error\r\n"); ++ } ++ ++ printf("221 Header follows\r\n"); ++ ++ while (u <= l) ++ { ++ struct overview *o; ++ ++ if ((o = find_overview(u))) ++ { ++ size_t pat; ++ char matchnum[12]; ++ char *match = i < 5 ? (&o->subject)[i] : ++ (sprintf(matchnum, "%u", ((unsigned *) ++ (&o->subject))[i]), ++ matchnum); ++ ++ for (pat = 0; pat < npats; ++pat) ++ { ++ if (match_pattern(patterns[pat], match)) ++ { ++ printf("%u %s\r\n", u, match); ++ } ++ } ++ } ++ ++u; ++ } ++ ++ printf(".\r\n"); ++ free(patterns); ++} ++ diff --git a/news/s-news/files/patch-qnews.c b/news/s-news/files/patch-qnews.c new file mode 100644 index 000000000000..415cbed2c9a7 --- /dev/null +++ b/news/s-news/files/patch-qnews.c @@ -0,0 +1,95 @@ +--- qnews.c 2002-05-18 20:21:42.000000000 +0100 ++++ qnews.c 2002-10-12 19:23:55.000000000 +0100 +@@ -2,6 +2,8 @@ + * S-News version 0.1.9 - A Simple News Server + * Copyright (C) 1998 Christopher John Purnell + * cjp@lost.org.uk ++ * flock modification (c) 2002 Tony Houghton ++ * tony@realh.co.uk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -22,7 +24,13 @@ + #include "config.h" + #endif + ++#include <sys/types.h> + #include <sys/stat.h> ++#ifdef HAVE_SYS_FILE_H ++#include <sys/file.h> ++#endif ++#include <fcntl.h> ++ + #ifdef HAVE_UNISTD_H + #include <unistd.h> + #endif +@@ -79,15 +87,37 @@ + if (match_group(ptr->value,line,end)) + { + FILE *fp; ++ #ifdef HAVE_SYS_FILE_H ++ int fd; ++ #endif + + sprintf(file,CONFDIR"/suck/%s/outgoing", +- ptr->name); ++ ptr->name); + +- if (!(fp = fopen(file,"a"))) ++ #ifdef HAVE_SYS_FILE_H ++ if ((fd = open(file,O_WRONLY|O_APPEND|O_CREAT, ++ 0644)) == -1) + { +- perror(file); +- return (1); ++ perror(file); ++ return (1); ++ } ++ if (flock(fd,LOCK_EX) == -1) ++ { ++ perror(file); ++ return (1); ++ } ++ if (!(fp = fdopen(fd,"a"))) ++ { ++ perror(file); ++ return (1); + } ++ #else ++ if (!(fp = fopen(file,"a"))) ++ { ++ perror(file); ++ return (1); ++ } ++ #endif + + if (fputs(line,fp) < 0 || + fputc('\n',fp) < 0) +@@ -103,6 +133,9 @@ + return (1); + } + ++ /* By commenting this break we can post to ++ * multiple servers instead of stopping after ++ * first match*/ + break; + } + } +@@ -204,7 +237,7 @@ + return (0); + break; + case '[': +- if (str>=end) ++ if (str<end) + { + unsigned char rev,mat=0,l=0,h,u=*str; + +@@ -229,6 +262,8 @@ + if (mat==rev) + return (0); + } ++ else ++ return (0); + break; + default: + if (str>=end || *str!=c) diff --git a/news/s-news/files/patch-rnews.c b/news/s-news/files/patch-rnews.c new file mode 100644 index 000000000000..5682144682b7 --- /dev/null +++ b/news/s-news/files/patch-rnews.c @@ -0,0 +1,453 @@ +--- rnews.c 2002-05-18 20:21:26.000000000 +0100 ++++ rnews.c 2002-09-08 12:50:41.000000000 +0100 +@@ -2,6 +2,8 @@ + * S-News version 0.1.9 - A Simple News Server + * Copyright (C) 1998 Christopher John Purnell + * cjp@lost.org.uk ++ * Supersedes/cancel modifications (C) 2002 Tony Houghton ++ * tony@realh.co.uk + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -50,6 +52,8 @@ + + #include "snews.h" + ++#define DEBLOG(a) /* fprintf a */ ++ + struct header + { + struct header *next; +@@ -78,14 +82,23 @@ + static FILE *open_lock(char *); + static int file_name(struct header *,char *,unsigned); + static GDBM_FILE open_history(char *,int); ++static int read_string(FILE *,char *,unsigned); ++static void delete_msg(const char *); ++static int whole_string(struct header_pointer *,char *,unsigned); ++static int read_line(FILE *,char *,unsigned); ++static int isolate_addr(char *); + + static char *progname; + static char fqdn[BUFLEN]; + static char msgid[BUFLEN]; + static char article[BUFLEN]; ++static char vsender[BUFLEN]; ++static char cancel[BUFLEN]; + static char queue=0,approved=0; ++static int cancel_only; + + struct header junk = { 0, "junk", 0 }; ++struct header control_cancel = { 0, "control.cancel", 0 }; + + int main(int argc,char **argv) + { +@@ -95,6 +108,16 @@ + + set_ug_id(); + ++ /* For logging, remove this in release */ ++ /* ++ i = open("/var/log/news/rnews", O_WRONLY|O_CREAT|O_APPEND, 0644); ++ if (i) ++ { ++ close(2); ++ dup2(i, 2); ++ } ++ */ ++ + progname = argv[0]; + + if (get_fqdn()) +@@ -116,12 +139,18 @@ + return (1); + } + ++ cancel[0] = 0; ++ vsender[0] = 0; ++ cancel_only = 0; ++ + if (!(hdr = read_header())) + return (1); + + if (!(ngrp = parse_header(hdr))) + return (1); + ++ DEBLOG((stderr, "Message-ID: %s\n", msgid)); ++ + if (!(fp = open_lock(CONFDIR"/active.n"))) + { + perror(progname); +@@ -130,8 +159,16 @@ + + if (!(i = chk_article(msgid))) + { +- if (!(ngrp = update_active(CONFDIR"/active",CONFDIR"/active.n", +- fp,ngrp))) ++ DEBLOG((stderr, "chk_article OK\n")); ++ if (cancel_only) ++ { ++ ngrp = update_active(CONFDIR"/active", ++ CONFDIR"/active.n", ++ fp,&control_cancel); ++ DEBLOG((stderr, "cancel_only, ngrp = %d\n", ngrp)); ++ } ++ else if (!(ngrp = update_active(CONFDIR"/active", ++ CONFDIR"/active.n",fp,ngrp))) + { + rewind(fp); + if (ftruncate(fileno(fp),0)) +@@ -144,8 +181,11 @@ + i = !ngrp; + } + ++ DEBLOG((stderr, "After chk_article and update_active, result = %d (0 is good)\n", i)); ++ + if (fclose(fp) || i || write_article(hdr,ngrp)) + { ++ DEBLOG((stderr, "fclose || i || write_article failed\n")); + unlink(CONFDIR"/active.n"); + return (1); + } +@@ -158,6 +198,9 @@ + return (1); + } + ++ if (cancel[0]) ++ delete_msg(cancel); ++ + if (!queue) return (0); + + execl(QNEWSPATH,QNEWSARG0,article,0); +@@ -301,11 +344,79 @@ + { + approved=1; + } ++ else if (!strncasecmp(hdr->line,"Sender:",7)) ++ { ++ hp.hdr = hdr; ++ hp.ptr = hdr->line+7; ++ if (whole_string(&hp,vsender,BUFLEN)<=0) ++ { ++ fprintf(stderr,"%s: bad Sender\n", ++ progname); ++ return (0); ++ } ++ DEBLOG((stderr, "Found Sender: %s\n", vsender)); ++ } ++ else if (!vsender[0] && !strncasecmp(hdr->line,"From:",5)) ++ { ++ hp.hdr = hdr; ++ hp.ptr = hdr->line+5; ++ if (whole_string(&hp,vsender,BUFLEN)<=0) ++ { ++ fprintf(stderr,"%s: bad From\n", ++ progname); ++ return (0); ++ } ++ DEBLOG((stderr, "Found From: %s\n", vsender)); ++ } ++ else if (!strncasecmp(hdr->line,"Supersedes:",11)) ++ { ++ hp.hdr = hdr; ++ hp.ptr = hdr->line+11; ++ if (whole_string(&hp,cancel,BUFLEN)<=0) ++ { ++ fprintf(stderr,"%s: bad Supersedes\n", ++ progname); ++ return (0); ++ } ++ DEBLOG((stderr, "Found Supersedes: %s\n", cancel)); ++ } ++ else if (!strncasecmp(hdr->line,"Control: cancel",15)) ++ { ++ hp.hdr = hdr; ++ hp.ptr = hdr->line+15; ++ if (whole_string(&hp,cancel,BUFLEN)<=0) ++ { ++ fprintf(stderr,"%s: bad cancel\n", ++ progname); ++ return (0); ++ } ++ DEBLOG((stderr, "Found cancel: %s\n", cancel)); ++ cancel_only = 1; ++ } ++ else if (!strncasecmp(hdr->line,"Also-Control: cancel",20)) ++ { ++ hp.hdr = hdr; ++ hp.ptr = hdr->line+20; ++ if (whole_string(&hp,cancel,BUFLEN)<=0) ++ { ++ fprintf(stderr,"%s: bad cancel\n", ++ progname); ++ return (0); ++ } ++ DEBLOG((stderr, "Found also-cancel: %s\n", cancel)); ++ } + + } + hdr = hdr->next; + } + ++ if (vsender[0]) ++ { ++ int ires=isolate_addr(vsender); ++ DEBLOG((stderr,"vsender address = %s (result %d)\n", ++ vsender,ires)); ++ } ++ + return (*msgid?ret:0); + } + +@@ -597,7 +708,10 @@ + int ret; + + if (!(dbf = open_history(CONFDIR"/history",GDBM_READER))) ++ { ++ DEBLOG((stderr, "chk_article: Couldn't open history\n")); + return (1); ++ } + + key.dsize = strlen(key.dptr = id) + 1; + +@@ -605,6 +719,7 @@ + + gdbm_close(dbf); + ++ DEBLOG((stderr, "chk_article: %s exists: %d\n", id, ret)); + return (ret); + } + +@@ -642,3 +757,232 @@ + } + return (dbf); + } ++ ++/* Added by Tony Houghton <tony@realh.co.uk>, mostly copied from expire.c */ ++ ++static void delete_msg(const char *msgid) ++{ ++ char buf[BUFLEN]; ++ char sender[BUFLEN]; ++ struct stat st; ++ FILE *fp; ++ GDBM_FILE dbf; ++ datum key,value; ++ char *file; ++ ++ DEBLOG((stderr, "Deleting %s\n", msgid)); ++ if (!(dbf = open_history(CONFDIR"/history",GDBM_READER))) ++ return; ++ key.dsize = strlen(key.dptr = (char *) msgid) + 1; ++ value = gdbm_fetch(dbf, key); ++ if ((file = value.dptr) == NULL) ++ return; ++ DEBLOG((stderr, "Filename is %s\n", file)); ++ ++ if (!(fp = fopen(file,"r"))) ++ { ++ if (errno != ENOENT) ++ perror(file); ++ free(file); ++ return; ++ } ++ ++ if (fstat(fileno(fp),&st)) ++ { ++ perror(file); ++ free(file); ++ return; ++ } ++ ++ sender[0] = 0; ++ while (fgets(buf,6,fp)) ++ { ++ if (!sender[0] && !strcasecmp(buf,"From:")) ++ { ++ if (read_line(fp,sender,BUFLEN) <= 0) ++ { ++ fclose(fp); ++ fprintf(stderr,"%s: bad From header\n",file); ++ free(file); ++ return; ++ } ++ DEBLOG((stderr, "From: %s\n", sender)); ++ } ++ else if (!strcasecmp(buf,"Sende") && fgetc(fp) == 'r' && ++ fgetc(fp) == ':') ++ { ++ if (read_line(fp,sender,BUFLEN) <= 0) ++ { ++ fclose(fp); ++ fprintf(stderr,"%s: bad Sender\n",file); ++ free(file); ++ return; ++ } ++ DEBLOG((stderr, "Sender: %s\n", sender)); ++ } ++ else if (buf[0] == '\n') ++ break; ++ } ++ rewind(fp); ++ if (isolate_addr(sender) == -1) ++ { ++ fprintf(stderr,"Invalid sender, can't cancel\n"); ++ free(file); ++ fclose(fp); ++ return; ++ } ++ DEBLOG((stderr,"Sender address = %s\n",sender)); ++ ++ if (strcasecmp(sender,vsender)) ++ { ++ fprintf(stderr,"Wrong sender, can't cancel\n"); ++ free(file); ++ fclose(fp); ++ return; ++ } ++ ++ while (fgets(buf,6,fp)) ++ { ++ char *cp; ++ int c; ++ ++ if (strcasecmp(buf,"Xref:")) ++ { ++ if ((cp = strchr(buf,'\n'))) ++ { ++ if (cp == buf) break; ++ } ++ else ++ { ++ while ((c = fgetc(fp)) != EOF && c != '\n'); ++ if (c == EOF) break; ++ } ++ } ++ else ++ { ++ if ((read_string(fp,buf,BUFLEN) <= 0) || ++ strcasecmp(buf,fqdn)) ++ { ++ fclose(fp); ++ fprintf(stderr,"%s: bad Xref line\n",file); ++ free(file); ++ return; ++ } ++ ++ while ((c = read_string(fp,buf,BUFLEN))) ++ { ++ if (c < 0) ++ { ++ fclose(fp); ++ fprintf(stderr,"%s: bad Xref line\n", ++ file); ++ free(file); ++ return; ++ } ++ ++ cp = buf; ++ while ((c = *cp)) ++ { ++ if (c == '.' || c ==':') ++ *cp = '/'; ++ ++cp; ++ } ++ ++ if (strcmp(file,buf) && ++ unlink(buf) && errno != ENOENT) ++ { ++ perror(buf); ++ fclose(fp); ++ free(file); ++ return; ++ } ++ } ++ ++ break; ++ } ++ } ++ if (ferror(fp)) ++ { ++ perror(file); ++ free(file); ++ fclose(fp); ++ return; ++ } ++ ++ fclose(fp); ++ if (unlink(file)) ++ perror(file); ++ free(file); ++} ++ ++static int read_string(FILE *fp,char *str,unsigned len) ++{ ++ int c; ++ unsigned i=0; ++ ++ while ((c = fgetc(fp)) != EOF && c != '\n' && isspace(c)); ++ ++ while (c != EOF && !isspace(c)) ++ { ++ str[i]=c; ++ if (++i>=len) return (-1); ++ c = fgetc(fp); ++ } ++ str[i]='\0'; ++ ++ return (i); ++} ++ ++static int whole_string(struct header_pointer *hp,char *str,unsigned len) ++{ ++ unsigned i=0; ++ unsigned char c; ++ ++ while ((c = next_char(hp)) && isspace(c)); ++ ++ while (c && c != '\n') ++ { ++ str[i]=c; ++ if (++i>=len) return (-1); ++ c = next_char(hp); ++ } ++ str[i]='\0'; ++ ++ return (i); ++} ++ ++static int read_line(FILE *fp,char *str,unsigned len) ++{ ++ int c; ++ unsigned i=0; ++ ++ while ((c = fgetc(fp)) != EOF && c != '\n' && isspace(c)); ++ ++ while (c != EOF && c != '\n') ++ { ++ str[i]=c; ++ if (++i>=len) return (-1); ++ c = fgetc(fp); ++ } ++ str[i]='\0'; ++ ++ return (i); ++} ++ ++static int isolate_addr(char *str) ++{ ++ char *at; ++ unsigned len; ++ ++ if (!(at=strchr(str,'@'))) ++ return -1; ++ while (at != str && !isspace(*(at-1)) && *(at-1) != '<') ++ --at; ++ for (len = 0; ++ len <= strlen(at) && !isspace(at[len]) && at[len] !='>'; ++ ++len); ++ memmove(str,at,len); ++ str[len]=0; ++ return 0; ++} ++ |