v07i053: 2.11 News Source, Part04/09
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Fri Nov 7 03:07:44 AEST 1986
Submitted by: seismo!rick (Rick Adams)
Mod.sources: Volume 7, Issue 53
Archive-name: 2.11news/Part14
# To extract, sh this file
#
# news 2.11 source part 4 of 9
#
if test ! -d src
then
mkdir src
fi
echo x - src/postnews.c 1>&2
sed 's/.//' >src/postnews.c <<'*-*-END-of-src/postnews.c-*-*'
-/*
- * This software is Copyright (c) 1986 by Rick Adams.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or
- * otherwise use this software as long as: there is no monetary
- * profit gained specifically from the use or reproduction or this
- * software, it is not sold, rented, traded or otherwise marketed, and
- * this copyright notice is included prominently in any copy
- * made.
- *
- * The author make no claims as to the fitness or correctness of
- * this software for any use whatsoever, and it is provided as is.
- * Any use of this software is at the user's own risk.
- *
- * Postnews: post a news message to Usenet. This C version replaces a shell
- * script, and does more intelligent prompting and filtering than possible
- * in a shell script.
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)postnews.c 1.28 10/23/86";
-#endif /* SCCSID */
-
-#include "params.h"
-
-#define APPEND 1
-#define REPLACE 2
-
-extern char *MAILPARSER;
-
-char tempfname[50]; /* file name used for making article */
-char original[BUFLEN]; /* file name of original, used in followup */
-char homedir[BUFLEN]; /* HOME environment setting */
-char user[SBUFLEN]; /* user name */
-char ccname[BUFLEN]; /* file name for article copy */
-
-/* article header information */
-char subject[BUFLEN];
-char distribution[BUFLEN];
-char references[BUFLEN];
-char newsgroups[BUFLEN];
-char isfrom[BUFLEN];
-char msgid[BUFLEN];
-char keywords[BUFLEN];
-char summary[BUFLEN];
-
-char ngsep[] = { NGDELIM, '\0' }; /* == "," */
-
-char *Progname = "postnews"; /* for xerror */
-
-time_t fmodtime;
-char buf[BUFLEN];
-
-#define MAXDISTR 16
-struct distr {
- char abbr[24];
- char descr[128];
-} distr[MAXDISTR];
-
-FILE *xfopen();
-
-main(argc, argv)
-char *argv[];
-{
- register int c;
-
- init();
-
- if (argc == 2) {
- if (!prefix(argv[1], SPOOL))
- xerror("Can only followup to articles in %s", SPOOL);
- followup(argv[1]);
- (void) strcpy(original, argv[1]);
- } else
- if (askyes("Is this message in response to some other message? ","no")) {
- char ng[BUFLEN], num[BUFLEN];
- long i, j, lastnum;
- register char *p;
- int fd, dir;
- char canpost;
-
- getpr("In what newsgroup was the article posted? ",ng);
- if (!valid_ng(ng, &i, &j, &canpost))
- if (canpost == 'i' )
- byebye("There is no such newsgroup.");
- else if (canpost == 'n')
- byebye("You are not allowed to post to that group.");
-
- printf("Valid article numbers are from %ld to %ld\n", j, i);
- lastnum = i + 1;
- dir = -1;
-
- for(;;) {
- getpr("\nWhat was the article number? ", num);
- switch(num[0]) {
- case '+':
- dir = 1;
- sprintf(num, "%ld", lastnum + 1);
- break;
- case '-':
- dir = -1;
- /* no break */
- case '\0':
- sprintf(num, "%ld", lastnum + dir);
- break;
- }
- (void) sprintf(original, "%s/%s", SPOOL, ng);
- for (p=original+strlen(SPOOL)+1; *p ;++p)
- if (*p == '.')
- *p = '/';
- (void) strcat(original, "/");
- (void) strcat(original, num);
-
- if ((fd=open(original,0)) >= 0) {
- (void) close(fd);
- printf("\narticle %s\n", original);
- if (article_line(original, "From: ", buf))
- printf("%s\n", buf);
- if (article_line(original, "Subject: ", buf))
- printf("%s\n", buf);
- if (askyes("Is this the one you want? ", "n"))
- break;
- } else
- printf("I can't find that article.\n");
- lastnum = atol(num);
- }
-
- followup(original);
- } else {
- do {
- getpr("Subject: ", subject);
- if (*subject == '?') {
-printf("People read the subject line to learn what your article is about.\n");
-printf("You want it to do the same job as a newspaper headline.\n");
-printf("So type in something both brief and descriptive.\n");
- *subject = '\0';
- }
- } while (*subject == '\0');
- getpr("Keywords: ", keywords);
-
- while (!get_newsgroup())
- ;
- get_distribution((char *)0);
- }
-
- if (pre_checks())
- exit(1);
-
- prep_article();
- c = 'e';
- for (;;) {
- if (c == 'e') {
- edit_article();
- post_checks();
- }
- do {
- do {
- getpr("\nWhat now? [send, edit, list, quit, write] ", buf);
- c = buf[0];
- } while (c == '\0');
- if (isupper(c))
- c = tolower(c);
- if (c == 'q') {
- (void) UNLINK(tempfname);
- exit(1);
- }
- if (c == 'l') {
- char *pager = getenv("PAGER");
- char lbuf[BUFLEN];
- if (pager == NULL || *pager == '\0') {
-#ifdef PAGE
-# ifdef IHCC
- (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
-# else /* !IHCC */
- (void) strcpy(lbuf, PAGE);
-# endif /* !IHCC */
- pager = lbuf;
-#else /* !PAGE */
- pager = "cat";
-#endif /* !PAGE */
- }
- sprintf(buf, "exec %s %s", pager, tempfname);
- (void) system(buf);
- }
- if (c == 'w') {
- register int ifd, ofd, nbytes;
- char iobuf[BUFSIZ];
- char fname[BUFLEN];
- getpr("Filename? ", fname);
- if (fname[0] == '\0')
- continue;
- ofd = creat(fname, 0666);
- if (ofd < 0)
- perror(fname);
- else {
- ifd = open(tempfname, 0);
- if (ifd < 0)
- xerror("Can't reopen %s\n", tempfname);
- while ((nbytes = read(ifd, iobuf, BUFSIZ)) > 0 )
- write(ofd, iobuf, nbytes);
- close(ofd);
- close(ifd);
- }
- }
- } while (!index("eps", c));
- if (c != 'e')
- post_article(); /* will exit if posted successfully */
- };
-}
-
-/*
- * Find out the topic of interest.
- */
-get_newsgroup()
-{
- int n;
- long i;
- char canpost;
- static int first = 1;
-
- printf("Newsgroups (enter one at a time, end with a blank line):\n");
- if (first) {
- printf("\nThe most relevant newsgroup should be the first, you should\n");
- printf("add others only if your article really MUST be read by people\n");
- printf("who choose not to read the appropriate group for your article.\n");
- printf("But DO use multiple newsgroups rather than posting many times.\n\n");
- first = 0;
- }
- printf("For a list of newsgroups, type ?\n");
- n = 0;
- newsgroups[0] = '\0';
-
- for(;;) {
- getpr("> ", buf);
- if (buf[0] == '\0')
- if (n == 0)
- return FALSE;
- else
- return TRUE;
- if (buf[0] == '?'){
- char *pager = getenv("PAGER");
- char lbuf[BUFLEN];
- if (pager == NULL) {
-#ifdef PAGE
-# ifdef IHCC
- (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
-# else /* !IHCC */
- (void) strcpy(lbuf, PAGE);
-# endif /* !IHCC */
- pager = lbuf;
-#else /* !PAGE */
- pager = "cat";
-#endif /* !PAGE */
- }
- printf("These are the currently active groups:\n");
- sprintf(buf, "exec %s %s/newsgroups", pager, LIB);
- (void) system(buf);
- continue;
- }
- if (valid_ng(buf, &i, &i, &canpost)) {
- if (n++ != 0)
- (void) strcat(newsgroups, ngsep);
- (void) strcat(newsgroups, buf);
- } else {
- if (canpost == 'n')
- printf("You are not allowed to post to %s\n",
- buf);
- else if (canpost == 'i')
- printf("%s is not a valid newsgroup.\n", buf);
- }
- }
-}
-
-/*
- * Find out how widely the author wants the message distributed.
- */
-get_distribution(deflt)
- char *deflt;
-{
- register int i;
- register char *r;
- char def[BUFLEN];
- char *lastgroup;
-
- lastgroup = newsgroups;
- (void) strcpy(def, newsgroups);
- r = index(def, NGDELIM);
- if (r)
- *r = '\0';
- r = index(def, '.');
- if (r) {
- *r = '\0';
- if (strcmp(def, "net") == 0)
- (void) strcpy(def, "world");
- } else {
- distribution[0] = '\0';
- return;
- }
-
- if (strcmp(def, "to") == 0) {
- /*
- * This only works if "to.xx" is the first (or only)
- * newsgroup, but it usually is ..
- * Perhaps we should make the distribution be "to.xxx" ??
- */
- distribution[0] = '\0';
- return; /* He's probably testing something */
- }
- if (deflt != (char *)0)
- (void) strcpy(def, deflt);
- if (ngmatch("net.test", newsgroups))
- (void) strcpy(def, "local");
- for(;;) {
- do {
- (void) sprintf(buf, "Distribution (default='%s', '?' for help) : ", def);
- getpr(buf, distribution);
- if (distribution[0] == '\0') {
- if (strcmp(def, "*None*") == 0)
- printf("You must enter a distribution, '?' for help.\n");
- (void) strcpy(distribution, def);
- }
- } while (strcmp(distribution, "*None*") == 0);
-
- /* Did the user ask for help? */
- if (distribution[0] == '?') {
- printf("How widely should your article be distributed?\n\n");
- for (i=0; distr[i].abbr[0]; i++)
- printf("%s\t%s\n", distr[i].abbr, distr[i].descr);
- printf("\nEnter the word that specifies the distribution that you require.\n");
- continue;
- }
-
- /* Check that it's a proper distribution */
- for (i=0; distr[i].abbr[0]; i++) {
- if (strncmp(distr[i].abbr, distribution, sizeof(distr[0].abbr)) == 0) {
- register int n;
- /* Found a match. Do any special rewriting. */
- r = newsgroups;
- n = strlen(distribution);
- /*
- * A distribution of foo is useless
- * if all the newsgroups are in foo.all
- */
- for (;;) {
- if (strncmp(r, distribution, n))
- return;
- if ((r = index(r, NGDELIM)) == NULL)
- break;
- ++r;
- }
- distribution[0] = '\0';
- return;
- }
- }
- if (strcmp(distribution, def) != 0)
- printf("Type ? for help.\n");
- else {
- int once = TRUE;
-
- do {
- r = lastgroup;
- while (r = index(r, NGDELIM))
- if (!prefix(++r, def))
- break;
- if (r == NULL) {
- /*
- * no newsgroups are distribution
- * names, and user simply will
- * not type a valid distribution,
- * assume that the default is OK.
- */
- distribution[0] = '\0';
- return;
- }
- lastgroup = r;
- if (once)
- printf("Sorry, '%s' is an unknown distribution. Type ? for help.\n", def);
- once = FALSE;
- strcpy(def, r);
- r = index(def, NGDELIM);
- if (r)
- *r = '\0';
- r = index(def, '.');
- } while (r == NULL);
- *r = '\0';
- if (strcmp(def, "net") == 0)
- strcpy(def, "world");
- }
- }
-}
-
-/*
- * Do sanity checks before the author types in the message.
- */
-pre_checks()
-{
- if (recording(newsgroups))
- return 1;
- return 0;
-}
-
-/*
- * Set up the temp file with headers.
- */
-prep_article()
-{
- FILE *tf, *of;
- struct stat stbuf;
-
- (void) strcpy(tempfname, "/tmp/postXXXXXX");
- (void) mktemp(tempfname);
-
- /* insert a header */
- tf = xfopen(tempfname, "w");
- fprintf(tf, "Subject: %s\n", subject);
- fprintf(tf, "Newsgroups: %s\n", newsgroups);
- if (distribution[0] != '\0' && strcmp(distribution, "world"))
- fprintf(tf, "Distribution: %s\n", distribution);
-
- if (keywords[0] != '\0')
- fprintf(tf, "Keywords: %s\n", keywords);
- if (summary[0] != '\0')
- fprintf(tf, "Summary: %s\n", summary);
-
- if (references[0] != '\0') {
- fprintf(tf, "References: %s\n\n", references);
-
- if (askyes("Do you want to include a copy of the article? ", "no")){
- of = xfopen(original, "r");
- while (fgets(buf, BUFSIZ, of) != NULL)
- if (buf[0] == '\n') /* skip headers */
- break;
- fprintf(tf, "In article %s, %s writes:\n", msgid, isfrom);
- while (fgets(buf, BUFSIZ, of) != NULL)
- fprintf(tf, "> %s", buf);
- (void) fclose(of);
- printf("OK, but please edit it to suppress unnecessary verbiage, signatures, etc.\n");
- }
- }
-
- fprintf(tf, "\n\n");
- (void) fflush(tf);
- (void) fstat(fileno(tf), &stbuf);
- fmodtime = stbuf.st_mtime;
- (void) fclose(tf);
-}
-
-edit_article()
-{
- register char *p;
- char *editor;
- char *endflag = "";
- char *getenv();
-
- /* edit the file */
- editor = getenv("EDITOR");
- if (editor == NULL)
- editor = DFTEDITOR;
-
- p = editor + strlen(editor) - 2;
- if (strcmp(p, "vi") == 0)
- endflag = "+";
-
- (void) sprintf(buf, "A=%s;export A;exec %s %s %s",
- original, editor, endflag, tempfname);
-
- (void) system(buf);
-}
-
-/*
- * Do sanity checks after the author has typed in the message.
- */
-post_checks()
-{
- char group[BUFLEN];
- register char *c, *p;
- struct stat stbuf;
-
- if (stat(tempfname, &stbuf) < 0) {
- printf("File deleted - no message posted.\n");
- (void) UNLINK(tempfname);
- exit(1);
- }
- if (stbuf.st_size < 5) {
- printf("File too small (<5 characters) - no message posted.\n");
- (void) UNLINK(tempfname);
- exit(1);
- }
-
- if (stbuf.st_mtime == fmodtime) {
- printf("File not modified - no message posted.\n");
- (void) UNLINK(tempfname);
- exit(1);
- }
-
- /*
- * Is this the right number? Most of the headers are yet to be added
- */
- if (stbuf.st_size > 64000) {
- printf("\nYour message will probably be truncated when it\n");
- printf("passes through a notesfile site, since it is\n");
- printf("greater than 64000 characters.\n\n");
- if (!askyes("Do you still want to post it? ","")) {
- sprintf(ccname, "%s/dead.article", homedir);
- save_article();
- (void) UNLINK(tempfname);
- exit(1);
- }
- }
-
- /*
- * get the newsgroups from the edited article, in
- * case they were altered in the editor
- */
- if (!article_line(tempfname, "Newsgroups: ", group)) {
- nogroups:
- printf("Not sending to any newsgroups - no message posted\n");
- (void) UNLINK(tempfname);
- exit(1);
- }
- c = &group[11];
- while (*c == ' ' || *c == '\t')
- c++;
- if (*c == '\0')
- goto nogroups;
- for (p = newsgroups; *c; c++) /* copy to newsgroups, w/o blanks */
- if (*c != ' ' && *c != '\t')
- *p++ = *c;
- *p = '\0';
-
- /* Sanity checks for certain newsgroups */
- if (ngmatch(newsgroups, "all.wanted") && ngmatch(distribution,"net,na,usa,att,btl,eunet,aus")) {
- printf("Is your message something that might go in your local\n");
- printf("newspaper, for example a used car ad, or an apartment\n");
- printf("for rent? ");
- if (askyes("","")) {
- printf("It's pointless to distribute your article widely, since\n");
- printf("people more than a hundred miles away won't be interested.\n");
- printf("Please use a more restricted distribution.\n");
- get_distribution("*None*");
- modify_article(tempfname, "Distribution: ", distribution,REPLACE);
- }
- }
-
- if (ngmatch(newsgroups, "all.jokes")) {
- if (askyes("Could this be offensive to anyone? ","")) {
- getpr("Whom might it offend? ", group);
- (void) sprintf(buf," - offensive to %s (rot 13)",group);
- modify_article(tempfname, "Subject: ", buf, APPEND);
- encode(tempfname);
- }
- }
-
- if (ngmatch(newsgroups, "net.general")) {
- if (index(newsgroups, NGDELIM)) {
- printf("Everybody in the world reads net.general, so it doesn't make\n");
- printf("sense to post to newsgroups in addition to net.general. If your\n");
- printf("article belongs in one of these other newsgroups, then you\n");
- printf("should not post to net.general. If it is important enough\n");
- printf("for net.general, then you shouldn't post it in other places\n");
- printf("as well. Please reenter the newsgroups.\n");
- while (!get_newsgroup())
- ;
- modify_article(tempfname, "Newsgroups: ", newsgroups,REPLACE);
- }
- if (ngmatch(newsgroups, "net.general")) {
- printf("net.general is for important announcements.\n");
- printf("It is not for items for which you couldn't think\n");
- printf("of a better place - those belong in net.misc.\n");
- if (!askyes("Are you sure your message belongs in net.general? ","")) {
- while (!get_newsgroup())
- ;
- modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
- }
- }
- }
-
- if (ngmatch(newsgroups, "net.sources,!net.sources.all")) {
- if (!article_line(tempfname, "Subject: ", group)) {
- nosubj:
- printf("There seems to be no subject for this article.\n");
- getpr("Subject: ", subject);
- modify_article(tempfname, "Subject: ", subject, REPLACE);
- } else {
- c = &group[8];
- while (*c == ' ' || *c == '\t')
- c++;
- if (*c == '\0')
- goto nosubj;
- strcpy(subject, c);
- }
- if (ngmatch(newsgroups, "all.wanted") || iswanted(subject)) {
- printf("Requests for sources should not be posted to any of\n");
- printf("the net.sources newsgroups, please post such requests\n");
- printf("to net.wanted.sources only. Please reenter the newsgroups.\n\n");
- while (!get_newsgroup())
- ;
- modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
- }
- if (ngmatch(newsgroups, "net.sources")) {
- if (!ngmatch(newsgroups, "net.sources.all") &&
- stbuf.st_size < (4*1024)) {
- printf("Your article seems rather small to be a source distribution.\n");
- if (!askyes("Are you certain that this is really source? ", "")) {
-
- while (!get_newsgroup())
- ;
- modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
- }
- }
- if (index(newsgroups, NGDELIM)) {
- printf("Sources should be posted to one newsgroup only.\n");
- printf("Please pick the most appropriate group for your article.\n\n");
- while (!get_newsgroup())
- ;
- modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
- }
- }
- }
-}
-
-iswanted(str)
-register char *str;
-{
- while (*str == ' ')
- str++;
-
- if (prefix(str, "Re:"))
- return (FALSE);
-
- if (isin(str, " wanted ") || isin(str, " can any") ||
- isin(str, " need ") || isin(str, " please ") || isin(str, " help ")
- || isin(str, " looking ") || index(str, '?'))
- return (TRUE);
-
- return (FALSE);
-}
-
-isin(str, words)
-register char *str, *words;
-{
- register char *p;
- register sc, wc;
-
- p = words;
- while (sc = *str++) {
- if ((wc = *p++) == '\0')
- return (TRUE);
- if (wc == ' ') {
- if (index(".,!?-; \t\n", sc))
- continue;
- } else {
- if (isupper(wc))
- wc = tolower(wc);
- if (isupper(sc))
- sc = tolower(sc);
- if (wc == sc)
- continue;
- }
- str -= p - words - 1;
- p = words;
- }
- if (*p == '\0')
- return (TRUE);
- return (FALSE);
-}
-
-/*
- * Save a copy of the article in the users NEWSARCHIVE directory.
- */
-save_article()
-{
- FILE *in, *out;
- int c;
- time_t timenow, time();
- char *today, *ctime();
- struct stat stbuf;
- char filename[BUFLEN];
-
- if (stat(ccname, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) {
- /*
- * It would be much nicer here to write articles
- * in MH format (numbered files, in rfc822 format)
- *
- * one day ..
- */
- (void) sprintf(filename, "%s/author_copy", ccname);
- (void) strcpy(ccname, filename);
- }
- in = xfopen(tempfname, "r");
- out = xfopen(ccname, "a");
- timenow = time((time_t)0);
- today = ctime(&timenow);
- fprintf(out,"From postnews %s",today);
- while ((c=getc(in)) != EOF)
- putc(c, out);
- putc('\n', out);
- (void) fclose(in);
- (void) fclose(out);
-}
-
-/*
- * Post the article to the net.
- */
-post_article()
-{
- int status;
-
- printf("Posting article...\n");
- fflush(stdout);
- (void) sprintf(buf, "exec %s/%s -h < %s", LIB, "inews", tempfname);
- status = system(buf);
-
- if (status) {
- printf("Article not posted - exit status %d\n", status);
- return;
- } else
- printf("Article posted successfully.\n");
-
- if (ccname[0]) {
- printf("A copy has been saved in %s\n", ccname);
- save_article();
- }
-
- (void) UNLINK(tempfname);
- exit(0);
-}
-
-/*
- * Initialization.
- */
-init()
-{
- FILE *fd;
- register char *p;
- int i;
- char *getenv();
- struct passwd *pw;
-
- references[0] = '\0';
- distribution[0] = '\0';
-
- uid = getuid();
- pw = getpwuid(uid);
- if (pw == NULL) {
- fprintf(stderr,"You're not in /etc/passwd\n");
- exit(1);
- }
- p = getenv("HOME");
- if (p == NULL) {
- p = getenv("LOGDIR");
- if (p == NULL)
- p = pw->pw_dir;
- }
- (void) strncpy(user, pw->pw_name, SBUFLEN);
- (void) strcpy(homedir, p);
-
- p = getenv("NEWSARCHIVE");
- if (p != NULL) {
- if (*p == '\0')
- sprintf(ccname, "%s/author_copy", homedir);
- else
- strcpy(ccname, p);
- }
-
- pathinit();
- (void) sprintf(buf, "%s/%s", LIB, "distributions");
- fd = xfopen(buf, "r");
- for (i=0; i < MAXDISTR; i++) {
- if (fscanf(fd, "%s %[^\n]", distr[i].abbr, distr[i].descr)
- != 2)
- break;
- }
- (void) fclose(fd);
-}
-
-/*
- * Get a yes or no answer to a question. A default may be used.
- */
-askyes(msg, def)
-char *msg, *def;
-{
- for(;;) {
- printf("%s", msg);
- buf[0] = 0;
- (void) gets(buf);
- switch(buf[0]) {
- case 'y':
- case 'Y':
- return TRUE;
- case 'n':
- case 'N':
- return FALSE;
- case '\0':
- switch(*def) {
- case 'y':
- case 'Y':
- return TRUE;
- case 'n':
- case 'N':
- return FALSE;
- }
- default:
- printf("Please answer yes or no.\n");
- }
- }
-}
-
-/*
- * Get a character string into buf, using prompt msg.
- */
-getpr(msg, bptr)
-char *msg, *bptr;
-{
- static int numeof = 0;
- printf("%s", msg);
- (void) gets(bptr);
- (void) nstrip(bptr);
- if (feof(stdin)) {
- if (numeof++ > 3) {
- fprintf(stderr,"Too many EOFs\n");
- exit(1);
- }
- clearerr(stdin);
- }
-}
-
-byebye(mesg)
-char *mesg;
-{
- printf("%s\n", mesg);
- exit(1);
-}
-
-/*
- * make a modification to the header of an article
- *
- * fname -- name of article
- * field -- header field to modify
- * line -- modification line
- * how -- APPEND or REPLACE
- *
- * example:
- * modify_article("/tmp/article" , "Subject:" , "new subject" , REPLACE);
- *
- *
- */
-modify_article(fname, field, line, how)
-char *fname, *field, *line;
-{
- FILE *fpart, *fptmp;
- char *temp2fname = "/tmp/postXXXXXX";
- char lbfr[BUFLEN];
- register found = FALSE;
-
- mktemp(temp2fname);
-
- fptmp = xfopen(temp2fname, "w");
- fpart = xfopen(fname, "r");
-
- while (fgets(lbfr, BUFLEN, fpart) != NULL) {
- if (prefix(lbfr, field)) {
- found = TRUE;
- (void) nstrip(lbfr);
- if (how == APPEND) {
- /* append to current field */
- (void) strcat(lbfr, line);
- (void) strcat(lbfr, "\n");
- } else
- /* replace current field */
- (void) sprintf(lbfr, "%s%s\n", field, line);
- }
- (void) fputs(lbfr, fptmp);
- }
-
- fclose(fpart);
- fclose(fptmp);
-
- fptmp = xfopen(temp2fname, "r");
- fpart = xfopen(fname, "w");
-
- if (!found)
- fprintf(fpart, "%s%s\n", field, line);
- while (fgets(buf,BUFLEN,fptmp) != NULL)
- (void) fputs(buf, fpart);
-
- (void) fclose(fpart);
- (void) fclose(fptmp);
- (void) UNLINK(temp2fname);
-}
-
-
-/* verify that newsgroup exists, and get number of entries */
-valid_ng(ng, maxart, minart, canpost)
-char *ng;
-long *maxart, *minart;
-char *canpost;
-{
- char ng_check[BUFLEN], ng_read[BUFLEN];
- FILE *fp;
-
- fp = xfopen(ACTIVE, "r");
- while (fgets(ng_read, BUFLEN, fp) != NULL) {
- switch (sscanf(ng_read, "%s %ld %ld %c", ng_check, maxart, minart, canpost)) {
- case 2:
- *minart = 1;
- /* fall through */
- case 3:
- *canpost = 'y';
- /* fall through */
- case 4:
- break;
-
- default:
- printf("Active file (%s) corrupted. ", ACTIVE);
- byebye("Seek help!");
- }
-
- if (strcmp(ng_check, ng) == 0) {
- (void) fclose(fp);
- if (*canpost != 'n') {
-#ifdef FASCIST
- if (uid && uid != ROOTID && fascist(user, ng)) {
- *canpost = 'n';
- return FALSE;
- }
-#endif FASCIST
- return TRUE;
- } else
- return FALSE;
- }
- }
- *canpost = 'i';
- *maxart = 0;
- *minart = 0;
- (void) fclose(fp);
- return FALSE;
-}
-
-/* get the line specified by field from an article */
-article_line(article, field, line)
-char *article, *field, *line;
-{
- FILE *fp;
- char *c;
-
- fp = xfopen(article,"r");
- while ((c=fgets(line,BUFLEN,fp)) != NULL && !prefix(line, field))
- if (line[0] == '\n') {
- c = NULL;
- break;
- }
- (void) fclose(fp);
- if (c != NULL) {
- (void) nstrip(line);
- return TRUE;
- } else {
- line[0] = '\0';
- return FALSE;
- }
-}
-
-/* get the header information for a followup article */
-followup(baseart)
-register char *baseart;
-{
- register char *p;
-
- /* subject */
- if (article_line(baseart, "Subject: ", buf)) {
- p = buf+9;
- for ( ; ; ) {
- while (*p == ' ' || *p == '\t')
- ++p;
- if ((*p != 'r' && *p != 'R') ||
- (p[1] != 'e' && p[1] != 'E') ||
- (p[2] != ':' && p[2] != ' '))
- break;
- p += 3;
- }
- (void) sprintf(subject, "Re: %s", p);
- } else {
- if (article_line(baseart, "From: ", buf))
- (void) sprintf(subject, "Re: orphan response from %s", buf);
- else
- (void) strcpy(subject, "Re: orphan response");
- }
-
- /* newsgroup */
- if (article_line(baseart, "Newsgroups: ", buf))
- (void) strcpy(newsgroups, buf+12);
- if (ngmatch(newsgroups, "net.general"))
- (void) strcpy(newsgroups,"net.followup");
- if (ngmatch(newsgroups, "net.sources,!net.sources.all"))
- (void) strcpy(newsgroups,"net.sources.d");
- if (ngmatch(newsgroups, "net.jobs")) {
- printf("net.jobs is for the direct posting of job announcements and requests.\n");
- printf("it is not for discussion. You followup has been directed to net.misc\n");
- (void) strcpy(newsgroups,"net.misc");
- }
-
- /* distribution */
- if (article_line(baseart, "Distribution: ", buf))
- (void) strcpy(distribution, buf+14);
-
- /* references */
- if (article_line(baseart, "References: ", buf)) {
- register char *rcp;
- (void) strcpy(references, buf+12);
- (void) strcat(references, " ");
- /* keep the number of references to a reasonable number */
- rcp = rindex(references, ' '); /* Can not fail */
- while ((int)(rcp - references) > 70) {
- while (*--rcp != ' ')
- ;
- rcp[1] = '\0';
- }
- }
- if (article_line(baseart, "Message-ID: ", buf)) {
- (void) strcat(references, buf+12);
- (void) strcpy(msgid, buf+12);
- }
-
- if (article_line(baseart, "From: ", buf))
- (void) strcpy(isfrom, buf+6);
-
- if (article_line(baseart, "Keywords: ", buf))
- (void) strcpy(keywords, buf+10);
-
- if (article_line(baseart, "Followup-To: ", buf)) {
- (void) strcpy(newsgroups, buf+13);
- if (strcmp(newsgroups, "poster") == 0)
- byebye("Mail followups directly to poster.");
- }
-
- get_summary();
-}
-
-get_summary()
-{
- register char *p;
- register i;
-
- printf("Please enter a short summary of your contribution to the discussion\n");
- printf("Just one or two lines ... (end with a blank line)\n");
- p = summary;
- for (i = 0; i < 3; i++) { /* 3 * 80 < 256, should be safe .. */
- getpr(">\t", p);
- if (*p == '\0')
- break;
- p = index(p, '\0');
- (void) strcpy(p, "\n\t ");
- p += 3;
- }
- if (p > summary)
- p[-3] = '\0';
-}
-
-encode(article)
-char *article;
-{
- FILE *fpart, *fphead, *fpcoded;
- char *headerfile = "/tmp/pheadXXXXXX";
- char *codedfile = "/tmp/pcodeXXXXXX";
-
- (void) mktemp(headerfile);
- (void) mktemp(codedfile);
-
- fpart = xfopen(article, "r");
-
- /* place article header in "headerfile" file */
- fphead = xfopen(headerfile, "w");
- while (fgets(buf, BUFLEN, fpart) != NULL) {
- (void) fputs(buf, fphead);
- if (buf[0] == '\n')
- break;
- }
- (void) fclose(fphead);
-
- /* place article body in "codedfile" file */
- fpcoded = xfopen(codedfile, "w");
- while (fgets(buf, BUFLEN, fpart) != NULL)
- (void) fputs(buf, fpcoded);
- (void) fclose(fpcoded);
- (void) fclose(fpart);
-
- /* encode body and put back together with header */
- (void) rename(headerfile, article);
-
- (void) sprintf(buf,"exec %s/%s 13 < %s >> %s\n", LIB, "caesar", codedfile, article);
- printf("Encoding article -- please stand by\n");
- if (system(buf)) {
- printf("encoding failed");
- exit(2);
- }
- (void) UNLINK(codedfile);
-}
-
-
-/*
- * Print a recorded message warning the poor luser what he is doing
- * and demand that he understands it before proceeding. Only do
- * this for newsgroups listed in LIBDIR/recording.
- */
-recording(ngrps)
-char *ngrps;
-{
- char recbuf[BUFLEN];
- FILE *fd;
- char nglist[BUFLEN], fname[BUFLEN];
- int c, n, yes, retval = 0;
-
- (void) sprintf(recbuf, "%s/%s", LIB, "recording");
- fd = fopen(recbuf, "r");
- if (fd == NULL)
- return 0;
- while ((fgets(recbuf, sizeof recbuf, fd)) != NULL) {
- (void) sscanf(recbuf, "%s %s", nglist, fname);
- if (ngmatch(ngrps, nglist)) {
- (void) fclose(fd);
- if (fname[0] == '/')
- (void) strcpy(recbuf, fname);
- else
- (void) sprintf(recbuf, "%s/%s", LIB, fname);
- fd = fopen(recbuf, "r");
- if (fd == NULL)
- return 0;
- while ((c = getc(fd)) != EOF)
- putc(c, stderr);
- fprintf(stderr, "Do you understand this? Hit <return> to proceed, <BREAK> to abort: ");
- n = read(2, recbuf, 100);
- c = recbuf[0];
- yes = (c=='y' || c=='Y' || c=='\n' || c=='\n' || c==0);
- if (n <= 0 || !yes)
- retval = -1;
- }
- }
- return retval;
-}
-
-xxit(i)
-{
- exit(i);
-}
-
-#if !defined(BSD4_2) && !defined(BSD4_1C)
-rename(from,to)
-register char *from, *to;
-{
- (void) unlink(to);
- if (link(from, to) < 0)
- return -1;
-
- (void) unlink(from);
- return 0;
-}
-#endif /* !BSD4_2 && ! BSD4_1C */
*-*-END-of-src/postnews.c-*-*
echo x - src/control.c 1>&2
sed 's/.//' >src/control.c <<'*-*-END-of-src/control.c-*-*'
-/*
- * This software is Copyright (c) 1986 by Rick Adams.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or
- * otherwise use this software as long as: there is no monetary
- * profit gained specifically from the use or reproduction or this
- * software, it is not sold, rented, traded or otherwise marketed, and
- * this copyright notice is included prominently in any copy
- * made.
- *
- * The author make no claims as to the fitness or correctness of
- * this software for any use whatsoever, and it is provided as is.
- * Any use of this software is at the user's own risk.
- *
- * Control message handling code. Deal with messages which are to be
- * acted on by netnews itself rather than by people.
- *
- * See defs.h "news_version" for the real version of netnews.
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)control.c 2.48 10/30/86";
-#endif /* SCCSID */
-
-#include "iparams.h"
-
-#define eq(msg) (strcmp(msg, cargv[0]) == 0)
-
-int cargc;
-char **cargv;
-
-FILE *hfopen();
-FILE *popen(), *mhopen(), *mailhdr();
-
-char *senderof();
-#ifdef u370
-static struct hbuf htmp;
-#endif /* u370 */
-
-/*
- * The global structure is initialized to NOTIFY as the default (if defined)
- * uid to send mail to for every state. The following conditions are
- * dealt with (assumes NOTIFY defined):
- *
- * 1) LIB/notify exists and is empty (or contains no recognizable control
- * message types).
- * Action: force TELLME = "";
- * 2) LIB/notify contains the control message name "all" and no associated
- * address.
- * Action: force TELLME = "";
- * 3) LIB/notify contains the control message name "all" and has an address.
- * Action: set TELLME = AlloCpy(address);
- * 4) LIB/notify contains only some of the known control message types.
- * Action: initialize all addresses to "" and set declared addresses
- * to listed address.
- */
-
-control(h)
-struct hbuf *h;
-{
- register char *ctlmsgtext;
- register struct msgtype *mp;
-
- if (strncmp(h->title, "cmsg ", 5) == 0) {
- register char *cp1, *cp2;
- cp1 = h->title;
- cp2 = h->title + 5;
- while (*cp1++ = *cp2++)
- ;
- }
-
- if (*h->ctlmsg)
- ctlmsgtext = h->ctlmsg;
- else
- ctlmsgtext = h->title;
- log("Ctl Msg %s from %s: %s", h->nbuf, h->path, ctlmsgtext);
- /*
- * Control messages have the standard format
- * command [args]
- * much like shell commands. Each site has the option
- * of customizing this code to deal with control messages
- * as they see fit, but we would like to buy back the
- * code, ifdeffed or otherwise parameterized, to simplify
- * the maintenence issues.
- */
- argparse(ctlmsgtext);
-
- /*
- * We look for a match of the control message name and then
- * set TELLME to the value parsed from the LIB/notify file
- * (if any).
- */
- for(mp=msgtype; mp->m_name; mp++) {
- if(eq(mp->m_name) ) { /* hit */
-#ifdef NOTIFY
- TELLME = mp->m_who_to; /* reset whom to tell */
-#endif /* NOTIFY */
- if(strcmp(mp->m_name, "cancel") == 0) /* special case */
- return (*mp->m_func)(cargc, cargv);
- (*mp->m_func)(cargc, cargv); /* do the function */
- break;
- }
- }
- if( !mp->m_name ) {
-#ifdef NOTIFY
- TELLME = NOTIFY;
-#endif /* NOTIFY */
- c_unknown(h, ctlmsgtext);
- }
- return 0;
-}
-
-/*
- * Parse the string str into separate words in cargc and cargv
- * as per the usual UNIX convention. Nothing fancy here, just
- * blanks and tabs separating words.
- */
-argparse(str)
-char *str;
-{
- static char *cavpbuf[20];
- static char cavbuf[256];
- char *nextfree = cavbuf;
-
- if (str == '\0')
- error("Control message %s has no title", header.ident);
- cargc = (*str != '\0');
- cargv = cavpbuf;
- cargv[0] = cavbuf;
-
- while (*str) {
- if (*str <= ' ') {
- *nextfree++ = 0;
- cargv[cargc] = nextfree;
- cargc++;
- /* skip over white space */
- while (*str != '\0' && *str <= ' ')
- str++;
- if (*str == '\0') /* line ends in white space */
- return;
- } else
- *nextfree++ = *str++;
- }
-}
-
-/*
- * ihave <artid> ... <remotesys>
- * or
- * ihave <remotesys>
- * with <artid>s in message body.
- *
- * The other system is telling you it has article <artid>, in case
- * you decide you want it to transmit it to you.
- * The assumption is that the other system only tells you about articles
- * in newsgroups you subscribe to.
- *
- * We turn the incoming ihave into an outgoing sendme on the fly.
- * It then gets saved in the SPOOL directory and transmitted to the
- * remote system. (This way the sendme messages can be batched.)
- */
-c_ihave(argc, argv)
-register char ** argv;
-{
- register int i;
- char list[sizeof header.title];
- extern char * findhist();
-
- if (argc < 2)
- error("ihave: Too few arguments.");
- if (strncmp(FULLSYSNAME, argv[argc - 1], SNLN) == 0)
- return;
- list[0] = '\0';
- if (argc > 2) {
- for (i = 1; i < (argc - 1); ++i)
- if (findhist(argv[i]) == NULL) {
- (void) strcat(list, " ");
- (void) strcat(list, argv[i]);
- }
- if (list[0] == '\0')
- return;
- } else {
- register FILE * outfp;
- register long outpos, inpos;
- char myid[256];
-
- outfp = xfopen(INFILE, "a");
- outpos = ftell(outfp);
- inpos = ftell(infp);
- while (ftell(infp) < outpos) {
- if (fgets(myid, sizeof myid, infp) != myid)
- error("iline: Can't rerear article");
- myid[strlen(myid) - 1] = '\0';
- if (findhist(myid) == NULL)
- (void) fprintf(outfp, "%s\n", myid);
- }
- if (outpos == ftell(outfp)) { /* if nothing is wanted */
- (void) fclose(outfp);
- (void) fseek(infp, inpos, 0);
- return;
- }
- (void) fclose(outfp);
- /*
- ** The close and open may just be paranoia.
- */
- (void) fclose(infp);
- infp = xfopen(INFILE, "r");
- (void) fseek(infp, outpos, 0);
- }
- /*
- ** Turn the ihave into a sendme.
- */
- (void) sprintf(header.nbuf, "to.%s.ctl", argv[argc - 1]);
- (void) sprintf(header.title, "sendme%s %s", list, FULLSYSNAME);
- (void) strcpy(header.ctlmsg, header.title);
- getident(&header);
- (void) sprintf(header.from, "%s@%s%s", "usenet", FULLSYSNAME, MYDOMAIN);
- (void) strcpy(header.path, NEWSUSR);
- header.subdate[0] = header.expdate[0] = '\0';
- dates(&header);
- /*
- ** What else of this kind should be done?
- */
- header.organization[0] = header.distribution[0] = '\0';
- for (i = 0; i < NUNREC && header.unrec[i] != NULL; ++i) {
- free(header.unrec[i]);
- header.unrec[i] = NULL;
- }
- /*
- ** Note that we do *not* change the history line
- ** so that if the "ihave" message comes in again it gets rejected.
- */
-}
-
-/*
- * sendme <artid> ... <remotesys>
- * or
- * sendme <remotesys>
- * with <artid>s in message body.
- * The other system wants me to send out article <artid>.
- * Give it to them with no fuss.
- */
-c_sendme(argc, argv)
-register char ** argv;
-{
- struct srec srec;
-
- if (argc < 2)
- error("sendme: Too few arguments.");
- if (strncmp(FULLSYSNAME, argv[argc - 1], SNLN) == 0)
- return;
- if (s_find(&srec, argv[argc - 1]) != TRUE)
- error("sendme: Can't find sys record for %s", argv[argc - 1]);
- /* Send the articles. */
- if (argc == 2) {
- register FILE * fp;
- char buf[256];
-
- fp = xfopen(INFILE, "r");
- while (fgets(buf, sizeof buf, fp) == buf) {
- buf[strlen(buf) - 1] = '\0'; /* zap trailing '\n' */
- sendmefunc(buf, &srec);
- }
- (void) fclose(fp);
- } else { /* argc > 2 */
- register int i;
-
- for (i = 1; i < (argc - 1); ++i)
- sendmefunc(argv[i], &srec);
- }
-}
-
-static
-sendmefunc(id, sp)
-register char * id;
-register struct srec * sp;
-{
- register FILE * fp;
- register char * cp;
- char savedbufname[256];
- extern char firstbufname[];
- extern char * dirname();
- extern char * findfname();
-
- cp = findfname(id);
- if (cp == NULL) {
- logerr("System %s wants unavailable article %s.",
- sp->s_name, id);
- return;
- }
- cp = dirname(cp);
- fp = fopen(cp, "r");
- if (fp == NULL) {
- logerr("Article %s unopenable as %s.", id, cp);
- return;
- }
- (void) strcpy(savedbufname, firstbufname);
- (void) strcpy(firstbufname, cp);
- transmit(sp, fp, FALSE, (char **) NULL, FALSE);
- /* transmit closes fp */
- (void) strcpy(firstbufname, savedbufname);
-}
-
-/*
- * newgroup <groupname>
- * A new newsgroup has been created.
- * The body of the article, if present, is a description of the
- * purpose of the newsgroup.
- *
- */
-c_newgroup(argc, argv)
-char **argv;
-{
- FILE *fd;
- char abuf[BUFLEN], subjline[BUFLEN];
- int didcreate = 0;
- register char *p, *q;
-# ifdef NONEWGROUPS
-# ifdef ORGDISTRIB
- /* local or ORGDISTRIB */
- int can_change = (strcmp(header.distribution, "local") == 0) ||
- (strcmp(header.distribution, ORGDISTRIB) == 0);
-# else /* ! ORGDISTRIB */
- /* local only */
- int can_change = strcmp(header.distribution, "local") == 0;
-# endif /* ORGDISTRIB */
-# else /* ! NONEWGROUPS */
- int can_change = 1; /* allow changes for all distributions */
-# endif /* NONEWGROUPS */
-
- if (argc < 2)
- error("newgroup: Too few arguments.");
-
- if (header.approved[0] == '\0')
- error("newgroup: %s not approved", argv[1]);
-
- /* see if it already exists */
- (void) rewind(actfp); clearerr(actfp);
- while(fgets(abuf, BUFLEN, actfp) != NULL) {
- p = abuf;
- q = argv[1];
- while (*p++ == *q++)
- ;
- if (*--q == '\0' && *--p == ' ') {
- int modified = 0;
- /* Now check if it's correctly moderated/unmoderated */
- while (*p++)
- ;
- p -= 3;
- if (argc > 2 && strcmp(argv[2], "moderated") == 0) {
- if (*p == 'm')
- return;
-# ifdef NONEWGROUPS
- if(can_change) {
- *p = 'm';
- modified = 1;
- }
-# else /* ! NONEWGROUPS */
- *p = 'm';
- modified = 1;
-#endif /* NONEWGROUPS */
- } else {
- if (*p != 'm')
- return;
-# ifdef NONEWGROUPS
- if(can_change) {
- *p = 'y';
- modified = 1;
- }
-# else /* ! NONEWGROUPS */
- *p = 'y';
- modified = 1;
-# endif /* NONEWGROUPS */
- }
-# ifdef NOTIFY
- (void) sprintf(subjline,
- "Newsgroup %s change from %smoderated to %smoderated",
- argv[1], *p=='y' ? "" : "un",
- *p=='y' ? "un" : "");
- fd = mailhdr((struct hbuf *)NULL, subjline);
- if (fd != NULL) {
- if(modified)
- fprintf(fd,
-"%s has been changed from %smoderated to %smoderated as requested by\n%s\n",
- argv[1], *p=='y' ? "" : "un",
- *p=='y' ? "un":"", header.path);
- else {
- fprintf(fd,
-"%s\nhas requested that %s be changed from %smoderated to %smoderated\n",
- header.path, argv[1],
- *p=='y' ? "un" : "",
- *p=='y' ? "" : "un");
-#ifdef ORGDISTRIB
- fprintf(fd,
-"You can accomplish this by re-creating the newsgroup with a distribution\n");
- fprintf(fd,
-"of '%s' by executing the command:\n", ORGDISTRIB);
- fprintf(fd,
- "%s/inews -d %s -C %s moderated\n",
- LIB, ORGDISTRIB, argv[1]);
-#else /* !ORGDISTRIB */
- fprintf(fd,
-"You can accomplish this by re-creating the newsgroup by executing the command:\n");
- fprintf(fd, "%s/inews -C %s moderated\n",
- LIB, argv[1]);
-#endif /* !ORGDISTRIB */
- }
- (void) mclose(fd);
- }
-# endif /* NOTIFY */
-# ifdef NONEWGROUPS
- /*
- * No permission to change
- */
- if(!can_change)
- return;
-# endif /* NONEWGROUPS */
- /* The active file was wrong about the state of the
- * group. Rewrite the active file
- */
- (void) fseek(actfp, -2L, 1); /* back up 2 characters */
-#ifdef USG
- /*
- * U G L Y K L U D G E
- * This utter piece of tripe is the only way I know of
- * to get around the fact that ATT BROKE standard IO
- * in System 5.2. Basically, you can't open a file for
- * "r+" and then try and write to it. This hack works
- * on all "real" USG Unix systems, It will probably
- * break on some obscure look alike that doesnt use the
- * real ATT stdio.h
- * Don't blame me, blame ATT. stdio should have
- * already done the following line for us, but it didn't
- */
- actfp->_flag |= _IOWRT;
-#endif /* USG */
- putc(*p, actfp);
- fflush(actfp);
- if (*p != 'm')
- logerr("Newsgroup %s changed from moderated to unmoderated",
- argv[1]);
- else
- logerr("Newsgroup %s changed from unmoderated to moderated",
- argv[1]);
- return;
- }
- }
-
- /* It doesn't already exist, we must create it */
-
- if(can_change) {
- didcreate++;
- (void) fseek(actfp, 0L, 2); clearerr(actfp);
- fprintf(actfp, "%s 00000 00001 %c\n", argv[1],
- (argc > 2 && strcmp(argv[2], "moderated") == 0)
- ? 'm' : 'y');
- fflush(actfp);
- }
-
-# ifdef NOTIFY
- (void) sprintf(subjline, "Newsgroup %s created", argv[1]);
- fd = mailhdr((struct hbuf *)NULL, subjline);
- if (fd != NULL) {
- if (didcreate)
- fprintf(fd,
- "A new newsgroup called '%s' has been created by %s.\n",
- argv[1], header.path);
- else {
- fprintf(fd,
- "%s requested that a new newsgroup called '%s' be created.\n",
- header.path, argv[1]);
- fprintf(fd,"It was approved by %s\n\n",header.approved);
- fprintf(fd,
- "You can accomplish this by creating the newgroup yourself\n");
-# ifdef ORGDISTRIB
- fprintf(fd,"with a distribution of '%s'.\n",
- ORGDISTRIB);
- fprintf(fd,
- "In other words, by executing the command:\n");
- fprintf(fd, "%s/inews -d %s -C %s\n", LIB,
- ORGDISTRIB, argv[1]);
-# else /* !ORGDISTRIB */
- fprintf(fd, "In other words, by executing the command:\n");
- fprintf(fd, "%s/inews -C %s\n", LIB, argv[1]);
-# endif /* !ORGDISTRIB */
- }
- (void) mclose(fd);
- }
-# endif /* NOTIFY */
-}
-
-/*
- * rmgroup <groupname>
- * An old newsgroup is being cancelled on a network wide basis.
- */
-c_rmgroup(argc, argv)
-char **argv;
-{
- FILE *fd;
- int shouldremove = 0;
-#ifdef NOTIFY
- char subjline[BUFLEN];
-#endif /* NOTIFY */
-
- if (argc < 2)
- error("rmgroup: Too few arguments.");
- if (!validng(argv[1]))
- return;
- if (header.approved[0] == '\0')
- error("rmgroup: %s not approved", argv[1]);
-
-#ifndef MANUALLY
-#ifdef ORGDISTRIB
- /*
- * Allow local as well as organizational removals
- */
- if (!strcmp(ORGDISTRIB, header.distribution)
- || !strcmp("local", header.distribution))
-#else /* !ORGDISTRIB */
- if (!strcmp("local", header.distribution))
-#endif /* !ORGDISTRIB */
- shouldremove++;
-#endif /* !MANUALLY */
-#ifdef NOTIFY
- sprintf(subjline, "Recevied rmgroup for %s", argv[1]);
- fd = mailhdr((struct hbuf *)NULL, subjline);
- if (fd != NULL) {
- if (shouldremove) {
- fprintf(fd, "Newsgroup '%s' has been removed by %s.\n\n",
- argv[1], header.path);
-# ifdef USG
- fprintf(fd, "You may need to remove the directory %s by hand\n",
- dirname(argv[1]));
-# endif
- } else {
- fprintf(fd, "%s requested that newsgroup %s be removed.\n",
- header.path, argv[1]);
- fprintf(fd, "You should remove it by hand\n");
- fprintf(fd, "To do this, execute the command\n");
- fprintf(fd, "\t%s/rmgroup %s\n", LIB, argv[1]);
- }
- (void) mclose(fd);
- }
-#endif /* NOTIFY */
-
- if (shouldremove) {
- int rc;
- /* We let the shell do all the work.
- * See the rmgrp shell script. */
- (void) setuid(geteuid()); /* otherwise it won't rmdir the dir */
- (void) sprintf(bfr, "exec %s/rmgroup %s", LIB, argv[1]);
- rc = system(bfr);
- log("system(%s) status %d", bfr, rc);
- }
-}
-
-/*
- * cancel <artid>
- * Cancel the named article
- */
-c_cancel(argc, argv)
-char **argv;
-{
- char *line, *p, *q, *r, *poster;
- char *findhist();
- register FILE *fp;
- char whatsisname[BUFLEN], nfilename[BUFLEN];
- time_t t;
- int su = 0;
-#ifndef u370
- struct hbuf htmp;
-#endif /* !u370 */
-
- if (argc < 2)
- error("cancel: Too few arguments.");
- (void) strcpy(whatsisname, senderof(&header));
- line = findhist(argv[1]);
- if (line == NULL) {
- struct tm *tm;
- log("Can't cancel %s: non-existent", argv[1]);
- (void) time(&t);
- tm = localtime(&t);
-#ifdef USG
- sprintf(bfr,"%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\tcancelled",
-#else /* !USG */
- sprintf(bfr,"%s\t%02d/%02d/%d %02d:%02d\tcancelled",
-#endif /* !USG */
- argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
- tm->tm_min);
- savehist(bfr);
- return 1;
- }
-
- q = index(line, '\t');
- p = index(q+1, '\t');
- if (p == NULL || *++p == '\0' || *p == '\n') {
- *q = '\0';
- log("Expired article %s", line);
- return 1;
- }
- if (strcmp(p, "cancelled") == 0) {
- *q = '\0';
- log("Already Cancelled %s", line);
- return 1;
- } else
- log("Cancelling %s", line);
- if ((uid == ROOTID||uid == 0) && strcmp(header.distribution, "local") == 0)
- su = 1;
- while (*p) {
- q = index(p, ' ');
- if (q)
- *q = '\0';
- (void) strcpy(nfilename, dirname(p));
- fp = fopen(nfilename, "r");
- if (fp == NULL) {
- log("Already Cancelled %s", line);
- return 1;
- }
- htmp.unrec[0] = NULL;
- if (hread(&htmp, fp, TRUE) == NULL) {
- if (bfr[0] == '/') {
- fp = fopen(bfr, "r");
- if (fp == NULL
- || hread(&htmp, fp, TRUE) == NULL)
- error("Article is garbled.");
- } else
- error("Article is garbled.");
- }
- (void) fclose(fp);
- poster = senderof(&htmp);
- /* only compare up to '.' or ' ' */
- r = index(poster,'.');
- if (r == NULL)
- r = index(poster,' ');
- if (r != NULL)
- *r = '\0';
- if (!su && strncmp(whatsisname, poster,strlen(poster))) {
- error("Not contributor: posted by %s, and you are %s", poster, whatsisname);
- }
-
- (void) unlink(nfilename);
- p = q+1;
- }
- return 0;
-}
-
-/*
- * sendsys (no arguments)
- *
- * Mail the sys file to the person submitting the article.
- * POLICY: the contents of your sys file are public information
- * and as such, you should not change this code. You may feel
- * free to arrange for it to manually notify you, in the event
- * that you want to do something to clean it up before it goes out.
- * Secret sites on the net are expressly frowned on.
- *
- * The purpose of this command is for making a network map. The
- * details of your link and which newsgroups are forwarded are not
- * important, in case you want to sanitize them. Since the definition
- * of USENET is those sites getting net.announce, you can disable this
- * on sites not getting net articles, but if you take out the list of
- * forwarded newsgroups, and you have sites that only get local newsgroups,
- * you should make this clear, or remove those sites from what you send out.
- */
-/* ARGSUSED */
-c_sendsys(argc, argv)
-char **argv;
-{
- register FILE *f, *u;
- int c;
-
-#ifdef NOTIFY
- f = mailhdr((struct hbuf *)NULL, "sendsys control message");
- if (f != NULL) {
- fprintf(f, "%s requested your %s/sys file.\n", header.path, LIB);
- fprintf(f, "It has been sent.\n");
- (void) mclose(f);
- }
-#endif /* NOTIFY */
- f = mailhdr(&header, "response to your sendsys request");
- u = fopen(SUBFILE, "r");
- if (f != NULL && u != NULL) {
- while ((c=getc(u)) != EOF)
- putc(c, f);
- (void) fclose(u);
- (void) mclose(f);
- }
-}
-
-/*
- * senduuname (no arguments)
- *
- * Run the "uuname" command and send it back to the person who submitted
- * the article. The purpose of this control message is for attempting to
- * make a uucp net map.
- *
- * POLICY: If you view this information as not public (because you have
- * a connection you consider secret, or know a site that considers itself
- * secret) you can feel free to change this code in whatever way is
- * appropriate, so long as it sends some response back to the sender. If
- * you don't run uucp, this code does not make sense, and so an error
- * message (or garbage, such as "research") will be mailed back.
- *
- * If you wish to add or remove sites from the output of uuname, you
- * may wish to use the euuname.sh shell script here.
- */
-/* ARGSUSED */
-c_senduuname(argc, argv)
-char **argv;
-{
- char buf[256];
- FILE *fd, *u;
- int c;
-
-#ifdef NOTIFY
- fd = mailhdr((struct hbuf *)NULL, "uuname control message");
- fprintf(fd, "%s requested your uuname output\n", header.path);
- (void) mclose(fd);
-#endif /* NOTIFY */
- fd = mailhdr(&header, "response to your senduuname request");
-#ifdef UUPROG
- if (UUPROG[0] == '/')
- (void) strcpy(buf, UUPROG);
- else
- (void) sprintf(buf, "%s/%s", LIB, UUPROG);
-#else
- (void) strcpy(buf, "uuname");
-#endif
- u = popen(buf, "r");
- if (fd != NULL && u != NULL) {
- while ((c=getc(u)) != EOF)
- putc(c, fd);
- (void) pclose(u);
- (void) mclose(fd);
- }
-}
-
-/*
- * Send the version number to the right person.
- */
-/* ARGSUSED */
-c_version(argc, argv)
-char **argv;
-{
- register FILE *f;
-
- f = mailhdr(&header, "Our news version");
- if (f == NULL)
- error("Cannot send back error message");
- fprintf(f, "Currently running news version %s.\n\n", news_version);
- fprintf(f, "The header of your message follows:\n\n");
- (void) hwrite(&header, f);
- (void) mclose(f);
-}
-
-/*
- * Check the active file for old or missing newsgroups
- * Body of article is list of valid groups
- */
-/* ARGSUSED */
-c_checkgroups(argc, argv)
-char **argv;
-{
- int rc;
-
- (void) setuid(geteuid());
- /* dont change the cat %s| to < %s, it breaks some "unix" systems */
- (void) sprintf(bfr, "cat %s | %s/checkgroups %s", INFILE, LIB,
-#ifdef NOTIFY
- (TELLME && *TELLME) ? TELLME : NEWSUSR );
-#else /* !NOTIFY */
- NEWSUSR);
-#endif /* !NOTIFY */
- rc = system(bfr);
- log("system(%s) status %d", bfr, rc);
-}
-
-/*
- * An unknown control message has been received.
- */
-c_unknown(h, ctlmsgtext)
-struct hbuf *h;
-char *ctlmsgtext;
-{
- register FILE *f;
-
- log("UNKNOWN Ctl Msg %s from %s", ctlmsgtext, h->path);
-#ifdef NOTIFY
- f = mailhdr((struct hbuf *)NULL, "Unrecognized Control Message");
- if (f != NULL) {
- fprintf(f, "Currently running news version %s.\n\n", news_version);
- fprintf(f, "The header of the message follows:\n\n");
- (void) hwrite(h, f);
- (void) mclose(f);
- }
-#endif /* NOTIFY */
-}
-
-/* ARGSUSED */
-c_unimp(argc, argv)
-char **argv;
-{
- register FILE *f;
-
-#ifdef NOTIFY
- f = mailhdr((struct hbuf*)NULL, "Unimplemented Control Message");
- if (f != NULL) {
- fprintf(f, "Currently running news version B %s.\n\n", news_version);
- fprintf(f, "The header of the message follows:\n\n");
- (void) hwrite(&header, f);
- (void) mclose(f);
- }
-#endif /* NOTIFY */
-}
-
-/*
- * This is a modified version of popen, made more secure. Rather than
- * forking off a shell, you get a bare process. You must have exactly
- * one argument, and the command must be mail (or sendmail if you have it).
- */
-#define RDR 0
-#define WTR 1
-static int mopen_pid[20];
-char *replyname();
-
-FILE *
-mhopen(hptr)
-struct hbuf *hptr;
-{
- int p[2];
- register myside, hisside, pid;
- char *sendto = "usenet";
-
- if (hptr)
- sendto = replyname(hptr);
- else {
-#ifdef NOTIFY
- if (TELLME)
- sendto = TELLME;
-#endif /* NOTIFY */
- if (sendto == NULL || *sendto == NULL)
- return NULL;
- }
- verifyname(sendto);
- if(pipe(p) < 0)
- return NULL;
- myside = p[WTR];
- hisside = p[RDR];
- if((pid = vfork()) == 0) {
- /* myside and hisside reverse roles in child */
- (void) close(myside);
- (void) close(0);
- (void) dup(hisside);
- (void) close(hisside);
- (void) setgid(gid);
- (void) setuid(uid);
-#ifdef SENDMAIL
- execl(SENDMAIL, "sendmail", "-oi", "-oeq", sendto, (char *)NULL);
-#endif /* SENDMAIL */
-#ifdef MMDF
- execl(MMDF, "inews-mail", "-smuxto,cc*", (char *)NULL);
-#endif /* MMDF */
- execl("/bin/mail", "mail", sendto, (char *)NULL);
- execl("/usr/bin/mail", "mail", sendto, (char *)NULL);
- execl("/usr/ucb/mail", "mail", sendto, (char *)NULL);
- _exit(1);
- }
- if(pid == -1)
- return NULL;
- mopen_pid[myside] = pid;
- (void) close(hisside);
- return(fdopen(myside, "w"));
-}
-
-mclose(ptr)
-FILE *ptr;
-{
- register f, r, (*hstat)(), (*istat)(), (*qstat)();
- int status;
-
- f = fileno(ptr);
- (void) fclose(ptr);
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
- hstat = signal(SIGHUP, SIG_IGN);
- while((r = wait(&status)) != mopen_pid[f] && r != -1)
- ;
- if(r == -1)
- status = -1;
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
- signal(SIGHUP, hstat);
- return status;
-}
-
-/*
- * mhopen a pipe to mail, write out a std header, and return the file ptr.
- *
- * We don't include a From: field because this is probably uucp, i.e.
- * explicitly routed. Leave it up to the recipient's mailer.
- * Always include the To: field because if we ge back failed mail, we
- * might be able to deliver it by hand if we know to wom it was addressed.
- * By convention, hptr==NULL means to send the message to the local contact person.
- */
-FILE *
-mailhdr(hptr, subject)
-struct hbuf *hptr;
-char *subject;
-{
- FILE *fp;
- time_t now;
- char *to = "usenet";
-
-#ifdef NOTIFY
- if (TELLME && *TELLME)
- to = TELLME;
-#endif /* NOTIFY */
- if (hptr)
- to = replyname(hptr);
-
- if ((fp = mhopen(hptr)) != NULL) {
- (void) time(&now);
- fprintf(fp, "Date: %s\n", arpadate(&now));
-#ifdef MMDF
- fprintf(fp, "From: The News System <usenet@%s%s>\n",
- FULLSYSNAME, MYDOMAIN);
-#endif /* MMDF */
- fprintf(fp, "To: %s\n", to);
- fprintf(fp, "Subject: %s\n", subject);
-#ifdef HIDDENNET
- if (strcmp(LOCALSYSNAME, FULLSYSNAME))
- fprintf(fp, "Responding-System: %s.%s%s\n\n",
- LOCALSYSNAME, FULLSYSNAME, MYDOMAIN);
- else
-#endif /* !HIDDENNET */
- fprintf(fp, "Responding-System: %s%s\n\n",
- FULLSYSNAME, MYDOMAIN);
- }
- return fp;
-}
-
-/*
- * verify that the name mail is being sent to does not contain any
- * nasty hooks to invoke funny functions from the shell or the like.
- */
-verifyname(sendto)
-char *sendto;
-{
- /* Be sure we DO allow alphabetics, !, :, ., -, @. *. */
- char *nasty = "\"'\\`^|;& <>/~";
- register char *p;
-
- if (sendto[0] <= ' ') {
- log("nasty mail name %s from %s", sendto, header.path);
- xxit(1);
- }
- for (p=sendto; *p; p++) {
- if (*p == ' ') {
- *p = 0;
- break;
- }
- }
- if (strpbrk(sendto, nasty) != NULL)
- error("nasty mail name %s from %s", sendto, header.path);
-
- for (nasty = sendto; (nasty = index(nasty, '.')) != NULL; ) {
- if (*++nasty == '.') /* check for .. */
- error("nasty mail name %s from %s", sendto, header.path);
- }
-}
-
-/*
- * Checks to make sure the control message is OK to post.
- */
-ctlcheck()
-{
- char msg[BUFLEN];
- char *p;
-
- if (!is_ctl)
- return;
-
- if (header.ctlmsg[0])
- (void) strcpy(msg, header.ctlmsg);
- else
- (void) strcpy(msg, header.title);
-
- p = index(msg, ' ');
- if (p)
- *p = 0;
-
- if (strcmp(msg, "ihave") == 0 || strcmp(msg, "sendbad") == 0 ||
- strcmp(msg, "sendme") == 0) {
- return; /* no restrictions */
- } else if (strcmp(msg, "newgroup") == 0) {
- suser();
- } else if (strcmp(msg, "rmgroup") == 0) {
- suser();
- } else if (strcmp(msg, "sendsys") == 0) {
- suser();
- } else if (strcmp(msg, "senduuname") == 0) {
- suser();
- } else if (strcmp(msg, "checkgroups") == 0) {
- suser();
- } else if (strcmp(msg, "version") == 0) {
- return; /* no restrictions */
- } else if (strcmp(msg, "cancel") == 0) {
- return; /* no restrictions at this level */
- } else if (strcmp(msg, "delsub") == 0) {
- if (!prefix(header.nbuf, "to.")) {
- printf("Must be in a 'to.system' newsgroup.");
- xxit(0);
- }
- return;
- } else {
- printf("Unrecognized control message - %s\n", msg);
- xxit(0);
- }
-}
-
-/* Make sure this guy is special. */
-suser()
-{
- if (uid == 0 || uid == ROOTID)
- return;
- /*
- * We assume that since our real uid is the same as NEWSUSR
- * (the euid) we were run by rootid and it did a setuid.
- * Too bad we can't set just the effective uid like suid does.
- */
- if (uid == geteuid())
- return;
-#ifdef IHCC
- printf("Please use the command:\n\ttoolnews providers\n");
- printf("then call one of the news people.\n");
-#else
- printf("Get your local netnews contact to do it for you.\n");
-#endif
- xxit(0);
-}
*-*-END-of-src/control.c-*-*
echo x - src/unbatch.c 1>&2
sed 's/.//' >src/unbatch.c <<'*-*-END-of-src/unbatch.c-*-*'
-/*
- * unbatchnews: extract news in batched format and process it one article
- * at a time. The format looks like
- * #! rnews 1234
- * article containing 1234 characters
- * #! rnews 4321
- * article containing 4321 characters
- *
- * or
- *
- * #! command [args]
- * calls LIBDIR/command [args] to process the news
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)unbatch.c 1.22 10/23/86";
-#endif /* SCCSID */
-
-#define MAXARGS 20
-
-#include "defs.h"
-#include <stdio.h>
-#include <ctype.h>
-#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
-#include <fcntl.h>
-#endif /* USG */
-
-char buf[BUFSIZ];
-char sibuf[BUFSIZ];
-
-main()
-{
- register int c;
- register FILE *pfn;
- register long size;
- char *filename;
- int pid, wpid, exstat;
- char *mktemp(), *gets();
- long atol();
-
- filename = mktemp("/tmp/unbnewsXXXXXX");
- setbuf(stdin, (char *)NULL); /* only for the first line */
- if (gets(buf) == NULL) {
- (void) unlink(filename);
- exit(0);
- }
- if (strncmp(buf, "#! rnews ", 9) != 0) {
- docmd(buf);
- /* should not return */
- logerr("unbatch: docmd returned!");
- exit(1);
- }
-
- setbuf(stdin, sibuf); /* buffer the rest of the file */
-
- do {
- while (strncmp(buf, "#! rnews ", 9)
- && strncmp(buf, "! rnews ", 8)) { /* kludge for bug */
- register char *cp;
- for (cp = buf; *cp != '\0'; ++cp)
- if (!isascii(*cp) ||
- (!isprint(*cp) && !isspace(*cp)))
- *cp = '?';
- logerr("out of sync, skipping %s", buf);
- if (gets(buf) == NULL)
- exit(0);
- }
- size = atol(buf + (buf[0] == '#' ? 9 : 8));
- if(size <= 0) {
- logerr("nonsense size %ld", size);
- continue;
- }
-#ifdef VMS
-/* The loop is to delete all versions. */
- while (unlink(filename) == 0)
- ;
-#endif /* VMS */
- pfn = fopen(filename, "w");
- while(--size >= 0 && (c = getc(stdin)) != EOF)
- putc(c, pfn);
- if (ferror(pfn) || fclose(pfn)) { /* disk full? */
- logerr("error writing temporary file");
- break;
- }
-
- /*
- * If we got a truncated batch, don't process the
- * last article; it will probably be received again.
- */
- if (size > 0) {
- logerr("truncated batch");
- break;
- }
-
- /*
- * rnews < filename
- */
- while ((pid = vfork()) == -1) {
- logerr("fork failed, waiting...\n");
- sleep(60);
- }
- if (pid == 0) {
- (void) close(0);
- (void) open(filename, 0);
-#ifdef IHCC
- (void) sprintf(buf, "%s/%s/rnews", logdir(HOME), LIBDIR);
-#else
- (void) sprintf(buf, "%s/rnews", BINDIR);
-#endif
-#ifdef SPOOLNEWS
- execlp(buf, "rnews", "-S", (char *)0);
-#else /* !SPOOLNEWS */
- execlp(buf, "rnews", (char *)0);
-#endif /* !SPOOLNEWS */
- perror("rnews");
- exit(1);
- }
- while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
- ;
- } while (gets(buf) != NULL);
- (void) unlink(filename);
- exit(0);
-}
-
-docmd(p)
-register char *p;
-{
- char *args[MAXARGS];
- register char **ap = args;
- char path[BUFSIZ];
- char *rindex(), *cp;
-
- while (*p && !isspace(*p)) /* skip leading #! crud */
- p++;
-
- while (isspace(*p))
- p++;
-
- while (*p != '\0') {
- *ap++ = p;
- if (ap >= &args[MAXARGS]) {
- logerr("unbatch: Too many args to %s", args[0]);
- exit(2);
- }
- while (*p && !isspace(*p))
- p++;
- if (*p)
- *p++ = '\0';
- while (isspace(*p))
- p++;
- }
- *ap = (char *)0;
-
- if (ap == args) {
- logerr("unbatch: no command to execute");
- exit(2);
- }
-
- /* strip off any leading pathname in case someone gets tricky */
- cp = rindex(args[0], '/');
- if (cp++ == NULL)
- cp = args[0];
-
- sprintf(path, "%s/%s", LIBDIR, cp);
-
- /*
- * "path" is absolute, no searching is needed, we use
- * 'execvp' solely so that sh scripts will be handled
- */
- (void) execvp(path, args);
- perror(path);
- exit(2);
-}
-
-/*
- * Log the given message, with printf strings and parameters allowed,
- * on the log file, if it can be written.
- */
-/* VARARGS1 */
-logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
-char *fmt;
-{
- FILE *logfile;
- char lfname[BUFSIZ]; /* the log file */
- char bfr[BUFSIZ];
- char *logtime, *ctime();
- long t;
-
- (void) time(&t);
- logtime = ctime(&t);
- logtime[16] = 0;
- logtime += 4;
-
-#ifdef IHCC
- (void) sprintf(lfname, "%s/%s/errlog", logdir(HOME), LIBDIR);
-#else
- (void) sprintf(lfname, "%s/errlog", LIBDIR);
-#endif
-
- (void) sprintf(bfr, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
- (void) fprintf(stderr, "%s\n", bfr);
- if (access(lfname, 0) == 0 && (logfile = fopen(lfname, "a")) != NULL) {
-#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
- int flags;
- flags = fcntl(fileno(logfile), F_GETFL, 0);
- (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND);
-#else /* v7 */
- (void) lseek(fileno(logfile), 0L, 2);
-#endif /* v7 */
- fprintf(logfile, "%s\tbatch\t%s\n", logtime, bfr);
- (void) fclose(logfile);
- }
-}
*-*-END-of-src/unbatch.c-*-*
echo x - src/euninstal.com 1>&2
sed 's/.//' >src/euninstal.com <<'*-*-END-of-src/euninstal.com-*-*'
-$ ! @(#)euninstal.com 1.2 10/28/86
-$ ! This DCL script installs inews and rnews with the necessary
-$ ! privileges in a Eunice system.
-$ SET PROCESS/PRIV=CMKRNL
-$ RUN SYS$SYSTEM:INSTALL
-EUN_USR:[USR.BIN]RNEWS. /OPEN/SHARED/PRIV=SYSPRV
-EUN_USR:[USR.LIB.NEWS]INEWS. /OPEN/SHARED/PRIV=SYSPRV
-$ EXIT
*-*-END-of-src/euninstal.com-*-*
exit
More information about the Mod.sources
mailing list