1: /* $Header: sw.c,v 4.3.1.2 85/05/21 13:36:23 lwall Exp $ 2: * 3: * $Log: sw.c,v $ 4: * Revision 4.3.1.2 85/05/21 13:36:23 lwall 5: * Sped up "rn -c" by not doing unnecessary initialization. 6: * 7: * Revision 4.3.1.1 85/05/10 11:40:38 lwall 8: * Branch for patches. 9: * 10: * Revision 4.3 85/05/01 11:50:54 lwall 11: * Baseline for release with 4.3bsd. 12: * 13: */ 14: 15: #include "EXTERN.h" 16: #include "common.h" 17: #include "util.h" 18: #include "head.h" 19: #include "only.h" 20: #include "term.h" 21: #include "ng.h" 22: #include "intrp.h" 23: #include "INTERN.h" 24: #include "sw.h" 25: 26: void 27: sw_init(argc,argv,tcbufptr) 28: int argc; 29: char *argv[]; 30: char **tcbufptr; 31: { 32: register int i; 33: 34: if (argc >= 2 && strEQ(argv[1],"-c")) 35: checkflag=TRUE; /* so we can optimize for -c */ 36: interp(*tcbufptr,1024,GLOBINIT); 37: sw_file(tcbufptr,FALSE); 38: safecpy(*tcbufptr,getenv("RNINIT"),1024); 39: if (**tcbufptr) { 40: if (**tcbufptr == '/') { 41: sw_file(tcbufptr,TRUE); 42: } 43: else 44: sw_list(*tcbufptr); 45: } 46: 47: for (i = 1; i < argc; i++) 48: decode_switch(argv[i]); 49: } 50: 51: void 52: sw_file(tcbufptr,bleat) 53: char **tcbufptr; 54: bool bleat; 55: { 56: int initfd = open(*tcbufptr,0); 57: 58: if (initfd >= 0) { 59: fstat(initfd,&filestat); 60: if (filestat.st_size > 1024) 61: *tcbufptr = saferealloc(*tcbufptr,(MEM_SIZE)filestat.st_size); 62: if (filestat.st_size) { 63: read(initfd,*tcbufptr,(int)filestat.st_size); 64: (*tcbufptr)[filestat.st_size-1] = '\0'; 65: /* wipe out last newline */ 66: sw_list(*tcbufptr); 67: } 68: else 69: **tcbufptr = '\0'; 70: close(initfd); 71: } 72: else { 73: if (bleat) 74: printf(cantopen,*tcbufptr) FLUSH; 75: **tcbufptr = '\0'; 76: } 77: } 78: 79: /* decode a list of space separated switches */ 80: 81: void 82: sw_list(swlist) 83: char *swlist; 84: { 85: char *tmplist = safemalloc((MEM_SIZE) strlen(swlist) + 2); 86: /* semi-automatic string */ 87: register char *p, inquote = 0; 88: 89: strcpy(tmplist,swlist); 90: for (p=tmplist; isspace(*p); p++) ; /* skip any initial spaces */ 91: while (*p) { /* "String, or nothing" */ 92: if (!inquote && isspace(*p)) { /* word delimiter? */ 93: *p++ = '\0'; /* chop here */ 94: while (isspace(*p)) /* these will be ignored later */ 95: p++; 96: } 97: else if (inquote == *p) { 98: strcpy(p,p+1); /* delete trailing quote */ 99: inquote = 0; /* no longer quoting */ 100: } 101: else if (!inquote && *p == '"' || *p == '\'') { 102: /* OK, I know when I am not wanted */ 103: inquote = *p; /* remember single or double */ 104: strcpy(p,p+1); /* delete the quote */ 105: } /* (crude, but effective) */ 106: else if (*p == '\\') { /* quoted something? */ 107: if (p[1] == '\n') /* newline? */ 108: strcpy(p,p+2); /* "I didn't see anything" */ 109: else { 110: strcpy(p,p+1); /* delete the backwhack */ 111: p++; /* leave the whatever alone */ 112: } 113: } 114: else 115: p++; /* normal char, leave it alone */ 116: } 117: *++p = '\0'; /* put an extra null on the end */ 118: if (inquote) 119: printf("Unmatched %c in switch\n",inquote) FLUSH; 120: for (p = tmplist; *p; /* p += strlen(p)+1 */ ) { 121: decode_switch(p); 122: while (*p++) ; /* point at null + 1 */ 123: } 124: free(tmplist); /* this oughta be in Ada */ 125: } 126: 127: /* decode a single switch */ 128: 129: void 130: decode_switch(s) 131: register char *s; 132: { 133: while (isspace(*s)) /* ignore leading spaces */ 134: s++; 135: #ifdef DEBUGGING 136: if (debug) 137: printf("Switch: %s\n",s) FLUSH; 138: #endif 139: if (*s != '-' && *s != '+') { /* newsgroup pattern */ 140: setngtodo(s); 141: } 142: else { /* normal switch */ 143: bool upordown = *s == '-' ? TRUE : FALSE; 144: char tmpbuf[LBUFLEN]; 145: 146: s++; 147: switch (*s) { 148: #ifdef TERMMOD 149: case '=': { 150: char *beg = s+1; 151: 152: while (*s && *s != '-' && *s != '+') s++; 153: cpytill(tmpbuf,beg,*s); 154: if (upordown ? strEQ(getenv("TERM"),tmpbuf) 155: : strNE(getenv("TERM"),tmpbuf) ) { 156: decode_switch(s); 157: } 158: break; 159: } 160: #endif 161: #ifdef BAUDMOD 162: case '0': case '1': case '2': case '3': case '4': 163: case '5': case '6': case '7': case '8': case '9': 164: if (upordown ? (just_a_sec*10 <= atoi(s)) 165: : (just_a_sec*10 >= atoi(s)) ) { 166: while (isdigit(*s)) s++; 167: decode_switch(s); 168: } 169: break; 170: #endif 171: case '/': 172: if (checkflag) 173: break; 174: #ifdef SETENV 175: setenv("SAVEDIR", upordown ? "%p/%c" : "%p" ); 176: setenv("SAVENAME", upordown ? "%a" : "%^C"); 177: #else 178: notincl("-/"); 179: #endif 180: break; 181: case 'c': 182: checkflag = upordown; 183: break; 184: case 'C': 185: s++; 186: if (*s == '=') s++; 187: docheckwhen = atoi(s); 188: break; 189: case 'd': { 190: if (checkflag) 191: break; 192: s++; 193: if (*s == '=') s++; 194: if (cwd) { 195: chdir(cwd); 196: free(cwd); 197: } 198: cwd = savestr(s); 199: break; 200: } 201: #ifdef DEBUGGING 202: case 'D': 203: s++; 204: if (*s == '=') s++; 205: if (*s) 206: if (upordown) 207: debug |= atoi(s); 208: else 209: debug &= ~atoi(s); 210: else 211: if (upordown) 212: debug |= 1; 213: else 214: debug = 0; 215: break; 216: #endif 217: case 'e': 218: erase_screen = upordown; 219: break; 220: case 'E': 221: #ifdef SETENV 222: s++; 223: if (*s == '=') 224: s++; 225: strcpy(tmpbuf,s); 226: s = index(tmpbuf,'='); 227: if (s) { 228: *s++ = '\0'; 229: setenv(tmpbuf,s); 230: } 231: else 232: setenv(tmpbuf,nullstr); 233: #else 234: notincl("-E"); 235: #endif 236: break; 237: case 'F': 238: s++; 239: indstr = savestr(s); 240: break; 241: #ifdef INNERSEARCH 242: case 'g': 243: gline = atoi(s+1)-1; 244: break; 245: #endif 246: case 'H': 247: case 'h': { 248: register int len, i; 249: char *t; 250: int flag = (*s == 'h' ? HT_HIDE : HT_MAGIC); 251: 252: if (checkflag) 253: break; 254: s++; 255: len = strlen(s); 256: for (t=s; *t; t++) 257: if (isupper(*t)) 258: *t = tolower(*t); 259: for (i=HEAD_FIRST; i<HEAD_LAST; i++) 260: if (!len || strnEQ(s,htype[i].ht_name,len)) 261: if (upordown) 262: htype[i].ht_flags |= flag; 263: else 264: htype[i].ht_flags &= ~flag; 265: break; 266: } 267: case 'i': 268: s++; 269: if (*s == '=') s++; 270: initlines = atoi(s); 271: break; 272: case 'l': 273: muck_up_clear = upordown; 274: break; 275: case 'L': 276: #ifdef CLEAREOL 277: can_home_clear = upordown; 278: #else 279: notincl("-L"); 280: #endif 281: break; 282: case 'M': 283: mbox_always = upordown; 284: break; 285: case 'm': 286: s++; 287: if (*s == '=') s++; 288: if (!upordown) 289: marking = NOMARKING; 290: else if (*s == 'u') 291: marking = UNDERLINE; 292: else { 293: marking = STANDOUT; 294: } 295: break; 296: case 'N': 297: norm_always = upordown; 298: break; 299: #ifdef VERBOSE 300: case 'n': 301: fputs("This isn't readnews. Don't use -n.\n\n",stdout) FLUSH; 302: break; 303: #endif 304: case 'r': 305: findlast = upordown; 306: break; 307: case 's': 308: s++; 309: if (*s == '=') s++; 310: if (*s) { 311: countdown = atoi(s); 312: suppress_cn = FALSE; 313: } 314: else { 315: if (!upordown) 316: countdown = 5; 317: suppress_cn = upordown; 318: } 319: break; 320: case 'S': 321: #ifdef ARTSEARCH 322: s++; 323: if (*s == '=') s++; 324: if (*s) 325: scanon = atoi(s); 326: else 327: scanon = upordown*3; 328: #else 329: notincl("-S"); 330: #endif 331: break; 332: case 't': 333: #ifdef VERBOSE 334: #ifdef TERSE 335: verbose = !upordown; 336: #else 337: notincl("+t"); 338: #endif 339: #else 340: notincl("+t"); 341: #endif 342: break; 343: case 'T': 344: typeahead = upordown; 345: break; 346: case 'v': 347: #ifdef VERIFY 348: verify = upordown; 349: #else 350: notincl("-v"); 351: #endif 352: break; 353: default: 354: #ifdef VERBOSE 355: IF(verbose) 356: printf("\nIgnoring unrecognized switch: -%c\n", *s) FLUSH; 357: ELSE 358: #endif 359: #ifdef TERSE 360: printf("\nIgnoring -%c\n", *s) FLUSH; 361: #endif 362: break; 363: } 364: } 365: } 366: 367: /* print current switch values */ 368: 369: void 370: pr_switches() 371: { 372: static char mp[2] = {'+','-'}; 373: register int i; 374: 375: fputs("\nCurrent switch settings:\n",stdout); 376: printf("%c/ ", mp[strEQ(getval("SAVEDIR",SAVEDIR),"%p/%c")]); 377: printf("%cc ", mp[checkflag]); 378: printf("-C%d ", docheckwhen); 379: printf("-d%s ", cwd); 380: #ifdef DEBUGGING 381: if (debug) 382: printf("-D%d ", debug); 383: #endif 384: printf("%ce ", mp[erase_screen]); 385: printf("-F\"%s\" ", indstr); 386: #ifdef INNERSEARCH 387: printf("-g%d", gline); 388: #endif 389: putchar('\n'); 390: #ifdef VERBOSE 391: if (verbose) { 392: for (i=HEAD_FIRST; i<HEAD_LAST; i++) 393: printf("%ch%s%c", 394: mp[htype[i].ht_flags & HT_HIDE], htype[i].ht_name, 395: (! (i % 5) ? '\n' : ' ') ); 396: } 397: #endif 398: printf("-i%d ", initlines); 399: printf("%cl ", mp[muck_up_clear]); 400: #ifdef CLEAREOL 401: printf("%cL ", mp[can_home_clear]); 402: #endif CLEAREOL 403: if (marking) 404: printf("-m%c ",marking==UNDERLINE?'u':'s'); 405: else 406: printf("+m "); 407: printf("%cM ", mp[mbox_always]); 408: printf("%cN ", mp[norm_always]); 409: printf("%cr ", mp[findlast]); 410: if (countdown) 411: printf("-s%d ", countdown); 412: else 413: printf("%cs ", mp[suppress_cn]); 414: #ifdef ARTSEARCH 415: if (scanon) 416: printf("-S%d ",scanon); 417: else 418: printf("+S "); 419: #ifdef VERBOSE 420: #ifdef TERSE 421: printf("%ct ", mp[!verbose]); 422: #endif 423: #endif 424: printf("%cT ", mp[typeahead]); 425: #ifdef VERIFY 426: printf("%cv ", mp[verify]); 427: #endif 428: #endif 429: fputs("\n\n",stdout) FLUSH; 430: #ifdef ONLY 431: if (maxngtodo) { 432: #ifdef VERBOSE 433: IF(verbose) 434: fputs("Current restriction:",stdout); 435: ELSE 436: #endif 437: #ifdef TERSE 438: fputs("Only:",stdout); 439: #endif 440: for (i=0; i<maxngtodo; i++) 441: printf(" %s",ngtodo[i]); 442: fputs("\n\n",stdout) FLUSH; 443: } 444: #ifdef VERBOSE 445: else if (verbose) 446: fputs("No restriction.\n\n",stdout) FLUSH; 447: #endif 448: #endif 449: } 450: 451: void 452: cwd_check() 453: { 454: char tmpbuf[LBUFLEN]; 455: 456: if (!cwd) 457: cwd = savestr(filexp("~/News")); 458: strcpy(tmpbuf,cwd); 459: if (chdir(cwd)) { 460: safecpy(tmpbuf,filexp(cwd),sizeof tmpbuf); 461: if (makedir(tmpbuf,MD_DIR) < 0 || chdir(tmpbuf) < 0) { 462: interp(cmd_buf, (sizeof cmd_buf), "%~/News"); 463: if (makedir(cmd_buf,MD_DIR) < 0) 464: strcpy(tmpbuf,homedir); 465: else 466: strcpy(tmpbuf,cmd_buf); 467: chdir(tmpbuf); 468: #ifdef VERBOSE 469: IF(verbose) 470: printf("\ 471: Cannot make directory %s--\n\ 472: articles will be saved to %s\n\ 473: \n\ 474: ",cwd,tmpbuf) FLUSH; 475: ELSE 476: #endif 477: #ifdef TERSE 478: printf("\ 479: Can't make %s--\n\ 480: using %s\n\ 481: \n\ 482: ",cwd,tmpbuf) FLUSH; 483: #endif 484: } 485: } 486: free(cwd); 487: getwd(tmpbuf); 488: if (eaccess(tmpbuf,2)) { 489: #ifdef VERBOSE 490: IF(verbose) 491: printf("\ 492: Current directory %s is not writeable--\n\ 493: articles will be saved to home directory\n\n\ 494: ",tmpbuf) FLUSH; 495: ELSE 496: #endif 497: #ifdef TERSE 498: printf("%s not writeable--using ~\n\n",tmpbuf) FLUSH; 499: #endif 500: strcpy(tmpbuf,homedir); 501: } 502: cwd = savestr(tmpbuf); 503: }