home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / XINIT.C < prev   
C/C++ Source or Header  |  1995-05-12  |  39KB  |  1,435 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15. #include "vars.h"
  16.  
  17. #pragma hdrstop
  18.  
  19. #include <dir.h>
  20. #include <math.h>
  21. #include "ini.h"
  22.  
  23. #ifndef __OS2__
  24. #define EMS_XMS
  25. #endif
  26.  
  27. /****************************************************************************/
  28.  
  29. #ifndef __OS2__
  30. void far interrupt inlii();
  31. void far interrupt checkai();
  32. void far interrupt plai();
  33. void far interrupt outchri();
  34. void far interrupt outstri();
  35. void far interrupt nli();
  36. void far interrupt pli();
  37. void far interrupt emptyi();
  38. void far interrupt inkeyi();
  39. void far interrupt getkeyi();
  40. void far interrupt inputi();
  41. void far interrupt inputli();
  42. void far interrupt yni();
  43. void far interrupt nyi();
  44. void far interrupt ansici();
  45. void far interrupt oneki();
  46. void far interrupt prti();
  47. void far interrupt mpli();
  48. #endif
  49.  
  50. #define INI_STRFILE 7
  51.  
  52. /****************************************************************************/
  53.  
  54. void far *mallocx(unsigned long l, char *where)
  55. {
  56.   void *x;
  57.   char huge *xx;
  58.  
  59.   if (!l)
  60.     l=1;
  61.   x=bbsmalloc(l);
  62.   if (!x) {
  63.     printf("Insufficient memory (%ld bytes) for %s.\n",l,where);
  64.     end_bbs(noklevel);
  65.   }
  66.  
  67.   xx=(char huge *)x;
  68.   while (l>0) {
  69.     if (l>32768) {
  70.       memset((void *)xx,0,32768);
  71.       l-=32768;
  72.       xx += 32768;
  73.     } else {
  74.       memset((void *)xx,0,l);
  75.       break;
  76.     }
  77.   }
  78.  
  79.   return(x);
  80. }
  81.  
  82. /****************************************************************************/
  83.  
  84. /* Turns a string into a bitmapped unsigned short flag for use with
  85.  * extern_prog calls.
  86.  */
  87.  
  88. unsigned short str2spawnopt(unsigned char *s)
  89. {
  90.   unsigned short return_val;
  91.   unsigned char ts[128];
  92.  
  93.   return_val=0;
  94.   strcpy(ts,s);
  95.   strupr(ts);
  96.  
  97.   if (strstr(ts, "ABORT")!=NULL)
  98.     return_val |= EFLAG_ABORT;
  99.   if (strstr(ts, "INTERNAL")!=NULL)
  100.     return_val |= EFLAG_INTERNAL;
  101.   if (strstr(ts, "NOHANGUP")!=NULL)
  102.     return_val |= EFLAG_NOHUP;
  103.   if (strstr(ts, "COMIO")!=NULL)
  104.     return_val |= EFLAG_COMIO;
  105.   if (strstr(ts, "SHRINK")!=NULL)
  106.     return_val |= EFLAG_SHRINK;
  107.   if (strstr(ts, "FILES")!=NULL)
  108.     return_val |= EFLAG_FILES;
  109.   if (strstr(ts, "NOPAUSE")!=NULL)
  110.     return_val |= EFLAG_NOPAUSE;
  111.   if (strstr(ts, "NETPROG")!=NULL)
  112.     return_val |= EFLAG_NETPROG;
  113.   if (strstr(ts, "TOPSCREEN")!=NULL)
  114.     return_val |= EFLAG_TOPSCREEN;
  115.  
  116.   return(return_val);
  117. }
  118.  
  119. /****************************************************************************/
  120.  
  121. /* Takes string s and creates restrict val
  122. */
  123.  
  124. unsigned short str2restrict(unsigned char *s)
  125. {
  126.   int i,r;
  127.   char *rs=restrict_string;
  128.   char s1[81];
  129.  
  130.   r=0;
  131.   strcpy(s1,s);
  132.   strupr(s1);
  133.  
  134.   for (i=strlen(rs)-1; i>=0; i--) {
  135.     if (strchr(s1,rs[i])) {
  136.       r |= (1<<i);
  137.     }
  138.   }
  139.  
  140.   return(r);
  141. }
  142.  
  143. /****************************************************************************/
  144.  
  145. #ifdef __OS2__
  146. #define OFFOF(x) (((long)&thisuser.x) - ((long)&thisuser))
  147. #else
  148. #define OFFOF(x) (FP_OFF(&(thisuser.x))-FP_OFF(&thisuser))
  149. #endif
  150.  
  151. /****************************************************************************/
  152.  
  153. /* Reads WWIV.INI info from [WWIV] subsection, overrides some config.dat
  154.  * settings (as appropriate), updates config.dat with those values. Also
  155.  * tries to read settings from [WWIV-<instnum>] subsection - this overrides
  156.  * those in [WWIV] subsection.
  157.  */
  158.  
  159. static unsigned char nucol[]  ={7,  11, 14, 5,  31, 2,  12,  9,  6,  3};
  160. static unsigned char nucolbw[]={7,  15, 15, 15, 112,15, 15,  7,  7,  7};
  161.  
  162. typedef struct {
  163.   unsigned char *name;
  164.   unsigned short eflags;
  165. } eventinfo_t;
  166.  
  167. static eventinfo_t eventinfo[] = {
  168.  {"TIMED",      EFLAG_SHRINK | EFLAG_FILES},
  169.  {"NEWUSER",    0},
  170.  {"BEGINDAY",   EFLAG_SHRINK},
  171.  {"LOGON",      EFLAG_COMIO},
  172.  {"ULCHK",      EFLAG_NOHUP | EFLAG_SHRINK},
  173.  {"FSED",       EFLAG_COMIO},
  174.  {"PROT_SINGLE",0},
  175.  {"PROT_BATCH", EFLAG_SHRINK|EFLAG_TOPSCREEN},
  176.  {"CHAT",       EFLAG_SHRINK|EFLAG_FILES},
  177.  {"ARCH_E",     EFLAG_COMIO|EFLAG_INTERNAL},
  178.  {"ARCH_V",     EFLAG_COMIO|EFLAG_INTERNAL|EFLAG_ABORT},
  179.  {"ARCH_A",     EFLAG_COMIO|EFLAG_INTERNAL},
  180. };
  181.  
  182. #define INI_STR_SPAWNOPT          1
  183. #define INI_STR_NUCOLOR           2
  184. #define INI_STR_NUCOLORBW         3
  185. #define INI_STR_TOPCOLOR          4
  186. #define INI_STR_F1COLOR           5
  187. #define INI_STR_EDITLINECOLOR     6
  188. #define INI_STR_CHATSELCOLOR      7
  189. #define INI_STR_TERMINAL_CMD      8
  190. #define INI_STR_EXECUTE_CMD       9
  191. #define INI_STR_UPLOAD_CMD        10
  192. #define INI_STR_BEGINDAY_CMD      11
  193. #define INI_STR_NEWUSER_CMD       12
  194. #define INI_STR_LOGON_CMD         13
  195. #define INI_STR_SYSTEMNAME        14
  196. #define INI_STR_SYSTEMPHONE       15
  197. #define INI_STR_SYSOPNAME         16
  198. #define INI_STR_FORCE_FBACK       17
  199. #define INI_STR_CHECK_DUP_PHONES  18
  200. #define INI_STR_HANGUP_DUP_PHONES 19
  201. #define INI_STR_POSTTIME_COMPENS  20
  202. #define INI_STR_USE_SIMPLE_ASV    21
  203. #define INI_STR_SIMPLE_ASV        22
  204. #define INI_STR_SHOW_HIER         23
  205. #define INI_STR_IDZ_DESC          24
  206. #define INI_STR_SETLDATE          25
  207. #define INI_STR_NEW_CHATSOUND     26
  208. #define INI_STR_SLASH_SZ          27
  209. #define INI_STR_READ_CD_IDZ       28
  210. #define INI_STR_FSED_EXT_DESC     29
  211. #define INI_STR_FAST_TAG_RELIST   30
  212. #define INI_STR_MAIL_PROMPT       31
  213. #define INI_STR_SHOW_CITY_ST      32
  214. #define INI_STR_LOCAL_SYSOP       33
  215. #define INI_STR_2WAY_CHAT         34
  216. #define INI_STR_OFF_HOOK          35
  217. #define INI_STR_PRINTER           36
  218. #define INI_STR_LOG_DL            37
  219. #define INI_STR_CLOSE_XFER        38
  220. #define INI_STR_ALL_UL_SYSOP      39
  221. #define INI_STR_NO_EASY_DL        40
  222. #define INI_STR_NEW_EXTRACT       41
  223. #define INI_STR_FAST_SEARCH       42
  224. #define INI_STR_RATIO             43
  225. #define INI_STR_NET_CALLOUT       44
  226. #define INI_STR_WFC_SCREEN        45
  227. #define INI_STR_FIDO_PROCESS      46
  228. #define INI_STR_USER_REGIST       47
  229. #define INI_STR_MSG_TAG           48
  230. #define INI_STR_CHAIN_REG         49
  231. #define INI_STR_CAN_SAVE_SSM      50
  232. #define INI_STR_PACKSCAN_FREQ     51
  233. #define INI_STR_EXTRA_COLOR       52
  234. #define INI_STR_MAX_BATCH         53
  235. #define INI_STR_MAX_CHAINS        54
  236. #define INI_STR_MAX_GFILESEC      55
  237. #define INI_STR_MSG_COLOR         56
  238. #define INI_STR_MAIL_WHO_LEN      57
  239. #define INI_STR_SCREEN_SAVER_TIME 58
  240. #define INI_STR_RIP_SUPPORT       59
  241. #define INI_STR_RIP_BBS_ID        60
  242. #define INI_STR_RIP_MENU_DATE     61
  243. #define INI_STR_RIP_ADJUST        62
  244. #define INI_STR_BEEP_CHAT         63
  245. #define INI_STR_TWO_COLOR_CHAT    64
  246. #define INI_STR_ALLOW_ALIASES     65
  247. #define INI_STR_UNUSED            66
  248. #define INI_STR_USE_LIST          67
  249. #define INI_STR_FREE_PHONE        68
  250. #define INI_STR_EXTENDED_USERINFO 69
  251. #define INI_STR_RIPDRIVE_ON       70
  252. #define INI_STR_MAX_EXTEND_LINES  71
  253.  
  254. static char *get_key_str(int n)
  255. {
  256.   return(get_stringx(INI_STRFILE, n));
  257. }
  258.  
  259. #define INI_INIT_A(n,i,f,s) \
  260.     {if (((ss=ini_get(get_key_str(n), i, s))!=NULL) && (atoi(ss)>0)) \
  261.       {sysinfo.f[i] = atoi(ss);}}
  262. #define INI_INIT_A_S(n,i,f,s) \
  263.     {if ((ss=ini_get(get_key_str(n), i, s))!=NULL) \
  264.       {sysinfo.f[i] = str2spawnopt(ss);}}
  265. #define INI_INIT(n,f) \
  266.     {if (((ss=ini_get(get_key_str(n), -1, NULL))!=NULL) && (atoi(ss)>0)) \
  267.       sysinfo.f = atoi(ss);}
  268. #define INI_INIT_N(n,f) \
  269.     {if (((ss=ini_get(get_key_str(n), -1, NULL))!=NULL)) \
  270.       sysinfo.f = atoi(ss);}
  271. #define INI_INIT_STR(n, f) \
  272.     set_string(n, syscfg.f, sizeof(syscfg.f), 0)
  273. #define INI_GET_ASV(s, f, func, d) \
  274.     {if ((ss=ini_get(get_key_str(INI_STR_SIMPLE_ASV), -1, s))!=NULL) \
  275.        sysinfo.asv.f = func (ss); \
  276.      else \
  277.        sysinfo.asv.f = d;}
  278.  
  279. #define NEL(s) (sizeof(s) / sizeof((s)[0]))
  280.  
  281.  
  282. static ini_flags_rec sysinfo_flags[] = {
  283.   {INI_STR_FORCE_FBACK,       0, OP_FLAGS_FORCE_NEWUSER_FEEDBACK},
  284.   {INI_STR_CHECK_DUP_PHONES,  0, OP_FLAGS_CHECK_DUPE_PHONENUM},
  285.   {INI_STR_HANGUP_DUP_PHONES, 0, OP_FLAGS_HANGUP_DUPE_PHONENUM},
  286.   {INI_STR_USE_SIMPLE_ASV,    0, OP_FLAGS_SIMPLE_ASV},
  287.   {INI_STR_POSTTIME_COMPENS,  0, OP_FLAGS_POSTTIME_COMPENSATE},
  288.   {INI_STR_SHOW_HIER,         0, OP_FLAGS_SHOW_HIER},
  289.   {INI_STR_IDZ_DESC,          0, OP_FLAGS_IDZ_DESC},
  290.   {INI_STR_SETLDATE,          0, OP_FLAGS_SETLDATE},
  291.   {INI_STR_NEW_CHATSOUND,     0, OP_FLAGS_NEW_CHATSOUND},
  292.   {INI_STR_SLASH_SZ,          0, OP_FLAGS_SLASH_SZ},
  293.   {INI_STR_READ_CD_IDZ,       0, OP_FLAGS_READ_CD_IDZ},
  294.   {INI_STR_FSED_EXT_DESC,     0, OP_FLAGS_FSED_EXT_DESC},
  295.   {INI_STR_FAST_TAG_RELIST,   0, OP_FLAGS_FAST_TAG_RELIST},
  296.   {INI_STR_MAIL_PROMPT,       0, OP_FLAGS_MAIL_PROMPT},
  297.   {INI_STR_SHOW_CITY_ST,      0, OP_FLAGS_SHOW_CITY_ST},
  298.   {INI_STR_NO_EASY_DL,        0, OP_FLAGS_NO_EASY_DL},
  299.   {INI_STR_NEW_EXTRACT,       0, OP_FLAGS_NEW_EXTRACT},
  300.   {INI_STR_FAST_SEARCH,       0, OP_FLAGS_FAST_SEARCH},
  301.   {INI_STR_NET_CALLOUT,       0, OP_FLAGS_NET_CALLOUT},
  302.   {INI_STR_WFC_SCREEN,        0, OP_FLAGS_WFC_SCREEN},
  303.   {INI_STR_FIDO_PROCESS,      0, OP_FLAGS_FIDO_PROCESS},
  304.   {INI_STR_USER_REGIST,       0, OP_FLAGS_USER_REGIST},
  305.   {INI_STR_MSG_TAG,           0, OP_FLAGS_MSG_TAG},
  306.   {INI_STR_CHAIN_REG,         0, OP_FLAGS_CHAIN_REG},
  307.   {INI_STR_CAN_SAVE_SSM,      0, OP_FLAGS_CAN_SAVE_SSM},
  308.   {INI_STR_PACKSCAN_FREQ,     0, OP_FLAGS_PACKSCAN_FREQ},
  309.   {INI_STR_EXTRA_COLOR,       0, OP_FLAGS_EXTRA_COLOR},
  310.   {INI_STR_RIP_SUPPORT,       0, OP_FLAGS_RIP_SUPPORT},
  311.   {INI_STR_RIPDRIVE_ON,       0, OP_FLAGS_RIPDRIVE_ON},
  312. };
  313.  
  314. static ini_flags_rec sysconfig_flags[] = {
  315.   {INI_STR_LOCAL_SYSOP,       1, sysconfig_no_local},
  316.   {INI_STR_2WAY_CHAT,         0, sysconfig_2_way},
  317.   {INI_STR_OFF_HOOK,          0, sysconfig_off_hook},
  318.   {INI_STR_PRINTER,           0, sysconfig_printer},
  319.   {INI_STR_LOG_DL,            0, sysconfig_log_dl},
  320.   {INI_STR_CLOSE_XFER,        0, sysconfig_no_xfer},
  321.   {INI_STR_ALL_UL_SYSOP,      0, sysconfig_all_sysop},
  322.   {INI_STR_BEEP_CHAT,         1, sysconfig_no_beep},
  323.   {INI_STR_TWO_COLOR_CHAT,    0, sysconfig_two_color},
  324.   {INI_STR_ALLOW_ALIASES,     1, sysconfig_no_alias},
  325.   {INI_STR_USE_LIST,          0, sysconfig_list},
  326.   {INI_STR_EXTENDED_USERINFO, 1, sysconfig_no_beep},
  327. };
  328.  
  329. /****************************************************************************/
  330. static void set_string(int key_idx, char *ptr, int len, int force)
  331. {
  332.   char *ss;
  333.  
  334.   ss=ini_get(get_key_str(key_idx), -1, NULL);
  335.  
  336.   if (force && !ss)
  337.     ss="";
  338.  
  339.   if (ss)
  340.     strncpy(ptr, ss, len);
  341. }
  342.  
  343. /****************************************************************************/
  344.  
  345. int read_ini_info(void)
  346. {
  347.   unsigned char s[81], *ss;
  348.   int i;
  349.   unsigned short omb, omc, omg;
  350.  
  351.   /* can't allow user to change these on-the-fly */
  352.   omb=sysinfo.max_batch;
  353.   omc=sysinfo.max_chains;
  354.   omg=sysinfo.max_gfilesec;
  355.  
  356.   /* clear out the struct */
  357.   memset(&sysinfo, 0, sizeof(system_operation_rec));
  358.  
  359.   /* Setup default sysinfo data */
  360.  
  361.   for (i=0; i<10; i++) {
  362.     sysinfo.newuser_colors[i]=nucol[i];
  363.     sysinfo.newuser_bwcolors[i]=nucolbw[i];
  364.   }
  365.  
  366.   sysinfo.topscreen_color=31;
  367.   sysinfo.f1_color=31;
  368.   sysinfo.editline_color=112;
  369.   sysinfo.chat_select_color=95;
  370.   sysinfo.msg_color=2;
  371.   sysinfo.max_batch=50;
  372.   sysinfo.max_extend_lines=10;
  373.   sysinfo.max_chains=50;
  374.   sysinfo.max_gfilesec=32;
  375.   sysinfo.mail_who_field_len=35;
  376.  
  377.   for (i=0; i<NEL(eventinfo); i++) {
  378.     sysinfo.spawn_opts[i]=eventinfo[i].eflags;
  379.   }
  380.  
  381.   /* put in default sysinfo.flags */
  382.   sysinfo.flags = OP_FLAGS_FIDO_PROCESS | OP_FLAGS_RIP_SUPPORT;
  383.  
  384.   if (ok_modem_stuff)
  385.     sysinfo.flags |= OP_FLAGS_NET_CALLOUT;
  386.   else
  387.     sysinfo.flags &= ~OP_FLAGS_NET_CALLOUT;
  388.  
  389.   /* open the string file for the .INI strings */
  390.   if (set_strings_fn(-(INI_STRFILE), syscfg.gfilesdir, "INI.STR", 0)) {
  391.     if (set_strings_fn(-(INI_STRFILE), languagedir, "INI.STR", 0)) {
  392.       if (set_strings_fn(-(INI_STRFILE), ".", "INI.STR", 0)) {
  393.         printf("WWIV.INI disabled; no INI.STR found\n");
  394.         return(1);
  395.       }
  396.     }
  397.   }
  398.  
  399.   /* initialize ini communication */
  400.   sprintf(s,"WWIV-%d",instance);
  401.   if (ini_init("WWIV.INI", s, "WWIV")==0) {
  402. /*
  403.  * DO NOT DO ANYTHING HERE WHICH ALLOCATES MEMORY
  404.  * the ini_init has allocated a lot of memory, and it will be freed
  405.  * by ini_done.  If you need to read anything here which will cause memory
  406.  * to be allocated, only store the size of the array here, and allocate it
  407.  * after ini_done.  Or, if necessary, call ini_done(), allocate the memory,
  408.  * then call ini_init again, and continue processing.
  409.  */
  410.  
  411.     /* found something */
  412.  
  413.     /* pull out event flags */
  414.     for (i=0; i<NEL(sysinfo.spawn_opts); i++) {
  415.       if (i<NEL(eventinfo)) {
  416.         INI_INIT_A_S(INI_STR_SPAWNOPT, i, spawn_opts, eventinfo[i].name);
  417.       } else {
  418.         INI_INIT_A_S(INI_STR_SPAWNOPT, i, spawn_opts, NULL);
  419.       }
  420.     }
  421.  
  422.     /* pull out newuser colors */
  423.     for (i=0; i<10; i++) {
  424.       INI_INIT_A(INI_STR_NUCOLOR,   i, newuser_colors, NULL);
  425.       INI_INIT_A(INI_STR_NUCOLORBW, i, newuser_bwcolors, NULL);
  426.     }
  427.  
  428.     /* pull out sysop-side colors */
  429.     INI_INIT(INI_STR_TOPCOLOR,      topscreen_color);
  430.     INI_INIT(INI_STR_F1COLOR,       f1_color);
  431.     INI_INIT(INI_STR_EDITLINECOLOR, editline_color);
  432.     INI_INIT(INI_STR_CHATSELCOLOR,  chat_select_color);
  433.  
  434.     /* pull out sizing options */
  435.     INI_INIT(INI_STR_MAX_BATCH,     max_batch);
  436.     INI_INIT(INI_STR_MAX_EXTEND_LINES,max_extend_lines);
  437.     INI_INIT(INI_STR_MAX_CHAINS,    max_chains);
  438.     INI_INIT(INI_STR_MAX_GFILESEC,  max_gfilesec);
  439.  
  440.     /* pull out strings */
  441.     INI_INIT_STR(INI_STR_TERMINAL_CMD,  terminal);
  442.     INI_INIT_STR(INI_STR_SYSTEMNAME,    systemname);
  443.     INI_INIT_STR(INI_STR_SYSTEMPHONE,   systemphone);
  444.     INI_INIT_STR(INI_STR_SYSOPNAME,     sysopname);
  445.     INI_INIT_STR(INI_STR_EXECUTE_CMD,   executestr);
  446.     INI_INIT_STR(INI_STR_UPLOAD_CMD,    upload_c);
  447.     INI_INIT_STR(INI_STR_BEGINDAY_CMD,  beginday_c);
  448.     INI_INIT_STR(INI_STR_NEWUSER_CMD,   newuser_c);
  449.     INI_INIT_STR(INI_STR_LOGON_CMD,     logon_c);
  450.  
  451.  
  452.     set_string(INI_STR_RIP_BBS_ID, sysinfo.ripbbsid, sizeof(sysinfo.ripbbsid), 0);
  453.     set_string(INI_STR_RIP_MENU_DATE, sysinfo.ripmenudate, sizeof(sysinfo.ripmenudate), 0);
  454.     INI_INIT_N(INI_STR_RIP_ADJUST, rip_rm_adjust);
  455.  
  456.     /* pull out sysinfo flags */
  457.     sysinfo.flags = ini_flags('Y', get_key_str, sysinfo_flags,
  458.                               NEL(sysinfo_flags), sysinfo.flags);
  459.  
  460.  
  461.     /* allow override of msg_color
  462.     INI_INIT(INI_STR_MSG_COLOR,     msg_color);
  463.  
  464.     /* get asv values */
  465.     INI_GET_ASV("SL", sl, atoi, syscfg.autoval[9].sl);
  466.     INI_GET_ASV("DSL", dsl, atoi, syscfg.autoval[9].dsl);
  467.     INI_GET_ASV("EXEMPT", exempt, atoi, 0);
  468.     INI_GET_ASV("AR", ar, str_to_arword, syscfg.autoval[9].ar);
  469.     INI_GET_ASV("DAR", dar, str_to_arword, syscfg.autoval[9].dar);
  470.     INI_GET_ASV("RESTRICT", restrict, str2restrict, 0);
  471.  
  472.     /* sysconfig flags */
  473.     syscfg.sysconfig = ini_flags('Y', get_key_str, sysconfig_flags,
  474.                                  NEL(sysconfig_flags), syscfg.sysconfig);
  475.  
  476.     /* misc stuff */
  477.     if (((ss=ini_get(get_key_str(INI_STR_MAIL_WHO_LEN), -1, NULL))!=NULL) &&
  478.         ((atoi(ss)>0) || (ss[0]=='0')))
  479.       sysinfo.mail_who_field_len = atoi(ss);
  480.     if ((ss=ini_get(get_key_str(INI_STR_RATIO), -1, NULL))!=NULL)
  481.       syscfg.req_ratio = atof(ss);
  482.  
  483.     INI_INIT_N(INI_STR_SCREEN_SAVER_TIME, screen_saver_time);
  484.  
  485.     /* now done */
  486.     ini_done();
  487.   }
  488.  
  489.   if (sysinfo.max_extend_lines>99)
  490.     sysinfo.max_extend_lines=99;
  491.   if (sysinfo.max_batch>999)
  492.     sysinfo.max_batch=999;
  493.   if (sysinfo.max_chains>999)
  494.     sysinfo.max_chains=999;
  495.   if (sysinfo.max_gfilesec>999)
  496.     sysinfo.max_gfilesec=999;
  497.  
  498.   if (omb)
  499.     sysinfo.max_batch=omb;
  500.   if (omc)
  501.     sysinfo.max_chains=omc;
  502.   if (omg)
  503.     sysinfo.max_gfilesec=omg;
  504.  
  505.  
  506.   set_strings_fn(INI_STRFILE, NULL, NULL, 0);
  507.  
  508.   /* Success if here */
  509.   return(1);
  510. }
  511.  
  512. /****************************************************************************/
  513.  
  514. int read_config(void)
  515. {
  516.   int f,i;
  517.  
  518.   f=sh_open1("CONFIG.DAT",O_RDONLY | O_BINARY);
  519.   if (f<0) {
  520.     printf("CONFIG.DAT NOT FOUND.\n");
  521.     return(1);
  522.   }
  523.   sh_read(f,(void *) (&syscfg), sizeof(configrec));
  524.   sh_close(f);
  525.  
  526.   f=sh_open1("CONFIG.OVR", O_RDONLY|O_BINARY);
  527.   if ((f>0) && (filelength(f) < (long)instance*(long)sizeof(configoverrec))) {
  528.     f=sh_close(f);
  529.     printf("Not enough instances configured.\n");
  530.     end_bbs(noklevel);
  531.   }
  532.   if (f<0) {
  533.     /* slap in the defaults */
  534.     for (i=0; i<4; i++) {
  535.       syscfgovr.com_ISR[i+1]=syscfg.com_ISR[i+1];
  536.       syscfgovr.com_base[i+1]=syscfg.com_base[i+1];
  537.       syscfgovr.com_ISR[i+5]=syscfg.com_ISR[i+1];
  538.       syscfgovr.com_base[i+5]=syscfg.com_base[i+1];
  539.     }
  540.     syscfgovr.primaryport=syscfg.primaryport;
  541.     strcpy(syscfgovr.modem_type, syscfg.modem_type);
  542.     strcpy(syscfgovr.tempdir, syscfg.tempdir);
  543.     strcpy(syscfgovr.batchdir, syscfg.batchdir);
  544.     if (syscfg.sysconfig & sysconfig_high_speed)
  545.       syscfgovr.comflags |= comflags_buffered_uart;
  546.   } else {
  547.     lseek(f, (instance-1)*sizeof(configoverrec), SEEK_SET);
  548.     read(f, &syscfgovr, sizeof(configoverrec));
  549.     sh_close(f);
  550.   }
  551.   return(0);
  552. }
  553.  
  554. /****************************************************************************/
  555.  
  556. int save_config(void)
  557. {
  558.   int f;
  559.  
  560.   f=sh_open1("CONFIG.DAT",O_RDWR | O_BINARY);
  561.   if (f>0) {
  562.     sh_write(f,(void *) (&syscfg), sizeof(configrec));
  563.     sh_close(f);
  564.     return(0);
  565.   }
  566.   return(1);
  567. }
  568.  
  569. /****************************************************************************/
  570.  
  571. void read_nextern(void)
  572. {
  573.   int f;
  574.   char s[81];
  575.   long l;
  576.  
  577.   if (externs)
  578.     bbsfree(externs);
  579.   externs=NULL;
  580.  
  581.   sprintf(s,"%sNEXTERN.DAT",syscfg.datadir);
  582.   f=sh_open1(s,O_RDONLY | O_BINARY);
  583.   if (f>0) {
  584.     l=filelength(f);
  585.     if (l>15*sizeof(newexternalrec))
  586.       l=15*sizeof(newexternalrec);
  587.     externs=mallocx(l+10, "external protocols");
  588.     numextrn=(sh_read(f,(void *)externs, (unsigned) l))/sizeof(newexternalrec);
  589.     sh_close(f);
  590.   } else
  591.     numextrn=0;
  592. }
  593.  
  594. /****************************************************************************/
  595.  
  596. void read_editors(void)
  597. {
  598.   int f;
  599.   char s[81];
  600.   long l;
  601.  
  602.   if (editors)
  603.     bbsfree(editors);
  604.   editors=NULL;
  605.   sprintf(s,"%sEDITORS.DAT",syscfg.datadir);
  606.   f=sh_open1(s,O_RDONLY | O_BINARY);
  607.   if (f>0) {
  608.     l=filelength(f);
  609.     if (l>10*sizeof(editorrec))
  610.       l=10*sizeof(editorrec);
  611.     editors=mallocx(l+10, "external editors");
  612.     numed=(sh_read(f,(void *)editors, (unsigned) l))/sizeof(editorrec);
  613.     sh_close(f);
  614.   }
  615. }
  616.  
  617. /****************************************************************************/
  618.  
  619. void read_nintern(void)
  620. {
  621.   int f;
  622.   char s[81];
  623.  
  624.   if (over_intern)
  625.     bbsfree(over_intern);
  626.   over_intern=NULL;
  627.   sprintf(s,"%sNINTERN.DAT",syscfg.datadir);
  628.   f=sh_open1(s,O_RDONLY|O_BINARY);
  629.   if (f>0) {
  630.     over_intern=mallocx(3*sizeof(newexternalrec),"internal protocol overrides");
  631.     sh_read(f,over_intern, 3*sizeof(newexternalrec));
  632.     sh_close(f);
  633.   }
  634. }
  635.  
  636. /****************************************************************************/
  637.  
  638. int read_subs(void)
  639. {
  640.   int f;
  641.   char s[81];
  642.  
  643.   if (subboards)
  644.     bbsfree(subboards);
  645.   subboards=NULL;
  646.   max_subs=syscfg.max_subs;
  647.   subboards=(subboardrec *) mallocx(max_subs*sizeof(subboardrec), "subboards");
  648.   sprintf(s,"%sSUBS.DAT",syscfg.datadir);
  649.   f=sh_open1(s,O_RDONLY | O_BINARY);
  650.   if (f<0) {
  651.     printf("%s NOT FOUND.\n",s);
  652.     return(1);
  653.   }
  654.   num_subs=(sh_read(f,subboards, (max_subs*sizeof(subboardrec))))/
  655.     sizeof(subboardrec);
  656.   f=sh_close(f);
  657.   return(read_subs_xtr(max_subs, num_subs, subboards));
  658. }
  659.  
  660. /****************************************************************************/
  661.  
  662. void read_networks(void)
  663. {
  664.   int f,i;
  665.   char s[81],*ss;
  666.  
  667.   if (net_networks)
  668.     bbsfree(net_networks);
  669.   net_networks=NULL;
  670.   sprintf(s,"%sNETWORKS.DAT", syscfg.datadir);
  671.   f=sh_open1(s,O_RDONLY|O_BINARY);
  672.   if (f>0) {
  673.     net_num_max=filelength(f)/sizeof(net_networks_rec);
  674.     if (net_num_max) {
  675.       net_networks=mallocx(net_num_max*sizeof(net_networks_rec),"networks.dat");
  676.       sh_read(f, net_networks, net_num_max*sizeof(net_networks_rec));
  677.     }
  678.     sh_close(f);
  679.     for (i=0; i<net_num_max; i++) {
  680.       ss=strchr(net_networks[i].name, ' ');
  681.       if (ss)
  682.         *ss=0;
  683.     }
  684.   }
  685.   if (!net_networks) {
  686.     net_networks=mallocx(sizeof(net_networks_rec), "networks.dat");
  687.     net_num_max=1;
  688.     strcpy(net_networks->name,"WWIVnet");
  689.     strcpy(net_networks->dir, syscfg.datadir);
  690.     net_networks->sysnum=syscfg.systemnumber;
  691.   }
  692. }
  693.  
  694. /****************************************************************************/
  695.  
  696. int read_names(void)
  697. {
  698.   int f;
  699.   char s[81];
  700.  
  701.   if (smallist)
  702.     bbsfree((void *)smallist);
  703.   smallist=NULL;
  704.   smallist=(smalrec *) mallocx(((long)syscfg.maxusers) * ((long)sizeof(smalrec)),
  705.                                "names.lst - try decreasing max users in INIT");
  706.   sprintf(s,"%sNAMES.LST",syscfg.datadir);
  707.   f=sh_open1(s,O_RDONLY | O_BINARY);
  708.   if (f<0) {
  709.     printf("%s NOT FOUND.\n",s);
  710.     return(1);
  711.   }
  712.   huge_xfer(f, smallist, sizeof(smalrec), status.users, 0);
  713.   sh_close(f);
  714.   read_status();
  715.   return(0);
  716. }
  717.  
  718. /****************************************************************************/
  719.  
  720. void read_voting(void)
  721. {
  722.   int f,n,i;
  723.   char s[81];
  724.   votingrec v;
  725.  
  726.   for (i=0; i<20; i++)
  727.     questused[i]=0;
  728.   sprintf(s,"%sVOTING.DAT",syscfg.datadir);
  729.   f=sh_open1(s,O_RDONLY | O_BINARY);
  730.   if (f>0) {
  731.     n=(int) (filelength(f) / sizeof(votingrec)) -1;
  732.     for (i=0; i<n; i++) {
  733.       sh_lseek(f,(long) i * sizeof(votingrec),SEEK_SET);
  734.       sh_read(f,(void *)&v,sizeof(votingrec));
  735.       if (v.numanswers)
  736.         questused[i]=1;
  737.     }
  738.     f=sh_close(f);
  739.   }
  740. }
  741.  
  742. /****************************************************************************/
  743.  
  744. int read_dirs(void)
  745. {
  746.   int f;
  747.   char s[81];
  748.  
  749.   if (directories)
  750.     bbsfree((void *)directories);
  751.   directories=NULL;
  752.   max_dirs=syscfg.max_dirs;
  753.   directories=(directoryrec huge *)mallocx(((long)max_dirs)*((long)sizeof(directoryrec)),
  754.     "directories");
  755.   sprintf(s,"%sDIRS.DAT",syscfg.datadir);
  756.   f=sh_open1(s,O_RDONLY | O_BINARY);
  757.   if (f<0) {
  758.     printf("%s NOT FOUND.\n",s);
  759.     return(1);
  760.   }
  761.   num_dirs=huge_xfer(f, directories, sizeof(directoryrec), max_dirs, 0) /
  762.     sizeof(directoryrec);
  763.   sh_close(f);
  764.   return(0);
  765. }
  766.  
  767. /****************************************************************************/
  768.  
  769. void read_chains(void)
  770. {
  771.   int f,i,i1;
  772.   char s[81];
  773.  
  774.   if (chains)
  775.     bbsfree(chains);
  776.   chains=NULL;
  777.   chains=(chainfilerec *) mallocx(sysinfo.max_chains* sizeof(chainfilerec), "chains");
  778.   sprintf(s,"%sCHAINS.DAT",syscfg.datadir);
  779.   f=sh_open1(s,O_RDONLY | O_BINARY);
  780.   if (f>0) {
  781.     numchain=(sh_read(f,(void *)chains, sysinfo.max_chains*sizeof(chainfilerec)))/
  782.       sizeof(chainfilerec);
  783.     numchain=numchain;
  784.   }
  785.   sh_close(f);
  786.   if (sysinfo.flags & OP_FLAGS_CHAIN_REG) {
  787.     if (chains_reg)
  788.       bbsfree(chains_reg);
  789.     chains_reg=NULL;
  790.     chains_reg=(chainregrec *) mallocx(sysinfo.max_chains* sizeof(chainregrec),
  791.       "chain registration");
  792.     sprintf(s,"%sCHAINS.REG",syscfg.datadir);
  793.     f=sh_open1(s,O_RDONLY | O_BINARY);
  794.     if (f>0) {
  795.       sh_read(f,(void *)chains_reg, sysinfo.max_chains*sizeof(chainregrec));
  796.     } else {
  797.       for(i=0;i<numchain;i++) {
  798.         for (i1=0; i1<sizeof(chains_reg[i].regby)/sizeof(chains_reg[i].regby[0]); i1++)
  799.           chains_reg[i].regby[i1]=0;
  800.         chains_reg[i].usage=0;
  801.         chains_reg[i].minage=0;
  802.         chains_reg[i].maxage=255;
  803.       }
  804.       f=sh_open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  805.       sh_write(f,(void *) (chains_reg), (sizeof(chainregrec) * numchain));
  806.     }
  807.     sh_close(f);
  808.   }
  809. }
  810.  
  811. /****************************************************************************/
  812.  
  813. int read_language(void)
  814. {
  815.   int f;
  816.   char s[81];
  817.  
  818.   if (languages)
  819.     bbsfree(languages);
  820.   languages=NULL;
  821.   sprintf(s,"%sLANGUAGE.DAT",syscfg.datadir);
  822.   f=sh_open1(s,O_RDONLY|O_BINARY);
  823.   if (f>=0) {
  824.     num_languages=filelength(f)/sizeof(languagerec);
  825.     if (num_languages) {
  826.       languages=mallocx(num_languages*sizeof(languagerec),"language.dat");
  827.       sh_read(f,languages,num_languages*sizeof(languagerec));
  828.     }
  829.     sh_close(f);
  830.   }
  831.   if (!num_languages) {
  832.     languages=mallocx(sizeof(languagerec),"language.dat");
  833.     num_languages=1;
  834.     strcpy(languages->name,"English");
  835.     strncpy(languages->dir,syscfg.gfilesdir, sizeof(languages->dir)-1);
  836.   }
  837.   cur_lang=-1;
  838.   if (set_language(0)) {
  839.     printf("You need the default language fully installed to run the BBS.\n");
  840.     return(1);
  841.   }
  842.   return(0);
  843. }
  844.  
  845. /****************************************************************************/
  846.  
  847. int read_modem(void)
  848. {
  849.   int f;
  850.   char s[81];
  851.   long l;
  852.  
  853.   if (modem_i)
  854.     bbsfree(modem_i);
  855.   modem_i=NULL;
  856.   if (!ok_modem_stuff)
  857.     return(0);
  858.   if (instance > 1)
  859.     sprintf(s,"%sMODEM.%3.3d",syscfg.datadir,instance);
  860.   else
  861.     sprintf(s,"%sMODEM.DAT",syscfg.datadir);
  862.   f=sh_open1(s,O_RDONLY | O_BINARY);
  863.   if (f>0) {
  864.     l=filelength(f);
  865.     modem_i = mallocx(l, "modem.dat");
  866.     sh_read(f,modem_i, (unsigned) l);
  867.     sh_close(f);
  868.     return(0);
  869.   } else {
  870.     printf("\nRun INIT.EXE to convert modem data.\n\n");
  871.     return(1);
  872.   }
  873. }
  874.  
  875. /****************************************************************************/
  876.  
  877. void read_gfile(void)
  878. {
  879.   int f;
  880.   char s[81];
  881.  
  882.   if (gfilesec)
  883.     bbsfree(gfilesec);
  884.   gfilesec=NULL;
  885.   gfilesec=(gfiledirrec *) mallocx((long) (sysinfo.max_gfilesec* sizeof(gfiledirrec)), "gfiles");
  886.   sprintf(s,"%sGFILE.DAT",syscfg.datadir);
  887.   f=sh_open1(s,O_RDONLY | O_BINARY);
  888.   if (f<0)
  889.     num_sec=0;
  890.   else
  891.     num_sec=sh_read(f,(void *)gfilesec,sysinfo.max_gfilesec*sizeof(gfiledirrec))/sizeof(gfiledirrec);
  892.   sh_close(f);
  893. }
  894.  
  895. /****************************************************************************/
  896.  
  897. int make_abs_path(unsigned char *checkdir)
  898. /*
  899.  * Makes a path into an absolute path, returns 1 if original path altered,
  900.  * else returns 0.
  901.  */
  902. {
  903.   unsigned char olddir[81];
  904.  
  905.   if ((strlen(checkdir)<3) || (checkdir[1]!=':') || (checkdir[2]!='\\')) {
  906.     get_dir(olddir,1);
  907.     cd_to(cdir);
  908.     cd_to(checkdir);
  909.     get_dir(checkdir, 1);
  910.     cd_to(olddir);
  911.     return(1);
  912.   }
  913.   return(0);
  914. }
  915.  
  916. /****************************************************************************/
  917.  
  918. void fix_paths(void)
  919. /*
  920.  * Makes relative paths into absolute paths. Can solve some hard-to-find
  921.  * problems.
  922.  */
  923. {
  924.   int f=-1, update=0;
  925.  
  926.   /* config.dat paths */
  927.   if (make_abs_path(syscfg.gfilesdir))
  928.     update|=1;
  929.   if (make_abs_path(syscfg.datadir))
  930.     update|=1;
  931.   if (make_abs_path(syscfg.msgsdir))
  932.     update|=1;
  933.   if (make_abs_path(syscfg.dloadsdir))
  934.     update|=1;
  935.  
  936.   /* config.ovr paths */
  937.   if (make_abs_path(syscfgovr.tempdir)) {
  938.     if (instance==1) {
  939.       strncpy(syscfg.tempdir,syscfgovr.tempdir,sizeof(syscfg.tempdir));
  940.       update|=1;
  941.     }
  942.     update|=2;
  943.   }
  944.   if (make_abs_path(syscfgovr.batchdir)) {
  945.     if (instance==1) {
  946.       strncpy(syscfg.batchdir,syscfgovr.batchdir,sizeof(syscfg.batchdir));
  947.       update|=1;
  948.     }
  949.     update|=2;
  950.   }
  951.  
  952.   if (update&1) {
  953.     save_config();
  954.   }
  955.   if (update&2) {
  956.     f=sh_open1("CONFIG.OVR", O_RDWR|O_BINARY);
  957.     if ((f<0) || (filelength(f) < (long)instance*(long)sizeof(configoverrec)))
  958.       f=sh_close(f);
  959.     else {
  960.       lseek(f, (instance-1)*sizeof(configoverrec), SEEK_SET);
  961.       write(f, &syscfgovr, sizeof(configoverrec));
  962.       sh_close(f);
  963.     }
  964.   }
  965. }
  966.  
  967. /****************************************************************************/
  968.  
  969. void init(void)
  970. {
  971.   char *ss,s[161];
  972.   int i,i1,sm;
  973.   int f1,f2,f3,f4,f5,f6,f7, pk;
  974. #ifndef __OS2__
  975.   union REGS r;
  976. #endif
  977.   struct date today;
  978.  
  979.  
  980. #ifdef __OS2__
  981.   VIOMODEINFO vmi;
  982.  
  983.   VioGetMode(&vmi, 0);
  984.   if (vmi.fbType & 0x02)
  985.     {
  986.       printf("\n\nYou must be in text mode to run WWIV.\n\n");
  987.       end_bbs(noklevel);
  988.     }
  989.   if (vmi.col != ((USHORT)80))
  990.     {
  991.       printf("%u\n\nYou must be in 80 column mode to run WWIV.\n\n", (unsigned int)vmi.col);
  992.       end_bbs(noklevel);
  993.     }
  994.   if ((!(vmi.fbType & 0x01)) || (vmi.color < 255))
  995.     crttype = 7;
  996.   else
  997.     crttype = 0;
  998.   defscreenbottom = vmi.row - 1;
  999. #else
  1000.   save_dos=find_interrupt();
  1001.   if (!save_dos) {
  1002.     printf("\nNo spare interrupt vector found to use.\n\n");
  1003.     end_bbs(noklevel);
  1004.   }
  1005.   crttype=peekb(0x0040,0x0049);
  1006.   if (crttype==7)
  1007.     scrn=MK_FP(0xb000,0x0000);
  1008.   else
  1009.     scrn=MK_FP(0xb800,0x0000);
  1010.  
  1011.   detect_multitask();
  1012.  
  1013.   r.h.ah=15;
  1014.   int86(0x10,&r,&r);
  1015.   sm=r.h.al;
  1016.   if (r.h.ah!=80) {
  1017.     printf("\n\nYou must be in 80 column mode to run WWIV.\n\n");
  1018.     end_bbs(noklevel);
  1019.   }
  1020.   if ((sm==4) || (sm==5) || (sm==6)) {
  1021.     printf("\n\nYou must be in text mode to run WWIV.\n\n");
  1022.     end_bbs(noklevel);
  1023.   }
  1024.   defscreenbottom=(int) peekb(0x0000,0x0484);
  1025.   if (defscreenbottom<24)
  1026.     defscreenbottom=24;
  1027.   if (defscreenbottom>63)
  1028.     defscreenbottom=24;
  1029.   if ((defscreenbottom!=42) && (defscreenbottom!=49))
  1030.     defscreenbottom=24;
  1031. #endif
  1032.   screenbottom=defscreenbottom;
  1033.   screenlen=160*(screenbottom+1);
  1034.   if (instance > 1)
  1035.     sprintf(s,"RESTORE.%3.3d",instance);
  1036.   else
  1037.     sprintf(s,"RESTORE.WWV");
  1038.   if (!exist(s)) {
  1039.     for (i=0; i<screenbottom; i++)
  1040.       printf("\n");
  1041.     strcpy(s,wwiv_version);
  1042.     strcat(s,", Copyright (c) 1988-1995 by Wayne Bell.\n\n");
  1043.     printf(s);
  1044.   }
  1045.   strcpy(cdir,"X:\\");
  1046.   cdir[0]='A'+getdisk();
  1047.   getcurdir(0,&(cdir[3]));
  1048.  
  1049.  
  1050. #ifdef EMS_XMS
  1051.   if (_OvrInitEms(0,0,16)!=0)
  1052.     _OvrInitExt(0L,0);
  1053. #endif
  1054.  
  1055.   curlsub=-1;
  1056.   curldir=-1;
  1057. #ifndef __OS2__
  1058.   setvect(save_dos, getvect(INT_REAL_DOS));
  1059. #endif
  1060.   oldx=0;
  1061.   oldy=0;
  1062. #ifndef __OS2__
  1063.   itimer();
  1064.   r.h.ah=0x33;
  1065.   r.h.al=0x01;
  1066.   r.h.dl=0x00;
  1067.   int86(INT_REAL_DOS,&r,&r);
  1068. #endif
  1069.   use_workspace=0;
  1070.   input_extern=0;
  1071.   chat_file=0;
  1072.   sysop_alert=0;
  1073.   global_handle=0;
  1074.   tagptr=0;
  1075.  
  1076.   for (i=0; i<25; i++)
  1077.     funcs[i]=NULL;
  1078. #ifndef __OS2__
  1079.   funcs[0]=(void far *)inlii;
  1080.   funcs[1]=(void far *)checkai;
  1081.   funcs[2]=(void far *)plai;
  1082.   funcs[3]=(void far *)outchri;
  1083.   funcs[4]=(void far *)outstri;
  1084.   funcs[5]=(void far *)nli;
  1085.   funcs[8]=(void far *)pli;
  1086.   funcs[9]=(void far *)emptyi;
  1087.   funcs[10]=(void far *)inkeyi;
  1088.   funcs[11]=(void far *)getkeyi;
  1089.   funcs[12]=(void far *)inputi;
  1090.   funcs[13]=(void far *)inputli;
  1091.   funcs[14]=(void far *)yni;
  1092.   funcs[15]=(void far *)nyi;
  1093.   funcs[16]=(void far *)ansici;
  1094.   funcs[17]=(void far *)oneki;
  1095.   funcs[18]=(void far *)prti;
  1096.   funcs[19]=(void far *)mpli;
  1097.   sprintf(ver_no2,"WWIV_FP=%04.4X:%04.4X",FP_SEG(funcs), FP_OFF(funcs));
  1098. #else
  1099.   strcpy(ver_no2, "WWIV_FP=0000:0000");
  1100. #endif
  1101.  
  1102.   strcpy(ver_no1,"BBS=");
  1103.   strcat(ver_no1,wwiv_version);
  1104.  
  1105.   getdate(&today);
  1106.   if (today.da_year<1988) {
  1107.     printf("You need to set the date & time before running the BBS.\n");
  1108.     end_bbs(noklevel);
  1109.   }
  1110.  
  1111.   if (read_config())
  1112.     end_bbs(noklevel);
  1113.  
  1114.   strcpy(s,syscfgovr.tempdir);
  1115.   i=strlen(s);
  1116.   if (s[0]==0)
  1117.     i1=1;
  1118.   else {
  1119.     if ((s[i-1]=='\\') && (s[i-2]!=':'))
  1120.       s[i-1]=0;
  1121.     i1=chdir(s);
  1122.   }
  1123.   if (i1) {
  1124.     printf("\nYour temp dir isn't valid.\n");
  1125.     printf("It is now set to: '%s'\n\n",syscfgovr.tempdir);
  1126.     end_bbs(noklevel);
  1127.   } else
  1128.     cd_to(cdir);
  1129.  
  1130.   strcpy(s,syscfgovr.batchdir);
  1131.   i=strlen(s);
  1132.   if (s[0]==0)
  1133.     i1=1;
  1134.   else {
  1135.     if ((s[i-1]=='\\') && (s[i-2]!=':'))
  1136.       s[i-1]=0;
  1137.     i1=chdir(s);
  1138.   }
  1139.   if (i1) {
  1140.     printf("\nYour batch dir isn't valid.\n");
  1141.     printf("It is now set to: '%s'\n\n",syscfgovr.batchdir);
  1142.     end_bbs(noklevel);
  1143.   } else
  1144.     cd_to(cdir);
  1145.  
  1146. #ifdef __OS2__
  1147.   stdprn = NULL;
  1148.   if (syscfg.sysconfig & sysconfig_printer)
  1149.     if ((stdprn = fopen("PRN", "wt")) == NULL)
  1150.       {
  1151.       printf("\nCannot open PRN device for output.\n");
  1152.       end_bbs(noklevel);
  1153.       }
  1154. #endif
  1155.  
  1156.  
  1157.   fix_paths();
  1158.  
  1159.   write_inst(INST_LOC_INIT,0,INST_FLAGS_NONE);
  1160.  
  1161.   /* make sure it is the new userrec structure */
  1162.   sprintf(s,"%sUSER.QSC",syscfg.datadir);
  1163.   if (!exist(s)) {
  1164.     printf("You must go into INIT and convert your userlist before running the BBS.\n");
  1165.     end_bbs(noklevel);
  1166.   }
  1167.  
  1168.   /* update user info data */
  1169.   f1=sizeof(userrec);
  1170.   f2=OFFOF(waiting);
  1171.   f3=OFFOF(inact);
  1172.   f4=OFFOF(sysstatus);
  1173.   f5=OFFOF(forwardusr);
  1174.   f6=OFFOF(forwardsys);
  1175.   f7=OFFOF(net_num);
  1176.  
  1177.   if ((f1!=syscfg.userreclen) ||
  1178.       (f2!=syscfg.waitingoffset) ||
  1179.       (f3!=syscfg.inactoffset) ||
  1180.       (f4!=syscfg.sysstatusoffset) ||
  1181.       (f5!=syscfg.fuoffset) ||
  1182.       (f6!=syscfg.fsoffset) ||
  1183.       (f7!=syscfg.fnoffset)) {
  1184.  
  1185.     syscfg.userreclen=f1;
  1186.     syscfg.waitingoffset=f2;
  1187.     syscfg.inactoffset=f3;
  1188.     syscfg.sysstatusoffset=f4;
  1189.     syscfg.fuoffset=f5;
  1190.     syscfg.fsoffset=f6;
  1191.     syscfg.fnoffset=f7;
  1192.  
  1193.     /* store the new config.dat file */
  1194.     save_config();
  1195.   }
  1196.  
  1197.   if (!syscfgovr.primaryport)
  1198.     ok_modem_stuff=0;
  1199.  
  1200.   languages=NULL;
  1201.   if (read_language())
  1202.     end_bbs(noklevel);
  1203.  
  1204.   if (!read_ini_info()) {
  1205.     printf("Insufficient memory for system info structure.\n");
  1206.     end_bbs(noklevel);
  1207.   }
  1208.  
  1209.   net_networks=NULL;
  1210.   net_num=0;
  1211.   read_networks();
  1212.   set_net_num(0);
  1213.  
  1214.  
  1215.   get_status(0, 1);
  1216.  
  1217.   status.wwiv_version=wwiv_num_version;
  1218.   if (status.callernum!=65535) {
  1219.     status.callernum1=(long)status.callernum;
  1220.     status.callernum=65535;
  1221.   }
  1222.   save_status();
  1223.  
  1224.   gat=(unsigned short *) mallocx(2048 * sizeof(short), "gat");
  1225.  
  1226.   gfilesec=NULL;
  1227.   read_gfile();
  1228.  
  1229.   smallist=NULL;
  1230.  
  1231.   if (read_names())
  1232.     end_bbs(noklevel);
  1233.  
  1234.   subboards=NULL;
  1235.  
  1236.   if (read_subs())
  1237.     end_bbs(noklevel);
  1238.  
  1239.   directories=NULL;
  1240.  
  1241.   if (read_dirs())
  1242.     end_bbs(noklevel);
  1243.  
  1244.   numchain=0;
  1245.   chains=NULL;
  1246.   read_chains();
  1247.  
  1248.   modem_i=NULL;
  1249.   if (read_modem())
  1250.     end_bbs(noklevel);
  1251.  
  1252.   numextrn=0;
  1253.   externs=NULL;
  1254.   read_nextern();
  1255.  
  1256.   over_intern=NULL;
  1257.   read_nintern();
  1258.  
  1259.   numed=0;
  1260.   editors=NULL;
  1261.   read_editors();
  1262.  
  1263.   /* allocate sub cache */
  1264.   iscan1(-1, 0);
  1265.  
  1266.   batch=mallocx(sysinfo.max_batch * sizeof(batchrec), "batch list");
  1267.  
  1268.   read_user(1,&thisuser);
  1269.   if (thisuser.inact & inact_deleted)
  1270.     fwaiting=0;
  1271.   else
  1272.     fwaiting=thisuser.waiting;
  1273.  
  1274.   read_status();
  1275.   if (ok_modem_stuff && !restoring_shrink) {
  1276.     initport(syscfgovr.primaryport);
  1277.     do_result(&(modem_i->defl));
  1278.   }
  1279.   if (syscfg.sysconfig & sysconfig_no_local)
  1280.     topdata=0;
  1281.   else
  1282.     topdata=2;
  1283.   ss=getenv("PROMPT");
  1284.   strcpy(newprompt,"PROMPT=WWIV: ");
  1285.   if (ss)
  1286.     strcat(newprompt,ss);
  1287.   else
  1288.     strcat(newprompt,"$P$G");
  1289.   if (instance > 1)
  1290.     sprintf(dszlog,"%s\\WWIVDSZ.%3.3d",cdir,instance);
  1291.   else
  1292.     sprintf(dszlog,"%s\\WWIVDSZ.LOG",cdir);
  1293.   sprintf(s,"DSZLOG=%s",dszlog);
  1294.   pk=i=i1=0;
  1295.   while (environ[i]!=NULL) {
  1296.     if (strncmp(environ[i],"PKNOFASTCHAR=",13)==0)
  1297.       pk=1;
  1298.     if (strncmp(environ[i],"PROMPT=",7)==0)
  1299.       xenviron[i1++]=newprompt;
  1300.     else
  1301.       if (strncmp(environ[i],"DSZLOG=",7)==0)
  1302.         xenviron[i1++]=strdup(s);
  1303.       else {
  1304.         if ((strncmp(environ[i],"BBS=",4)) &&
  1305.             (strncmp(environ[i],"WWIV_FP=",8)) &&
  1306.             (strncmp(environ[i],"WWIV_NET=",8)))
  1307.           xenviron[i1++]=environ[i];
  1308.       }
  1309.     ++i;
  1310.   }
  1311.   if (!getenv("DSZLOG"))
  1312.     xenviron[i1++]=strdup(s);
  1313.   if (!ss)
  1314.     xenviron[i1++]=newprompt;
  1315.   xenviron[i1++]=ver_no1;
  1316.   xenviron[i1++]=ver_no2;
  1317.   xenviron[i1++]=wwiv_net_no;
  1318.   if (!pk)
  1319.     xenviron[i1++]="PKNOFASTCHAR=Y";
  1320.   xenviron[i1]=NULL;
  1321.  
  1322.   read_voting();
  1323.  
  1324.   if (syscfgovr.comflags & comflags_buffered_uart)
  1325.     high_speed=1;
  1326.   else
  1327.     high_speed=0;
  1328.   time_event=((double)syscfg.executetime)*60.0;
  1329.   last_time=time_event-timer();
  1330.   if (last_time<0.0)
  1331.     last_time+=24.0*3600.0;
  1332.   do_event=0;
  1333.   usub=(usersubrec *)mallocx(max_subs*sizeof(usersubrec), "usub");
  1334.   sub_dates=(unsigned long *) mallocx(max_subs*sizeof(long),"sub_dates");
  1335.  
  1336.   udir=(usersubrec *)mallocx(max_dirs*sizeof(usersubrec), "udir");
  1337.   dir_dates=(unsigned long *) mallocx(max_dirs*sizeof(long),"dir_dates");
  1338.  
  1339.   uconfsub=(userconfrec *)mallocx(MAX_CONFERENCES*sizeof(userconfrec), "uconfsub");
  1340.   uconfdir=(userconfrec *)mallocx(MAX_CONFERENCES*sizeof(userconfrec), "uconfdir");
  1341.  
  1342.   qsc=(unsigned long *)mallocx(syscfg.qscn_len, "quickscan");
  1343.   qsc_n=qsc+1;
  1344.   qsc_q=qsc_n+(max_dirs+31)/32;
  1345.   qsc_p=qsc_q+(max_subs+31)/32;
  1346.  
  1347.   ss=getenv("WWIV_INSTANCE");
  1348.   if (ss) {
  1349.     i=atoi(ss);
  1350.     if (i>0)
  1351.       sprintf(nete,".%3.3d",i);
  1352.     else
  1353.       strcpy(nete,".NET");
  1354.   } else {
  1355.     strcpy(nete,".NET");
  1356.   }
  1357.  
  1358.   read_bbs_list_index();
  1359.   frequent_init();
  1360.   if (!restoring_shrink && !already_on) {
  1361.     tmp_disable_pause(1);
  1362.     remove_from_temp("*.*", syscfgovr.tempdir, 1);
  1363.     remove_from_temp("*.*", syscfgovr.batchdir, 1);
  1364.     tmp_disable_pause(0);
  1365.     imodem(1);
  1366.     cleanup_net();
  1367.   }
  1368.  
  1369.   lecho=ok_local();
  1370.   daylight=0;
  1371.   find_devices();
  1372.  
  1373.   subconfnum=dirconfnum=0;
  1374.   read_all_conferences();
  1375.  
  1376.   if (!restoring_shrink && !already_on) {
  1377.     sprintf(s,get_stringx(1,130),wwiv_version,
  1378.             instance, times(), date());
  1379.     sl1(0,"");
  1380.     sl1(0,s);
  1381.     sl1(0,"");
  1382.   }
  1383.  
  1384.   if (instance > 1)
  1385.     sprintf(s,"WWIV_NET.%3.3d",instance);
  1386.   else
  1387.     sprintf(s,"WWIV_NET.DAT");
  1388.   unlink(s);
  1389.  
  1390.   randomize();
  1391.  
  1392.   if (!restoring_shrink)
  1393.     catsl();
  1394.  
  1395.   write_inst(INST_LOC_WFC,0,INST_FLAGS_NONE);
  1396. }
  1397. /****************************************************************************/
  1398.  
  1399. void gotcaller(unsigned int ms, unsigned int cs)
  1400. {
  1401.   double d;
  1402.  
  1403.   frequent_init();
  1404.   com_speed = cs;
  1405.   modem_speed = ms;
  1406.   sl1(1,"");
  1407.   read_user(1,&thisuser);
  1408.   read_qscn(1,qsc,0);
  1409.   reset_act_sl();
  1410.   usernum=1;
  1411.   if (thisuser.inact & inact_deleted) {
  1412.     thisuser.screenchars=80;
  1413.     thisuser.screenlines=25;
  1414.   }
  1415.   screenlinest=25;
  1416.   clrscrb();
  1417.   outs(get_string(46));
  1418.   outs(curspeed);
  1419.   outs("...\r\n");
  1420.   if (ms) {
  1421.     set_baud(cs);
  1422.     incom=1;
  1423.     outcom=1;
  1424.     using_modem=1;
  1425.   } else {
  1426.     using_modem=incom=outcom=0;
  1427.   }
  1428.   d=(timer()) / 102.723;
  1429.   d-=floor(d);
  1430.   d*=10000.0;
  1431.   srand((unsigned int)d);
  1432. }
  1433.  
  1434. /****************************************************************************/
  1435.