From owner-freebsd-ports-bugs@FreeBSD.ORG Sun Jul 25 07:50:16 2004 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B29F416A4CE for ; Sun, 25 Jul 2004 07:50:16 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 99F7743D2F for ; Sun, 25 Jul 2004 07:50:16 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i6P7oGR7099061 for ; Sun, 25 Jul 2004 07:50:16 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i6P7oGxL099060; Sun, 25 Jul 2004 07:50:16 GMT (envelope-from gnats) Resent-Date: Sun, 25 Jul 2004 07:50:16 GMT Resent-Message-Id: <200407250750.i6P7oGxL099060@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andrey Slusar Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D6BC816A4CE for ; Sun, 25 Jul 2004 07:46:58 +0000 (GMT) Received: from mail-kv.alkar.net (mail-kv.alkar.net [195.248.176.165]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2FB8A43D53 for ; Sun, 25 Jul 2004 07:46:58 +0000 (GMT) (envelope-from vasallia@ukr.net) Received: from [212.86.235.191] (helo=santinel.home.ua) by mail-kv.alkar.net with esmtp (Exim 4.34 (FreeBSD)) id 1Bodif-000God-Du for FreeBSD-gnats-submit@freebsd.org; Sun, 25 Jul 2004 10:46:57 +0300 Received: from anray by santinel.home.ua with local (Exim 4.41; FreeBSD) id 1BodhD-000DNh-Cb for ; Sun, 25 Jul 2004 10:45:23 +0300 Message-Id: Date: Sun, 25 Jul 2004 10:45:23 +0300 From: Andrey Slusar To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: ports/69551: [MAINTAINER] news/s-news: added XPAT, locking of outgoing files, support supersedes and cancel messages X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Andrey Slusar List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Jul 2004 07:50:16 -0000 >Number: 69551 >Category: ports >Synopsis: [MAINTAINER] news/s-news: added XPAT, locking of outgoing files, support supersedes and cancel messages >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: maintainer-update >Submitter-Id: current-users >Arrival-Date: Sun Jul 25 07:50:16 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Andrey Slusar >Release: FreeBSD 5.2-CURRENT i386 >Organization: Santinel >Environment: System: FreeBSD santinel.home.ua 5.2-CURRENT FreeBSD 5.2-CURRENT #1: Tue Jul 20 16:55:39 EEST 2004 root@santinel.home.ua:/usr/obj/usr/src/sys/ANRAY i386 >Description: Added new files: files/patch-active files/patch-config.h.in files/patch-configure files/patch-nntpd.c files/patch-qnews.c files/patch-rnews.c Added lock outgoing files with flock, XPAT command, ability to handle supersedes and cancel control messages. >How-To-Repeat: >Fix: --- s-news.diff begins here --- diff -ruN /usr/ports/news/s-news/Makefile s-news/Makefile --- /usr/ports/news/s-news/Makefile Sat Jul 17 22:11:03 2004 +++ s-news/Makefile Sun Jul 25 04:46:56 2004 @@ -7,6 +7,7 @@ PORTNAME= s-news PORTVERSION= 0.1.11 +PORTREVISION= 1 CATEGORIES= news MASTER_SITES= http://www.lost.org.uk/ diff -ruN /usr/ports/news/s-news/files/patch-active s-news/files/patch-active --- /usr/ports/news/s-news/files/patch-active Thu Jan 1 03:00:00 1970 +++ s-news/files/patch-active Sun Jul 25 10:24:17 2004 @@ -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 -ruN /usr/ports/news/s-news/files/patch-config.h.in s-news/files/patch-config.h.in --- /usr/ports/news/s-news/files/patch-config.h.in Thu Jan 1 03:00:00 1970 +++ s-news/files/patch-config.h.in Sun Jul 25 10:24:21 2004 @@ -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 header file. */ + #undef HAVE_MALLOC_H + ++/* Define if you have the header file. */ ++#undef HAVE_SYS_FILE_H ++ + /* Define if you have the header file. */ + #undef HAVE_MEMORY_H + diff -ruN /usr/ports/news/s-news/files/patch-configure s-news/files/patch-configure --- /usr/ports/news/s-news/files/patch-configure Thu Jan 1 03:00:00 1970 +++ s-news/files/patch-configure Sun Jul 25 10:24:26 2004 @@ -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 -ruN /usr/ports/news/s-news/files/patch-newfeed.in s-news/files/patch-newfeed.in --- /usr/ports/news/s-news/files/patch-newfeed.in Thu Jul 15 16:34:30 2004 +++ s-news/files/patch-newfeed.in Sun Jul 25 04:42:16 2004 @@ -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 -ruN /usr/ports/news/s-news/files/patch-nntpd.c s-news/files/patch-nntpd.c --- /usr/ports/news/s-news/files/patch-nntpd.c Thu Jan 1 03:00:00 1970 +++ s-news/files/patch-nntpd.c Sun Jul 25 10:24:33 2004 @@ -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 + * + * 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 -ruN /usr/ports/news/s-news/files/patch-qnews.c s-news/files/patch-qnews.c --- /usr/ports/news/s-news/files/patch-qnews.c Thu Jan 1 03:00:00 1970 +++ s-news/files/patch-qnews.c Sun Jul 25 10:24:36 2004 @@ -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 + #include ++#ifdef HAVE_SYS_FILE_H ++#include ++#endif ++#include ++ + #ifdef HAVE_UNISTD_H + #include + #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 || *str!=c) diff -ruN /usr/ports/news/s-news/files/patch-rnews.c s-news/files/patch-rnews.c --- /usr/ports/news/s-news/files/patch-rnews.c Thu Jan 1 03:00:00 1970 +++ s-news/files/patch-rnews.c Sun Jul 25 10:24:40 2004 @@ -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 , 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; ++} ++ --- s-news.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted: