home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / dominion / part16 / file.c < prev   
C/C++ Source or Header  |  1992-02-11  |  18KB  |  700 lines

  1.   /* file.c -- file operations */
  2.  
  3. /*
  4.  * Copyright (C) 1990 Free Software Foundation, Inc.
  5.  * Written by the dominion project.
  6.  *
  7.  * This file is part of dominion.
  8.  *
  9.  * dominion is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This software is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this software; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. /* this module contains routines that read and write the
  25.    world data file, and also routines that handle lock files.
  26.  */
  27.  
  28. #include <stdio.h>
  29. #ifdef SYSV
  30. # include <string.h>
  31. #else
  32. # include <strings.h>
  33. #endif /* SYSV */
  34. #include "dominion.h"
  35. #include "misc.h"
  36. #define UPDATE_FILE "last_update"
  37.  
  38. extern int debug, compressed_world;
  39. extern struct race_list *races;
  40. extern Suser user;
  41.  
  42. read_world(wp, fname)
  43.      Sworld *wp;
  44.      char fname[];
  45. {
  46.   int i, j;
  47.   FILE *fp, *fopen();
  48.   char cmd[200];
  49.  
  50.   compressed_world = check_compressed_world(fname);
  51.   if (compressed_world) {
  52.     sprintf(cmd, "zcat %s", fname);
  53.     if ((fp = popen(cmd, "r")) == NULL) {
  54.       printf("\r\ncannot open pipe <%s> for reading\r\n", cmd);
  55.       clean_exit();
  56.       exit(1);
  57.     }
  58.   } else {
  59.     if ((fp = fopen(fname, "r")) == NULL) {
  60.       printf("\r\ncannot open file <%s> for reading\r\n", fname);
  61.       clean_exit();
  62.       exit(1);
  63.     }
  64.   }
  65.   fprintf(stderr, "reading world data file %s", fname);
  66.  
  67.   fread(&wp->turn, sizeof(int), 1, fp); /* get current turn */
  68.   fread(&wp->xmax, sizeof(int), 1, fp);    /* get world size */
  69.   fread(&wp->ymax, sizeof(int), 1, fp);
  70. /*  fprintf(stderr, "world size is %dx%d\n", wp->xmax, wp->ymax); */
  71.  
  72.     /* make space for world sectors */
  73.   wp->map = (Ssector **) malloc(wp->xmax*sizeof(Ssector *));
  74.   for (i =  0; i < wp->xmax; ++i) {
  75.     wp->map[i] = (Ssector *) malloc(wp->ymax * sizeof(Ssector));
  76.   }
  77.     /* now read in the world map */
  78.   for (i = 0; i < wp->xmax; ++i) {
  79.     for (j = 0; j < wp->ymax; ++j) {
  80.       fread(&wp->map[i][j], sizeof(Ssector), 1, fp);
  81.       wp->map[i][j].alist = NULL;
  82.     }
  83.     if (i % (wp->xmax/8) == 0) {
  84.       fprintf(stderr, ".");
  85.       fflush(stdout);
  86.     }
  87.   }
  88.     /* load geography */
  89.   fread(&wp->geo, sizeof(wp->geo), 1, fp);
  90.   fprintf(stderr, ".");
  91.   fflush(stdout);
  92.         /* now read in nations */
  93.   fread(&wp->n_nations, sizeof(int), 1, fp);
  94. /*  printf("reading in %d nation%c\n",
  95.      wp->n_nations, wp->n_nations == 1 ? ' ' : 's'); */
  96.   for (i = 0; i < wp->n_nations; ++i) {
  97.       /* must find a better way of loading linked lists
  98.          (when I make the nations be a linked list!!)
  99.        */
  100.     read_nation(&wp->nations[i], fp, wp);
  101.     load_options(&wp->nations[i]);
  102.  
  103.     fprintf(stderr, ".");
  104.     fflush(stdout);
  105. /*    if (debug) {
  106.       printf("just read nation %d\n", i);
  107.       show_nation(&wp->nations[i]);
  108.       putchar('.');
  109.     }
  110. */
  111.   }
  112.   if (compressed_world) {
  113.     pclose(fp);
  114.   } else {
  115.     fclose(fp);
  116.   }
  117.   init_wrap();
  118.   fprintf(stderr, "\n");
  119. }
  120.  
  121.   /* save the world data file */
  122. write_world(wp, fname)
  123.      Sworld *wp;        /* pointer to the world */
  124.      char fname[];
  125. {
  126.   int i, j;
  127.   FILE *fp, *fopen();
  128.   char cmd[200];        /* for compression command */
  129.  
  130.   if (compressed_world) {
  131.     sprintf(cmd, "compress > %s.Z", fname);
  132.     if ((fp = popen(cmd, "w")) == NULL) {
  133.       printf("\r\ncannot open pipe <%s> for writing\r\n", cmd);
  134.       clean_exit();
  135.       exit(1);
  136.     }
  137.   } else {
  138.     if ((fp = fopen(fname, "w")) == NULL) {
  139.       printf("cannot open file <%s> for writing\n", fname);
  140.       clean_exit();
  141.       exit(1);
  142.     }
  143.   }
  144.   critical();
  145.   fwrite(&wp->turn, sizeof(int), 1, fp); /* write current turn number */
  146.   fwrite(&wp->xmax, sizeof(int), 1, fp);
  147.   fwrite(&wp->ymax, sizeof(int), 1, fp);
  148.   for (i = 0; i < wp->xmax; ++i) {
  149.     for (j = 0; j < wp->ymax; ++j) {
  150.       fwrite(&wp->map[i][j], sizeof(Ssector), 1, fp);
  151.     }
  152.   }
  153.     /* write out geography */
  154.   fwrite(&wp->geo, sizeof(wp->geo), 1, fp);
  155.  
  156.   printf("writing out %d nation%c\n",
  157.      wp->n_nations, wp->n_nations == 1 ? ' ' : 's');
  158.   fwrite(&wp->n_nations, sizeof(int), 1, fp);
  159.     /* only save as many nations as there are */
  160.   for (i = 0; i < wp->n_nations; ++i) {
  161.     write_nation(&wp->nations[i], fp);
  162.     if (debug) {
  163.       putchar('.');
  164.     }
  165.   }
  166.  
  167.   if (compressed_world) {
  168.     pclose(fp);
  169.   } else {
  170.     fclose(fp);
  171.   }
  172.   noncritical();        /* delicate phase over */
  173. }
  174.  
  175.   /* short hand */
  176. #define WRITE_DATUM(x) fwrite(&x, sizeof(x), 1, fp)
  177.  
  178. write_nation(np, fp)
  179.      Snation *np;
  180.      FILE *fp;
  181. {
  182.   int i;
  183.   Sarmy *ap;            /* for armies */
  184.   struct pt_list *pp;        /* for owned sectors */
  185.  
  186.     /* here is how we save a nation:  write out the actual nation data
  187.        structure first, and after it write out the various linked lists
  188.        (which are the army list and the list of owned points).
  189.      */
  190.  
  191.   fwrite(np, sizeof(Snation), 1, fp);
  192.  
  193.     /* write out list of country's armies */
  194.   ap = np->armies;
  195.   for (i = 0; i < np->n_armies; ++i) {
  196.     fwrite(ap, sizeof(Sarmy), 1, fp);
  197.     if (debug) {
  198.       putchar('a');
  199.     }
  200.     ap = ap->next;
  201.   }
  202.  
  203.     /* write list of owned locations */
  204.   pp = np->ptlist;
  205.   for (i = 0; i < np->n_sects; ++i) {
  206.     fwrite(pp, sizeof(struct pt_list), 1, fp);
  207.     if (debug) {
  208.       putchar('s');
  209.     }
  210.     pp = pp->next;
  211.   }
  212. }
  213.  
  214. read_nation(np, fp, wp)
  215.      Snation *np;
  216.      FILE *fp;
  217.      Sworld *wp;
  218. {
  219.   int i, x, y;
  220.   Ssector *sp;            /* for tmp use */
  221.   Sarmy army;            /* for armies */
  222.   struct pt_list *pp;        /* for owned sectors */
  223.  
  224.     /* here is how we load a nation:  read out the actual nation data
  225.        structure first, and after it read out the various linked lists
  226.        (which are the army list and the list of owned
  227.        points).  This is harder than writing because we must insert
  228.        all into linked lists.
  229.      */
  230.  
  231.   fread(np, sizeof(Snation), 1, fp); /* this is the easy part */
  232.  
  233.     /* now reset to zero the nation's "current" R&D values:
  234.        that way the special R&D investments of the previous turn
  235.        are zeroed, and only the percent-of-revenue values are saved
  236.      */
  237.   np->cur_mag_r_d = np->cur_mag_r_d_jewels = 0;
  238.   np->cur_tech_r_d = np->cur_tech_r_d_metal = 0;
  239.   np->cur_spy_r_d = 0;
  240.  
  241.   /* read list of country's armies add each army to the list for
  242.      its nation and for its sector. Special case for first army.
  243.    */
  244.   np->armies = NULL;
  245.   for (i = 0; i < np->n_armies; ++i) {
  246.     fread(&army, sizeof(Sarmy), 1, fp);
  247.     army.next = NULL;
  248.     x = army.pos.x;
  249.     y = army.pos.y;
  250.     sp = &(wp->map[x][y]);
  251.     if (i == 0) {
  252. /*      army.id = 0; */
  253.       np->armies = (Sarmy *) malloc(sizeof(Sarmy));
  254.       *(np->armies) = army;
  255.       np->armies->next = NULL;
  256.     } else {
  257. /*      if (debug) {
  258.     printf("Calling insert_army_nation, id=%d\n", army.id);
  259.       }
  260. */
  261.       insert_army_nation(np, &army, army.id);
  262. /*      if (debug) {
  263.     printf("Called insert_army_nation.\n");
  264.       }
  265. */
  266.     }
  267. /*    if (debug) {
  268.       printf("Calling insert_army_sector (%d,%d)\n", sp->loc.x, sp->loc.y);
  269.     }
  270. */
  271.     insert_army_sector(sp, &army);
  272.   /*  if (debug) {
  273.       printf("Called insert_army_sector.\n");
  274.     }
  275. */
  276.   }
  277.  
  278.   /* read list of owned locations (special case for first one) */
  279.   if (np->n_sects > 0) {
  280.     np->ptlist = (struct pt_list *) malloc(sizeof(struct pt_list));
  281.     fread(np->ptlist, sizeof(struct pt_list), 1, fp);
  282.     /*    np->ptlist->pt = np->capital; */
  283.     np->ptlist->next = NULL;
  284.     pp = np->ptlist;
  285.   }
  286.   for (i = 1; i < np->n_sects; ++i) {
  287.     pp->next = (struct pt_list *) malloc(sizeof(struct pt_list));
  288.     fread(pp->next, sizeof(struct pt_list), 1, fp);
  289.     pp = pp->next;
  290.     pp->next = NULL;
  291.     if (debug) {
  292.       putchar('s');
  293.     }
  294.   }
  295. }
  296.  
  297.   /* reads in the list of all races */
  298. read_races()
  299. {
  300.   FILE *fp, *fopen();
  301.   char s[200];
  302.   int i, n_races;
  303.   Srace tmp_race;        /* for temporary use */
  304.   struct race_list *rlp;    /* to make the linked list */
  305.  
  306.   if ((fp = fopen(RACES_FILE, "r")) == NULL) {
  307.     printf("cannot open races file.  you might have the wrong directory..\n");
  308.     clean_exit();
  309.     exit(1);
  310.   }
  311.  
  312.     /* the initial race is the master, and is hardwired */
  313.   races = (struct race_list *) malloc(sizeof(struct race_list));
  314.   strcpy(races->race.name, "Master");
  315.   races->race.mark = 'C';
  316.   races->race.strength = 0;
  317.   races->race.repro = 0;
  318.   races->race.mortality = 0;
  319.   races->race.intel = 0;
  320.   races->race.speed = 0;
  321.   races->race.stealth = 0;
  322.   races->race.pref_alt = 0;
  323.   races->race.pref_terrain = 0;
  324.   races->race.pref_climate = 0;
  325.   races->race.mag_apt = 0;
  326.   races->race.farming = 0;
  327.   races->race.mining = 0;
  328.   races->next = NULL;
  329.  
  330.   rlp = races;
  331.  
  332.     /* now get the number of races from the file
  333.        (we trust that the file is consistent)
  334.      */
  335.   fgets(s, 180, fp);
  336.   while (s[0] == '#') {        /* ignore comments */
  337. /*    if (debug) {
  338.       printf("<%s>", s);
  339.     }
  340. */
  341.     fgets(s, 180, fp);
  342.   }
  343. /*  if (debug) {
  344.     printf("<%s>", s);
  345.   }
  346. */
  347.   sscanf(s, "%d", &n_races);    /* first line has number of races */
  348.  
  349.   for (i = 0; i < n_races; ) { /* now read them in!! */
  350.     char c;
  351.     char name[180];
  352.     fgets(s, 180, fp);
  353.     s[strlen(s)-1] = '\0';
  354. /*    if (debug) {
  355.       printf("<%s>", s);
  356.     }
  357. */
  358.     if (s[0] != '#') {        /* skip comments */
  359.       ++i;
  360.       sscanf(s,
  361.         "%s : %1s : %d : %d : %d : %d : %d : %d : %d : %d : %d : %d : %d : %d",
  362.          tmp_race.name, &tmp_race.mark, &tmp_race.strength,
  363.          &tmp_race.repro, &tmp_race.mortality, &tmp_race.intel,
  364.          &tmp_race.speed, &tmp_race.stealth, &tmp_race.pref_alt,
  365.          &tmp_race.pref_terrain, &tmp_race.pref_climate,
  366.          &tmp_race.mag_apt, &tmp_race.farming, &tmp_race.mining);
  367.  
  368. /*      if (debug) {
  369.     show_race(&tmp_race);
  370.       }
  371. */
  372.         /* now that we have loaded it, add it to the list */
  373.       rlp->next = (struct race_list *) malloc(sizeof(struct race_list));
  374.       rlp = rlp->next;
  375.       rlp->race = tmp_race;
  376.       rlp->next = NULL;
  377.     }
  378.   }
  379.   fclose(fp);
  380. }
  381.  
  382.   /* this routine checks to see if the world file is
  383.      in a compressed format.  It it is, it returns 1.
  384.      Otherwise, 0.
  385.    */
  386. check_compressed_world(fname)
  387.      char fname[];
  388. {
  389.   char Zname[200];
  390.   FILE *fopen(),*fp;
  391.  
  392.   strcpy(Zname, fname);
  393.   strcat(Zname, ".Z");        /* if .Z file exists, it must be compressed! */
  394.   if ((fp = fopen(Zname, "r")) != NULL) {
  395.     fclose(fp);
  396.     return 1;
  397.   }
  398.   return 0;
  399. }
  400.  
  401.   /* sets a master lock file */
  402. set_master_lock()
  403. {
  404.   close(creat("lock.master", 0600));
  405. }
  406.  
  407.   /* sets a lock for the given nation id */
  408. set_lock(id)
  409.      int id;
  410. {
  411.   char fname[PATHLEN];
  412.   FILE *fp, *fopen();
  413.   extern Sworld world;
  414.   extern int ruid;
  415.   long now_secs;
  416.  
  417.   sprintf(fname, "lock.%d", id);
  418. /*  close(creat(fname, 0666)); */
  419.   if ((fp = fopen(fname, "w")) == NULL) {
  420.     printf("cannot open the lock file file <%s> for writing\n", fname);
  421.     clean_exit();
  422.     exit(1);
  423.   }
  424.   now_secs = time(0L);
  425.     /* now put some titbits of information into the lock file */
  426.   fprintf(fp, "%ld; Nation %s; real uid %d; time: %s", now_secs,
  427.       world.nations[id].name, ruid, ctime(&now_secs));
  428.   fclose(fp);
  429. }
  430.  
  431.   /* removes a lock for the given nation id */
  432. del_lock(id)
  433.      int id;
  434. {
  435.   char fname[PATHLEN];
  436.  
  437.   sprintf(fname, "lock.%d", id);
  438.   unlink(fname);
  439. }
  440.  
  441.   /* removes the master lock file */
  442. del_master_lock()
  443. {
  444.   unlink("lock.master");
  445. }
  446.  
  447.   /* tries to open the lock file.  returns the file pointer
  448.      it gets, with the file open for reading (if it exists)
  449.    */
  450. FILE *is_locked(id)
  451.      int id;
  452. {
  453.   FILE *fopen();
  454.   char fname[PATHLEN];
  455.  
  456.   sprintf(fname, "lock.%d", id);
  457.   return fopen(fname, "r");
  458. /*  if ((fp = fopen(fname, "r")) != NULL) {
  459.     fclose(fp);
  460.     return 1;            /* yeah, it is locked */
  461. /*  }
  462.   return 0; */
  463. }
  464.  
  465.   /* checks if even a single nation has a lock or not */
  466. is_any_lock()
  467. {
  468.   int i;
  469.   FILE *fp;
  470.  
  471.   for (i = 0; i < NATIONS; ++i) {
  472.     if (fp = is_locked(i)) {
  473.       fclose(fp);
  474.       return 1;
  475.     }
  476.   }
  477.   return 0;
  478. }
  479.  
  480.   /* cheks if there is a master lock file */
  481. is_master_lock()
  482. {
  483.   FILE *fp, *fopen();
  484.  
  485.   if ((fp = fopen("lock.master", "r")) != NULL) {
  486.     fclose(fp);
  487.     return 1;
  488.   }
  489.   return 0;
  490. }
  491.  
  492. set_update_time()
  493. {
  494.   char fname[PATHLEN];
  495.   FILE *fp, *fopen();
  496.   extern Sworld world;
  497.   extern int ruid;
  498.   long now_secs;
  499.  
  500.   sprintf(fname, UPDATE_FILE);
  501.   if ((fp = fopen(fname, "w")) == NULL) {
  502.     printf("cannot open the update file file <%s> for writing\n", fname);
  503.     clean_exit();
  504.     exit(1);
  505.   }
  506.   now_secs = time(0L);
  507.     /* now put some titbits of information into the lock file */
  508.   fprintf(fp, "%ld; time: %s", now_secs, ctime(&now_secs));
  509.   fclose(fp);
  510. }
  511.  
  512. char *get_update_time()
  513. {
  514.   char fname[PATHLEN];
  515.   FILE *fp, *fopen();
  516.   extern Sworld world;
  517.   extern int ruid;
  518.   long secs, len;
  519.   char s[300], *rtvl, *tmp;
  520.  
  521.   sprintf(fname, UPDATE_FILE);
  522.   if ((fp = fopen(fname, "r")) == NULL) {
  523.     set_update_time();
  524.   }
  525.   fgets(s,299,fp);
  526.   if ((rtvl = (char *) malloc(strlen(s) * sizeof(char))) == NULL) mem_error();
  527.   tmp = strchr(s,(int)':');
  528.   strcpy(rtvl,(tmp+1));
  529.   fclose(fp);
  530.   return rtvl;
  531. }
  532.  
  533. mem_error()
  534. /* 
  535.   If we can't allocate any more memory, then tell the user that's the
  536.   case, and then die quietly, rather than the horrible death not 
  537.   checking mallocs would cause.
  538. */
  539. {
  540.   fprintf(stderr,"Error: Couldn't allocate requested memory");
  541.   cleanup();
  542.   clean_exit();
  543.   exit(1);
  544. }     
  545.  
  546. load_options(np)
  547. Snation *np;
  548. /* Loads various options form the options file into the user's option record */
  549. {
  550.   char opt_file[PATHLEN], opt_line[100];
  551.   FILE *fopt;
  552.   int len;
  553.  
  554.   init_options(np);
  555.   sprintf(opt_file, "%s/opt.%d", OPT_DIR, np->id);
  556.   if ((fopt = fopen(opt_file,"r")) == NULL) {
  557.     save_options(np);
  558.     return;
  559.   }
  560.   while (fgets(opt_line, 99, fopt) != NULL) {
  561.     if (strncmp(opt_line, "EXPERT_MODE: ", 13) == 0)
  562.     {
  563.       np->opts->expert_mode = atoi(&(opt_line[13]));
  564.       user.xmode = np->opts->expert_mode;
  565.     } else if (strncmp(opt_line, "CIV_MOVEMODE: ", 14) == 0) {
  566.       np->opts->civ_movemode = atoi(&(opt_line[14]));
  567.     } else if (strncmp(opt_line, "MAIL_FORWARD: ", 14) == 0) {
  568.       if (opt_line[14] == '\n') { 
  569.         np->opts->mail_forward = NULL;
  570.         continue;
  571.       }
  572.       len = strlen(&(opt_line[14]));
  573.       if ((np->opts->mail_forward = (char *)malloc((len + 1)* sizeof(char)))
  574.            == NULL) { mem_error(); }
  575.       strcpy(np->opts->mail_forward,&(opt_line[14]));
  576.       len = strlen(np->opts->mail_forward);
  577.       if (np->opts->mail_forward[len - 1] == '\n') {
  578.         np->opts->mail_forward[len - 1] = '\0';
  579.       }
  580.     } else if (strncmp(opt_line, "MAIL_READER: ", 13) == 0) {
  581.       if (opt_line[13] == '\n') { 
  582.         np->opts->mail_reader = NULL;
  583.         continue;
  584.       }
  585.       len = strlen(&(opt_line[13]));
  586.       if ((np->opts->mail_reader = (char *)malloc((len + 1)* sizeof(char)))
  587.            == NULL) { mem_error(); }
  588.       strcpy(np->opts->mail_reader,&(opt_line[13]));
  589.       len = strlen(np->opts->mail_reader);
  590.       if (np->opts->mail_reader[len - 1] == '\n') {
  591.         np->opts->mail_reader[len - 1] = '\0';
  592.       }
  593.     } else {
  594.       fprintf(stderr,"Error: Bad Option %s\n",opt_line);
  595.     }
  596.   }
  597.   fclose(fopt);
  598. }
  599.  
  600. save_options(np)
  601. /* Save all of the user's optoins to a file. */
  602. Snation *np;
  603. {
  604.   FILE *fopt;
  605.   char opt_file[PATHLEN], opt_line[100], *rtvl = NULL;
  606.   int len;
  607.  
  608.   sprintf(opt_file, "%s/opt.%d", OPT_DIR, np->id);
  609.   if ((fopt = fopen(opt_file,"w")) == NULL) {
  610.     clean_exit();
  611.     fprintf(stderr,"Error: Cannot Open Options File %s\n",opt_file);
  612.     exit(1);
  613.   }
  614.  
  615.   fprintf(fopt,"EXPERT_MODE: %d\n",np->opts->expert_mode);
  616.   fprintf(fopt,"CIV_MOVEMODE: %d\n", np->opts->civ_movemode);
  617.   if (np->opts->mail_forward == NULL) {
  618.     fprintf(fopt,"MAIL_FORWARD: \n");
  619.   } else {
  620.     fprintf(fopt,"MAIL_FORWARD: %s\n",np->opts->mail_forward);
  621.   }
  622.   if (np->opts->mail_reader == NULL) {
  623.     fprintf(fopt,"MAIL_READER: \n");
  624.   } else {
  625.     fprintf(fopt,"MAIL_READER: %s\n",np->opts->mail_reader);
  626.   }
  627.   fclose (fopt);
  628. }
  629.  
  630. char *get_char_option(user_num, optname)
  631. /* This function returns a character option for the given user */
  632. int user_num;
  633. char *optname;
  634. {
  635.   FILE *fopt;
  636.   char opt_file[PATHLEN], opt_line[100], *rtvl = NULL;
  637.   int len, optlen = strlen(optname);
  638.  
  639.   sprintf(opt_file, "%s/opt.%d", OPT_DIR, user_num);
  640.   if ((fopt = fopen(opt_file,"r")) == NULL) {
  641.     return NULL;
  642.   }
  643.  
  644.   while (fgets(opt_line, 99, fopt) != NULL) {
  645.     if (strncmp(opt_line, optname, optlen) == 0) {
  646.       if (opt_line[optlen + 2] == '\n') { 
  647.         rtvl = NULL;
  648.         break;
  649.       }
  650.       len = strlen(&(opt_line[optlen + 2]));
  651.       if ((rtvl = (char *)malloc((len + 1)* sizeof(char))) == NULL) { 
  652.        mem_error(); }
  653.       strcpy(rtvl,&(opt_line[optlen + 2]));
  654.       len = strlen(rtvl);
  655.       if (rtvl[len - 1] == '\n') {
  656.         rtvl[len - 1] = '\0';
  657.       }
  658.     }
  659.   }
  660.   fclose(fopt);
  661.   return rtvl;
  662. }
  663.  
  664. int get_int_option(user_num, optname)
  665. /* This function returns an integer option for a given user */
  666. int user_num;
  667. char *optname;
  668. {
  669.   FILE *fopt;
  670.   char opt_file[PATHLEN], opt_line[100];
  671.   int len, optlen = strlen(optname), rtvl;
  672.  
  673.   sprintf(opt_file, "%s/opt.%d", OPT_DIR, user_num);
  674.   if ((fopt = fopen(opt_file,"r")) == NULL) {
  675.     return NULL;
  676.   }
  677.  
  678.   while (fgets(opt_line, 99, fopt) != NULL) {
  679.     if (strncmp(opt_line, optname, optlen) == 0) {
  680.       rtvl = atoi(&(opt_line[optlen + 2]));
  681.       break;
  682.     }
  683.   }
  684.  
  685.   fclose(fopt);
  686.   return rtvl;
  687. }
  688.   
  689. init_options(np)
  690. /* Init an unused option record */
  691. Snation *np;
  692. {
  693.   if ((np->opts = (Soptions *)malloc(sizeof(Soptions))) == NULL){mem_error();}
  694.   
  695.   np->opts->expert_mode = 0;
  696.   np->opts->civ_movemode = 2; /* Move freely unless restricted by gov */
  697.   np->opts->mail_forward = NULL;
  698.   np->opts->mail_reader = NULL;
  699. }
  700.