home *** CD-ROM | disk | FTP | other *** search
- /* Snuz -- an NNTP News Reader for the IBM-PC */
-
-
- /*
- * This program is a vastly enlarged and improved version of the program
- * "red" from the pcip distribution. The new parts are written by J.D.
- * McDonald and are public domain. The older parts are also freely
- * distributable. See the pcip distribution for more details. The version of
- * pcip this compiles with was obtained from husc6.harvard.edu. It probably
- * will not work with other versions. To compile this, use Microsoft C 5.1
- * and the include files provided with pcip - not Microsoft's ones. It is
- * small model and probably needs the /Gs switch. The picp libraries needed
- * are tcp, domain, udp, packet, ip, net, task, and pc. Also needed is the
- * file proto.c.
- */
-
- /*
- * Further note: I don't really understand how the Internet works, or the
- * internals of pcip, at least not completely. NNTP itself is fairly easy to
- * understand. Basically, this was cooked up using by expanding on code
- * somebody else had written.
- */
-
-
-
- #include <stdio.h>
- #include <ctype.h>
- #include <process.h>
- #include <string.h>
-
-
- long time(long *);
- char *malloc(unsigned);
- int kbhit(void);
- int rename(char *, char *);
- int remove(char *);
- void perror(char *);
- int atoi(char *);
-
- extern int errno;
-
- #define NGROUPS 600
- #define STRING 512
-
-
- char serverhost[128];
- char newsrc[128] = "snuz.rc";
- char fromline[128];
- char editorpath[128];
- char smtppath[128];
- char tmpdir[128] = "c:";
-
-
-
- char *version = "\nSnuz ver. 1.00\n\n";
- char tmpfil[128];
- struct servent *ser;
- struct hostent *hp;
-
- FILE *server;
- int serverfd;
-
- int reply;
- unsigned long reparticle;
-
- char cur_gname[STRING];
- int cur_group;
- unsigned long cur_numa, cur_first, cur_last;
-
- unsigned long cur_article;
- unsigned long follow_up_article;
- char cur_articleid[STRING];
- char cur_path[STRING], cur_from[STRING], cur_subject[STRING], cur_replyto[STRING];
- char cur_newsgroups[STRING], cur_message_ID[STRING], cur_references[STRING];
- char cur_date[STRING];
-
- char *groups[NGROUPS];
- unsigned long firsts[NGROUPS];
- int ngroups;
- int bogus = 0;
-
- char *servp;
- int servf;
- char servb[2048];
-
- void startup(int, char **);
- void compactgroups(void);
- void qexit(int);
- int cstat(unsigned long);
- void docommand(void);
- void dumpnewsrc(void);
- int postnews(void);
- void sendmail(void);
- int extract(char *, char *, char *);
- void pcip_exit(void);
- int netsocket(void);
- void getserv(char *, int);
- int saveactive(char *);
- void getnewsrc(void);
- int cgroup(char *);
- int cnext(void);
- int chead(void);
- int checkx(void);
- int ngetc(void);
- int showbody(void);
- int savebody(int);
- int getgroup(char *);
- void putserv(char *);
- int tcpwrite(int, char *, int);
- void usleep(void);
- void xabort(void);
- void clearscreen(void);
- int showindex(int);
- void listgroups(void);
- int getpost(int);
- void reversevideo(char *);
- void normalvideo(void);
- void backline(void);
- int tcpread(int, char *, int);
- int tcpopen(char *, int);
- int valid_header(char *);
- char *getenv(char *);
-
- int
- main(int argc, char **argv)
- {
- startup(argc, argv);
- docommand();
- dumpnewsrc();
- postnews();
- qexit(0);
- pcip_exit(); /* this routine does all the 'onexit' processing which has
- * been called for when initializing the pcip package */
- sendmail(); /* this routine never returns */
- return 0;
- }
-
-
- void
- startup(int argc, char **argv)
- {
- char buf[STRING];
- FILE *cfgfile;
- char *ptr;
- int i;
-
- if (argc == 2 || argc > 3 || (argc == 3 && (!argv[2] ||
- argv[1][0] != '-' || argv[1][1] != 'S'))) {
- printf("Useage: snuz [-S filename] (-S makes list of newsgroups)\n");
- exit(1);
- }
- ptr = argv[0];
- while (*ptr)
- *ptr++;
- while (*ptr != ':' && *ptr != '\\' && *ptr != '/' && ptr != argv[0])
- *(ptr--) = 0;
- if((ptr = getenv("SNUZCFG")) == NULL)
- strcpy(buf, argv[0]);
- else {
- strcpy(buf, ptr);
- strcat(buf, "\\");
- }
-
- strcat(buf, "snuz.cfg");
- if ((cfgfile = fopen(buf, "r")) == NULL) {
- printf("can't open snuz.cfg file %s\n", buf);
- exit(1);
- }
- while (1) {
- if (fgets(buf, 126, cfgfile) == NULL)
- break;
- extract(newsrc, "SNUZRC=", buf);
- extract(serverhost, "NNTPHOST=", buf);
- extract(fromline, "NNTPFROM=", buf);
- extract(editorpath, "EDITOR=", buf);
- extract(tmpdir, "TMP=", buf);
- extract(smtppath, "SMTPPATH=", buf);
- }
- fclose(cfgfile);
- for (i = 0; i < 128; i++) {
- if (newsrc[i] == '\n')
- newsrc[i] = 0;
- if (serverhost[i] == '\n')
- serverhost[i] = 0;
- if (fromline[i] == '\n')
- fromline[i] = 0;
- if (editorpath[i] == '\n')
- editorpath[i] = 0;
- if (tmpdir[i] == '\n')
- tmpdir[i] = 0;
- if (smtppath[i] == '\n')
- smtppath[i] = 0;
- }
- if (!(*serverhost) || !(*fromline) || !(*editorpath) || !(*smtppath)) {
- printf("incomplete snuz.cfg file\n");
- exit(1);
- }
- strcat(tmpdir, "\\");
-
- printf(version);
-
- if (argc == 3) {
- serverfd = netsocket();
- servf = 0;
- getserv(buf, sizeof buf);
- saveactive(argv[2]);
- qexit(1);
- }
- getnewsrc();
- if (ngroups < 2) {
- printf("You need at least two newsgroups\n");
- exit(1);
- }
- serverfd = netsocket(); /* Note: this call does a lot, including
- * setting up some important onexit routines. */
- servf = 0;
- getserv(buf, sizeof buf);
- buf[77] = '\0';
- printf("[%s]\n", buf);
- }
-
- void
- docommand()
- {
- char buf[128];
- char *ptr;
- int cug, nug;
- int ch, i, qhead;
- int skipgroup = 0;
- int noquery = 0;
- int oldquery = 0;
- int noxpost = 1;
- int skipalready = 0;
- FILE *qfile, *ifile;
- long xtime;
- unsigned long ltemp;
- long save_article;
-
- cug = 0;
- cur_article = firsts[0];
- cur_group = -1;
- nug = 1;
- while (1) {
- if (nug) {
- nug = 0;
- follow_up_article = 0xffffffff;
- if (cug < 0) {
- printf("▒▒▒▒▒▒ trying to read before first group ▒▒▒▒▒▒ *\n");
- cug = 0;
- cur_article = firsts[cug];
- cur_group = -1;
-
- }
- if (cug >= ngroups) {
- printf("▒▒▒▒▒▒ trying to read after last group ▒▒▒▒▒▒ \n");
- cug = ngroups - 1;
- cur_article = firsts[cug];
- cur_group = -1;
- }
- if (cug != cur_group) {
- printf("\n▒▒▒▒▒▒ %s ▒▒▒▒▒▒\n", groups[cug]);
- if (cgroup(groups[cug])) {
- printf("[invalid or deleted group]\n");
- if (++bogus >= 30) {
- qexit(10);
- }
- groups[cug] = NULL;
- firsts[cug] = 0;
- compactgroups();
- cug++;
- cur_group = -1;
- if (cug >= ngroups)
- cug = 0;
- nug++;
- continue;
- }
- printf("First: %U Last: %U Current: %U\n\n",
- cur_first, cur_last, firsts[cug] > cur_last ? cur_last :
- firsts[cug]);
- }
- cur_group = cug;
- if (firsts[cug] < cur_first)
- firsts[cug] = cur_first;
- if (firsts[cug] > cur_last + 1)
- firsts[cug] = cur_last + 1;
- if (cur_numa == 0) {
- if (!skipalready || cug >= ngroups - 1 || kbhit()) {
- printf("▒▒▒▒▒▒ no articles in this group ▒▒▒▒▒▒\n");
- skipgroup = 2;
- } else {
- cug++;
- nug++;
- continue;
- }
-
- } else if (cstat(firsts[cug]) && cstat(cur_last)) {
- if (!skipalready || cug >= ngroups - 1 || kbhit()) {
- printf("▒▒▒▒▒▒ group inaccessible ▒▒▒▒▒▒\n");
- skipgroup = 2;
- } else {
- cug++;
- nug++;
- continue;
- }
- } else if (firsts[cug] > cur_last) {
- if (!skipalready || cug >= ngroups - 1 || kbhit()) {
- printf(
- "▒▒▒▒▒▒ already read last article - <RETURN> will skip group ▒▒▒▒▒▒\n");
- skipgroup = 1;
- } else {
- cug++;
- nug++;
- continue;
- }
- }
- } else {
- if (cnext()) {
- printf("▒▒▒▒▒▒ End of group %s ▒▒▒▒▒▒\n", groups[cug]);
- skipgroup = 2;
- firsts[cug] = cur_last + 1;
- }
- }
- qhead = chead();
- if (!skipgroup) {
- if (qhead) {
- printf("[article %U: bad header]\n", cur_article);
- firsts[cug] = cur_article + 1;
- continue;
- }
- if (noxpost && checkx()) {
- firsts[cug] = cur_article + 1;
- continue;
- }
- }
- query:
- {
- if (noquery)
- ch = 'y';
- else if (oldquery)
- ch = oldquery;
- else {
- printf(">");
- ch = ngetc();
- }
- oldquery = 0;
- noquery = 0;
- if ((skipgroup && ch == '\r') || (skipgroup == 2 && ch == 'y'))
- ch = 'N';
-
- skipgroup = 0;
-
-
- switch (ch) {
- case '?':
- case 'H':
- case 'h':
- printf("\n<RETURN> or y - read next article\n");
- printf("= - reread current article\n");
- printf("- - read previous article\n");
- printf("g - go to article #\n");
- printf("q - quit\n");
- printf("e - exit without changing .rc file\n");
- printf("s - save article in file\n");
- printf("a - append article to file\n");
- printf("c - mark all articles in group as read\n");
- printf("P - go to previous newsgroup\n");
- printf("N - go to next newsgroup\n");
- printf("G - go to specified new group \n");
- printf("L - list news groups subscribed to \n");
- printf("i - list index \n");
- printf("I - list index with keyword\n");
- printf("X - toggle reading cross posts\n");
- printf("Z - toggle reading already read groups\n");
- printf("F or f - followup, [F includes text] \n");
- printf("M or m - send mail, [M includes text] \n");
- printf("S - Subscribe to new group\n");
- printf("U - unsubscribe current group\n");
- break;
- case 'q':
- return;
- case 'X':
- noxpost ^= 1;
- if (noxpost)
- printf("No cross posts\n");
- else
- printf("Read cross posts\n");
- break;
- case 'Z':
- skipalready ^= 1;
- if (skipalready)
- printf("Skip already read groups\n");
- else
- printf("Don't skip already read groups\n");
- nug++;
- continue;
- case 'e':
- qexit(1);
- case 'y':
- case '\r':
- strncpy(buf, cur_subject, 80);
- buf[80] = 0;
- do {
- clearscreen();
- printf("****** (%U/%U) [%s]******\n%s\n(%s) %s\n\n",
- cur_article, cur_last, groups[cur_group], buf, cur_from,
- cur_date);
- follow_up_article = cur_article;
- } while ((oldquery = showbody()) == 'a');
- if (oldquery == 'q' || oldquery < 0 ||
- (oldquery == '\r' && cur_article == cur_last))
- oldquery = 0;
- firsts[cug] = cur_article + 1;
- continue;
- case 's':
- case 'a':
- if (follow_up_article == 0xffffffff) {
- printf("Not on an article\n");
- } else {
- save_article = cur_article;
- cstat(follow_up_article);
- chead();
- (void) savebody(ch == 'a' ? 1 : 0);
- cur_article = save_article;
- cstat(cur_article);
- chead();
- if(firsts[cug] == cur_last + 1)skipgroup = 2;
- }
- break;
- case 'c':
- firsts[cug] = cur_last + 1;
- cug++;
- nug++;
- continue;
- case 'P':
- cug--;
- nug++;
- continue;
- case 'N':
- cug++;
- nug++;
- continue;
- case '-':
- case '=':
- if (follow_up_article != 0xffffffff) {
- if (ch == '-') {
- if (cur_first != follow_up_article)
- noquery = 1;
- if (follow_up_article > cur_first)
- firsts[cug]
- = follow_up_article - 1;
- } else {
- noquery = 1;
- firsts[cug] = follow_up_article;
- }
- nug++;
- continue;
- }
- printf("Not on an article\n");
- break;
- case 'g':
- fflush(stdin);
- fflush(stdout);
- printf("Article number >");
- fgets(buf, 20, stdin);
- sscanf(buf, "%U", <emp);
- if ((ltemp <= cur_last)) {
- firsts[cug] = ltemp;
- nug++;
- noquery = 1;
- continue;
- }
- printf("[article out of range]\n");
- break;
- case 'S':
- i = getgroup(buf);
- if (i == -2)
- break;
- if (i != -1) {
- printf("Already subscribed!!\n");
- } else if ((ptr = malloc(strlen(buf) + 1)) == NULL ||
- ngroups >= NGROUPS - 2) {
- printf("Out of memory\n");
- } else {
- groups[ngroups] = ptr;
- ptr = buf;
- while (*ptr == ' ')
- ptr++;
- strcpy(groups[ngroups], ptr);
- firsts[ngroups] = 1;
- cug = ngroups++;
- cur_group = -1;
- groups[ngroups] = NULL;
- nug++;
- continue;
- }
- break;
- case 'U':
- if (ngroups <= 2) {
- printf("too few groups to delete one\n");
- break;
- }
- groups[cur_group] = NULL;
- firsts[cur_group] = 0;
- compactgroups();
- cug++;
- nug++;
- cur_group = -1;
- if (cug >= ngroups)
- cug = ngroups - 1;
- continue;
- case 'G':
- i = getgroup(buf);
- if (i == -2)
- break;
- if (i != -1) {
- cug = i;
- nug++;
- continue;
- }
- printf("group not found");
- break;
- case 'i':
- case 'I':
- showindex((ch == 'I') ? 1 : 0);
- if (chead())
- continue;
- break;
- case 'L':
- listgroups();
- break;
- case 'F':
- case 'f':
- case 'M':
- case 'm':
- if (follow_up_article == 0xffffffff) {
- printf("Not on an article\n");
- } else {
- save_article = cur_article;
- cstat(follow_up_article);
- chead();
- if (!getpost(ch)) {
- errno = 0;
- i = spawnl(P_WAIT, editorpath,
- editorpath, tmpfil,
- NULL);
- if (i)
- printf("error number from spawn = %d\n",
- errno);
- printf("Type y to actually %s article\n",
- (ch == 'M' || ch == 'm') ? "mail" : "post");
- if ((i = ngetc()) == 'y' || i == 'Y') {
- /* postnews(); */
-
- strcpy(buf, tmpdir);
- if (ch == 'M' || ch == 'm')
- strcat(buf, "sendmail.lst");
- else
- strcat(buf, "postnews.lst");
-
- qfile = fopen(buf, "a");
- if (!qfile) {
- printf("failed\n");
- } else {
- ifile = NULL;
- strcpy(buf, tmpfil);
- xtime = time(NULL) & 4194303l;
- do {
- xtime++;
- if (ifile)
- fclose(ifile);
- sprintf(tmpfil, "%sx%ld.nuz", tmpdir, xtime);
- } while (ifile = fopen(tmpfil, "r"));
- rename(buf, tmpfil);
- fprintf(qfile, "%s\n", tmpfil);
- fclose(qfile);
- }
- } else
- remove(tmpfil);
- }
- cur_article = save_article;
- cstat(cur_article);
- chead();
- if(firsts[cug] == cur_last + 1)skipgroup = 2;
- }
- break;
- default:
- printf("[illegal command, try ?]\n");
- break;
- }
- }
- goto query;
- }
- }
-
- void
- getserv(char *b, int sb)
- {
- char *p = b;
- sb--;
- while (sb > 0) {
- while (!servf) {
- servp = servb;
- servf = tcpread(serverfd, servb, sizeof servb);
- }
- if (*servp == '\n') {
- *b++ = 0;
- servp++, servf--;
- break;
- } else if (*servp == '\r')
- servp++, servf--;
- else
- *b++ = *servp++, servf--;
- }
- }
- void
- putserv(char *b)
- {
- tcpwrite(serverfd, b, strlen(b));
- }
-
- void
- compactgroups()
- {
- int i;
- for (i = 0; i < ngroups; i++)
- if (groups[i] == NULL)
- break;
- if (i != ngroups - 1) {
- for (i++; i < ngroups; i++) {
- groups[i - 1] = groups[i];
- firsts[i - 1] = firsts[i];
- }
- }
- ngroups--;
- }
-
- void
- getnewsrc(void)
- {
- char group[STRING];
- unsigned long first;
- int i;
- char *ptr, *ptr2;
- FILE *rec;
-
- rec = fopen(newsrc, "r");
- if (!rec) {
- perror(newsrc);
- exit(1);
- }
- i = 0;
- while ((i < NGROUPS) && (fscanf(rec, "%s %U", group, &first) == 2)) {
- ptr2 = group;
- while (*ptr2 == ' ')
- ptr2++;
- ptr = malloc(strlen(ptr2) + 1);
- if (!ptr) {
- printf("Out of memory for groups\n");
- break;
- }
- groups[i] = strcpy(ptr, ptr2);
- firsts[i] = first;
- i++;
- }
- ngroups = i;
- }
-
- void
- dumpnewsrc(void)
- {
- int i;
- FILE *rec;
-
- rec = fopen(newsrc, "w");
- for (i = 0; i < ngroups; i++)
- if (groups[i])
- fprintf(rec, "%s %U\n", groups[i], firsts[i]);
- fclose(rec);
- }
-
- int
- cgroup(char *s)
- {
- char buf[STRING];
-
- sprintf(buf, "GROUP %s\n", s);
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 411)
- return -1;
- else if (reply == 211) {
- sscanf(buf, "%d %U %U %U %s",
- &reply, &cur_numa, &cur_first, &cur_last, cur_gname);
- return 0;
- } else
- printf("cgroup: %s\n", buf);
- return -1;
- }
-
- cstat(i)
- unsigned long i;
- {
- char buf[STRING], *p, *q;
-
- sprintf(buf, "STAT %U\n", i);
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 423)
- return -1;
- else if (reply == 223) {
- cur_article = reparticle;
- p = buf;
- q = cur_articleid;
- while ((p < buf + STRING - 2) && (*p != '<'))
- p++;
- while ((p < buf + STRING - 2) && (*p != '>'))
- *q++ = *p++;
- *q++ = '>';
- *q++ = '\0';
- return 0;
- } else
- printf("cstat: %s\n", buf);
- return -1;
- }
-
- #if 0
- int
- current(void)
- {
- char buf[STRING], *p, *q;
-
- sprintf(buf, "STAT\n");
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 423)
- return -1;
- else if (reply == 412)
- return -1;
- else if (reply == 223) {
- cur_article = reparticle;
- p = buf;
- q = cur_articleid;
- while ((p < buf + STRING - 2) && (*p != '<'))
- p++;
- while ((p < buf + STRING - 2) && (*p != '>'))
- *q++ = *p++;
- *q++ = '>';
- *q++ = '\0';
- return 0;
- } else
- printf("current: %s\n", buf);
- return -1;
- }
- #endif
-
- int
- cnext(void)
- {
- char buf[STRING], *p, *q;
-
- sprintf(buf, "NEXT\n");
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 421)
- return -1;
- else if (reply == 223) {
- cur_article = reparticle;
- p = buf;
- q = cur_articleid;
- while ((p < buf + STRING - 2) && (*p != '<'))
- p++;
- while ((p < buf + STRING - 2) && (*p != '>'))
- *q++ = *p++;
- *q++ = '>';
- *q++ = '\0';
- return 0;
- } else
- printf("cnext: %s\n", buf);
- return -1;
- }
-
- int
- extract(char *to, char *key, char *from)
- {
- if (!strncmp(from, key, strlen(key))) {
- from += strlen(key);
- while (*from == ' ')
- from++;
- strcpy(to, from);
- return 1;
- } else
- return 0;
- }
-
- chead()
- {
- char buf[STRING];
-
- *cur_path = 0;
- *cur_from = 0;
- *cur_replyto = 0;
- *cur_subject = 0;
- *cur_newsgroups = 0;
- *cur_message_ID = 0;
- *cur_references = 0;
- *cur_date = 0;
-
- sprintf(buf, "HEAD %U\n", cur_article);
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 423)
- return -1;
- else if (reply == 221)
- while (1) {
- getserv(buf, sizeof buf);
- if (!strcmp(buf, ".")) {
- if (!*cur_replyto)
- strcpy(cur_replyto, cur_from);
- return 0;
- }
- extract(cur_path, "Path:", buf) ||
- extract(cur_from, "From:", buf) ||
- extract(cur_subject, "Subject:", buf) ||
- extract(cur_replyto, "Reply-To:", buf) ||
- extract(cur_newsgroups, "Newsgroups:", buf) ||
- extract(cur_message_ID, "Message-ID:", buf) ||
- extract(cur_references, "References:", buf) ||
- extract(cur_date, "Date:", buf);
- } else
- printf("chead: %s\n", buf);
- return -1;
- }
- int
- showbody(void)
- {
- char buf[STRING];
- int line = 0;
- int ch;
-
- sprintf(buf, "BODY %U\n", cur_article);
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 423)
- return -1;
- else if (reply == 222)
- while (1) {
- if (line == 18) {
- reversevideo("more(<SPACE> to continue)?");
- fflush(stdout);
- ch = ngetc();
- if (ch != ' ') {
- while (getserv(buf, sizeof buf), strcmp(buf, "."));
- normalvideo();
- return ch;
- }
- backline();
- line = 0;
- }
- getserv(buf, sizeof buf);
- if (strcmp(buf, ".")) {
- /* printf("%s", buf); */
- fputs(buf,stdout);
- if (strlen(buf) != 80)
- printf("\n");
- } else {
- reversevideo(" End of article ");
- printf("\n");
- normalvideo();
- return 0;
- }
- line++;
- } else
- printf("showbody: %d %s\n", reply, buf);
- return -1;
- }
-
- int
- savebody(int type)
- {
- char buf[STRING];
- FILE *f;
- char sss[72];
- char *s, *ss;
-
-
- s = &sss[0];
- fflush(stdin);
- fflush(stdout);
- printf("Filename >");
- fgets(s, 70, stdin);
-
- sss[71] = '\n';
- while (*s == ' ')
- s++;
- ss = s;
- while (*ss != '\n')
- ss++;
- *ss = 0;
- if (!(f = fopen(s, type ? "a" : "w"))) {
- perror(s);
- return -1;
- }
- sprintf(buf, "BODY %U\n", cur_article);
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 423)
- goto badsave;
- else if (reply == 222) {
- fprintf(f, "Subject: %s\n", cur_subject);
- fprintf(f, "From: %s\n", cur_from);
- fprintf(f, "Path: %s\n", cur_path);
- fprintf(f, "Reply-To: %s\n", cur_replyto);
- fprintf(f, "Newsgroups: %s\n", cur_newsgroups);
- fprintf(f, "Message-ID: %s\n", cur_message_ID);
- fprintf(f, "References: %s\n", cur_references);
- fprintf(f, "Date: %s\n", cur_date);
- fprintf(f, "\n");
- while (1) {
- getserv(buf, sizeof buf);
- if (strcmp(buf, "."))
- fprintf(f, "%s\n", buf);
- else
- break;
- }
- fclose(f);
- return 0;
- } else
- printf("savebody: %d %s\n", reply, buf);
- badsave:
- fclose(f);
- return -1;
- }
-
- int
- saveactive(char *s)
- {
- char buf[256];
- FILE *f;
-
- if (!(f = fopen(s, "w"))) {
- perror(s);
- return -1;
- }
- sprintf(buf, "LIST\n");
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 215) {
- while (1) {
- char group[256];
- unsigned long to, from;
- char act;
-
- getserv(buf, sizeof buf);
- if (!strcmp(buf, "."))
- break;
- sscanf(buf, "%s %U %U %c", group, &to, &from, &act);
- fprintf(f, "%s %U\n", group, to);
- }
- fclose(f);
- return 0;
- } else
- printf("saveactive: %d %s\n", reply, buf);
- fclose(f);
- return -1;
- }
-
- int
- netsocket(void)
- {
- int fd;
-
- if ((fd = tcpopen(serverhost, 119)) < 0) {
- fprintf(stderr, "tcpopen failed\n");
- exit(9);
- }
- return (fd);
- }
-
- int
- getgroup(char *buf)
- {
- char *s, *ss;
- int i;
-
- fflush(stdin);
- fflush(stdout);
- printf("New group >");
- fgets(buf, 70, stdin);
- if (*buf == 0 || *buf == '\n')
- return -2;
-
- s = &buf[0];
-
- buf[71] = '\n';
- while (*s == ' ')
- s++;
- ss = s;
- while (*ss != '\n')
- ss++;
- *ss = 0;
-
- for (i = 0; i < ngroups; i++) {
- if (!strcmp(s, groups[i]))
- return i;
- }
- return -1;
- }
-
- void
- listgroups(void)
- {
- int line = 0;
- int ch, i;
-
- printf("\n\n");
- for (i = 0; i < ngroups; i++) {
- if (line == 18) {
- reversevideo("more(<RETURN> or <SPACE> to continue, q or . to quit)?");
- fflush(stdout);
- ch = ngetc();
- if (ch == 'q' || ch == '.') {
- normalvideo();
- return;
- }
- backline();
- line = 0;
- }
- printf(" %s %U\n", groups[i], firsts[i]);
- line++;
- }
- }
-
- int
- showindex(int flag)
- {
- char buf[80], test_string[80], test_string2[150];
- int line = 0;
- int ch, i, j;
- unsigned long save_article;
-
- if (flag) {
- printf("Enter matching string: ");
- fgets(test_string, 78, stdin);
- for (i = 0; test_string[i] != 0; i++) {
- if (test_string[i] == '\n')
- test_string[i] = 0;
- if (test_string[i] >= 'a' && test_string[i] <= 'z')
- test_string[i] -= 'a' - 'A';
- }
- }
- save_article = cur_article;
- if (cur_article < cur_first)
- cur_article = cur_first;
- printf("\n\n");
- for (; cur_article <= cur_last; cur_article++) {
- if (line == 18) {
- reversevideo("more(<RETURN> or <SPACE> to continue, q or . to quit)?");
- fflush(stdout);
- ch = ngetc();
- if (ch == 'q' || ch == '.') {
- cur_article = save_article;
- normalvideo();
- return 0;
- }
- backline();
- line = 0;
- }
- if (chead())
- continue;
- strncpy(buf, cur_subject, 70);
- buf[70] = 0;
-
-
- if (flag) {
- strcpy(test_string2, buf);
- strncat(test_string2, cur_from, 70);
- for (j = 0; j < 145 && test_string2[j] != 0; j++) {
- if (test_string2[j] >= 'a' && test_string2[j] <= 'z')
- test_string2[j] -= 'a' - 'A';
- }
- }
- test_string2[j] = 0;
- if (!flag || strstr(test_string2, test_string)) {
- printf("%U%c %s\n",
- cur_article, checkx() ? '*' : ' ', buf);
- fflush(stdout);
- line++;
- }
- }
- cur_article = save_article;
- return 0;
- }
-
- int
- getpost(int f)
- {
-
- char buf[STRING];
- FILE *ifile = NULL;
-
- sprintf(tmpfil, "%stmp.nuz", tmpdir);
-
- ifile = fopen(tmpfil, "w");
- if (!ifile) {
- printf("Can't open temporary file \n");
- return 1;
- }
- fprintf(ifile, "From: %s\n", fromline);
- if (f == 'm' || f == 'M') {
- fprintf(ifile, "To: %s\n", (cur_replyto != NULL) ?
- cur_replyto : cur_from);
- }
- if (!strncmp(cur_subject, "Re:", 3))
- fprintf(ifile, "Subject: %s\n", cur_subject);
- else
- fprintf(ifile, "Subject: Re: %s\n", cur_subject);
-
- if (f == 'f' || f == 'F') {
- fprintf(ifile, "Newsgroups: %s\n", cur_newsgroups);
- fprintf(ifile, "Summary: \nFollowup-To: \nDistribution: \n");
- /* fprintf(ifile, "Date: %s\n", cur_date); */
- fprintf(ifile, "References: %s", cur_message_ID);
- if (cur_references)
- fprintf(ifile, " %s", cur_references);
- fprintf(ifile, "\n");
- }
- fprintf(ifile, "\n\n");
-
-
- if (f == 'F' || f == 'M') {
- fprintf(ifile, "In article %s %s writes:\n", cur_message_ID, cur_from);
-
- sprintf(buf, "BODY %U\n", cur_article);
- putserv(buf);
- getserv(buf, sizeof buf);
- sscanf(buf, "%d %U", &reply, &reparticle);
- if (reply == 222) {
- while (1) {
- getserv(buf, sizeof buf);
- if (strcmp(buf, ".")) {
- fprintf(ifile, ">%s\n", buf);
- } else
- break;
- }
- } else {
- printf("savebody error: %d %s\n", reply, buf);
- fclose(ifile);
- return 1;
- }
- }
- fclose(ifile);
- return 0;
- }
-
-
- int
- postnews(void)
- {
-
- char buf[STRING], s[STRING], fbuf[128];
- int seen_fromline, in_header, seen_header;
- FILE *ifile, *pfile;
- char *cp, *bp;
- int count, i;
-
-
- strcpy(fbuf, tmpdir);
- strcat(fbuf, "postnews.lst");
- pfile = fopen(fbuf, "r");
- if (!pfile) {
- printf("No News to post\n");
- return 1;
- } else
- printf("Now trying to post your News\n");
-
- while (1) {
- if (fgets(fbuf, 126, pfile) == NULL)
- break;
- for (i = 0; fbuf[i]; i++)
- if (fbuf[i] == '\n')
- fbuf[i] = 0;
-
- ifile = fopen(fbuf, "r");
- if (!ifile) {
- printf("Can't open temporary file %s\n", fbuf);
- continue;
- }
- putserv("POST\n");
- getserv(buf, sizeof buf);
- if (*buf != '3') {
- if (atoi(buf) == 440) {
- printf("No posting!\n");
- } else {
- printf("Remote error: %s\n", buf);
- }
- fclose(pfile);
- fclose(ifile);
- return 0;
- }
- printf("Sending file\n");
-
- in_header = 1;
- seen_header = 0;
- seen_fromline = 0;
-
-
- count = 0;
- bp = buf;
- while (fgets(s, 510, ifile) != NULL) {
- s[511] = '\n';
- cp = s;
- while (*cp != '\n')
- cp++;
- *cp = 0;
- if (s[0] == '.') { /* Single . is eof, so put in extra one */
- *bp++ = '.';
- if (++count == 512) {
- tcpwrite(serverfd, buf, 512);
- usleep();
- /*
- * Note on all these 'usleep' calls: Without them this
- * program crashes our Proteon fiber-optic network
- * gateway. It is known that this gateway has software
- * problems. They promise to fix it 'real soon now'. But
- * on the other hand no other computer crashes is, nor
- * does NCSA Telnet or NCSA FTP used on my very own PC.
- * So this appears to be a terrible kludge.
- */
- count = 0;
- bp = buf;
- }
- }
- if (in_header && !strnicmp(s, "From:", sizeof("From:") - 1)) {
- seen_header = 1;
- seen_fromline = 1;
- }
- if (in_header && s[0] == '\0') {
- if (seen_header) {
- in_header = 0;
- if (!seen_fromline) {
- strcpy(s, "From: ");
- strcpy(s, fromline);
- strcat(s, "\r\n");
- }
- } else {
- continue;
- }
- } else if (in_header) {
- if (valid_header(s))
- seen_header = 1;
- else
- continue;
- }
- cp = s;
- while (*cp) {
- *bp++ = *cp++;
- if (++count == 512) {
- tcpwrite(serverfd, buf, 512);
- usleep();
- count = 0;
- bp = buf;
- }
- }
- cp = "\r\n";
- while (*cp) {
- *bp++ = *cp++;
- if (++count == 512) {
- tcpwrite(serverfd, buf, 512);
- usleep();
- count = 0;
- bp = buf;
- }
- }
- }
-
- fclose(ifile);
-
- cp = ".\r\n";
- while (*cp) {
- *bp++ = *cp++;
- if (++count == 512) {
- tcpwrite(serverfd, buf, 512);
- usleep();
- count = 0;
- bp = buf;
- }
- }
-
- if (count) {
- tcpwrite(serverfd, buf, count);
- usleep();
- }
- printf("waiting for reply\n");
- (void) getserv(buf, sizeof(buf));
- printf("got reply\n");
- if (*buf != '2') {
- if (atoi(buf) == 441) {
- printf("Article not accepted by server; not post*ed.\n");
- for (cp = buf + 4; *cp && *cp != '\r'; cp++)
- if (*cp == '\\')
- putchar('\n');
- else
- putchar(*cp);
- fclose(pfile);
- return 0;
- } else {
- printf("Remote error: %s\n", buf);
- fclose(pfile);
- return 0;
- }
- }
- remove(fbuf);
- }
- strcpy(fbuf, tmpdir);
- strcat(fbuf, "postnews.lst");
- remove(fbuf);
- return 0;
- }
-
-
-
-
- int
- valid_header(char *h)
- {
- char *colon, *space;
-
- /*
- * blank or tab in first position implies this is a continuation header
- */
- if (h[0] == ' ' || h[0] == '\t')
- return (1);
-
- /*
- * just check for initial letter, colon, and space to make sure we
- * discard only invalid headers
- */
- colon = strchr(h, ':');
- space = strchr(h, ' ');
- if (isalpha(h[0]) && colon && space == colon + 1)
- return (1);
-
- /*
- * anything else is a bad header -- it should be ignored
- */
- return (0);
- }
-
-
-
- void
- qexit(int n)
- {
- char buf[512];
-
- if (n >= 10)
- printf("Horrible error: read manual \n");
- fflush(stdout);
- putserv("QUIT\n");
- getserv(buf, sizeof buf);
- if (*buf != '2')
- printf("Tried to quit, but failed\n");
- if (n)
- exit(n);
- }
-
-
- int
- checkx(void)
- {
- char buf[256];
- int i, k;
- char *ptr, *ptr2, *ptr3;
-
- if (cur_group == 0)
- return 0;
- ptr = cur_newsgroups;
- while (*ptr == ' ')
- ptr++;
- k = 0;
- while (1) {
- if (*ptr == 0)
- break;
- if (*ptr == ',')
- ptr++;
- while (*ptr == ' ')
- ptr++;
- ptr2 = ptr;
- ptr3 = buf;
- while (*ptr2 != 0 && *ptr2 != ',')
- *ptr3++ = *ptr2++;
- *ptr3 = 0;
- while (*(--ptr3) == ' ')
- *ptr3 = 0;
- ptr = ptr2;
- for (i = 0; i < cur_group; i++) {
- if (strcmp(buf, groups[i]) == 0)
- return 1;
- }
- }
- return 0;
- }
- void
- sendmail()
- {
- char buf[128];
- FILE *mfile;
- int i;
-
- strcpy(buf, tmpdir);
- strcat(buf, "sendmail.lst");
-
- mfile = fopen(buf, "r");
- fclose(mfile);
-
- if (mfile != NULL) {
- printf("Sending mail\n");
- for (i = 0; i < 10; i++)
- usleep();
- spawnl(P_OVERLAY, smtppath, smtppath, buf, serverhost, NULL);
- /* this does not normally return, but might if some spawn error */
- } else {
- printf("No mail to process\n");
- for (i = 0; i < 4; i++)
- usleep();
- }
- xabort(); /* don't do onexit processing, we already did it */
- }
-