1 /*
2    ATP QWK MAIL READER FOR READING AND REPLYING TO QWK MAIL PACKETS.
3    Copyright (C) 1992, 1993, 1997  Thomas McWilliams
4    Copyright (C) 1990  Rene Cougnenc
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 /*
22 rdconfig.c
23 */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 
31 #define _ATP_RDCONFIG_C
32 #include "reader.h"
33 #include "readlib.h"
34 #include "makemail.h"
35 #include "qlib.h"
36 #include "ansi.h"
37 
38 /************************ BEGIN GLOBAL VARIABLES ****************************/
39 
40 /* global pointers */                                                          /*@+voidabstract */
41 FILE *fidx  = NULL;             /* current open conference index stream     */
42 FILE *fmsg  = NULL;             /* current open conference message stream   */ /*@=voidabstract */
43 char *rbuf  = NULL;             /* Pointer to work buffer for messages      */
44 
45 /* global constants */
46 const size_t mybuf  = MYBUF ;
47 const size_t maxbuf = MAXBUF ;
48 const size_t one_record = (size_t)1;
49 const size_t header_SIZE = (size_t)HDRSIZE ;
50 const size_t block_SIZE = (size_t)BLKSIZE;
51 const size_t index_SIZE = (size_t)IDXSIZE;
52 
53  /* passed text to readline editor */
54 const char *luxptr;
55 
56 /* local path data */
57 static char rc_HomePath[MAXPATHS]; /* Home directory root of msg dirs       */
58 static char rc_MailPath[MAXPATHS]; /* Where to look for new mail            */
59 static char rc_ReplyPath[MAXPATHS];/* Where to put replies                  */
60 static char rc_WorkPath[MAXPATHS]; /* Where to archive/unarchive mail       */
61 static char rc_CurBoard[50];       /* Name of the current board...          */
62 static char rc_termtype[80];       /* TERM environ variable                 */
63 
64 /* public access to path data */
65 const char CONSPTR HomePath  = rc_HomePath;
66 const char CONSPTR MailPath  = rc_MailPath;
67 const char CONSPTR ReplyPath = rc_ReplyPath;
68 const char CONSPTR WorkPath  = rc_WorkPath;
69 const char CONSPTR CurBoard  = rc_CurBoard;
70 const char CONSPTR atp_termtype  = rc_termtype;
71 
72 /* local strings set by atprc */
73 static char User1Name[50];         /* user name taken from atprc            */
74 static char Editor[50];            /* name of the standard text editor      */
75 static char Archiver[50];          /* program to pack qwk message replies   */
76 static char UnArchiver[50];        /* program to unpack qwk message packets */
77 static char qwklist[100];          /* command line for listing QWK packet   */
78 static char bltlist[100];          /* command line for listing bulletins    */
79 static char speller[100];          /* command line for invoking speller     */
80 
81 /* pseudo const boolean flag variables set from atprc */
82 atp_BOOL_T autotag  = TRUE;        /* flag for random taglines              */
83 atp_BOOL_T graphics = FALSE;       /* flag for VT102 line graphics mode     */
84 atp_BOOL_T ansi     = TRUE;        /* flag true if ansi output is on        */
85 atp_BOOL_T silent   = FALSE;       /* flag for no tty bell                  */
86 atp_BOOL_T fido     = FALSE;       /* flag for tagline style                */
87 atp_BOOL_T color    = TRUE;        /* flag true if ansi output is on        */
88 atp_BOOL_T pcbext   = TRUE;        /* flag true to display long subjects    */
89 
90 /*  local state flags */
91 static atp_BOOL_T pmail = FALSE;   /* flag true if personal mail waiting    */
92 static atp_BOOL_T caps  = FALSE;   /* true if bbs prefers caps for to/from  */
93 static atp_BOOL_T HeadLetter = TRUE; /* true if automatic header is active  */
94 static atp_CODE_T charset = CHR7BIT; /* latin1, msdos, or 7-bit ascii.      */
95 static int ScrnRows = 0;           /* initialized by TTYinfo() or atprc     */
96 static int ScrnCols = 0;           /* initialized by TTYinfo() or atprc     */
97 
98 /************ end of globals **********/
99 
100 
101 /*
102  * public access functions
103  *
104  */
105 
106 
107 /*
108  * toglpcb - toggle support for PCBoard long subjects and features.
109  */
110 void
toglpcb(void)111 toglpcb(void)
112 {
113     pcbext = pcbext ? FALSE : TRUE ;
114     yellow();
115     high();
116     printf("%s %s .\n", "PCBoard long subjects are", pcbext ? txt[85] : txt[86]);
117 }
118 
119 
120 /*
121  * toglfido - toggle tagline styles between FIDO and PCBoard.
122  */
123 void
toglfido(void)124 toglfido(void)
125 {
126     fido = fido ? FALSE : TRUE ;
127 }
128 
129 
130 /*
131  * toglauto - toggle tagline styles between FIDO and PCBoard.
132  */
133 void
toglauto(void)134 toglauto(void)
135 {
136     autotag = autotag ? FALSE : TRUE;
137 }
138 
139 
140 /*
141  * test_line_graphics - displays a small test pattern.
142  */
143 void
test_line_graphics(void)144 test_line_graphics(void)
145 {
146     graphics = graph_togl(graphics);
147 }
148 
149 /*@-strictops */
150 /*
151  * set_CurBoard - restricted write access to Bbs name buffer.
152  */
153 void
set_CurBoard(const char * str,const curbrd_access_t perm)154 set_CurBoard(const char *str, const curbrd_access_t perm)
155 {
156     if (cb_RdCn_main_init <= perm && perm <= cb_Read)
157 	strcpy(rc_CurBoard, str);
158 #ifdef ATPDBG
159     else
160 	assert(cb_RdCn_main_init <= perm && perm <= cb_Read);
161 #endif
162 }
163 
164 
165 /*
166  * set_ScrnRows - restricted write access to ScrnRows variable.
167  */
168 void
set_ScrnRows(const int siz,const scrn_access_t perm)169 set_ScrnRows(const int siz, const scrn_access_t perm)
170 {
171     if (ss_getwinders <= perm && perm <= ss_TTYinfo)
172 	ScrnRows = siz;
173 #ifdef ATPDBG
174     else
175 	assert(ss_getwinders <= perm && perm <= ss_TTYinfo);
176 #endif
177 }
178 
179 
180 /*
181  * set_ScrnCols - restricted write access to ScrnCols variable.
182  */
183 void
set_ScrnCols(const int siz,const scrn_access_t perm)184 set_ScrnCols(const int siz, const scrn_access_t perm)
185 {
186     if (ss_getwinders <= perm && perm <= ss_TTYinfo)
187 	ScrnCols = siz;
188 #ifdef ATPDBG
189     else
190 	assert(ss_getwinders <= perm && perm <= ss_TTYinfo);
191 #endif
192 }
193 
194 
195 /*
196  * set_pmail - restricted write access to pmail flag.
197  */
198 void
set_pmail(const atp_BOOL_T mode,const pmail_access_t perm)199 set_pmail(const atp_BOOL_T mode, const pmail_access_t perm)
200 {
201     if (pmPurge_D <= perm && perm <= pmLoad)
202 	pmail = mode;
203 #ifdef ATPDBG
204     else
205 	assert(pmPurge_D <= perm && perm <= pmLoad);
206 #endif
207 }
208 /*@=strictops */
209 
210 /*
211  * get_pmail - read access for pmail flag.
212  */
213 atp_BOOL_T
get_pmail(void)214 get_pmail(void)
215 {
216     return pmail;
217 }
218 
219 
220 /*
221  * get_ScrnRows - read access for ScrnRows variable.
222  */
223 int
get_ScrnRows(void)224 get_ScrnRows(void)
225 {
226     return ScrnRows;
227 }
228 
229 
230 /*
231  * get_ScrnCols - read access for ScrnCols variable.
232  */
233 int
get_ScrnCols(void)234 get_ScrnCols(void)
235 {
236     return ScrnCols;
237 }
238 
239 
240 /*
241  * get_charset - read access for charcter set variable.
242  */
243 atp_CODE_T
get_charset(void)244 get_charset(void)
245 {
246     return charset;
247 }
248 
249 
250 /*
251  * get_caps - allows global read access to caps variable.
252  */
253 atp_BOOL_T
get_caps(void)254 get_caps(void)
255 {
256     return caps;
257 }
258 
259 
260 /*
261  * set_caps - allows global write access to caps variable.
262  */
263 void
set_caps(const atp_BOOL_T val)264 set_caps(const atp_BOOL_T val)
265 {
266     caps = val;
267 }
268 
269 
270 /*
271  * get_HeadLetter - allows global read access to HeadLetter variable.
272  */
273 atp_BOOL_T
get_HeadLetter(void)274 get_HeadLetter(void)
275 {
276     return HeadLetter;
277 }
278 
279 
280 /*
281  * ansi_toggle - flips mode from ansi to non-ansi.
282  */
283 void
ansi_toggle(void)284 ansi_toggle(void)
285 {
286     ansi = ansi ? FALSE : TRUE;
287     yellow();
288     high();
289     printf("%s %s .\n", txt[84], ansi ? txt[85] : txt[86]);
290 }
291 
292 
293 /*
294  * head_toggle - called by ReadShell().
295  */
296 void
head_toggle(void)297 head_toggle(void)
298 {
299     blue();
300     high();
301     HeadLetter = HeadLetter ? FALSE : TRUE ;
302     printf("%s ", txt[101]);    /* "Automatic H." */
303     printf("%s\n", HeadLetter ? txt[85] : txt[86]);     /* "on" / "off"   */
304     green();
305     fflush(stdout);
306 }
307 
308 
309 /* used by DoLoad(), Read(), Reply(), */
310 
311 /*
312  * test_for_caps - called by PutHeader(). checks to/from fields for upper case.
313  */
314 void
test_for_caps(const char * Header)315 test_for_caps(const char *Header)
316 {
317     int i ;
318     const char CONSPTR pntr = Header + HForWhom;
319     caps = TRUE;
320     for (i = HForWhom; i < HSubject; i++) /*@-strictops */
321         if (pntr[i] >= 'a' && pntr[i] <= 'z') /*@=strictops */
322             caps = FALSE;
323 }
324 
325 
326 /*
327  * get_atprc_str - returns copies of the atprc string variables.
328  */
329 char *
get_atprc_str(const atprc_str_t token)330 get_atprc_str(const atprc_str_t token)
331 {
332     char *strnm = NULL;
333     switch (token) {
334     case usr1nm:
335         strnm = strdup(User1Name);
336         break;
337     case editr:
338         strnm = strdup(Editor);
339         break;
340     case archivr:
341         strnm = strdup(Archiver);
342         break;
343     case unarchvr:
344         strnm = strdup(UnArchiver);
345         break;
346     case qwklst:
347         strnm = strdup(qwklist);
348         break;
349     case bltlst:
350         strnm = strdup(bltlist);
351         break;
352     case spellr:
353         strnm = strdup(speller);
354         break;
355     default:
356         /* switch() case error */
357 	error_switch_case((int)token, __FILE__, __LINE__);
358     }
359     test_fatal_malloc(strnm, __FILE__, __LINE__);
360     return strnm;
361 }
362 
363 
364 /*
365  * Clean - builds the full work directory pathname and cleans work directory.
366  *
367  * ( System dependent functions are in system.c )
368  */
369 void
Clean(void)370 Clean(void)
371 {   /*@-strictops */
372     if (WorkPath[0] == NUL_CHAR) {  /*@=strictops */
373         strcpy(rc_WorkPath, HomePath);
374         strcat(rc_WorkPath, WORK_DIR);
375     }
376     if (access(WorkPath, F_OK) == FAILURE)
377         (void)my_mkdir(WorkPath);
378     else {
379         printf("%s %s...\n", txt[57], WorkPath);        /* "Cleaning" */
380         Erase(WorkPath);
381     }
382 }
383 
384 
385 /*
386  * PrePath, adds the last separator to a pathname.
387  * Must be room enough for that in the string !
388  */
389 static void
PrePath(char * path)390 PrePath(char *path)
391 {
392     int l;
393 
394     ADDRIVE(path);
395     l = strlen(path); /*@-strictops */
396     if (path[l - 1] != SEP && path[l - 1] != SEPDOS) {  /*@=strictops */
397 	path[l] = SEP;
398 	path[l + 1] = NUL_CHAR;
399     }
400 }
401 
402 /*
403  * MakeHomePath - creates the Home directory pathname string.
404  *
405  *  In the Unix version we look for for the environment variable
406  *  ATP. If that is not found we look for the HOME variable and
407  *  make our home path with that. If that fails we use the current
408  *  working directory as out home path. If that fails, we exit
409  *  after printing an error message. Note that Unix doesn't pass
410  *  the path in argv[0], only the name of the program. The MS-DOS
411  *  version assumes that argv[0] contains the current path.
412  *  MakeHomePath is invoked from main() and is passed argv[0].
413  */
414 atp_BOOL_T
MakeHomePath(void)415 MakeHomePath(void)
416 {
417     atp_BOOL_T ret_code = FALSE;
418     char *pt;
419     if (strlen(getenv("PATH")) > (size_t) MAXPATHS) {
420         printf("PATH environment too long: %d\n", (int) MAXPATHS);
421     } else if ((pt = (char *) getenv("ATP")) != NULL
422                || (pt = (char *) getenv("HOME")) != NULL
423                || (pt = GETCWD(rc_HomePath, MAXPATHS)) != NULL) {
424         size_t path_len;
425         strcpy(rc_HomePath, pt);
426         PrePath(rc_HomePath);
427         path_len = strlen(rc_HomePath);
428         while (path_len != (size_t)0) {          /*@-strictops */
429             if (rc_HomePath[path_len] == SEP ||
430 	        rc_HomePath[path_len] == ':' ||
431                 rc_HomePath[path_len] == SEPDOS) /*@=strictops */
432                 break;
433             rc_HomePath[path_len] = NUL_CHAR;
434             path_len--;
435         }
436         pt = rc_HomePath;           /*@-strictops */
437         while (*pt != NUL_CHAR) {
438             if (*pt == SEPDOS)      /*@=strictops */
439                 *pt = SEP;
440             pt++;
441         }
442         ret_code = TRUE;
443     } else {
444         printf("\nERROR: MakeHomePath() module readlib.c\n");
445     }
446     return ret_code;
447 }
448 
449 /*
450  * init_termtype - set terminal type from TERM environment variable.
451  */
452 void
init_term_type(void)453 init_term_type(void)
454 {
455     luxptr = getenv("TERM");
456     if (luxptr == NULL)
457         strcpy(rc_termtype, " ");
458     else
459         strcpy(rc_termtype, luxptr);
460 }
461 
462 /*
463  * init_charset, set character set to latin1 or 7-bit or msdos per atprc.
464  */
465 static void
init_charset(char * value)466 init_charset(char *value)
467 {
468     if (strnicmp(value, "iso", 3) == SUCCESS
469 	|| strnicmp(value, "lat", 3) == SUCCESS) {
470 	charset = ISOLAT1;
471     } else if (strnicmp(value, "dos", 3) == SUCCESS
472 	       || strnicmp(value, "msd", 3) == SUCCESS) {
473 	charset = CHRDOS;
474     } else {
475 	charset = CHR7BIT;
476     }
477 }
478 
479 /*
480  * init_warning, warn about old atp version 1.3 atprc files.
481  */
482 static void
init_warning(void)483 init_warning(void)
484 {
485     printf("\n\n\n READ THE DOCS: you must update your atprc file!\n\n");
486     printf(" \"taglist\"  not valid opton for this release. \n");
487     printf(" Taglines are now stored in textfile \"taglines.atp\".\n\n");
488     abort();
489 }
490 
491 /*
492  * init_screen, set screen row and columns from atprc.
493  */
494 static void
init_screen(const char * var,const char * value)495 init_screen(const char *var, const char *value)
496 {
497     if (Numeric(value)) {
498         int tmpint = atoi(value);
499         tmpint = (tmpint < 0) ? -tmpint : tmpint;
500         if (2 < tmpint && tmpint < 301) {       /* range check */
501             if (strcmp(var, "screenlen") == SUCCESS)
502                 set_ScrnRows(tmpint, ss_init_screen);
503             else
504                 set_ScrnCols(tmpint, ss_init_screen);
505         }
506     }
507 }
508 
509 /* default confernce truncation number */
510 static long TruncNum  = 50L;
511 
512 /*
513  * get_TruncNum - returns the current value for truncation length.
514  */
515 long
get_TruncNum(void)516 get_TruncNum(void)
517 {
518     return TruncNum;
519 }
520 
521 /*
522  * init_truncate, set truncation length from atprc for "clean" command.
523  */
524 static void
init_truncate(const char * value)525 init_truncate(const char *value)
526 {
527     if (Numeric(value)) {
528         long tmplong = atol(value);
529         tmplong = (tmplong < 0L) ? -tmplong : tmplong;
530         if (tmplong < 1L)
531             tmplong = 1L;
532         TruncNum = tmplong;
533     }
534 }
535 
536 
537 
538 /*
539  * init_program, parses atprc for editor/archiver/unarchiver/speller.
540  */
541 static atp_ERROR_T
init_program(char * var,char * value,char * aLine)542 init_program(char *var, char *value, char *aLine)
543 {
544     atp_ERROR_T ret_code = ATP_OK;
545     char *tptr;
546     if ((tptr = strstr(aLine, " = ")) != NULL
547         && (tptr = strstr(tptr, value)) != NULL) {
548         if (strcmp(var, "archiver") == SUCCESS) {
549             strcpy(Archiver, tptr);
550         } else if (strcmp(var, "unarchiver") == SUCCESS) {
551             strcpy(UnArchiver, tptr);
552         } else if (strcmp(var, "speller") == SUCCESS) {
553             strcpy(speller, tptr);
554         } else if (strcmp(var, "editor") == SUCCESS) {
555             strcpy(Editor, tptr);
556         } else
557             ret_code = ATP_ERROR;
558     } else
559         ret_code = ATP_ERROR;
560     return ret_code;
561 }
562 
563 
564 /*
565  * init_workpath, setup various paths used by ATP from atprc entries.
566  */
567 static void
init_path(const char * var,const char * value)568 init_path(const char *var, const char *value)
569 {
570     char *newpath = NULL;
571     if (strcmp(var, "workpath") == SUCCESS)
572         newpath = rc_WorkPath;
573     else if (strcmp(var, "mail") == SUCCESS)
574         newpath = rc_MailPath;
575     else if (strcmp(var, "reply") == SUCCESS)
576         newpath = rc_ReplyPath;
577     if (newpath != NULL) { /*@-strictops */
578         if (value[0] != SEP && value[1] != ':') { /*@=strictops */
579 	    /*@-returnval */
580             GETCWD(newpath, MAXPATHS);
581 	    /*@=returnval */
582             PrePath(newpath);
583         }
584         strcat(newpath, value);
585         PrePath(newpath);
586         if (strcmp(var, "workpath") == SUCCESS)
587             strcat(newpath, WORK_DIR);
588     }
589 }
590 
591 
592 /*
593  * affect, initialize configuration variables to their global values.
594  * returns ATP_ERROR on an invalid line. Ignores unknown variables.
595  */
596 static atp_ERROR_T
affect(char * var,const char * sign,char * value1,char * value2,char * aLine)597 affect(char *var, const char *sign, char *value1, char *value2, char *aLine)
598 {
599     atp_ERROR_T ret_code = ATP_OK;
600     (void)strlwr(var);
601     if (strcmp(sign, "=") != SUCCESS) {
602 	ret_code = ATP_ERROR;
603     } else {
604 	if (strcmp(var, "workpath") == SUCCESS) {
605 	    init_path(var, value1);
606 	} else if (strcmp(var, "mail") == SUCCESS) {
607 	    init_path(var, value1);
608 	} else if (strcmp(var, "reply") == SUCCESS) {
609 	    init_path(var, value1);
610 	} else if (strcmp(var, "ansi") == SUCCESS) {
611 	    /* Starting in ansi mode or not... */
612 	    ansi = stricmp(value1, "off") == SUCCESS ? FALSE : TRUE;
613 	} else if (strcmp(var, "bell") == SUCCESS) {
614 	    silent = stricmp(value1, "on") == SUCCESS ? FALSE : TRUE;
615 	} else if (strcmp(var, "user") == SUCCESS) {
616 	    /* Get User First and Last Name      */
617 	    sprintf(User1Name, "%s %s", value1, value2);
618 	} else if (strcmp(var, "tagline") == SUCCESS) {
619 	    init_tagpers(value1, sign, aLine);
620 	} else if (strcmp(var, "tagstyle") == SUCCESS) {
621 	    /* default tag style Fido or PCB */
622 	    init_tagstyle(value1);
623 	} else if (strcmp(var, "color") == SUCCESS) {
624 	    /* Starting in ansi color mode or not... */
625 	    color = stricmp(value1, "on") == SUCCESS ? TRUE : FALSE;
626 	} else if (strcmp(var, "autotag") == SUCCESS
627 		   && stricmp(value1, "OFF") == SUCCESS) {
628 	    autotag = FALSE;
629 	} else if (strcmp(var, "graphics") == SUCCESS
630 		   && stricmp(value1, "ON") == SUCCESS) {
631 	    graphics = TRUE;
632 	} else if (strcmp(var, "pcb") == SUCCESS &&
633 		   stricmp(value1, "OFF") == SUCCESS) {
634 	    pcbext = FALSE;
635 	} else if (strcmp(var, "header") == SUCCESS
636 		   && stricmp(value1, "OFF") == SUCCESS) {
637 	    HeadLetter = FALSE;
638 	} else if (strcmp(var, "charset") == SUCCESS) {
639 	    init_charset(value1);
640 	} else if (strcmp(var, "taglist") == SUCCESS) {
641 	    /* warn that old atprc was found */
642 	    init_warning();
643 	} else if (strcmp(var, "screenlen") == SUCCESS) {
644 	    /* default screenlength */
645 	    init_screen(var, value1);
646 	} else if (strcmp(var, "screencol") == SUCCESS) {
647 	    /* default screenwidth */
648 	    init_screen(var, value1);
649 	} else if (strcmp(var, "truncate") == SUCCESS) {
650 	    /* default database truncation length */
651 	    init_truncate(value1); /*@-strictops */
652 	} else if (value1[0] != NUL_CHAR) { /*@=strictops */
653 	    char *tptr = NULL;
654 	    if (strcmp(var, "qlist") == SUCCESS
655 		&& (tptr = strstr(aLine, value1)) != NULL) {
656 		/* get command for listing packets */
657 		assert(tptr != NULL);
658 		strcpy(qwklist, tptr);
659 	    } else if (strcmp(var, "blist") == SUCCESS
660 		       && (tptr = strstr(aLine, value1)) != NULL) {
661 		/* get command for listing packets */
662 		assert(tptr != NULL);
663 		strcpy(bltlist, tptr);
664 	    } else if (strcmp(var, "speller") == SUCCESS
665 		       || strcmp(var, "archiver") == SUCCESS
666 		       || strcmp(var, "unarchiver") == SUCCESS
667 		       || strcmp(var, "editor") == SUCCESS) {
668 		ret_code = init_program(var, value1, aLine);
669 	    }
670 	}
671     }
672     return ret_code;
673 }
674 
675 /*
676  * open_atprc, opens atprc configuration file for ReadConfig.
677  */
678 static FILE *
open_atprc(char * Path)679 open_atprc(char *Path)
680 {
681     FILE *cfg;
682     strcpy(Path, HomePath);
683     strcat(Path, ".");
684     strcat(Path, CONFIG_FILE);
685     /* try to open cfg "dot" file */
686     if ((cfg = fopen(Path, "rb")) == NULL) {
687         strcpy(Path, HomePath);
688         strcat(Path, CONFIG_FILE);
689         /* try again non-dot file     */
690         if ((cfg = fopen(Path, "rb")) == NULL) {
691             /* "Unable to open config file" */
692             printf("\n%s %s or .%s ! \n", txt[52], Path, CONFIG_FILE);
693 	    /*@+voidabstract */
694             cfg = NULL;
695 	    /*@=voidabstract */
696         }
697     }
698     return cfg;
699 }
700 
701 
702  /*
703  * parse_config, called by ReadConfig().
704  */
705 static atp_ERROR_T
parse_config(FILE * cfg,char * Path)706 parse_config(FILE * cfg, char *Path) /* !! */
707 {
708     atp_ERROR_T our_status = ATP_OK; /* !! do we need both of these? */
709     atp_ERROR_T ret_code = ATP_OK;
710     int count = 0;
711 
712     char RCLine[MAXPATHS], var[100], sign[100], value1[100], value2[100];
713     /*@-strictops */
714     while (ret_code == ATP_OK && our_status == ATP_OK && /*@i1*/ fget(RCLine, 255, cfg)) {
715         count++; /*@=strictops */
716         StripLSpace(RCLine); /*@-strictops */
717         if (RCLine[0] != '#' && (strlen(RCLine) >= (size_t) 2)) { /*@=strictops */
718             var[0] = sign[0] = value1[0] = value2[0] = NUL_CHAR;
719             sscanf(RCLine, "%s %s %s %s", var, sign, value1, value2); /*@-strictops */
720             if ((our_status = affect(var, sign, value1, value2, RCLine)) == ATP_ERROR) {
721                 /* "error in config file in line..." */ /*@=strictops */
722                 printf("%s %s %s %d\n", txt[54], Path, txt[55], count);
723                 printf("%s %d : %s\n", txt[56], count, RCLine);
724                 ret_code = ATP_ERROR;
725                 break;
726             }
727         }
728     }
729     return ret_code;
730 }
731 
732 
733 /*
734  * ReadConfig - read the configuration file by invoking parse_config().
735  */
736 atp_ERROR_T
ReadConfig(void)737 ReadConfig(void)
738 {
739     char Path[MAXPATHS];
740     atp_ERROR_T ret_code = ATP_ERROR;
741     FILE *cfg;
742     printf("%s...\n", txt[53]); /* "Reading config file" */
743     speller[0] = NUL_CHAR;
744     strcpy(Archiver, "zip");    /* initialize default packer */
745     strcpy(UnArchiver, "unzip");        /* initialize default unpacker */
746     strcpy(Editor, "vi");       /* initialize default editor */
747 #ifdef UNIXCMDS
748     strcpy(qwklist, "ls *.q* ");        /* initialize qwklist command */
749     strcpy(bltlist, "ls blt*.* ");      /* initialize qwklist command */
750 #else
751     strcpy(qwklist, "dir *.q* ");
752     strcpy(bltlist, "dir blt*.* ");
753 #endif
754     if ((cfg = open_atprc(Path)) != NULL) {
755         ret_code = parse_config(cfg, Path);
756         fclose(cfg);
757     }
758     return ret_code;
759 }
760 
761 #if defined(TIOCGWINSZ) && defined(SIGWINCH)
762 /*@-paramuse */
763 /*
764  * getwinders - signal handler for SIGWINCH.
765  */
766 RETSIGTYPE
getwinders(int dummy_arg)767 getwinders(int dummy_arg)
768 {
769     struct winsize siz;
770 #if !defined(HAVE_LIBTERMCAP)
771     static int firstWinSz = FALSE;
772 #endif
773 #ifndef HAVE_SIGACTION
774     signal(SIGWINCH, getwinders);
775 #endif
776     if (ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &siz) < 0) {
777 	printf("\nTIOCGWINSZ error getwinder()\n");
778 	(void) sleep(3);
779     } else {
780 /*
781    We need a sanity check the first time this is called because if we
782    are using a tty and not the console, the row and column sizes may be
783    set to zero. This will cause Display() to fail by truncating output.
784    Note that after initialization, this routine is only likely to be
785    invoked by a SIGWINCH generated by running ATP under X Window system.
786 
787    If we don't have termcap, we must do sanity check *here* because
788    because without termcap, sanity checks in TTYinfo are bypassed
789  */
790 #if !defined(HAVE_LIBTERMCAP)
791 	if (firstWinSz || (!firstWinSz && siz.ws_row > 2 && siz.ws_col > 2)) {
792 	    set_ScrnRows(siz.ws_row, ss_getwinders);
793 	    set_ScrnCols(siz.ws_col, ss_getwinders);
794 	    firstWinSz = TRUE;
795 	}
796 #else
797 	set_ScrnRows(siz.ws_row, ss_getwinders);
798 	set_ScrnCols(siz.ws_col, ss_getwinders);
799 #endif
800     }
801 }
802 /*@=paramuse */
803 #endif
804 
805 
806 
807 /*
808  * BEGIN REUP MEMORY MANAGEMENT ROUTINES
809  *
810  */
811 
812 static size_t RbufSize = MYBUF;
813 static size_t RbufRecs = (MYBUF+(size_t)(BLKSIZE - 1))/(size_t)BLKSIZE;
814 
815 /*
816  * get_RbufSize - returns the size of the message buffer.
817  */
818 size_t
get_RbufSize(void)819 get_RbufSize(void)
820 {
821     assert(RbufSize == (RbufRecs * block_SIZE));
822     return RbufSize;
823 }
824 
825 /*
826  * get_RbufRecs - returns the message buffer size in number of 128 byte records.
827  */
828 size_t
get_RbufRecs(void)829 get_RbufRecs(void)
830 {
831     assert(RbufRecs == (RbufSize / block_SIZE));
832     return RbufRecs;
833 }
834 
835 /*
836  * reup - reallocate rbuf message buffer. returns TRUE = success. FALSE = fail.
837  */
838 atp_BOOL_T
reup(const size_t bfsz)839 reup(const size_t bfsz)
840 {
841     atp_BOOL_T ret_code = FALSE;
842     char *tptr = NULL;
843 
844     assert(mybuf <= bfsz && rbuf != NULL);
845     if (bfsz <= maxbuf && (tptr = (char *)realloc(rbuf, bfsz + block_SIZE)) != NULL) {
846         /* realloc succeeded */
847         rbuf = tptr;
848         /* bfsz = msgheader + message */
849         RbufSize = bfsz;
850         /* round upward the number of blocks in RbufRecs */
851         RbufRecs = (size_t) ((bfsz + block_SIZE - (size_t)1) / block_SIZE);
852         ret_code = TRUE;
853     }
854 #ifdef ATPDBG2
855     printf("Inside reup()  bufsize = %lu \n", (unsigned long)bfsz), sleep(2);
856 #endif
857     return ret_code;
858 }
859 
860 /* end of rdconfig.c */
861