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

Defined functions

IF defined in line 414; never used
followup defined in line 354; used 2 times
fputs defined in line 416; used 139 times
invoke defined in line 392; used 3 times
printf defined in line 404; used 227 times
reply defined in line 310; used 2 times
respond_init defined in line 36; used 2 times

Defined variables

nullart defined in line 34; used 2 times
Last modified: 1986-03-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1653
Valid CSS Valid XHTML 1.0 Strict