home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / d-linux.zip / dm-dist / modify.c < prev    next >
C/C++ Source or Header  |  1992-11-21  |  19KB  |  945 lines

  1. /* ************************************************************************
  2. *  file: modify.c                                         Part of DIKUMUD *
  3. *  Usage: Run-time modification (by users) of game variables              *
  4. *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
  5. ************************************************************************ */
  6.  
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <time.h>
  12.  
  13. #include "structs.h"
  14. #include "utils.h"
  15. #include "interpreter.h"
  16. #include "handler.h"
  17. #include "db.h"
  18. #include "comm.h"
  19.  
  20. #define REBOOT_AT    10  /* 0-23, time of optional reboot if -e lib/reboot */
  21.  
  22.  
  23. #define TP_MOB    0
  24. #define TP_OBJ       1
  25. #define TP_ERROR  2
  26.  
  27.  
  28. void show_string(struct descriptor_data *d, char *input);
  29.  
  30.  
  31.  
  32. char *string_fields[] =
  33. {
  34.     "name",
  35.     "short",
  36.     "long",
  37.     "description",
  38.     "title",
  39.     "delete-description",
  40.     "\n"
  41. };
  42.  
  43.  
  44.  
  45.  
  46. /* maximum length for text field x+1 */
  47. int length[] =
  48. {
  49.     15,
  50.     60,
  51.     256,
  52.     240,
  53.     60
  54. };
  55.  
  56.  
  57.  
  58.  
  59. char *skill_fields[] = 
  60. {
  61.     "learned",
  62.     "affected",
  63.     "duration",
  64.     "recognize",
  65.     "\n"
  66. };
  67.  
  68.  
  69.  
  70.  
  71. int max_value[] =
  72. {
  73.     255,
  74.     255,
  75.     10000,
  76.     1
  77. };
  78.  
  79. /* ************************************************************************
  80. *  modification of malloc'ed strings                                      *
  81. ************************************************************************ */
  82.  
  83. /* Add user input to the 'current' string (as defined by d->str) */
  84. void string_add(struct descriptor_data *d, char *str)
  85. {
  86.     char *scan;
  87.     int terminator = 0;
  88.  
  89.     /* determine if this is the terminal string, and truncate if so */
  90.     for (scan = str; *scan; scan++)
  91.        if (terminator = (*scan == '@'))
  92.        {
  93.             *scan = '\0';
  94.             break;
  95.        }
  96.     
  97.     if (!(*d->str))
  98.     {
  99.         if (strlen(str) > d->max_str)
  100.         {
  101.             send_to_char("String too long - Truncated.\n\r",
  102.                d->character);
  103.             *(str + d->max_str) = '\0';
  104.             terminator = 1;
  105.         }
  106.         CREATE(*d->str, char, strlen(str) + 3);
  107.         strcpy(*d->str, str);
  108.     }
  109.     else
  110.     {
  111.         if (strlen(str) + strlen(*d->str) > d->max_str)
  112.         {
  113.             send_to_char("String too long. Last line skipped.\n\r",
  114.                d->character);
  115.             terminator = 1;
  116.         }
  117.         else 
  118.         {
  119.             if (!(*d->str = (char *) realloc(*d->str, strlen(*d->str) + 
  120.                strlen(str) + 3)))
  121.             {
  122.                 perror("string_add");
  123.                 exit(1);
  124.             }
  125.             strcat(*d->str, str);
  126.         }
  127.     }
  128.  
  129.     if (terminator)
  130.     {
  131.         d->str = 0;
  132.         if (d->connected == CON_EXDSCR)
  133.         {
  134.             SEND_TO_Q(MENU, d);
  135.             d->connected = CON_SLCT;
  136.         }
  137.     }
  138.     else
  139.        strcat(*d->str, "\n\r");
  140. }
  141.  
  142.  
  143. #undef MAX_STR
  144.  
  145. /* interpret an argument for do_string */
  146. void quad_arg(char *arg, int *type, char *name, int *field, char *string)
  147. {
  148.     char buf[MAX_STRING_LENGTH];
  149.     int i;
  150.  
  151.     /* determine type */
  152.     arg = one_argument(arg, buf);
  153.     if (is_abbrev(buf, "char"))
  154.        *type = TP_MOB;
  155.     else if (is_abbrev(buf, "obj"))
  156.        *type = TP_OBJ;
  157.     else
  158.     {
  159.         *type = TP_ERROR;
  160.         return;
  161.     }
  162.  
  163.     /* find name */
  164.     arg = one_argument(arg, name);
  165.  
  166.     /* field name and number */
  167.     arg = one_argument(arg, buf);
  168.     if (!(*field = old_search_block(buf, 0, strlen(buf), string_fields, 0)))
  169.        return;
  170.  
  171.     /* string */
  172.     for (; isspace(*arg); arg++);
  173.     for (; *string = *arg; arg++, string++);
  174.  
  175.     return;
  176. }
  177.     
  178.      
  179.  
  180.  
  181. /* modification of malloc'ed strings in chars/objects */
  182. void do_string(struct char_data *ch, char *arg, int cmd)
  183. {
  184.     char name[MAX_STRING_LENGTH], string[MAX_STRING_LENGTH];
  185.     int field, type;
  186.     struct char_data *mob;
  187.     struct obj_data *obj;
  188.     struct extra_descr_data *ed, *tmp;
  189.  
  190.     if (IS_NPC(ch))
  191.        return;
  192.  
  193.     quad_arg(arg, &type, name, &field, string);
  194.  
  195.     if (type == TP_ERROR)
  196.     {
  197.         send_to_char(
  198.          "Syntax:\n\rstring ('obj'|'char') <name> <field> [<string>].",
  199.          ch);
  200.         return;
  201.     }
  202.  
  203.     if (!field)
  204.     {
  205.         send_to_char("No field by that name. Try 'help string'.\n\r",
  206.            ch);
  207.         return;
  208.     }
  209.  
  210.     if (type == TP_MOB)
  211.     {
  212.         /* locate the beast */
  213.         if (!(mob = get_char_vis(ch, name)))
  214.         {
  215.             send_to_char("I don't know anyone by that name...\n\r",
  216.                ch);
  217.             return;
  218.         }
  219.  
  220.         switch(field)
  221.         {
  222.             case 1:
  223.                 if (!IS_NPC(mob) && GET_LEVEL(ch) < 24)
  224.                 {
  225.                     send_to_char("You can't change that field for players.", ch);
  226.                     return;
  227.                 }
  228.                 ch->desc->str = &GET_NAME(mob);
  229.                 if (!IS_NPC(mob))
  230.                     send_to_char(
  231.                         "WARNING: You have changed the name of a player.\n\r", ch);
  232.             break;
  233.             case 2:
  234.                if (!IS_NPC(mob))
  235.                {
  236.                     send_to_char(
  237.                    "That field is for monsters only.\n\r", ch);
  238.                    return;
  239.                }
  240.                ch->desc->str = &mob->player.short_descr;
  241.             break;
  242.             case 3:
  243.                if (!IS_NPC(mob))
  244.                {
  245.                 send_to_char(
  246.                    "That field is for monsters only.\n\r", ch);
  247.                    return;
  248.                }
  249.                ch->desc->str = &mob->player.long_descr;
  250.             break;
  251.             case 4:ch->desc->str = &mob->player.description; break;
  252.             case 5:
  253.                if (IS_NPC(mob))
  254.                {
  255.                 send_to_char("Monsters have no titles.\n\r",
  256.                    ch);
  257.                 return;
  258.                }
  259.                ch->desc->str = &mob->player.title;
  260.             break;
  261.             default:
  262.                send_to_char(
  263.                   "That field is undefined for monsters.\n\r", ch);
  264.                return;
  265.             break;
  266.         }
  267.     }
  268.     else    /* type == TP_OBJ */
  269.     {
  270.         /* locate the object */
  271.         if (!(obj = get_obj_vis(ch, name)))
  272.         {
  273.             send_to_char("Can't find such a thing here..\n\r", ch);
  274.             return;
  275.         }
  276.  
  277.         switch(field)
  278.         {
  279.             case 1: ch->desc->str = &obj->name; break;
  280.             case 2: ch->desc->str = &obj->short_description; break;
  281.             case 3: ch->desc->str = &obj->description; break;
  282.             case 4:
  283.                 if (!*string)
  284.                 {
  285.                     send_to_char("You have to supply a keyword.\n\r", ch);
  286.                     return;
  287.                 }
  288.                 /* try to locate extra description */
  289.                 for (ed = obj->ex_description; ; ed = ed->next)
  290.                     if (!ed) /* the field was not found. create a new one. */
  291.                     {
  292.                         CREATE(ed , struct extra_descr_data, 1);
  293.                         ed->next = obj->ex_description;
  294.                         obj->ex_description = ed;
  295.                         CREATE(ed->keyword, char, strlen(string) + 1);
  296.                         strcpy(ed->keyword, string);
  297.                         ed->description = 0;
  298.                         ch->desc->str = &ed->description;
  299.                         send_to_char("New field.\n\r", ch);
  300.                         break;
  301.                     }
  302.                     else if (!str_cmp(ed->keyword, string)) /* the field exists */
  303.                     {
  304.                         free(ed->description);
  305.                         ed->description = 0;
  306.                         ch->desc->str = &ed->description;
  307.                         send_to_char(
  308.                             "Modifying description.\n\r", ch);
  309.                         break;
  310.                     }
  311.                 ch->desc->max_str = MAX_STRING_LENGTH;
  312.                 return; /* the stndrd (see below) procedure does not apply here */
  313.             break;
  314.             case 6: 
  315.                 if (!*string)
  316.                 {
  317.                     send_to_char("You must supply a field name.\n\r", ch);
  318.                     return;
  319.                 }
  320.                 /* try to locate field */
  321.                 for (ed = obj->ex_description; ; ed = ed->next)
  322.                     if (!ed)
  323.                     {
  324.                         send_to_char("No field with that keyword.\n\r", ch);
  325.                         return;
  326.                     }
  327.                     else if (!str_cmp(ed->keyword, string))
  328.                     {
  329.                         free(ed->keyword);
  330.                         if (ed->description)
  331.                             free(ed->description);
  332.                         
  333.                         /* delete the entry in the desr list */                        
  334.                         if (ed == obj->ex_description)
  335.                             obj->ex_description = ed->next;
  336.                         else
  337.                         {
  338.                             for(tmp = obj->ex_description; tmp->next != ed; 
  339.                                 tmp = tmp->next);
  340.                             tmp->next = ed->next;
  341.                         }
  342.                         free(ed);
  343.  
  344.                         send_to_char("Field deleted.\n\r", ch);
  345.                         return;
  346.                     }
  347.             break;                
  348.             default:
  349.                send_to_char(
  350.                   "That field is undefined for objects.\n\r", ch);
  351.                return;
  352.             break;
  353.         }
  354.     }
  355.  
  356.     if (*ch->desc->str)
  357.     {
  358.         free(*ch->desc->str);
  359.     }
  360.  
  361.     if (*string)   /* there was a string in the argument array */
  362.     {
  363.         if (strlen(string) > length[field - 1])
  364.         {
  365.             send_to_char("String too long - truncated.\n\r", ch);
  366.             *(string + length[field - 1]) = '\0';
  367.         }
  368.         CREATE(*ch->desc->str, char, strlen(string) + 1);
  369.         strcpy(*ch->desc->str, string);
  370.         ch->desc->str = 0;
  371.         send_to_char("Ok.\n\r", ch);
  372.     }
  373.     else          /* there was no string. enter string mode */
  374.     {
  375.         send_to_char("Enter string. terminate with '@'.\n\r", ch);
  376.         *ch->desc->str = 0;
  377.         ch->desc->max_str = length[field - 1];
  378.     }
  379. }
  380.             
  381.             
  382.  
  383.  
  384.  
  385.  
  386.  
  387. /* **********************************************************************
  388. *  Modification of character skills                                     *
  389. ********************************************************************** */
  390.  
  391.  
  392. void do_setskill(struct char_data *ch, char *arg, int cmd)
  393. {
  394.     struct char_data *vict;
  395.     char name[100], num[100], buf[100], help[MAX_STRING_LENGTH];
  396.     int skill, field, value, i;
  397.     static char *skills[] = 
  398.     {
  399.         "search", "frighten", "telepath", "detect-evil",
  400.         "sense-life", "cure", "bless", "remove",
  401.         "poison", "blind", "neutralize", "purify",
  402.         "hide", "cover", "backstab", "detect-invisible",
  403.         "detect-magic", "enchant", "teleport", "create",
  404.         "sanctuary", "resist", "drain", "turn",
  405.         "protect", "light", "charm", "floating",
  406.         "lightning-bolt", "sleep", "wake", "paralysis",
  407.         "recharge", "shield", "fireball", "knock",
  408.         "ventricolism", "double", "invisible", "death-ray",
  409.         "bash", "dodge", "kick", "uppercut",
  410.         "defend", "dirk", "listen", "missile", "detect", "\n"
  411.     };
  412.  
  413.     send_to_char("This routine is disabled untill it fitts\n\r", ch);
  414.     send_to_char("The new structures (sorry Quinn) ....Bombman\n\r", ch);
  415.     return;
  416.  
  417.     arg = one_argument(arg, name);
  418.     if (!*name) /* no arguments. print an informative text */
  419.     {
  420.         send_to_char("Syntax:\n\rsetskill <name> <skill> <field> <value>\n\r",
  421.            ch);
  422.         strcpy(help, "Skill being one of the following:\n\r\n\r");
  423.         for (i = 1; *skills[i] != '\n'; i++)
  424.         {
  425.             sprintf(help + strlen(help), "%18s", skills[i]);
  426.             if (!(i % 4))
  427.             {
  428.                 strcat(help, "\n\r");
  429.                 send_to_char(help, ch);
  430.                 *help = '\0';
  431.             }
  432.         }
  433.         if (*help)
  434.             send_to_char(help, ch);
  435.         return;
  436.     }
  437.     if (!(vict = get_char_vis(ch, name)))
  438.     {
  439.         send_to_char("No living thing by that name.\n\r", ch);
  440.         return;
  441.     }
  442.     arg = one_argument(arg, buf);
  443.     if (!*buf)
  444.     {
  445.         send_to_char("Skill name expected.\n\r", ch);
  446.         return;
  447.     }
  448.     if ((skill = old_search_block(buf, 0, strlen(buf), skills, 1)) < 0)
  449.     {
  450.         send_to_char("No such skill is known. Try 'setskill' for list.\n\r", ch);
  451.         return;
  452.     }
  453.     argument_interpreter(arg, buf, num);
  454.     if (!*num || !*buf)
  455.     {
  456.         send_to_char("Field name or value undefined.\n\r", ch);
  457.         return;
  458.     }
  459.     if ((field = old_search_block(buf, 0, strlen(buf), skill_fields, 0)) < 0)
  460.     {
  461.         send_to_char("Unrecognized field.\n\r", ch);
  462.         return;
  463.     }
  464.     value = atoi(num);
  465.     if (field == 3)
  466.     {
  467.         if (value < -1)
  468.         {
  469.             send_to_char("Minimum value for that is -1.\n\r", ch);
  470.             return;
  471.         }
  472.     }
  473.     else
  474.         if (value < 0)
  475.         {
  476.             send_to_char("Minimum value for that is 0.\n\r", ch);
  477.             return;
  478.         }
  479.     if (value > max_value[field - 1])
  480.     {
  481.         sprintf(buf, "Max value for that is %d.\n\r", max_value[field - 1]);
  482.         send_to_char(buf, ch);
  483.         return;
  484.     }
  485.  
  486.     switch (field)
  487.     {
  488.         case 1: vict->skills[skill].learned = value; break;
  489.         /* case 2: vict->skills[skill].affected_by = value; break; */
  490.         /* case 3: vict->skills[skill].duration = value; break;    */
  491.         case 4: vict->skills[skill].recognise = value; break;
  492.     }
  493.  
  494.     send_to_char("Ok.\n\r", ch);
  495. }
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504. /* db stuff *********************************************** */
  505.  
  506.  
  507. /* One_Word is like one_argument, execpt that words in quotes "" are */
  508. /* regarded as ONE word                                              */
  509.  
  510. char *one_word(char *argument, char *first_arg )
  511. {
  512.     int found, begin, look_at;
  513.  
  514.     found = begin = 0;
  515.  
  516.     do
  517.     {
  518.         for ( ;isspace(*(argument + begin)); begin++);
  519.  
  520.         if (*(argument+begin) == '\"') {  /* is it a quote */
  521.  
  522.             begin++;
  523.  
  524.             for (look_at=0; (*(argument+begin+look_at) >= ' ') && 
  525.                 (*(argument+begin+look_at) != '\"') ; look_at++)
  526.                 *(first_arg + look_at) = LOWER(*(argument + begin + look_at));
  527.  
  528.             if (*(argument+begin+look_at) == '\"')
  529.                 begin++;
  530.  
  531.         } else {
  532.  
  533.             for (look_at=0; *(argument+begin+look_at) > ' ' ; look_at++)
  534.                 *(first_arg + look_at) = LOWER(*(argument + begin + look_at));
  535.  
  536.         }
  537.  
  538.         *(first_arg + look_at) = '\0';
  539.         begin += look_at;
  540.     }
  541.     while (fill_word(first_arg));
  542.  
  543.     return(argument+begin);
  544. }
  545.  
  546.  
  547. struct help_index_element *build_help_index(FILE *fl, int *num)
  548. {
  549.     int nr = -1, issorted, i;
  550.     struct help_index_element *list = 0, mem;
  551.     char buf[81], tmp[81], *scan;
  552.     long pos;
  553.  
  554.     for (;;)
  555.     {
  556.         pos = ftell(fl);
  557.         fgets(buf, 81, fl);
  558.         *(buf + strlen(buf) - 1) = '\0';
  559.         scan = buf;
  560.         for (;;)
  561.         {
  562.             /* extract the keywords */
  563.             scan = one_word(scan, tmp);
  564.  
  565.             if (!*tmp)
  566.                 break;
  567.  
  568.             if (!list)
  569.             {
  570.                 CREATE(list, struct help_index_element, 1);
  571.                 nr = 0;
  572.             }
  573.             else
  574.                 RECREATE(list, struct help_index_element, ++nr + 1);
  575.  
  576.             list[nr].pos = pos;
  577.             CREATE(list[nr].keyword, char, strlen(tmp) + 1);
  578.             strcpy(list[nr].keyword, tmp);
  579.         }
  580.         /* skip the text */
  581.         do
  582.             fgets(buf, 81, fl);
  583.         while (*buf != '#');
  584.         if (*(buf + 1) == '~')
  585.             break;
  586.     }
  587.     /* we might as well sort the stuff */
  588.     do
  589.     {
  590.         issorted = 1;
  591.         for (i = 0; i < nr; i++)
  592.             if (str_cmp(list[i].keyword, list[i + 1].keyword) > 0)
  593.             {
  594.                 mem = list[i];
  595.                 list[i] = list[i + 1];
  596.                 list[i + 1] = mem;
  597.                 issorted = 0;
  598.             }
  599.     }
  600.     while (!issorted);
  601.  
  602.     *num = nr;
  603.     return(list);
  604. }
  605.  
  606.  
  607.  
  608. void page_string(struct descriptor_data *d, char *str, int keep_internal)
  609. {
  610.     if (!d)
  611.         return;
  612.  
  613.     if (keep_internal)
  614.     {
  615.         CREATE(d->showstr_head, char, strlen(str) + 1);
  616.         strcpy(d->showstr_head, str);
  617.         d->showstr_point = d->showstr_head;
  618.     }
  619.     else
  620.         d->showstr_point = str;
  621.  
  622.     show_string(d, "");
  623. }
  624.  
  625.  
  626.  
  627. void show_string(struct descriptor_data *d, char *input)
  628. {
  629.     char buffer[MAX_STRING_LENGTH], buf[MAX_INPUT_LENGTH];
  630.     register char *scan, *chk;
  631.     int lines = 0, toggle = 1;
  632.  
  633.     one_argument(input, buf);
  634.  
  635.     if (*buf)
  636.     {
  637.         if (d->showstr_head)
  638.         {
  639.             free(d->showstr_head);
  640.             d->showstr_head = 0;
  641.         }
  642.         d->showstr_point = 0;
  643.         return;
  644.     }
  645.  
  646.     /* show a chunk */
  647.     for (scan = buffer;; scan++, d->showstr_point++)
  648.         if((((*scan = *d->showstr_point) == '\n') || (*scan == '\r')) &&
  649.             ((toggle = -toggle) < 0))
  650.             lines++;
  651.         else if (!*scan || (lines >= 22))
  652.         {
  653.             *scan = '\0';
  654.             SEND_TO_Q(buffer, d);
  655.  
  656.             /* see if this is the end (or near the end) of the string */
  657.             for (chk = d->showstr_point; isspace(*chk); chk++);
  658.             if (!*chk)
  659.             {
  660.                 if (d->showstr_head)
  661.                 {
  662.                     free(d->showstr_head);
  663.                     d->showstr_head = 0;
  664.                 }
  665.                 d->showstr_point = 0;
  666.             }
  667.             return;
  668.         }
  669. }
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676. void night_watchman(void)
  677. {
  678.     long tc;
  679.     struct tm *t_info;
  680.  
  681.     extern int shutdown;
  682.  
  683.     void send_to_all(char *messg);
  684.  
  685.     tc = time(0);
  686.     t_info = localtime(&tc);
  687.  
  688.     if ((t_info->tm_hour == 8) && (t_info->tm_wday > 0) &&
  689.         (t_info->tm_wday < 6))
  690.         if (t_info->tm_min > 50)
  691.         {
  692.             log("Leaving the scene for the serious folks.");
  693.             send_to_all("Closing down. Thank you for flying DikuMUD.\n\r");
  694.             shutdown = 1;
  695.         }
  696.         else if (t_info->tm_min > 40)
  697.             send_to_all("ATTENTION: DikuMUD will shut down in 10 minutes.\n\r");
  698.         else if (t_info->tm_min > 30)
  699.             send_to_all("Warning: The game will close in 20 minutes.\n\r");
  700. }
  701.  
  702.  
  703. void check_reboot(void)
  704. {
  705.     long tc;
  706.     struct tm *t_info;
  707.     char dummy;
  708.     FILE *boot;
  709.  
  710.     extern int shutdown, reboot;
  711.  
  712.     tc = time(0);
  713.     t_info = localtime(&tc);
  714.  
  715.     if ((t_info->tm_hour + 1) == REBOOT_AT && t_info->tm_min > 30)
  716.         if (boot = fopen("./reboot", "r"))
  717.         {
  718.             if (t_info->tm_min > 50)
  719.             {
  720.                 log("Reboot exists.");
  721.                 fread(&dummy, sizeof(dummy), 1, boot);
  722.                 if (!feof(boot))   /* the file is nonepty */
  723.                 {
  724.                     log("Reboot is nonempty.");
  725.                     if (system("./reboot"))
  726.                     {
  727.                         log("Reboot script terminated abnormally");
  728.                         send_to_all("The reboot was cancelled.\n\r");
  729.                         system("mv ./reboot reboot.FAILED");
  730.                         fclose(boot);
  731.                         return;
  732.                     }
  733.                     else
  734.                         system("mv ./reboot reboot.SUCCEEDED");
  735.                 }
  736.  
  737.                 send_to_all("Automatic reboot. Come back in a little while.\n\r");
  738.                 shutdown = reboot = 1;
  739.             }
  740.             else if (t_info->tm_min > 40)
  741.                 send_to_all("ATTENTION: DikuMUD will reboot in 10 minutes.\n\r");
  742.             else if (t_info->tm_min > 30)
  743.                 send_to_all(
  744.                     "Warning: The game will close and reboot in 20 minutes.\n\r");
  745.  
  746.             fclose(boot);
  747.         }
  748. }
  749.  
  750.  
  751. #define GR
  752. #define NEW
  753. #ifdef GR
  754.  
  755.  
  756.  
  757.  
  758. int workhours()
  759. {
  760.     long tc;
  761.     struct tm *t_info;
  762.  
  763.     tc = time(0);
  764.     t_info = localtime(&tc);
  765.  
  766.     return((t_info->tm_wday > 0) && (t_info->tm_wday < 6) && (t_info->tm_hour >= 9)
  767.         && (t_info->tm_hour < 17));
  768. }
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775. /*
  776. * This procedure is *heavily* system dependent. If your system is not set up
  777. * properly for this particular way of reading the system load (It's weird all
  778. * right - but I couldn't think of anything better), change it, or don't use -l.
  779. * It shouldn't be necessary to use -l anyhow. It's oppressive and unchristian
  780. * to harness man's desire to play. Who needs a friggin' degree, anyhow?
  781. */
  782.  
  783. int load(void)
  784. {
  785.     struct syslinfo {
  786.         char    sl_date[12];    /* "Tue Sep 16\0" */
  787.         char    sl_time[8];    /* "11:10\0" */
  788.         char    sl_load1[6];    /* "12.0\0" */
  789.         char    sl_load2[10];    /* "+2.3 14u\0" */
  790.     } info;
  791.     FILE *fl;
  792.     int ld, i, sum;
  793.     static int previous[5];
  794.     static int p_point = -1;
  795.     extern int slow_death;
  796.  
  797.     if (!(fl = fopen("/tmp/.sysline", "r")))
  798.     {
  799.         perror("sysline. (dying)");
  800.         slow_death = 1;
  801.         return(-1);
  802.     }
  803.     if (!fread(&info, sizeof(info), 1, fl))
  804.     {
  805.         perror("fread sysline (dying)");
  806.         slow_death = 1;
  807.         return(-1);
  808.     }
  809.     fclose(fl);
  810.  
  811.     if (p_point < 0)
  812.     {
  813.         previous[0] = atoi(info.sl_load1);
  814.         for (i = 1; i< 5; i++)
  815.             previous[i] = previous[0];
  816.         p_point = 1;
  817.         return(previous[0]);
  818.     }
  819.     else
  820.     {
  821.         /* put new figure in table */
  822.         previous[p_point] = atoi(info.sl_load1);
  823.         if (++p_point > 4)
  824.             p_point = 0;
  825.  
  826.         for (i = 0, sum = 0; i < 5; i++)
  827.             sum += previous[i];
  828.         return((int) sum / 5);
  829.     }
  830. }
  831.  
  832.  
  833.  
  834.  
  835. char *nogames(void)
  836. {
  837.     static char text[200];
  838.     FILE *fl;
  839.  
  840.     if (fl = fopen("lib/nogames", "r"))
  841.     {
  842.         log("/usr/games/nogames exists");
  843.         fgets(text,200,fl);
  844.         return(text);
  845.         fclose(fl);
  846.     }
  847.     else
  848.         return(0);
  849. }
  850.  
  851.  
  852. #ifdef OLD_COMA
  853.  
  854. void coma(void)
  855. {
  856.     extern struct descriptor_data *descriptor_list;
  857.     extern int tics;
  858.  
  859.     void close_socket(struct descriptor_data *d);
  860.  
  861.     log("Entering comatose state");
  862.  
  863.     while (descriptor_list)
  864.         close_socket(descriptor_list);
  865.  
  866.     do
  867.     {
  868.         sleep(300);
  869.         tics = 1;
  870.         if (workhours())
  871.         {
  872.             log("Working hours collision during coma. Exit.");
  873.             exit(0);
  874.         }
  875.     }
  876.     while (load() >= 6);
  877.  
  878.     log("Leaving coma");
  879. }
  880.  
  881. #endif
  882.  
  883.  
  884.  
  885. /* emulate the game regulator */
  886. void gr(int s)
  887. {
  888.     char *txt = 0, buf[1024];
  889.     int ld = 0;
  890.     static char *warnings[3] =
  891.     {
  892.         "If things don't look better within 3 minutes, the game will pause.\n\r",
  893.         "The game will close temporarily 2 minutes from now.\n\r",
  894.         "WARNING: The game will close in 1 minute.\n\r"
  895.      };
  896.     static int wnr = 0;
  897.  
  898.     extern int slow_death, shutdown;
  899.  
  900.     void send_to_all(char *messg);
  901.  
  902.     void coma(int s);
  903.  
  904.     if (((ld = load()) >= 6) || (txt = nogames()) || slow_death)
  905.     {
  906.         if (ld >= 6)
  907.         {
  908.             sprintf(buf, "The system load is greater than 6.0 (%d)\n\r", ld);
  909.             send_to_all(buf);
  910.         }
  911.         else if (slow_death)
  912.             send_to_all("The game is dying.\n\r");
  913.         else
  914.         {
  915.             strcpy(buf,
  916.                 "Game playing is no longer permitted on this machine:\n\r");
  917.             strcat(buf, txt);
  918.             strcat(buf, "\n\r"); 
  919.             send_to_all(buf);
  920.         }
  921.  
  922.         if (wnr < 3)
  923.             send_to_all(warnings[wnr++]);
  924.         else
  925.             if (ld >= 6)
  926.             {
  927.                 coma(s);
  928.                 wnr = 0;
  929.             }
  930.             else
  931.                 shutdown = 1;
  932.     }
  933.     else if (workhours())
  934.         shutdown = 1;                /* this shouldn't happen */
  935.     else if (wnr)
  936.     {
  937.         send_to_all("Things look brighter now - you can continue playing.\n\r");
  938.         wnr = 0;
  939.     }
  940. }
  941.  
  942.  
  943.  
  944. #endif
  945.