Annotation of 43BSDTahoe/new/nntp/xfer/nntpxfer.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * nntpxfer
        !             3:  *
        !             4:  * Connects to the specified nntp server, and transfers all new news
        !             5:  * since the last successful invocation.
        !             6:  *
        !             7:  * last successful invocation date and time are stored in a file at
        !             8:  * /usr/spool/news/nntp.<hostname> as 
        !             9:  *     groups YYMMDD HHMMSS distributions\n
        !            10:  * in case you need to edit it.  You can also override this on 
        !            11:  * the command line in the same format, in which case the file won't
        !            12:  * be updated.
        !            13:  *
        !            14:  *     Brian Kantor, UCSD 1986
        !            15:  * (some bug fixes by [email protected])
        !            16:  */
        !            17: 
        !            18: #define DEBUG
        !            19: 
        !            20: /* you'd think that 4096 articles at one go is enough.... */
        !            21: #define MAXARTS        4096
        !            22: 
        !            23: #include <sys/types.h>
        !            24: #include <sys/dir.h>
        !            25: #include <sys/socket.h>
        !            26: #include <sys/stat.h>
        !            27: #include <sys/ioctl.h>
        !            28: #include <sys/file.h>
        !            29: #include <sys/time.h>
        !            30: #include <sys/wait.h>
        !            31: #include <sys/resource.h>
        !            32: 
        !            33: #include <net/if.h>
        !            34: #include <netinet/in.h>
        !            35: 
        !            36: #include <stdio.h>
        !            37: #include <errno.h>
        !            38: #include <ctype.h>
        !            39: #include <netdb.h>
        !            40: #include <signal.h>
        !            41: #include <dbm.h>
        !            42: 
        !            43: #define INEWS  "/usr/lib/news/inews -p"
        !            44: #define HIST   "/usr/lib/news/history"
        !            45: 
        !            46: char   *malloc();
        !            47: char   *strcpy();
        !            48: char   *strcat();
        !            49: long   time();
        !            50: u_long inet_addr();
        !            51: 
        !            52: extern int errno;
        !            53: char *artlist[MAXARTS];
        !            54: int server;                    /* stream socket to the nntp server */
        !            55: int newart, dupart, misart;
        !            56: 
        !            57: main(argc, argv)
        !            58: int argc;
        !            59: char *argv[];
        !            60:        {
        !            61:        FILE *dtfile;           /* where last xfer date/time stored */
        !            62:        char buf[BUFSIZ];
        !            63:        char lastdate[16];
        !            64:        char distributions[BUFSIZ];
        !            65:        char dtname[128];
        !            66:        char newsgroups[BUFSIZ];
        !            67:        char lasttime[16];
        !            68:        int connected = 0;              /* 1 = connected */
        !            69:        int i;
        !            70:        int omitupdate = 0;             /* 1 = don't update datetime */
        !            71:        long clock;
        !            72:        long newdate, newtime;
        !            73:        struct hostent *hp;
        !            74:        struct servent *sp;
        !            75:        struct sockaddr_in sin;
        !            76:        struct tm *now;
        !            77: 
        !            78:        /* OPTIONS
        !            79:                argv[1] MUST be the host name
        !            80:                argv[2-4] MAY be "newsgroups YYMMDD HHMMSS"
        !            81:                        argv[5] MAY be distributions
        !            82:                (otherwise use 2-4/5 from the file
        !            83:                "/usr/spool/news/nntp.hostname")
        !            84:        */
        !            85: 
        !            86:        if (argc != 2 && argc != 5 && argc != 6)
        !            87:                {
        !            88:                (void) printf("Usage: %s host [groups YYMMDD HHMMSS [<dist>]]\n",
        !            89:                        argv[0]);
        !            90:                exit(1);
        !            91:                }
        !            92:        
        !            93:        if (argc > 2)
        !            94:                {
        !            95:                omitupdate++;
        !            96:                (void) strcpy(newsgroups, argv[2]);
        !            97:                (void) strcpy(lastdate, argv[3]);
        !            98:                (void) strcpy(lasttime, argv[4]);
        !            99:                (void) strcpy(distributions, "");
        !           100:                if (argc > 5)
        !           101:                        (void) strcpy(distributions, argv[5]);
        !           102:                }
        !           103:        else
        !           104:                {
        !           105:                (void) strcpy(dtname, "/usr/spool/news/nntp.");
        !           106:                (void) strcat(dtname, argv[1]);
        !           107:                dtfile = fopen(dtname, "r");
        !           108:                if (dtfile == NULL)
        !           109:                        {
        !           110:                        (void) printf("%s not found; using * 860101 000000 \n", 
        !           111:                                dtname);
        !           112:                        (void) strcpy(newsgroups, "*");
        !           113:                        (void) strcpy(lastdate, "860101");
        !           114:                        (void) strcpy(lasttime, "000000");
        !           115:                        (void) strcpy(distributions, "");
        !           116:                        }
        !           117:                else
        !           118:                        {
        !           119:                        if (fscanf(dtfile, "%s %s %s %s",
        !           120:                                newsgroups, lastdate, lasttime, distributions) < 3)
        !           121:                                {
        !           122:                                (void) printf("%s invalid; using * 860101 000000\n",
        !           123:                                        dtname);
        !           124:                                (void) strcpy(newsgroups, "*");
        !           125:                                (void) strcpy(lastdate, "860101");
        !           126:                                (void) strcpy(lasttime, "000000");
        !           127:                                (void) strcpy(distributions, "");
        !           128:                                }
        !           129:                        (void) fclose(dtfile);
        !           130:                        }
        !           131:                clock = time((long *)0);
        !           132:                now = gmtime(&clock);
        !           133:                newdate = (now->tm_year * 10000) +
        !           134:                        ((now->tm_mon + 1) * 100) + now->tm_mday;
        !           135:                newtime = (now->tm_hour * 10000) +
        !           136:                        (now->tm_min * 100) + now->tm_sec;
        !           137:                }
        !           138: 
        !           139: #ifdef DEBUG
        !           140:        (void) printf("newsgroups = '%s'\n", newsgroups);
        !           141:        (void) printf("date = '%s'\n", lastdate);
        !           142:        (void) printf("time = '%s'\n", lasttime);
        !           143:        (void) printf("distributions = '%s'\n", distributions);
        !           144:        (void) printf("now is = %06d %06d\n", newdate, newtime);
        !           145: #endif
        !           146: 
        !           147:        if (dbminit(HIST) < 0)
        !           148:                {
        !           149:                perror("couldn't open history file");
        !           150:                exit(1);
        !           151:                }
        !           152: 
        !           153:        sin.sin_addr.s_addr = inet_addr(argv[1]);
        !           154:        if (sin.sin_addr.s_addr != -1) 
        !           155:                {
        !           156:                sin.sin_family = AF_INET;
        !           157:                }
        !           158:        else 
        !           159:                {
        !           160:                hp = gethostbyname(argv[1]);
        !           161:                if (hp == NULL) 
        !           162:                        {
        !           163:                        (void) printf("%s: unknown host\n", argv[1]);
        !           164:                        exit(1);
        !           165:                        }
        !           166: 
        !           167:                sin.sin_family = hp->h_addrtype;
        !           168: #ifdef BSD43
        !           169:                bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
        !           170:                        hp->h_length);
        !           171: #else  BSD43
        !           172:                bcopy(hp->h_addr, (caddr_t)&sin.sin_addr,
        !           173:                        hp->h_length);
        !           174: #endif BSD43
        !           175:                }
        !           176:        
        !           177:        sp = getservbyname("nntp", "tcp");
        !           178:        if (sp == NULL)
        !           179:                {
        !           180:                perror("nntp/tcp");
        !           181:                exit(1);
        !           182:                }
        !           183: 
        !           184:        sin.sin_port = sp->s_port;
        !           185: 
        !           186:        do      {
        !           187:                server = socket(AF_INET, SOCK_STREAM, 0);
        !           188:                if (server < 0) 
        !           189:                        {
        !           190:                        perror("nntpxfer: socket");
        !           191:                        exit(1);
        !           192:                        }
        !           193: 
        !           194:                if (connect(server, (struct sockaddr *)&sin, sizeof (sin)) < 0) 
        !           195:                        {
        !           196: #ifdef BSD43
        !           197:                        if (hp && hp->h_addr_list[1]) 
        !           198:                                {
        !           199:                                hp->h_addr_list++;
        !           200:                                bcopy(hp->h_addr_list[0],
        !           201:                                    (caddr_t)&sin.sin_addr, hp->h_length);
        !           202:                                (void) close(server);
        !           203:                                continue;
        !           204:                                }
        !           205: #endif BSD43
        !           206:                        perror("nntpxfer: connect");
        !           207:                        exit(1);
        !           208:                        }
        !           209:                connected++;
        !           210:                }
        !           211:        while (connected == 0);
        !           212: 
        !           213: #ifdef DEBUG
        !           214:        (void) printf("connected to nntp server at %s\n", argv[1]);
        !           215: #endif
        !           216:        /*
        !           217:        * ok, at this point we're connected to the nntp daemon 
        !           218:        * at the distant host.
        !           219:        */
        !           220: 
        !           221:        /* get the greeting herald */
        !           222:        (void) sockread(buf);
        !           223: #ifdef DEBUG
        !           224:        (void) printf("%s\n", buf);
        !           225: #endif
        !           226:        if (buf[0] != '2')      /* uh-oh, something's wrong! */
        !           227:                {
        !           228:                (void) printf("protocol error: got '%s'\n", buf);
        !           229:                (void) close(server);
        !           230:                exit(1);
        !           231:                }
        !           232: 
        !           233: 
        !           234:        /* first, tell them we're a slave process to get priority */
        !           235:        sockwrite("SLAVE");
        !           236:        (void) sockread(buf);
        !           237: #ifdef DEBUG
        !           238:        (void) printf("%s\n", buf);
        !           239: #endif
        !           240:        if (buf[0] != '2')      /* uh-oh, something's wrong! */
        !           241:                {
        !           242:                (void) printf("protocol error: got '%s'\n", buf);
        !           243:                (void) close(server);
        !           244:                exit(1);
        !           245:                }
        !           246:        
        !           247:        /* now, ask for a list of new articles */
        !           248:        if (strlen(distributions))
        !           249:                (void) sprintf(buf,"NEWNEWS %s %s %s GMT <%s>", 
        !           250:                        newsgroups, lastdate, lasttime, distributions);
        !           251:        else
        !           252:                (void) sprintf(buf,"NEWNEWS %s %s %s GMT", 
        !           253:                        newsgroups, lastdate, lasttime);
        !           254:        sockwrite(buf);
        !           255:        (void) sockread(buf);
        !           256: #ifdef DEBUG
        !           257:        (void) printf("%s\n", buf);
        !           258: #endif
        !           259:        if (buf[0] != '2')      /* uh-oh, something's wrong! */
        !           260:                {
        !           261:                (void) printf("protocol error: got '%s'\n", buf);
        !           262:                (void) close(server);
        !           263:                exit(1);
        !           264:                }
        !           265:        /* and here comes the list, terminated with a "." */
        !           266: #ifdef DEBUG
        !           267:        (void) printf("data\n");
        !           268: #endif
        !           269:        while (1)
        !           270:                {
        !           271:                (void) sockread(buf);
        !           272:                if (!strcmp(buf,"."))
        !           273:                        break;
        !           274:                if (wewant(buf))
        !           275:                        {
        !           276:                        if (newart > MAXARTS)
        !           277:                                {
        !           278:                                omitupdate++;
        !           279:                                continue;
        !           280:                                }
        !           281:                        artlist[newart] = malloc((unsigned)(strlen(buf)+1));
        !           282:                        (void) strcpy(artlist[newart], buf);
        !           283:                        newart++;
        !           284:                        }
        !           285:                else
        !           286:                        dupart++;
        !           287:                }
        !           288: #ifdef DEBUG
        !           289:        (void) printf(".\n%d new, %d dup articles\n", newart, dupart);
        !           290: #endif
        !           291: 
        !           292:        /* now that we know which articles we want, retrieve them */
        !           293:        for (i=1; i < newart; i++)
        !           294:                (void) artfetch(artlist[i]);
        !           295: 
        !           296: #ifdef DEBUG
        !           297:        (void) printf("%d missing articles\n", misart);
        !           298: #endif
        !           299:        /* we're all done, so tell them goodbye */
        !           300:        sockwrite("QUIT");
        !           301:        (void) sockread(buf);
        !           302: #ifdef DEBUG
        !           303:        (void) printf("%s\n", buf);
        !           304: #endif
        !           305:        if (buf[0] != '2')      /* uh-oh, something's wrong! */
        !           306:                {
        !           307:                (void) printf("error: got '%s'\n", buf);
        !           308:                (void) close(server);
        !           309:                exit(1);
        !           310:                }
        !           311:        (void) close(server);
        !           312: 
        !           313:        /* do we want to update the timestamp file? */
        !           314:        if (!omitupdate)
        !           315:                {
        !           316:                (void) sprintf(buf, "%s %06d %06d %s\n",
        !           317:                        newsgroups, newdate, newtime, distributions);
        !           318: #ifdef DEBUG
        !           319:                (void) printf("updating %s:\n\t%s\n", dtname, buf);
        !           320: #endif
        !           321:                dtfile = fopen(dtname, "w");
        !           322:                if (dtfile == NULL)
        !           323:                        {
        !           324:                        perror(dtname);
        !           325:                        exit(1);
        !           326:                        }
        !           327:                (void) fputs(buf,dtfile);
        !           328:                (void) fclose(dtfile);
        !           329:                }
        !           330:        exit(0);
        !           331: }
        !           332: 
        !           333: artfetch(articleid)
        !           334: char *articleid;
        !           335:        {
        !           336:        int lines = 0;
        !           337:        char buf[BUFSIZ];
        !           338:        FILE *inews;
        !           339: 
        !           340:        /* now, ask for the article */
        !           341:        (void) sprintf(buf,"ARTICLE %s", articleid);
        !           342:        sockwrite(buf);
        !           343:        (void) sockread(buf);
        !           344: #ifdef DEBUG
        !           345:        (void) printf("%s\n", buf);
        !           346: #endif
        !           347:        if (buf[0] == '4')      /* missing article, just skipit */
        !           348:                {
        !           349:                misart++;
        !           350:                return(0);
        !           351:                }
        !           352: 
        !           353:        if (buf[0] != '2')      /* uh-oh, something's wrong! */
        !           354:                {
        !           355:                (void) printf("protocol error: got '%s'\n", buf);
        !           356:                (void) close(server);
        !           357:                exit(1);
        !           358:                }
        !           359: #ifdef DEBUG
        !           360:        (void) printf("command: %s\n", INEWS);
        !           361: #endif
        !           362:        if ( (inews = popen(INEWS, "w")) == NULL)
        !           363:                {
        !           364:                perror(INEWS);
        !           365:                exit(1);
        !           366:                }
        !           367: 
        !           368:        /* and here comes the article, terminated with a "." */
        !           369: #ifdef DEBUG
        !           370:        (void) printf("data\n");
        !           371: #endif
        !           372:        while (1)
        !           373:                {
        !           374:                (void) sockread(buf);
        !           375:                if (buf[0] == '.' && buf[1] == '\0')
        !           376:                        break;
        !           377:                lines++;
        !           378:                (void) strcat(buf,"\n");
        !           379:                (void) fputs(((buf[0] == '.') ? buf + 1 : buf),
        !           380:                           inews);
        !           381:                }
        !           382: #ifdef DEBUG
        !           383:        (void) printf(".\n%d lines\n", lines);
        !           384: #endif
        !           385:        (void) fflush(inews);
        !           386:        (void) pclose(inews);
        !           387:        return(0);
        !           388:         }
        !           389: 
        !           390: int
        !           391: sockread(buf)
        !           392: char *buf;
        !           393:        {
        !           394:        char c;
        !           395:        int j = 0;
        !           396: #ifdef BSD43
        !           397:        fd_set rf;
        !           398: #else BSD43
        !           399:        int rf;
        !           400: #endif BSD43
        !           401:        struct timeval tv;
        !           402:        int r;
        !           403:        char *p = buf;
        !           404: 
        !           405:        while ( 1 )
        !           406:                {
        !           407:                tv.tv_sec = 1800;       /* 15 minutes */
        !           408:                tv.tv_usec = 0L;
        !           409: #ifdef BSD43
        !           410:                FD_ZERO(&rf);
        !           411:                FD_SET(server, &rf);
        !           412: #else BSD43
        !           413:                rf = 1 << server;
        !           414: #endif BSD43
        !           415:                r = select(20, (fd_set *)&rf, (fd_set *)0, (fd_set *)&rf, &tv);
        !           416: 
        !           417:                if (r < 0)
        !           418:                        {
        !           419:                        if (errno == EINTR)
        !           420:                                continue;
        !           421:                        perror("getsock select");
        !           422:                        exit(1);
        !           423:                        }
        !           424:                if (r == 0)
        !           425:                        {
        !           426:                        printf("read timed out.\n");
        !           427:                        exit(1);
        !           428:                        }
        !           429: 
        !           430:                if (read(server, &c, 1) <= 0)
        !           431:                        break;
        !           432: 
        !           433:                /* mask off any chance parity bits */
        !           434:                *p = c & 0x7f;
        !           435: 
        !           436:                /* look for end of line (== LF) */
        !           437:                if (c == 0x0a)
        !           438:                        {
        !           439:                        if (j > 0 && *(p-1) == 0x0d)
        !           440:                                *(p-1) = '\0';
        !           441:                        else
        !           442:                                *p = '\0';
        !           443:                        return(strlen(buf));
        !           444:                        }
        !           445:                j++; p++;
        !           446:                }
        !           447:        perror("sockread");
        !           448:        (void) close(server);
        !           449:        exit(1);
        !           450:        /* NOTREACHED */
        !           451:        }
        !           452: 
        !           453: sockwrite(buf)
        !           454: char *buf;
        !           455:        {
        !           456:        register int sz;
        !           457:        char buf2[BUFSIZ];
        !           458: #ifdef DEBUG
        !           459:        (void) printf(">>> %s\n", buf);
        !           460: #endif
        !           461:        (void) strcpy(buf2,buf);
        !           462:        (void) strcat(buf2,"\r\n");
        !           463:        sz = strlen(buf2);
        !           464:        if (write(server,buf2,sz) != sz)
        !           465:                {
        !           466:                (void) printf("write error on server socket\n");
        !           467:                (void) close(server);
        !           468:                exit(1);
        !           469:                }
        !           470:        }
        !           471: 
        !           472: int
        !           473: wewant(articleid)
        !           474: char *articleid;
        !           475:        {
        !           476:        datum k, d;
        !           477:        char id[BUFSIZ];
        !           478:        char *p;
        !           479: 
        !           480:        /* remove any case sensitivity */
        !           481:        (void) strcpy(id, articleid);
        !           482:        p = id;
        !           483:        while (*p)
        !           484:                {
        !           485:                if (isupper(*p))
        !           486:                        *p = tolower(*p);
        !           487:                p++;
        !           488:                }
        !           489: 
        !           490:        k.dptr = id;
        !           491:        k.dsize = strlen(articleid) + 1;
        !           492: 
        !           493:        d = fetch(k);
        !           494: 
        !           495:        if (d.dptr)
        !           496:                {
        !           497: #ifdef DEBUG
        !           498:                (void) printf("dup: '%s'\n", articleid);
        !           499: #endif
        !           500:                return(0);
        !           501:                }
        !           502: 
        !           503: #ifdef DEBUG
        !           504:        (void) printf("new: '%s'\n", articleid);
        !           505: #endif
        !           506:        return(1);
        !           507:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.