|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.