home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / MISC / stf.lzh / stf.c < prev    next >
Text File  |  1994-04-24  |  11KB  |  422 lines

  1. /************************************************************************
  2. * stfortune.c                                                            *
  3. *************************************************************************
  4. * A program designed to print Star Trek quotes from a disk file. This   *
  5. * program has successfully been compiled on a variety of platforms and  *
  6. * operating systems.                                                    *
  7. *************************************************************************
  8. * Original Code: Scott McGee  8/28/92                                    *
  9. *************************************************************************
  10. * Copyright 1992, 1993 by Scott McGee                                   *
  11. *                                                                        *
  12. * This program is my own work and is protected by copyright laws. It is *
  13. * provided free of charge on the condition that it not be altered or    *
  14. * sold for profit without my prior express written permission. If you   *
  15. * make changes you feel improve the program, please send them to me. If *
  16. * I agree, I will add your changes to my code (with comments giving you *
  17. * credit, of course). I can be reached by email at smcgee@microware.com *
  18. ************************************************************************/
  19.  
  20. /************************************************************************
  21.  revision history
  22.  
  23.  date     who what
  24.  12/15/92 sam added -f and -I options
  25.  01/07/93 sam added ranges
  26.  01/11/93 sam added coco modifications from Boisy Pitre
  27.  01/13/93 sam fixed bug in ranges
  28.  01/27/93 sam added environment variables
  29.  01/29/93 sam fixed bug in ranges when end_range > number of quotes
  30.  02/19/93 sam fixed bug with program name in help output
  31.  02/19/93 sam made do_index close files (fixed "read error in index file")
  32.  02/21/93 sam coco fixes from Boisy Pitre (8 significant chars on #defines!)
  33.  03/09/93 sam changes to compile on OS-9000 without Ultra C
  34.  03/14/93 sam changes in header format for portability (define capabilities)
  35. ************************************************************************/
  36.  
  37.  
  38. /* NOTE TO USERS: if you are compiling this on anything other than an OS-9
  39.    system, or a sun3 or sun4, you may have to look through the following
  40.    definitions to see if you need to define any from the command line for
  41.    your compiler. For instance, if you are compiling on a system that has
  42.    no string.h header, you should define NO_STRING_H on the compiler command
  43.    line. Also, be sure to modify the default paths found below the defines!
  44. */
  45.  
  46. /* define some capabilities dealing with portability issues:
  47.  
  48. NO_STRING_H        system DOES NOT HAVE a string.h header (use strings.h)
  49. */
  50.  
  51. #ifndef _UCC        /* no Ultra C compiler */
  52. #    ifdef OSK        /* old cc for osk */
  53. #        define NO_STRING_H
  54. #    endif
  55. #    ifdef _OS9000    /* old cc for os-9000 */
  56. #        define NO_STRING_H
  57. #    endif
  58. #endif
  59.  
  60. /*
  61. OSK_HELP        system CAN use -? for help (otherwise, use -h)
  62. */
  63.  
  64. #ifdef OSK            /* OS-9 680x0 system */
  65. #    define OSK_HELP
  66. #endif
  67.  
  68. #ifdef _OS9000        /* OS-9000 system */
  69. #    define OSK_HELP
  70. #endif
  71.  
  72. #ifdef OS9            /* OS-9 6809 system */
  73. #    define OSK_HELP
  74. #endif
  75.  
  76. /*
  77. NO_ENVIRONMENT        system does NOT support environment variables
  78. */
  79.  
  80. #ifdef OS9
  81. #    define NO_ENVIRONMENT
  82. #endif
  83.  
  84.  
  85. #include <stdio.h>
  86. #include <time.h>
  87. #include <stdlib.h>
  88. #include <ctype.h>
  89. #include <math.h>
  90.  
  91. #ifndef NO_STRING_H
  92. #    include <string.h>            /* good, we can use string.h */
  93. #else
  94. #    include <strings.h>            /* use strings.h and redefine rindex */
  95. #    define strrchr(a,b) rindex(a,b)
  96. #endif
  97.  
  98.  
  99. /* platform specific stuff */
  100.  
  101. /* OS-9 6809 has no void and must define unsigned int as just int */
  102. #ifdef OS9
  103. #    define u_int int
  104. #    define void int
  105. #else
  106. #    define u_int unsigned int
  107. #endif
  108.  
  109.  
  110. #define TRUE 1
  111. #define FALSE 0
  112.  
  113.  
  114. /*
  115.     These are the default paths for the stquote file and the index file. These
  116.     locations is valid on MY machine only. If you compile this on your machine,
  117.     make sure to change this!
  118. */
  119. #define QUOTEFILE_DEFAULT "/home/bear/smcgee/usr/lib/stquotes"
  120. #define INDEXFILE_DEFAULT "/home/bear/smcgee/usr/lib/stqindex"
  121.  
  122. /*
  123.     These global variables hold the names of the index and quote file. These
  124.     are initialized to the constants defined above.
  125. */
  126. char *filename;
  127. char *indexname;
  128.  
  129.  
  130. void do_help(prog_name)
  131.   char *prog_name;
  132. {
  133.     char *tmp;
  134.  
  135.     tmp = strrchr(prog_name, '/');
  136.     if(tmp != NULL)
  137.         prog_name = tmp+1;
  138.  
  139.     fprintf(stderr, "\n%s: a program to print out quotes from Star Trek\n\n", prog_name);
  140.     fprintf(stderr, "Usage:\n");
  141.     fprintf(stderr, "  %s (opts)   : print a quote at random\n", prog_name);
  142.     fprintf(stderr, "  %s (opts) n : print quote number n\n", prog_name);
  143.     fprintf(stderr, "     The value of n is used mod the number of quotes.\n");
  144.     fprintf(stderr, "     Multiple quote numbers may be specified on one line.\n");
  145.     fprintf(stderr, "     Ranges may be specified by placing a dash ('-') \n");
  146.     fprintf(stderr, "     between the two number. (ie 1-4)\n\n");
  147.     fprintf(stderr, "Options      -i      : remake index file\n");
  148.     fprintf(stderr, "             -u      : don't use index file\n");
  149.     fprintf(stderr, "             -n      : print quote number before quote\n");
  150.     fprintf(stderr, "             -f=file : use 'file' for quotefile\n");
  151.     fprintf(stderr, "             -I=file : use 'file' for indexfile\n");
  152. #ifdef OSK_HELP
  153.     fprintf(stderr, "             -?      : print this help message\n");
  154. #else
  155.     fprintf(stderr, "             -h      : print this help message\n");
  156. #endif
  157. #ifndef OS9
  158.     fprintf(stderr, "\nThe environment variables QUOTEFILE and INDEXFILE can\n");
  159.     fprintf(stderr, "be used to specify the quotefile and indexfile used.\n");
  160. #endif
  161.     fprintf(stderr, "\n\t(Copyright 1992 by Scott McGee)\n\n");
  162.     exit(0);
  163. }
  164.  
  165.  
  166. void seek(count, quotefp)
  167.   int count;
  168.   FILE *quotefp;
  169. {
  170.     long fpos;
  171.     char buf[255];
  172.     FILE *indexfp;
  173.     int  status;
  174.     
  175.     strcpy(buf, indexname);
  176.     if((indexfp = fopen(buf, "r")) == NULL){
  177.         fprintf(stderr, "Cannot open index file \"%s\"!\n", buf);
  178.         exit(0);
  179.      }
  180.  
  181.      status = fseek(indexfp, (long)(count*sizeof(long)), 0);
  182.     if(status != 0){
  183.         fprintf(stderr, "Seek error in index file!\n");
  184.         exit(0);
  185.     }
  186.  
  187.     status = fread(&fpos, sizeof(long), 1, indexfp);
  188.     if(status == 0){
  189.         fprintf(stderr, "Error reading file position from index file!\n");
  190.         exit(0);
  191.     }
  192.  
  193.     status = fseek(quotefp, fpos, 0);
  194.     if(status != 0){
  195.         fprintf(stderr, "Seek error in quote file!\n");
  196.         exit(0);
  197.     }
  198. }
  199.  
  200.  
  201. int do_index(){
  202.     long fpos;
  203.     int  entry;
  204.     int  count;
  205.     char buf[255];
  206.     char *not_done;
  207.     FILE *infp;
  208.     FILE *outfp;
  209.     
  210.     strcpy(buf, indexname);
  211.     if((outfp=fopen(buf, "w")) == NULL){
  212.         fprintf(stderr, "Cannot open output file \"%s\"!\n", buf);
  213.         exit(0);
  214.     }
  215.  
  216.     strcpy(buf, filename);
  217.     if((infp=fopen(buf, "r")) == NULL){
  218.         fclose(outfp);
  219.         fprintf(stderr, "Cannot open input file \"%s\"!\n", buf);
  220.         exit(0);
  221.     }
  222.     
  223.     printf("Please wait while index file is created!\n");
  224.     count = -1;
  225.     not_done = (char *) 1;
  226.     fgets(buf, 255, infp);            /* skip count */
  227.     while(not_done){
  228.         fpos = ftell(infp);
  229.         not_done = fgets(buf, 255, infp);
  230.         if(not_done){
  231.             buf[5] = '\0';
  232.             entry = atoi(buf);
  233.             if(entry != count){
  234.                 fwrite(&fpos, sizeof(long), 1, outfp);
  235.                 count = entry;
  236.             }
  237.         }
  238.     }
  239.     fclose(outfp);
  240.     fclose(infp);
  241.     return(count);
  242. }
  243.  
  244.  
  245. int read_quote(filename, unindex, got_quote_number, print_number, quote_number)
  246.   char    *filename;
  247.   int    unindex;
  248.   int    got_quote_number;
  249.   int    print_number;
  250.   int    quote_number;
  251. {
  252.     int        quotes;
  253.     int        number;
  254.     u_int    rand;
  255.     char    *not_done;
  256.     char    line[255];
  257.     FILE    *stqfile;
  258.                     
  259.     if((stqfile = fopen(filename, "r")) != NULL){
  260.         not_done = fgets(line, 255, stqfile);
  261.         if(not_done){
  262.             quotes = atoi(line);
  263.             if(!quotes){
  264.                 fprintf(stderr, "Number of quotes not accessible!\n");
  265.                 exit(0);
  266.             }
  267.             
  268.             if(!got_quote_number){
  269.                     rand = (unsigned) time(0) & 0xffff;
  270.                     rand = (rand * 25173 + 13849) % 65536;
  271.                 quote_number = (abs(rand%quotes)+1);
  272.             }else
  273.                 if((quote_number < 0) || (quote_number > quotes))
  274.                     quote_number = quote_number%quotes;
  275.  
  276.             if(unindex){
  277.                 do{
  278.                     not_done = fgets(line, 255, stqfile);
  279.                     line[5] = '\0';
  280.                     number = atoi(line);
  281.                 }while(not_done && (number < quote_number));
  282.             }else{
  283.                 seek(quote_number, stqfile);
  284.                 not_done = fgets(line, 255, stqfile);
  285.                 line[5] = '\0';
  286.                 number = atoi(line);
  287.             }
  288.  
  289.             if(print_number)
  290.                 printf("Quote number %d\n", quote_number);
  291.  
  292.             while(not_done && (number == quote_number)){
  293.                 printf("%s", &line[6]);
  294.                 not_done = fgets(line, 255, stqfile);
  295.                 line[5] = '\0';
  296.                 number = atoi(line);
  297.             }
  298.  
  299.             printf("\n");
  300.             
  301.         }else{
  302.             fprintf(stderr, "Invalid file contents in file \"%s\"!\n", filename);
  303.             exit(0);
  304.         }        
  305.     }else{
  306.         fprintf(stderr, "Whoops! Can't open \"%s\" !!\n", filename);
  307.         exit(0);
  308.     }
  309.     return(quotes);
  310. }
  311.  
  312. int main(argc, argv)
  313.   int argc;
  314.   char *argv[];
  315. {
  316.     int        quote_number;
  317.     int        i;
  318.     int        u_flag;
  319.     int        number_flag;
  320.     int        n_flag;
  321.     int        range;
  322.     int        range_end;
  323.     int        env_index;
  324.     int        quotes;
  325.     char*    ptr;
  326.  
  327. /* initialize global filename variables */
  328.     env_index = FALSE;
  329.  
  330. #ifdef NO_ENVIRONMENT
  331.     filename = QUOTEFILE_DEFAULT;
  332.     indexname = INDEXFILE_DEFAULT;
  333. #else
  334.     filename = getenv("QUOTEFILE");
  335.     if(filename == NULL)
  336.         filename = QUOTEFILE_DEFAULT;
  337.  
  338.     indexname = getenv("INDEXFILE");
  339.     if(indexname == NULL)
  340.         indexname = INDEXFILE_DEFAULT;
  341.     else
  342.         env_index = TRUE;
  343. #endif
  344.  
  345. /* initialize arguement flag variables */
  346.     u_flag = FALSE;
  347.     number_flag = FALSE;
  348.     n_flag = FALSE;
  349.  
  350. /* parse arguements */
  351.     for(i=1;i<argc;i++){
  352.         if((argv[i][0] == '-') || (argv[i][0] == '/')){
  353.             switch (argv[i][1]){
  354.                 case '?':
  355.                 case 'h':
  356.                     do_help(argv[0]);
  357.                 case 'i':
  358.                     quote_number = do_index();
  359.                     number_flag = TRUE;
  360.                     n_flag = TRUE;
  361.                     break;
  362.                 case 'u':
  363.                     u_flag = TRUE;
  364.                     break;
  365.                 case 'n':
  366.                     n_flag = TRUE;
  367.                     break;
  368.                 case 'f':
  369.                     filename = &argv[i][3];
  370.                     if((indexname == INDEXFILE_DEFAULT) || (env_index == TRUE))
  371.                         u_flag = TRUE;
  372.                     break;
  373.                 case 'I':
  374.                     indexname = &argv[i][3];
  375.                     u_flag = FALSE;
  376.                     break;
  377.                 default :
  378.                     fprintf(stderr, "stfortune: unknown option \"%s\"\n", argv[i]);
  379.                     do_help(argv[0]);
  380.             }
  381.         }else{
  382.             range = FALSE;
  383.             quote_number = 0;
  384.             quotes = 0;
  385.             ptr = argv[i];
  386.  
  387.             while(isdigit(*ptr)){
  388.                 quote_number *= 10;
  389.                 quote_number += *ptr - '0';
  390.                 ptr++;
  391.             }
  392.  
  393.             if(*ptr == '-'){
  394.                 ptr++;
  395.                 range = TRUE;
  396.                 range_end = atoi(ptr);
  397.                 if(range_end < quote_number)
  398.                     range = FALSE;
  399.             }
  400.  
  401.             number_flag = TRUE;
  402.             if((i<(argc-1)) || (range == TRUE)){
  403.                 if(range == FALSE){
  404.                     range_end = quote_number;
  405.                     range = TRUE;
  406.                 }
  407.                 while(range_end > quote_number){
  408.                     quotes = read_quote(filename, u_flag, number_flag, n_flag, quote_number);
  409.                     quote_number++;
  410.                     if((quotes != 0) && (range_end > quotes))
  411.                          range_end = quotes;
  412.                 }
  413.                 if(i<(argc-1))
  414.                 read_quote(filename, u_flag, number_flag, n_flag, quote_number);
  415.             }
  416.         }
  417.     }
  418.     read_quote(filename, u_flag, number_flag, n_flag, quote_number);
  419.     exit(0);    
  420. }
  421.  
  422.