home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume14 / mine / part01 / main.c < prev    next >
C/C++ Source or Header  |  1992-08-31  |  14KB  |  778 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <errno.h>
  5. #include <fcntl.h>
  6. #include <termio.h>
  7. #include <signal.h>
  8. #include <unistd.h>
  9. #include <sys/time.h>
  10. #include <pwd.h>
  11.  
  12. static char copyright[] = "@(#) Copyright (c) O. Thery 1992";
  13.  
  14. #define VERSION "1.4"
  15. #define X_SCORE 60
  16. #define Y_SCORE 7
  17.  
  18. extern int    errno;
  19.  
  20. char *basename();
  21. char *getenv();
  22. char    *shell;
  23.  
  24. extern char    *logname;
  25. extern int logfile;
  26.  
  27. char *k_lft = "h";    /* left key */
  28. char *k_rgt = "l";    /* right key */
  29. char *k_up = "k";    /* up key */
  30. char *k_dwn = "j";    /* down key */
  31.  
  32. int l_lft = 1;
  33. int l_rgt = 1;
  34. int l_up = 1;
  35. int l_dwn = 1;
  36.  
  37. static ocount;
  38. static oremain;
  39.  
  40.  
  41. int found; /* Found bomds */
  42. int remain; /* Posed bomb */
  43.  
  44. int good_found;
  45. int max_found;
  46.  
  47. int best_count = 10000;
  48. int counter;
  49. int counter0;
  50.  
  51. #define F_L 58
  52. #define F_H 22
  53.  
  54. #define F_X 32
  55. #define F_Y 16
  56.  
  57. unsigned char field[F_L * F_H];
  58.  
  59. int f_x = F_X;
  60. int f_y = F_Y;
  61.  
  62. int f_x0; /* Left corner of the field */
  63. int f_y0;
  64.  
  65. int bomb;
  66.  
  67. int pos_x;
  68. int pos_y;
  69. int pos_n;
  70.  
  71. char ibuf[128];
  72.  
  73. #define BOOM 128
  74. #define FLAG 64
  75. #define DONE 32
  76. #define MASK 31
  77.  
  78.  
  79. struct termio tinit;
  80.  
  81. struct w {
  82.     char n[14];
  83.     short t;
  84. };
  85.  
  86. struct w *score;
  87. struct w *get_score();
  88.  
  89. myexit(i)
  90. {
  91.     s_pc(0, 23, 0);
  92.     sleep(1);
  93.     ioctl(0, TCSETA, &tinit);
  94.     s_term();
  95.     if(i == 5)
  96.         abort();
  97.     exit(i);
  98. }
  99.  
  100. sigalr()
  101. {
  102.     myexit(5);
  103. }
  104.  
  105. main(argc, argv)
  106. int    argc;
  107. char    *argv[];
  108. {
  109.     struct fd_set ibits;
  110.     struct timeval tim;
  111.     int i = 0;
  112.     int k;
  113.  
  114.     signal(SIGALRM, sigalr);
  115.     argc--, argv++;
  116.     while (argc > 0) {
  117.         switch (argv[0][0]) {
  118.         case '-':
  119.             if(argv[0][1] == 'n' && argv[0][2] == 0) {
  120.                 argv++;
  121.                 argc--;
  122.                 bomb = atoi(*argv);
  123.             } else if(argv[0][1] == 'f' && argv[0][2] == 0) {
  124.                 bomb = 10;
  125.                 f_x = 8;
  126.                 f_y = 8;
  127.             } else if(!strcmp(&argv[0][1], "score")) {
  128.                 char *n;
  129.                 int t;
  130.                 int chk;
  131.                 argv++;
  132.                 argc--;
  133.                 chk = f_x = atoi(*argv);
  134.                 argv++;
  135.                 argc--;
  136.                 chk ^= f_y = atoi(*argv);
  137.                 argv++;
  138.                 argc--;
  139.                 chk ^= bomb = atoi(*argv);
  140.                 argv++;
  141.                 argc--;
  142.                 n = *argv;
  143.                 t = 0;
  144.                 for(i = 0; n[i]; i++)
  145.                     t += n[i]<<i;
  146.                 chk ^= t;
  147.                 argv++;
  148.                 argc--;
  149.                 chk ^= t = atoi(*argv);
  150.                 argv++;
  151.                 argc--;
  152.                 if(atoi(*argv) != chk)
  153.                     exit(1);
  154.                 set_score(f_x, f_y, bomb, n, t);
  155.                 exit(0);
  156.             } else
  157.                 usage();
  158.             break;
  159.         case '0':
  160.         case '1':
  161.         case '2':
  162.         case '3':
  163.         case '4':
  164.         case '5':
  165.         case '6':
  166.         case '7':
  167.         case '8':
  168.         case '9':
  169.             if(!i++) {
  170.                 k = atoi(*argv);
  171.                 if(k < 3)
  172.                     break;
  173.                 if(k > F_L)
  174.                     k = F_L;
  175.                 f_x = k;
  176.             } else {
  177.                 k = atoi(*argv);
  178.                 if(k < 3)
  179.                     break;
  180.                 if(k > F_H)
  181.                     k = F_H;
  182.                 f_y = k;
  183.             }
  184.             break;
  185.         default:
  186.             usage();
  187.         }
  188.         argc--;
  189.         argv++;
  190.     }
  191.  
  192.     tim.tv_sec = 0;
  193.     tim.tv_usec = 0;
  194.  
  195.     FD_ZERO(&ibits);
  196.  
  197.     while(1) {
  198.         char tmp[256];
  199.         char c;
  200.  
  201.         init();
  202.         if(mloop())
  203.             continue;
  204.         FD_SET(0, &ibits);
  205.         i = select(2, &ibits, (fd_set *)0, (fd_set *)0, &tim);
  206.         if(i)
  207.             read(0, tmp, 250);
  208.         while(1) {
  209.             FD_SET(0, &ibits);
  210.             i = select(2, &ibits, (fd_set *)0, (fd_set *)0, 0);
  211.             read(0, &c, 1);
  212.             if(c == 'q' || c == 'Q')
  213.                 myexit(0);
  214.             else if(c == 'n' || c == 'N')
  215.                 break;
  216.             else if(c == 'c' || c == 'C') {
  217.                 chief();
  218.                 break;
  219.             }
  220.         }
  221.     }
  222. }
  223.  
  224. mloop()
  225. {
  226.     int i, k, rc, l = 0;
  227.     struct fd_set ibits;
  228.     struct timeval tim;
  229.  
  230.     tim.tv_sec = 1;
  231.     tim.tv_usec = 0;
  232.  
  233.     FD_ZERO(&ibits);
  234.  
  235.     for (; ; ) {
  236.         FD_SET(0, &ibits);
  237.         upd_counter();
  238.         switch (select(2, &ibits, (fd_set *)0, (fd_set *)0, &tim)) {
  239.         case -1:
  240.             if (errno == EINTR)
  241.                 continue;
  242.             myexit(1);
  243.         case 0:
  244.             break;
  245.         case 1:
  246.             rc = read(0, ibuf + l, sizeof(ibuf) - 1 - l);
  247.             rc += l;
  248.             l = 0;
  249.             ibuf[rc] = 0;
  250.             for(i = 0; i < rc;) {
  251.                 if(!strncmp(&ibuf[i], k_up, l_up))  {
  252.                     if(pos_y) {
  253.                         pos_y--;
  254.                         pos_n -= f_x;
  255.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  256.                     }
  257.                     i += l_up;
  258.                 } else if(!strncmp(&ibuf[i], k_dwn, l_dwn))  {
  259.                     if(pos_y < f_y - 1) {
  260.                         pos_y++;
  261.                         pos_n += f_x;
  262.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  263.                     }
  264.                     i += l_dwn;
  265.                 } else if(!strncmp(&ibuf[i], k_lft, l_lft))  {
  266.                     if(pos_x) {
  267.                         pos_x--;
  268.                         pos_n -= 1;
  269.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  270.                     }
  271.                     i += l_lft;
  272.                 } else if(!strncmp(&ibuf[i], k_rgt, l_rgt))  {
  273.                     if(pos_x < f_x - 1) {
  274.                         pos_x++;
  275.                         pos_n += 1;
  276.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  277.                     }
  278.                     i += l_rgt;
  279.                 } else if(ibuf[i] == 'F' || ibuf[i] == 'f') {
  280.                     if(field[pos_n] & FLAG) {
  281.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, ' ');
  282.                         field[pos_n] &= ~FLAG;
  283.                         if(field[pos_n] & BOOM) {
  284.                             found--;
  285.                         }
  286.                         remain++;
  287.                     } else if(!(field[pos_n] & DONE)){
  288.                         s_bold();
  289.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, 'F');
  290.                         s_rmso();
  291.                         field[pos_n] |= FLAG;
  292.                         if(field[pos_n] & BOOM) {
  293.                             found++;
  294.                         }
  295.                         remain--;
  296.                     }
  297.                     i = rc;
  298.                     upd_counter();
  299.                 } else if (ibuf[i] == ' ') {
  300.                     if(!counter0){
  301.                         fill_field(pos_n);
  302.                     }
  303.                     if((field[pos_n] & BOOM) && !(field[pos_n] & FLAG)) {
  304.                         sleep(1);
  305.                         s_bold();
  306.                         s_pc(f_x0 + pos_x, f_y0 + pos_y, '@');
  307.                         s_rmso();
  308.                         field[pos_n] |= FLAG;
  309.                         bad_exit();
  310.                         return(0);
  311.                     } else if (!(field[pos_n]&(FLAG|DONE))) {
  312.                         make_move(pos_n, pos_x, pos_y);
  313.                         upd_counter();
  314.  
  315.                         if(good_found == max_found) {
  316.                             return(good_exit());
  317.                         }
  318.                     }
  319.                     i = rc;
  320.                 } else if (ibuf[i] == 'q' || ibuf[i] == 'Q') {
  321.                     myexit(0);
  322.                 } else if(ibuf[i] == 'n' || ibuf[i] == 'N') {
  323.                     return(1);
  324.                 } else if(ibuf[i] == 'r' || ibuf[i] == 'R') {
  325.                     redraw();
  326.                     i = rc;
  327.                 } else if(ibuf[i] == 'c' || ibuf[i] == 'C') {
  328.                     chief();
  329.                     i = rc;
  330.                 } else if(ibuf[i] == 'p' || ibuf[i] == 'P') {
  331.                     pausing();
  332.                     i = rc;
  333.                 } else {
  334.                     l = rc - i;
  335.                     if(!strncmp(&ibuf[i], k_rgt, l) || !strncmp(&ibuf[i], k_lft, l) ||
  336. !strncmp(&ibuf[i],
  337.                         k_dwn, l) || !strncmp(&ibuf[i], k_up, l)) {
  338.                         for(k = 0; k < l; k++)
  339.                             ibuf[k] = ibuf[k+i];
  340.                         i = rc;
  341.                     } else {
  342.                         l = 0;
  343.                         i++;
  344.                     }
  345.                 }
  346.             }
  347.         }
  348.     }
  349. }
  350.  
  351. make_move(n, x, y)
  352. int n;
  353. int x;
  354. int y;
  355. {
  356.     if(field[n]&~MASK)
  357.         return;
  358.     field[n] |= DONE;
  359.     good_found++;
  360.     s_pc(f_x0 + x, f_y0 + y, '0' + (field[n]&MASK));
  361.     if(field[n]&MASK)
  362.         return;
  363.     if(x > 0) {
  364.         make_move(n - 1, x - 1, y);
  365.         if(y > 0) {
  366.             make_move(n - 1 - f_x, x - 1, y - 1);
  367.         }
  368.  
  369.     }
  370.     if(y > 0) {
  371.         make_move(n - f_x, x, y - 1);
  372.         if(x < f_x - 1) {
  373.             make_move(n + 1 - f_x, x + 1, y - 1);
  374.         }
  375.     }
  376.     if(x < f_x - 1) {
  377.         make_move(n + 1, x + 1, y);
  378.         if(y < f_y - 1) {
  379.             make_move(n + f_x + 1, x + 1, y + 1);
  380.         }
  381.     }
  382.     if(y < f_y - 1) {
  383.         make_move(n + f_x, x, y + 1);
  384.         if(x > 0) {
  385.             make_move(n - 1 + f_x, x - 1, y + 1);
  386.         }
  387.     }
  388. }
  389.  
  390. good_exit()
  391. {
  392.     char n[14];
  393.     int i;
  394.     char c;
  395.     FILE *fd;
  396.  
  397.     s_pr(X_SCORE + 3, Y_SCORE - 1, "Won !!!");
  398.     if(counter >= best_count)
  399.         return(0);
  400.     sleep(1);
  401.     for(i = 0; i < 14; i++)
  402.         n[i] = 0;
  403. #define X_NAME 30
  404. #define Y_NAME 11
  405.     s_box(X_NAME, Y_NAME, 15, 2);
  406.     s_pr(X_NAME + 1, Y_NAME + 1, "              ");
  407.     s_pc(X_NAME + 1, Y_NAME + 1, 0);
  408.     i = 0;
  409.     while(1) {
  410.         read(0, &c, 1);
  411.         switch(c) {
  412.         case 8:
  413.             if(i == 0)
  414.                 break;
  415.             i--;
  416.             s_pc(X_NAME + 1 + i, Y_NAME + 1, ' ');
  417.             s_pc(X_NAME + 1 + i, Y_NAME + 1, 0);
  418.             break;
  419.         case '\n':
  420.         case '\r':
  421.             set_score(f_x, f_y, bomb, n, counter);
  422.             fd = fopen("/etc/mine.score", "r");
  423.             if(fd) {
  424.                 char cmd[256];
  425.                 char tmp[256];
  426.                 int chk = f_x ^ f_y ^ bomb ^ counter;
  427.                 int j;
  428.                 for(j = i = 0; n[i]; i++)
  429.                     j += n[i] << i;
  430.                 chk ^= j;
  431.                 while(fgets(tmp, 255, fd)) {
  432.                     tmp[strlen(tmp) - 1] = 0;
  433.                     sprintf(cmd, "rshell %s mine -score %d %d %d \"\\\"%s\\\"\" %d %d&\n", tmp, f_x,
  434.                         f_y, bomb, n, counter, chk);
  435.                     system(cmd);
  436.                 }
  437.                 fclose(fd);
  438.             }
  439.             return(1);
  440.             break;
  441.         default:
  442.             if(c < 32 || c > 126)
  443.                 break;
  444.             n[i] = c;
  445.             s_pc(X_NAME + 1 + i, Y_NAME + 1, c);
  446.             if(i < 14)
  447.                 i++;
  448.             s_pc(X_NAME + 1 + i, Y_NAME + 1, 0);
  449.             break;
  450.         }
  451.     }
  452. }
  453.  
  454. bad_exit()
  455. {
  456.     int i;
  457.     int x, y;
  458.     sleep(1);
  459.     s_pr(X_SCORE + 3, Y_SCORE -1, "Lost !!!");
  460.     s_bold();
  461.     for(i = y = 0; y < f_y; y++) {
  462.         for(x = 0; x < f_x; x++, i++) {
  463.             if(field[i] & BOOM) {
  464.                 if(!(field[i] & FLAG))
  465.                     s_pc(f_x0 +x, f_y0 + y, '*');
  466.             } else if(field[i] & FLAG) {
  467.                 s_pc(f_x0 +x, f_y0 + y, '#');
  468.             }
  469.         }
  470.     }
  471.     s_rmso();
  472.     return;
  473. }
  474.  
  475. usage()
  476. {
  477.     fprintf(stderr, "usage:\n    mine [-f] [-n <bombs>] [<x>] [<y>]\n");
  478.     exit(1);
  479. }
  480.  
  481. init()
  482. {
  483.     struct termio tem;
  484.     static ft = 1;
  485.     int i;
  486.  
  487.     if(ft) {
  488.         struct passwd *getpwnam();
  489.         struct passwd *p;
  490.         p = getpwnam("mine");
  491.         if(p)
  492.             setreuid(p->pw_uid, p->pw_uid);
  493.         ioctl(0, TCGETA, &tinit);
  494.         /* Mise du tty en mode raw */
  495.         tem = tinit;
  496.         tem.c_oflag = 0;
  497.         tem.c_lflag = 0;
  498.         tem.c_iflag = 0;
  499.         tem.c_cc[VMIN] = 1;
  500.         tem.c_cc[VTIME] = 1;
  501.         ioctl(0, TCSETA, &tem);
  502.         s_init();
  503.         ft = 0;
  504.     }
  505.     s_clear();
  506.     for(i = 0; i < F_H * F_L; i++)
  507.         field[i] = 0;
  508.     ocount = -1;
  509.     oremain = -1;
  510.     counter0 = 0;
  511.     counter = 0;
  512.     if(!bomb || bomb > f_x * f_y / 2) {
  513.         bomb = 3 * f_x + 3;
  514.         if(bomb > f_x * f_y / 2)
  515.             bomb = (f_x * f_y) / 2;
  516.     }
  517.     remain = bomb;
  518.     good_found = 0;
  519.     max_found = f_x * f_y - bomb;
  520.     pos_x = f_x / 2;
  521.     pos_y = f_y / 2;
  522.     pos_n =  pos_x + pos_y * f_x;
  523.     f_x0 = (F_L - f_x) / 2 + 1;
  524.     f_y0 = (F_H - f_y) / 2 + 1;
  525.     s_box(f_x0 - 1, f_y0 - 1, f_x + 1, f_y + 1);
  526.     score = get_score(f_x, f_y, bomb);
  527.     if(score) {
  528.         best_count = score[4].t ? score[4].t : 10000;
  529.     }
  530.     draw_screen();
  531.     
  532. }
  533.  
  534. draw_screen()
  535. {
  536. int i;
  537.     s_bold();
  538.     s_pr(X_SCORE + 3 , 1, "MineSweeper %s", VERSION);
  539.     s_rmso();
  540.     s_box(X_SCORE, Y_SCORE, 19, 8);
  541.     s_bold();
  542.     s_pr(X_SCORE + 1, Y_SCORE + 1, "    Top  scores   ");
  543.     s_pr(X_SCORE + 1, Y_SCORE + 2, "------------------");
  544.     if(score) {
  545.         for(i = 0; i < 5; i++) {
  546.             if(!score[i].n[0])
  547.                 break;
  548.             s_pr(X_SCORE + 1, Y_SCORE + 3 + i, "%.14s", score[i].n);
  549.             s_pr(X_SCORE + 16, Y_SCORE + 3 + i, "%.3d", score[i].t);
  550.         }
  551.     }
  552.     s_rmso();
  553.     s_pr(X_SCORE, Y_SCORE + 10, " f       : (un)mark");
  554.     s_pr(X_SCORE, Y_SCORE + 11, " <SPACE> : discover");
  555.     s_pr(X_SCORE, Y_SCORE + 12, " n       : new game");
  556.     s_pr(X_SCORE, Y_SCORE + 13, " q       : quit");
  557.     s_pr(X_SCORE, Y_SCORE + 14, " r       : redraw");
  558.     s_pr(X_SCORE, Y_SCORE + 15, " p       : pause");
  559.     s_pr(X_SCORE, Y_SCORE + 16, " c       : boss");
  560.     s_box(63, 3, 6, 2);
  561.     s_box(71, 3, 6, 2);
  562. }
  563.  
  564. fill_field(n)
  565. int n;
  566. {
  567.     int i;
  568.     int s = f_x * f_y;
  569.  
  570.     counter0 = time(0);
  571.     memset(field, 0, sizeof(field));
  572.     found = 0;
  573.     remain = 0;
  574.     do {
  575.         int x, y;
  576.         i = aleat(s);
  577.         if(field[i] & BOOM || i == n)
  578.             continue;
  579.         field[i] |= BOOM;
  580.         if(field[i]&FLAG)
  581.             found++;
  582.         x = i % f_x;
  583.         y = i / f_x;
  584.         if(x > 0)
  585.             field[i - 1]++;
  586.         if(y > 0) {
  587.             field[i - f_x]++;
  588.             if(x > 0)
  589.                 field[i - 1 - f_x]++;
  590.             if(x < f_x - 1)
  591.                 field[i + 1 - f_x]++;
  592.         }
  593.         if(y < f_y - 1) {
  594.             field[i + f_x]++;
  595.             if(x < f_x - 1)
  596.                 field[i + 1 + f_x]++;
  597.             if(x > 0)
  598.                 field[i - 1 + f_x]++;
  599.         }
  600.         if(x < f_x - 1)
  601.             field[i + 1]++;
  602.         remain++;
  603.     } while(remain != bomb);
  604. }
  605.  
  606. aleat(s)
  607. unsigned int s;
  608. {
  609.     static unsigned int ft;
  610.  
  611.     if(!ft) {
  612.         ft = time(0);
  613.     }
  614.     ft *= 3793;
  615.     ft ^= 49834897;
  616.     ft >>= 2;
  617.     return(ft % s);
  618. }
  619.  
  620. upd_counter()
  621. {
  622.  
  623.     if(counter0) {
  624.         counter = time(0) - counter0;
  625.         if(counter > 999)
  626.             counter = 999;
  627.     }
  628.     if(oremain == remain && ocount == counter) {
  629.         s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  630.         return;
  631.     }
  632.     s_civis();
  633.     if(ocount != counter) {
  634.         s_pr(64, 4, " %3.3d", counter);
  635.         ocount = counter;
  636.     }
  637.     if(remain != oremain) {
  638.         if(remain < 0)
  639.             s_pr(72, 4, "%3.3d", remain);
  640.         else 
  641.             s_pr(72, 4, " %3.3d", remain);
  642.         oremain = remain;
  643.     }
  644.     s_cnorm();
  645.     s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  646. }
  647.  
  648. redraw() {
  649.     int i;
  650.     int j;
  651.     int k;
  652.     int l;
  653.     int p;
  654.     char tmp[256];
  655.  
  656.     s_clear();
  657.     s_civis();
  658.     s_box(f_x0 - 1, f_y0 - 1, f_x + 1, f_y + 1);
  659.     for(i = 0, k = 0; i < f_y; i++) {
  660.         for(j = 0, l = 0, p = 0; j < f_x; j++, k++) {
  661.             if(field[k] & FLAG) {
  662.                 if(l) {
  663.                     tmp[l] = 0;
  664.                     s_pr(f_x0 + p, f_y0 + i, "%s", tmp);
  665.                     l = 0;
  666.                 }
  667.                 s_bold();
  668.                 s_pc(f_x0 + j, f_y0 + i, 'F');
  669.                 s_rmso();
  670.                 p = j+1;
  671.             } else {
  672.                 tmp[l++] = (field[k] & DONE) ? (field[k] & MASK) + '0' : ' ';
  673.             }
  674.         }
  675.         if(l) {
  676.             tmp[l] = 0;
  677.             s_pr(f_x0 + p, f_y0 + i, "%s", tmp);
  678.         }
  679.     }
  680.     draw_screen();
  681.     s_pr(64, 4, " %3.3d", counter);
  682.     if(remain < 0)
  683.         s_pr(72, 4, "%3.3d", remain);
  684.     else 
  685.         s_pr(72, 4, " %3.3d", remain);
  686.     s_pc(f_x0 + pos_x, f_y0 + pos_y, 0);
  687.     s_cnorm();
  688. }
  689.  
  690. #define LENGTH  35
  691. #define FORMAT "%35.35s"
  692. #define X_MIDLE ((80 - LENGTH) / 2 - 1)
  693. #define Y_MIDLE 11
  694.  
  695. pausing() {
  696.     int i;
  697.     int j;
  698.     char tmp[256];
  699.     int pos;
  700.     int len;
  701.     struct fd_set ibits;
  702.     struct timeval tim;
  703.     int t;
  704.  
  705.     s_civis();
  706.     for(j = 0; j < f_x; j++) {
  707.         tmp[j] = ' ';
  708.     }
  709.     tmp[j] = 0;
  710.     for(i = 0; i < f_y; i++) {
  711.         s_pr(f_x0, f_y0 + i, "%s", tmp);
  712.     }
  713.  
  714.     s_box(X_MIDLE, Y_MIDLE, LENGTH + 1, 2);
  715.     t = time(0);
  716.     strftime(tmp, 256, "Local time is %R, press a key to continue. ", localtime(&t));
  717.     len = strlen(tmp);
  718.  
  719.     tim.tv_sec = 0;
  720.     tim.tv_usec = 450000;
  721.  
  722.     FD_ZERO(&ibits);
  723.  
  724.     pos = 0;
  725.     while(1) {
  726.         FD_SET(0, &ibits);
  727.         i = select(2, &ibits, (fd_set *)0, (fd_set *)0, &tim);
  728.         if(i) {
  729.             read(0, tmp, 250);
  730.             redraw();
  731.             if(counter0)
  732.                 counter0 = time(0) - counter;
  733.             return;
  734.         } else {
  735.             s_pr(X_MIDLE + 1, Y_MIDLE + 1, FORMAT, tmp+pos++);
  736.             if(pos + LENGTH == len) {
  737.                 t = time(0);
  738.                 strftime(tmp + len, 256 - len, "Local time is %R, press a key to continue. ", localtime(&t));
  739.             } else if(pos == len) {
  740.                 strcpy(tmp, tmp+len);
  741.                 len = strlen(tmp);
  742.                 pos = 0;
  743.             }
  744.         }
  745.     }
  746. }
  747.  
  748. chief() {
  749. char *n = getenv("CHIEFCMD");
  750. struct fd_set ibits;
  751. int i;
  752. char b[250];
  753. struct termio nterm;
  754.  
  755.     s_clear();
  756.     if(n) {
  757.         ioctl(0, TCGETA, &nterm);
  758.         ioctl(0, TCSETA, &tinit);
  759.         system(n);
  760.         ioctl(0, TCSETA, &nterm);
  761.     } else {
  762.         printf("$ ");
  763.         fflush(stdout);
  764.     }
  765.     FD_ZERO(&ibits);
  766.     while(1) {
  767.         FD_SET(0, &ibits);
  768.         i = select(2, &ibits, (fd_set *)0, (fd_set *)0, 0);
  769.         if(i) {
  770.             read(0, b, 250);
  771.             redraw();
  772.             if(counter0)
  773.                 counter0 = time(0) - counter;
  774.             return;
  775.         }
  776.     }
  777. }
  778.