1 /* sw.c
2  */
3 /* This software is copyrighted as detailed in the LICENSE file. */
4 
5 
6 #include "EXTERN.h"
7 #include "common.h"
8 #include "list.h"
9 #include "hash.h"
10 #include "env.h"
11 #include "util.h"
12 #include "util2.h"
13 #include "cache.h"
14 #include "head.h"
15 #include "init.h"
16 #include "opt.h"
17 #include "only.h"
18 #include "term.h"
19 #include "intrp.h"
20 #include "trn.h"
21 #include "ngdata.h"
22 #include "rt-page.h"
23 #include "charsubst.h"
24 #include "INTERN.h"
25 #include "sw.h"
26 
27 void
sw_file(tcbufptr)28 sw_file(tcbufptr)
29 char** tcbufptr;
30 {
31     int initfd = open(*tcbufptr,0);
32 
33     if (initfd >= 0) {
34 	fstat(initfd,&filestat);
35 	if (filestat.st_size >= TCBUF_SIZE-1)
36 	    *tcbufptr = saferealloc(*tcbufptr,(MEM_SIZE)filestat.st_size+1);
37 	if (filestat.st_size) {
38 	    int len = read(initfd,*tcbufptr,(int)filestat.st_size);
39 	    (*tcbufptr)[len] = '\0';
40 	    sw_list(*tcbufptr);
41 	}
42 	else
43 	    **tcbufptr = '\0';
44 	close(initfd);
45     }
46 }
47 
48 /* decode a list of space separated switches */
49 
50 void
sw_list(swlist)51 sw_list(swlist)
52 char* swlist;
53 {
54     register char* s;
55     register char* p;
56     register char inquote = 0;
57 
58     s = p = swlist;
59     while (*s) {			/* "String, or nothing" */
60 	if (!inquote && isspace(*s)) {	/* word delimiter? */
61 	    for (;;) {
62 		while (isspace(*s)) s++;
63 		if (*s != '#')
64 		    break;
65 		while (*s && *s++ != '\n') ;
66 	    }
67 	    if (p != swlist)
68 		*p++ = '\0';		/* chop here */
69 	}
70 	else if (inquote == *s) {
71 	    s++;			/* delete trailing quote */
72 	    inquote = 0;		/* no longer quoting */
73 	}
74 	else if (!inquote && (*s == '"' || *s == '\'')) {
75 					/* OK, I know when I am not wanted */
76 	    inquote = *s++;		/* remember & del single or double */
77 	}
78 	else if (*s == '\\') {		/* quoted something? */
79 	    if (*++s != '\n') {		/* newline? */
80 		s = interp_backslash(p, s);
81 		p++;
82 	    }
83 	    s++;
84 	}
85 	else
86 	    *p++ = *s++;		/* normal char */
87     }
88     *p++ = '\0';
89     *p = '\0';				/* put an extra null on the end */
90     if (inquote) {
91 	printf("Unmatched %c in switch\n",inquote) FLUSH;
92 	termdown(1);
93     }
94     for (p = swlist; *p; /* p += strlen(p)+1 */ ) {
95 	decode_switch(p);
96 	while (*p++) ;			/* point at null + 1 */
97     }
98 }
99 
100 /* decode a single switch */
101 
102 void
decode_switch(s)103 decode_switch(s)
104 register char* s;
105 {
106     while (isspace(*s)) s++;		/* ignore leading spaces */
107 #ifdef DEBUG
108     if (debug) {
109 	printf("Switch: %s\n",s) FLUSH;
110 	termdown(1);
111     }
112 #endif
113     if (*s != '-' && *s != '+') {	/* newsgroup pattern */
114 	setngtodo(s);
115 	if (mode == 'i')
116 	    ng_min_toread = 0;
117     }
118     else {				/* normal switch */
119 	bool upordown = *s == '-' ? TRUE : FALSE;
120 	char tmpbuf[LBUFLEN];
121 
122 	switch (*++s) {
123 #ifdef TERMMOD
124 	case '=':
125 	    /*$$ fix this */
126 	    break;
127 #endif
128 #ifdef BAUDMOD
129 	case '0': case '1': case '2': case '3': case '4':
130 	case '5': case '6': case '7': case '8': case '9':
131 	    /*$$ fix this */
132 	    break;
133 #endif
134 	case '/':
135 	    set_option(OI_AUTO_SAVE_NAME, YESorNO(upordown));
136 	    break;
137 	case '+':
138 	    set_option(OI_USE_ADD_SEL, YESorNO(upordown));
139 	    set_option(OI_USE_NEWSGROUP_SEL, YESorNO(upordown));
140 	    if (upordown)
141 		set_option(OI_INITIAL_GROUP_LIST, YESorNO(0));
142 	    else
143 		set_option(OI_USE_NEWSRC_SEL, YESorNO(0));
144 	    break;
145 	case 'a':
146 	    set_option(OI_BKGND_THREADING, YESorNO(!upordown));
147 	    break;
148 	case 'A':
149 	    set_option(OI_AUTO_ARROW_MACROS, YESorNO(upordown));
150 	    break;
151 	case 'b':
152 	    set_option(OI_READ_BREADTH_FIRST, YESorNO(upordown));
153 	    break;
154 	case 'B':
155 	    set_option(OI_BKGND_SPINNER, YESorNO(upordown));
156 	    break;
157 	case 'c':
158 	    checkflag = upordown;
159 	    break;
160 	case 'C':
161 	    if (*++s == '=') s++;
162 	    set_option(OI_CHECKPOINT_NEWSRC_FREQUENCY, s);
163 	    break;
164 	case 'd': {
165 	    if (*++s == '=') s++;
166 	    set_option(OI_SAVE_DIR, s);
167 	    break;
168 	}
169 	case 'D':
170 #ifdef DEBUG
171 	    if (*++s == '=') s++;
172 	    if (*s) {
173 		if (upordown)
174 		    debug |= atoi(s);
175 		else
176 		    debug &= ~atoi(s);
177 	    }
178 	    else {
179 		if (upordown)
180 		    debug |= 1;
181 		else
182 		    debug = 0;
183 	    }
184 #else
185 	    printf("Trn was not compiled with -DDEBUG.\n") FLUSH;
186 	    termdown(1);
187 #endif
188 	    break;
189 	case 'e':
190 	    set_option(OI_ERASE_SCREEN, YESorNO(upordown));
191 	    break;
192 	case 'E':
193 	    if (*++s == '=') s++;
194 	    strcpy(tmpbuf,s);
195 	    s = index(tmpbuf,'=');
196 	    if (s) {
197 		*s++ = '\0';
198 		s = export(tmpbuf,s) - (s-tmpbuf);
199 		if (mode == 'i')
200 		    save_init_environment(s);
201 	    }
202 	    else {
203 		s = export(tmpbuf,nullstr) - strlen(tmpbuf) - 1;
204 		if (mode == 'i')
205 		    save_init_environment(s);
206 	    }
207 	    break;
208 	case 'f':
209 	    set_option(OI_NOVICE_DELAYS, YESorNO(!upordown));
210 	    break;
211 	case 'F':
212 	    set_option(OI_CITED_TEXT_STRING, s+1);
213 	    break;
214 	case 'g':
215 #ifdef INNERSEARCH
216 	    set_option(OI_GOTO_LINE_NUM, s+1);
217 #else
218 	    notincl("-g");
219 #endif
220 	    break;
221 	case 'G':
222 #ifdef EDIT_DISTANCE
223 	    set_option(OI_FUZZY_NEWSGROUP_NAMES, YESorNO(upordown));
224 #else
225 	    notincl("-G");
226 #endif
227 	    break;
228 	case 'h':
229 	    if (!s[1]) {
230 		/* Free old user_htype list */
231 		while (user_htype_cnt > 1)
232 		    free(user_htype[--user_htype_cnt].name);
233 		bzero((char*)user_htypeix, 26);
234 	    }
235 	    /* FALL THROUGH */
236 	case 'H':
237 	    if (checkflag)
238 		break;
239 	    set_header(s+1,*s == 'h'? HT_HIDE : HT_MAGIC, upordown);
240 	    break;
241 	case 'i':
242 	    if (*++s == '=') s++;
243 	    set_option(OI_INITIAL_ARTICLE_LINES, s);
244 	    break;
245 	case 'I':
246 	    set_option(OI_APPEND_UNSUBSCRIBED_GROUPS, YESorNO(upordown));
247 	    break;
248 	case 'j':
249 	    set_option(OI_FILTER_CONTROL_CHARACTERS, YESorNO(!upordown));
250 	    break;
251 	case 'J':
252 	    if (*++s == '=') s++;
253 	    set_option(OI_JOIN_SUBJECT_LINES,
254 		       upordown && *s? s : YESorNO(upordown));
255 	    break;
256 	case 'k':
257 	    set_option(OI_IGNORE_THRU_ON_SELECT, YESorNO(upordown));
258 	    break;
259 	case 'K':
260 	    set_option(OI_AUTO_GROW_GROUPS, YESorNO(!upordown));
261 	    break;
262 	case 'l':
263 	    set_option(OI_MUCK_UP_CLEAR, YESorNO(upordown));
264 	    break;
265 	case 'L':
266 	    set_option(OI_ERASE_EACH_LINE, YESorNO(upordown));
267 	    break;
268 	case 'M':
269 	    if (upordown)
270 		set_option(OI_SAVEFILE_TYPE, "mail");
271 	    break;
272 	case 'm':
273 	    set_option(OI_PAGER_LINE_MARKING, s+1);
274 	    break;
275 	case 'N':
276 	    if (upordown)
277 		set_option(OI_SAVEFILE_TYPE, "norm");
278 	    break;
279 	case 'o':
280 	    if (*++s == '=') s++;
281 	    set_option(OI_OLD_MTHREADS_DATABASE, s);
282 	    break;
283 	case 'O':
284 	    if (*++s == '=') s++;
285 	    set_option(OI_NEWS_SEL_MODE, s);
286 	    if (*++s) {
287 		char tmpbuf[4];
288 		sprintf(tmpbuf, "%s%c", isupper(*s)? "r " : nullstr, *s);
289 		set_option(OI_NEWS_SEL_ORDER, tmpbuf);
290 	    }
291 	    break;
292 	case 'p':
293 	    if (*++s == '=') s++;
294 	    if (!upordown)
295 		s = YESorNO(0);
296 	    else {
297 		switch (*s) {
298 		case '+':
299 		    s = "thread";
300 		    break;
301 		case 'p':
302 		    s = "parent";
303 		    break;
304 		default:
305 		    s = "subthread";
306 		    break;
307 		}
308 	    }
309 	    set_option(OI_SELECT_MY_POSTS, s);
310 	    break;
311 	case 'q':
312 	    set_option(OI_NEWGROUP_CHECK, YESorNO(!upordown));
313 	    break;
314         case 'Q':
315 #ifdef CHARSUBST
316 	    if (*++s == '=') s++;
317 	    set_option(OI_CHARSET, s);
318 #else
319 	    notincl("-Q");
320 #endif
321 	    break;
322 	case 'r':
323 	    set_option(OI_RESTART_AT_LAST_GROUP, YESorNO(upordown));
324 	    break;
325 	case 's':
326 	    if (*++s == '=') s++;
327 	    set_option(OI_INITIAL_GROUP_LIST, isdigit(*s)? s : YESorNO(0));
328 	    break;
329 	case 'S':
330 	    if (*++s == '=') s++;
331 	    set_option(OI_SCANMODE_COUNT, s);
332 	    break;
333 	case 't':
334 	    set_option(OI_TERSE_OUTPUT, YESorNO(upordown));
335 	    break;
336 	case 'T':
337 	    set_option(OI_EAT_TYPEAHEAD, YESorNO(!upordown));
338 	    break;
339 	case 'u':
340 	    set_option(OI_COMPRESS_SUBJECTS, YESorNO(!upordown));
341 	    break;
342 	case 'U':
343 	    unsafe_rc_saves = upordown;
344 	    break;
345 	case 'v':
346 	    set_option(OI_VERIFY_INPUT, YESorNO(upordown));
347 	    break;
348 	case 'V':
349 	    if (mode == 'i') {
350 		tc_LINES = 1000;
351 		tc_COLS = 1000;
352 		erase_screen = FALSE;
353 	    }
354 	    trn_version();
355 	    newline();
356 	    if (mode == 'i')
357 		exit(0);
358 	    break;
359 	case 'x':
360 	    if (*++s == '=') s++;
361 	    if (isdigit(*s)) {
362 		set_option(OI_ARTICLE_TREE_LINES, s);
363 		while (isdigit(*s)) s++;
364 	    }
365 	    if (*s)
366 		set_option(OI_NEWS_SEL_STYLES, s);
367 	    set_option(OI_USE_THREADS, YESorNO(upordown));
368 	    break;
369 	case 'X':
370 	    if (*++s == '=') s++;
371 	    if (isdigit(*s)) {
372 		set_option(OI_USE_NEWS_SEL, s);
373 		while (isdigit(*s)) s++;
374 	    }
375 	    else
376 		set_option(OI_USE_NEWS_SEL, YESorNO(upordown));
377 	    if (*s)
378 		set_option(OI_NEWS_SEL_CMDS, s);
379 	    break;
380 	case 'z':
381 	    if (*++s == '=') s++;
382 	    set_option(OI_DEFAULT_REFETCH_TIME,
383 		       upordown && *s? s : YESorNO(upordown));
384 	    break;
385 	default:
386 #ifdef VERBOSE
387 	    IF(verbose)
388 		printf("\nIgnoring unrecognized switch: -%c\n", *s) FLUSH;
389 	    ELSE
390 #endif
391 #ifdef TERSE
392 		printf("\nIgnoring -%c\n", *s) FLUSH;
393 #endif
394 	    termdown(2);
395 	    break;
396 	}
397     }
398 }
399 
400 void
save_init_environment(str)401 save_init_environment(str)
402 char* str;
403 {
404     if (init_environment_cnt >= init_environment_max) {
405 	init_environment_max += 32;
406 	init_environment_strings = (char**)
407 	  saferealloc((char*)init_environment_strings,
408 		      init_environment_max * sizeof (char*));
409     }
410     init_environment_strings[init_environment_cnt++] = str;
411 }
412 
413 void
write_init_environment(fp)414 write_init_environment(fp)
415 FILE* fp;
416 {
417     int i;
418     char* s;
419     for (i = 0; i < init_environment_cnt; i++) {
420 	s = index(init_environment_strings[i],'=');
421 	if (!s)
422 	    continue;
423 	*s = '\0';
424 	fprintf(fp, "%s=%s\n", init_environment_strings[i],quote_string(s+1));
425 	*s = '=';
426     }
427     init_environment_cnt = init_environment_max = 0;
428     free((char*)init_environment_strings);
429     init_environment_strings = NULL;
430 }
431