Annotation of 43BSD/contrib/rn/respond.c, revision 1.1.1.1

1.1       root        1: /* $Header: respond.c,v 4.3.1.5 85/09/10 11:05:00 lwall Exp $
                      2:  *
                      3:  * $Log:       respond.c,v $
                      4:  * Revision 4.3.1.5  85/09/10  11:05:00  lwall
                      5:  * Improved %m in in_char().
                      6:  * 
                      7:  * Revision 4.3.1.4  85/05/23  17:24:49  lwall
                      8:  * Now allows 'r' and 'f' on null articles.
                      9:  * 
                     10:  * Revision 4.3.1.3  85/05/15  14:42:32  lwall
                     11:  * Removed duplicate include of intrp.h.
                     12:  * 
                     13:  * Revision 4.3.1.2  85/05/14  08:55:15  lwall
                     14:  * Default for normal/mailbox question was applied to wrong buffer.
                     15:  * 
                     16:  * Revision 4.3.1.1  85/05/10  11:37:33  lwall
                     17:  * Branch for patches.
                     18:  * 
                     19:  * Revision 4.3  85/05/01  11:47:04  lwall
                     20:  * Baseline for release with 4.3bsd.
                     21:  * 
                     22:  */
                     23: 
                     24: #include "EXTERN.h"
                     25: #include "common.h"
                     26: #include "intrp.h"
                     27: #include "head.h"
                     28: #include "term.h"
                     29: #include "ng.h"
                     30: #include "util.h"
                     31: #include "rn.h"
                     32: #include "artio.h"
                     33: #include "final.h"
                     34: #include "INTERN.h"
                     35: #include "respond.h"
                     36: 
                     37: static char nullart[] = "\nNull article\n";
                     38: 
                     39: void
                     40: respond_init()
                     41: {
                     42:     ;
                     43: }
                     44: 
                     45: int
                     46: save_article()
                     47: {
                     48:     bool use_pref;
                     49:     register char *s, *c;
                     50:     char altbuf[CBUFLEN];
                     51:     int iter;
                     52:     bool interactive = (buf[1] == FINISHCMD);
                     53:     
                     54:     if (!finish_command(interactive))  /* get rest of command */
                     55:        return SAVE_ABORT;
                     56:     use_pref = isupper(*buf);
                     57: #ifdef ASYNC_PARSE
                     58:     parse_maybe(art);
                     59: #endif
                     60:     savefrom = (*buf=='w' || *buf=='W' ? htype[PAST_HEADER].ht_minpos : 0);
                     61:     if (artopen(art) == Nullfp) {
                     62: #ifdef VERBOSE
                     63:        IF(verbose)
                     64:            fputs("\n\
                     65: Saving null articles is not very productive!  :-)\n\
                     66: ",stdout) FLUSH;
                     67:        ELSE
                     68: #endif
                     69: #ifdef TERSE
                     70:            fputs(nullart,stdout) FLUSH;
                     71: #endif
                     72:        return SAVE_DONE;
                     73:     }
                     74:     if (chdir(cwd)) {
                     75:        printf(nocd,cwd) FLUSH;
                     76:        sig_catcher(0);
                     77:     }
                     78:     if (savedest)
                     79:        free(savedest);
                     80:     if ((s = index(buf,'|')) != Nullch) {
                     81:                                /* is it a pipe command? */
                     82:        s++;                    /* skip the | */
                     83:        while (*s == ' ') s++;
                     84:        safecpy(altbuf,filexp(s),sizeof altbuf);
                     85:        savedest = altbuf;
                     86:        interp(cmd_buf, (sizeof cmd_buf), getval("PIPESAVER",PIPESAVER));
                     87:                                /* then set up for command */
                     88:        resetty();              /* restore tty state */
                     89:        if (use_pref)           /* use preferred shell? */
                     90:            doshell(Nullch,cmd_buf);
                     91:                                /* do command with it */
                     92:        else
                     93:            doshell(sh,cmd_buf);        /* do command with sh */
                     94:        noecho();               /* and stop echoing */
                     95:        crmode();               /* and start cbreaking */
                     96:        savedest = savestr(savedest);
                     97:     }
                     98:     else {                     /* normal save */
                     99:        bool there, mailbox;
                    100:        char *savename = getval("SAVENAME",SAVENAME);
                    101: 
                    102:        s = buf+1;              /* skip s or S */
                    103:        if (*s == '-') {        /* if they are confused, skip - also */
                    104: #ifdef VERBOSE
                    105:            IF(verbose)
                    106:                fputs("Warning: '-' ignored.  This isn't readnews.\n",stdout)
                    107:                  FLUSH;
                    108:            ELSE
                    109: #endif
                    110: #ifdef TERSE
                    111:                fputs("'-' ignored.\n",stdout) FLUSH;
                    112: #endif
                    113:            s++;
                    114:        }
                    115:        for (; *s == ' '; s++); /* skip spaces */
                    116:        safecpy(altbuf,filexp(s),sizeof altbuf);
                    117:        s = altbuf;
                    118:        if (! index(s,'/')) {
                    119:            interp(buf, (sizeof buf), getval("SAVEDIR",SAVEDIR));
                    120:            if (makedir(buf,MD_DIR))    /* ensure directory exists */
                    121:                strcpy(buf,cwd);
                    122:            if (*s) {
                    123:                for (c = buf; *c; c++) ;
                    124:                *c++ = '/';
                    125:                strcpy(c,s);            /* add filename */
                    126:            }
                    127:            s = buf;
                    128:        }
                    129:        for (iter = 0;
                    130:            (there = stat(s,&filestat) >= 0) &&
                    131:            (filestat.st_mode & S_IFDIR);
                    132:            iter++) {                   /* is it a directory? */
                    133: 
                    134:            c = (s+strlen(s));
                    135:            *c++ = '/';                 /* put a slash before filename */
                    136:            interp(c, s==buf?(sizeof buf):(sizeof altbuf),
                    137:                iter ? "News" : savename );
                    138:                                /* generate a default name somehow or other */
                    139:            if (index(c,'/')) {         /* yikes, a '/' in the filename */
                    140:                makedir(s,MD_FILE);
                    141:            }
                    142:        }
                    143:        if (*s != '/') {                /* relative path? */
                    144:            c = (s==buf ? altbuf : buf);
                    145:            sprintf(c, "%s/%s", cwd, s);
                    146:            s = c;                      /* absolutize it */
                    147:        }
                    148:        s = savedest = savestr(s);      /* doesn't move any more */
                    149:                                        /* make it handy for %b */
                    150:        if (!there) {
                    151:            if (mbox_always)
                    152:                mailbox = TRUE;
                    153:            else if (norm_always)
                    154:                mailbox = FALSE;
                    155:            else {
                    156:                char *dflt = (instr(savename,"%a") ? "nyq" : "ynq");
                    157:                
                    158:                sprintf(cmd_buf,
                    159:                "\nFile %s doesn't exist--\n    use mailbox format? [%s] ",
                    160:                  s,dflt);
                    161:              reask_save:
                    162:                in_char(cmd_buf, 'M');
                    163:                putchar('\n') FLUSH;
                    164:                setdef(buf,dflt);
                    165: #ifdef VERIFY
                    166:                printcmd();
                    167: #endif
                    168:                if (*buf == 'h') {
                    169: #ifdef VERBOSE
                    170:                    IF(verbose)
                    171:                        printf("\n\
                    172: Type y to create %s as a mailbox.\n\
                    173: Type n to create it as a normal file.\n\
                    174: Type q to abort the save.\n\
                    175: ",s) FLUSH;
                    176:                    ELSE
                    177: #endif
                    178: #ifdef TERSE
                    179:                        fputs("\n\
                    180: y to create mailbox.\n\
                    181: n to create normal file.\n\
                    182: q to abort.\n\
                    183: ",stdout) FLUSH;
                    184: #endif
                    185:                    goto reask_save;
                    186:                }
                    187:                else if (*buf == 'n') {
                    188:                    mailbox = FALSE;
                    189:                }
                    190:                else if (*buf == 'y') {
                    191:                    mailbox = TRUE;
                    192:                }
                    193:                else if (*buf == 'q') {
                    194:                    goto s_bomb;
                    195:                }
                    196:                else {
                    197:                    fputs(hforhelp,stdout) FLUSH;
                    198:                    settle_down();
                    199:                    goto reask_save;
                    200:                }
                    201:            }
                    202:        }
                    203:        else if (filestat.st_mode & S_IFCHR)
                    204:            mailbox = FALSE;
                    205:        else {
                    206:            int tmpfd;
                    207:            
                    208:            tmpfd = open(s,0);
                    209:            if (tmpfd == -1)
                    210:                mailbox = FALSE;
                    211:            else {
                    212:                read(tmpfd,buf,LBUFLEN);
                    213:                c = buf;
                    214:                if (!isspace(MBOXCHAR))
                    215:                    while (isspace(*c))
                    216:                        c++;
                    217:                mailbox = (*c == MBOXCHAR);
                    218:                close(tmpfd);
                    219:            }
                    220:        }
                    221: 
                    222:        safecpy(cmd_buf, filexp(mailbox ?
                    223:            getval("MBOXSAVER",MBOXSAVER) :
                    224:            getval("NORMSAVER",NORMSAVER) ), sizeof cmd_buf);
                    225:                                /* format the command */
                    226:        resetty();              /* make terminal behave */
                    227:        if (doshell(use_pref?Nullch:SH,cmd_buf))
                    228:            fputs("Not saved",stdout);
                    229:        else
                    230:            printf("%s to %s %s",
                    231:              there?"Appended":"Saved",
                    232:              mailbox?"mailbox":"file",
                    233:              s);
                    234:        if (interactive)
                    235:            putchar('\n') FLUSH;
                    236:        noecho();               /* make terminal do what we want */
                    237:        crmode();
                    238:     }
                    239: s_bomb:
                    240:     if (chdir(spool) || chdir(ngdir)) {
                    241:        printf(nocd,ngdir) FLUSH;
                    242:        sig_catcher(0);
                    243:     }
                    244:     return SAVE_DONE;
                    245: }
                    246: 
                    247: int
                    248: cancel_article()
                    249: {
                    250:     char *artid_buf;
                    251:     char *ngs_buf;
                    252:     char *from_buf;
                    253:     char *reply_buf;
                    254:     int myuid = getuid();
                    255:     int r = -1;
                    256: 
                    257:     if (artopen(art) == Nullfp) {
                    258: #ifdef VERBOSE
                    259:        IF(verbose)
                    260:            fputs("\n\
                    261: Cancelling null articles is your idea of fun?  :-)\n\
                    262: ",stdout) FLUSH;
                    263:        ELSE
                    264: #endif
                    265: #ifdef TERSE
                    266:            fputs(nullart,stdout) FLUSH;
                    267: #endif
                    268:        return r;
                    269:     }
                    270:     reply_buf = fetchlines(art,REPLY_LINE);
                    271:     from_buf = fetchlines(art,FROM_LINE);
                    272:     artid_buf = fetchlines(art,ARTID_LINE);
                    273:     ngs_buf = fetchlines(art,NGS_LINE);
                    274:     if (!instr(from_buf,sitename) ||
                    275:        (!instr(from_buf,logname) &&
                    276:         !instr(reply_buf,logname) &&
                    277: #ifdef NEWSADMIN
                    278:         myuid != newsuid &&
                    279: #endif
                    280:         myuid != ROOTID ) )
                    281: #ifdef VERBOSE
                    282:            IF(verbose)
                    283:                fputs("You can't cancel someone else's article\n",stdout)
                    284:                  FLUSH;
                    285:            ELSE
                    286: #endif
                    287: #ifdef TERSE
                    288:                fputs("Not your article\n",stdout) FLUSH;
                    289: #endif
                    290:     else {
                    291:        tmpfp = fopen(headname,"w");    /* open header file */
                    292:        if (tmpfp == Nullfp) {
                    293:            printf(cantcreate,headname) FLUSH;
                    294:            goto no_cancel;
                    295:        }
                    296:        interp(buf, (sizeof buf), getval("CANCELHEADER",CANCELHEADER));
                    297:        fputs(buf,tmpfp);
                    298:        fclose(tmpfp);
                    299:        r = doshell(sh,filexp(getval("CANCEL",CANCEL)));
                    300:     }
                    301: no_cancel:
                    302:     free(artid_buf);
                    303:     free(ngs_buf);
                    304:     free(from_buf);
                    305:     free(reply_buf);
                    306:     return r;
                    307: }
                    308: 
                    309: void
                    310: reply()
                    311: {
                    312:     bool incl_body = (*buf == 'R');
                    313:     char *maildoer = savestr(filexp(getval("MAILPOSTER",MAILPOSTER)));
                    314: 
                    315:     artopen(art);
                    316:     tmpfp = fopen(headname,"w");       /* open header file */
                    317:     if (tmpfp == Nullfp) {
                    318:        printf(cantcreate,headname) FLUSH;
                    319:        goto no_reply;
                    320:     }
                    321:     interp(buf, (sizeof buf), getval("MAILHEADER",MAILHEADER));
                    322:     fputs(buf,tmpfp);
                    323:     if (!instr(maildoer,"%h"))
                    324: #ifdef VERBOSE
                    325:        IF(verbose)
                    326:            printf("\n%s\n(Above lines saved in file %s)\n",buf,headname)
                    327:              FLUSH;
                    328:        ELSE
                    329: #endif
                    330: #ifdef TERSE
                    331:            printf("\n%s\n(Header in %s)\n",buf,headname) FLUSH;
                    332: #endif
                    333:     if (incl_body && artfp != Nullfp) {
                    334:        interp(buf, (sizeof buf), getval("YOUSAID",YOUSAID));
                    335:        fprintf(tmpfp,"%s\n",buf);
                    336: #ifdef ASYNC_PARSE
                    337:        parse_maybe(art);
                    338: #endif
                    339:        fseek(artfp,(long)htype[PAST_HEADER].ht_minpos,0);
                    340:        while (fgets(buf,LBUFLEN,artfp) != Nullch) {
                    341:            fprintf(tmpfp,"%s%s",indstr,buf);
                    342:        }
                    343:        fprintf(tmpfp,"\n");
                    344:     }
                    345:     fclose(tmpfp);
                    346:     interp(cmd_buf, (sizeof cmd_buf), maildoer);
                    347:     invoke(cmd_buf,origdir);
                    348:     UNLINK(headname);          /* kill the header file */
                    349: no_reply:
                    350:     free(maildoer);
                    351: }
                    352: 
                    353: void
                    354: followup()
                    355: {
                    356:     bool incl_body = (*buf == 'F');
                    357: 
                    358:     artopen(art);
                    359:     tmpfp = fopen(headname,"w");
                    360:     if (tmpfp == Nullfp) {
                    361:        printf(cantcreate,headname) FLUSH;
                    362:        return;
                    363:     }
                    364:     interp(buf, (sizeof buf), getval("NEWSHEADER",NEWSHEADER));
                    365:     fprintf(tmpfp,"%s",buf);
                    366:     if (incl_body && artfp != Nullfp) {
                    367: #ifdef VERBOSE
                    368:        if (verbose)
                    369:            fputs("\n\
                    370: (Be sure to double-check the attribution against the signature, and\n\
                    371: trim the quoted article down as much as possible.)\n\
                    372: ",stdout) FLUSH;
                    373: #endif
                    374:        interp(buf, (sizeof buf), getval("ATTRIBUTION",ATTRIBUTION));
                    375:        fprintf(tmpfp,"%s\n",buf);
                    376: #ifdef ASYNC_PARSE
                    377:        parse_maybe(art);
                    378: #endif
                    379:        fseek(artfp,(long)htype[PAST_HEADER].ht_minpos,0);
                    380:        while (fgets(buf,LBUFLEN,artfp) != Nullch) {
                    381:            fprintf(tmpfp,"%s%s",indstr,buf);
                    382:        }
                    383:        fprintf(tmpfp,"\n");
                    384:     }
                    385:     fclose(tmpfp);
                    386:     safecpy(cmd_buf,filexp(getval("NEWSPOSTER",NEWSPOSTER)),sizeof cmd_buf);
                    387:     invoke(cmd_buf,origdir);
                    388:     UNLINK(headname);
                    389: }
                    390: 
                    391: void
                    392: invoke(cmd,dir)
                    393: char *cmd,*dir;
                    394: {
                    395:     if (chdir(dir)) {
                    396:        printf(nocd,dir) FLUSH;
                    397:        return;
                    398:     }
                    399: #ifdef VERBOSE
                    400:     IF(verbose)
                    401:        printf("\n(leaving cbreak mode; cwd=%s)\nInvoking command: %s\n\n",
                    402:            dir,cmd) FLUSH;
                    403:     ELSE
                    404: #endif
                    405: #ifdef TERSE
                    406:        printf("\n(-cbreak; cwd=%s)\nInvoking: %s\n\n",dir,cmd) FLUSH;
                    407: #endif
                    408:     resetty();                 /* make terminal well-behaved */
                    409:     doshell(sh,cmd);           /* do the command */
                    410:     noecho();                  /* set no echo */
                    411:     crmode();                  /* and cbreak mode */
                    412: #ifdef VERBOSE
                    413:     IF(verbose)
                    414:        fputs("\n(re-entering cbreak mode)\n",stdout) FLUSH;
                    415:     ELSE
                    416: #endif
                    417: #ifdef TERSE
                    418:        fputs("\n(+cbreak)\n",stdout) FLUSH;
                    419: #endif
                    420:     if (chdir(spool) || chdir(ngdir)) {
                    421:        printf(nocd,ngdir) FLUSH;
                    422:        sig_catcher(0);
                    423:     }
                    424: }
                    425: 

unix.superglobalmegacorp.com

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