home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / bootflag.lzh / BootFlag22 / source / BootFlag.c
C/C++ Source or Header  |  1992-09-19  |  9KB  |  313 lines

  1. /*
  2. ** FreeWare! by John Edward Mosley, jem3@engr.uark.edu
  3. ** BootFlag.c - Allows manipulation of an 32-bit flag register in a file on a
  4. ** given disk (usually a Workbench disk) so that bit pattern comparisons of
  5. ** flags can set the Shell script condition to Warn of the patterns match.
  6. */
  7. #include <stdio.h>
  8. #include <ctype.h>
  9.  
  10. #define DEF_STAT_FILE "sys:s/BootFlags"
  11. #define VERSION_INFO "BootFlag version 2.2 for the Amiga (FreeWare) by John Mosley 9-19-1992\n"
  12. #define ENV_VARNAME "ENV:BF_ENV"
  13. typedef char *CHARPTR;
  14.  
  15. void parse_flags(char *, unsigned int *, unsigned int *);
  16. int return_status(unsigned int, unsigned int);
  17. void print_flags(char *);
  18. void set_status(char *, unsigned int);
  19. unsigned int read_status(void);
  20. void update_status(unsigned int *);
  21. unsigned int atoui(CHARPTR *, int);
  22. void print_usage(void);
  23.  
  24. char STAT_FILE[41];
  25.  
  26. void main(int argc, char *argv[]) {
  27.     unsigned int ONflags, OFFflags;
  28.  
  29.     if(*argv[argc - 1] == '-' && *(argv[argc - 1] + 1) == 'f') {
  30.         strcpy(STAT_FILE, argv[argc - 1] + 2);
  31.         argc--;
  32.     } /* if */
  33.     else strcpy(STAT_FILE, DEF_STAT_FILE);
  34.     switch(argc) {
  35.         case 3:
  36.             if(strcmp(argv[1], "check") == 0) {
  37.                 parse_flags(argv[2], &ONflags, &OFFflags);
  38.                 if(return_status(ONflags, OFFflags))
  39.                     exit(5);
  40.                 else
  41.                     exit(0);
  42.             } /* if */
  43.             else if(*argv[1] == 'p' || *argv[1] == 'P')
  44.                 print_flags(argv[2]);
  45.             else {
  46.                 parse_flags(argv[2], &ONflags, &OFFflags);
  47.                 set_status(argv[1], ONflags);
  48.             } /* else */
  49.             break;
  50.         case 2:
  51.             if(*argv[1] == 'p' || *argv[1] == 'P')
  52.                 print_flags(NULL);
  53.             break;
  54.         default:
  55.             printf("BootFlag: Wrong number of arguments\n");
  56.             print_usage();
  57.     } /* switch */
  58. } /* main() */
  59.  
  60.  
  61. void parse_flags(char *strptr, unsigned int *ONflags, unsigned int *OFFflags) {
  62.     int sign;
  63.     unsigned int temp;
  64.     char num[41], *numptr;
  65.  
  66.     *ONflags = *OFFflags = 0;
  67.     while(*strptr) {
  68.         sign = 1;
  69.         /* check for a sign on the flags */
  70.         if(*strptr == '+')
  71.             strptr++;
  72.         else if(*strptr == '-') {
  73.             sign = 0;
  74.             strptr++;
  75.         } /* else if */
  76.         /* check to see if it's just a decimal value */
  77.         if(isdigit(*strptr)) {
  78.             numptr = num;
  79.             while(isdigit(*strptr)) *(numptr++) = *(strptr++);
  80.             *numptr = NULL;
  81.             temp = (unsigned int)atol(num);
  82.         } /* if */
  83.         /* check for a $hex, &oct, or %binary number & convert */    
  84.         else switch(*strptr) {
  85.             case '$':    /* hexadecimal number */
  86.                 strptr++;
  87.                 temp = atoui(&strptr, 4);
  88.                 break;
  89.             case '&':    /* octal number */
  90.                 strptr++;
  91.                 temp = atoui(&strptr, 3);
  92.                 break;
  93.             case '%':    /* binary number */
  94.                 strptr++;
  95.                 temp = atoui(&strptr, 1);
  96.                 break;
  97.             default:
  98.                 printf("BootFlag: Unknown number system \"%c\"\n",
  99.                     *strptr);
  100.                 print_usage();
  101.         } /* else switch */
  102.         if(sign) *ONflags = temp;
  103.         else *OFFflags = temp;
  104.     } /* while */
  105. } /* parse_flags() */
  106.  
  107.  
  108. int return_status(unsigned int ONflags, unsigned int OFFflags) {
  109.     unsigned int status;
  110.     int check_result;
  111.  
  112.     status = read_status();
  113.     check_result = 1;
  114.     if(ONflags) check_result = ((status & ONflags) == ONflags);
  115.     if(OFFflags) check_result &= ((~status & OFFflags) == OFFflags);
  116.     return(check_result);
  117. } /* return_status() */
  118.  
  119.  
  120. void print_flags(char *format) {
  121.     unsigned int status, bit;
  122.     char printing_zeros = 0;
  123.  
  124.     status = read_status();
  125.     if(format) {    /* determine format specification */
  126.         switch(*format) {
  127.             case '$':
  128.                 printf("Boot flags are set at $%x.\n", status);
  129.                 break;
  130.             case '&':
  131.                 printf("Boot flags are set at &%o.\n", status);
  132.                 break;
  133.             case '%':
  134.                 printf("Boot flags are set at %%");
  135.                 for(bit = 0x80000000; bit; bit >>= 1)
  136.                     if(status & bit) {
  137.                         printf("1");
  138.                         printing_zeros = 1;
  139.                     } /* if */
  140.                     else if(printing_zeros || bit == 1)
  141.                         printf("0");
  142.                 printf(".\n");
  143.                 break;
  144.             default:
  145.                 printf("pmod: Unknown display format \"%c\"\n", *format);
  146.         } /* switch */
  147.     } /* if */
  148.     else
  149.         printf("Boot flags are set at %u.\n", status);
  150. } /* print_flags() */
  151.  
  152.  
  153. void set_status(char *operation, unsigned int flags) {
  154.     unsigned int status;
  155.  
  156.     if(flags < 0 || flags > 0xffffffff) {
  157.           printf("BootFlag: Given flag out of range\n");
  158.         print_usage();
  159.     } /* if */
  160.     if(*operation != '=') status = read_status();
  161.     switch(*operation) {
  162.         case 's':
  163.         case 'S':
  164.             status |= flags;
  165.             break;
  166.         case 'c':
  167.         case 'C':
  168.             status &= ~flags;
  169.             break;
  170.         case 't':
  171.         case 'T':
  172.             status ^= flags;
  173.             break;
  174.         case '=':
  175.             status = flags;
  176.             break;
  177.         default:
  178.             printf("BootFlag: Unknown command \"%s\"\n", operation);
  179.             print_usage();
  180.     } /* switch */
  181.     update_status(&status);
  182. } /* set_status() */
  183.  
  184.  
  185. unsigned int read_status(void) {
  186.     unsigned int status;
  187.     FILE *fptr;
  188.     char env_doesnt_exist = 0;
  189.  
  190.     if((fptr = fopen(ENV_VARNAME, "rb")) == NULL) {
  191.         if((fptr = fopen(STAT_FILE, "rb")) == NULL) {
  192.             printf("BootFlag: Cannot access status file\n");
  193.             exit(10);
  194.         } /* if */
  195.         env_doesnt_exist = 1;
  196.     } /* if */
  197.     if(fread((char *)&status, sizeof(unsigned int), 1, fptr) == EOF) {
  198.         fclose(fptr);
  199.         printf("BootFlag: Status file corrupt?\n");
  200.         exit(10);
  201.     } /* if */
  202.     fclose(fptr);
  203.     if(env_doesnt_exist) {        /* create the sukka */
  204.         if((fptr = fopen(ENV_VARNAME, "wb")) == NULL) {
  205.             printf("BootFlag: Cannot access status file\n");
  206.             exit(10);
  207.         } /* if */
  208.         if(fwrite((char *)&status, sizeof(unsigned int), 1, fptr) == NULL)
  209.             printf("BootFlag: Unable to place flags in ENV:\n");
  210.         fclose(fptr);
  211.     } /* if */
  212.     return(status);
  213. } /* read_status() */
  214.  
  215.  
  216. void update_status(unsigned int *status) {
  217.     FILE *fptr;
  218.  
  219.     if((fptr = fopen(STAT_FILE, "wb")) == NULL) {
  220.         printf("BootFlag: Cannot access status file\n");
  221.         exit(10);
  222.     } /* if */
  223.     if(fwrite((char *)status, sizeof(unsigned int), 1, fptr) == NULL) {
  224.         fclose(fptr);
  225.         printf("BootFlag: Unable to update flags in status file\n");
  226.         exit(10);
  227.     } /* if */
  228.     fclose(fptr);
  229.     if((fptr = fopen(ENV_VARNAME, "wb")) == NULL) {
  230.         printf("BootFlag: Cannot access status file\n");
  231.         exit(10);
  232.     } /* if */
  233.     if(fwrite((char *)status, sizeof(unsigned int), 1, fptr) == NULL) {
  234.         fclose(fptr);
  235.         printf("BootFlag: Unable to update flags in ENV:\n");
  236.         exit(10);
  237.     } /* if */
  238.     fclose(fptr);
  239. } /* update_status() */
  240.  
  241.  
  242. unsigned int atoui(CHARPTR *lineptr, int shift_base) {
  243.     int digit, place = 1;
  244.     unsigned int value, sum = 0;
  245.     char num[41], *ptr;
  246.  
  247.     /* place the current number from the command-line string into num[] */
  248.     ptr = num;
  249.     while(**lineptr && **lineptr != '+' && **lineptr != '-')
  250.         *(ptr++) = *((*lineptr)++);
  251.     *ptr = NULL;
  252.     ptr = num;
  253.     /* reverse string to start conversion from Least Sig digit */
  254.     strrev(ptr);
  255.     /* loop through each digit and convert to integer */
  256.     while(*ptr) {
  257.         *ptr = toupper(*ptr);
  258.         switch(shift_base) {
  259.             case 4:
  260.                 if(!isxdigit(*ptr)) {
  261.                     printf("BootFlag: Bad hexadecimal digit \"%c\"\n", *ptr);
  262.                     print_usage();
  263.                 } /* if */
  264.                 digit = (isdigit(*ptr) != 0)*(*ptr - '0') + (isalpha(*ptr))*(*ptr - 'A' + 10);
  265.                 break;
  266.             case 3:
  267.                 if(!isdigit(*ptr) || *ptr < '0' || *ptr > '7') {
  268.                     printf("BootFlag: Bad octal digit \"%c\"\n", *ptr);
  269.                     print_usage();
  270.                 } /* if */
  271.                 digit = (*ptr - '0');
  272.                 break;
  273.             case 1:
  274.                 if(*ptr != '0' && *ptr != '1') {
  275.                     printf("BootFlag: Bad binary digit \"%c\"\n", *ptr);
  276.                     print_usage();
  277.                 } /* if */
  278.                 digit = (*ptr - '0');
  279.                 break;
  280.             default:
  281.                 printf("BootFlag: atoui: Unknown base %d\n", shift_base);
  282.                 print_usage();
  283.         } /* switch */
  284.         value = digit*place;
  285.         place <<= shift_base;
  286.         sum += value;
  287.         ptr++;
  288.     } /* while */
  289.     return(sum);
  290. } /* atoui() */
  291.  
  292.  
  293. void print_usage(void) {
  294.     printf(VERSION_INFO);
  295.     printf("USAGE: BootFlag <check|print|set|clear|tog|=> <flags> [-f<file>]\n");
  296.     printf("\tflags : specifier representing 32 binary flags to manipulate\n");
  297.     printf("\t\tSyntax: [+|-][$|&|%]<digits>[<+|->[$|&|%]<digits>]\n");
  298.     printf("\t\t+: check if flags are ON, -: check if flags are OFF\n");
  299.     printf("\t\t$hexadecimal#, &octal#, %binary#, or (none)decimal#\n");
  300.     printf("\tcheck : compare flags, return Warn if the given pattern matches\n");
  301.     printf("\tprint : print out current flag settings\n");
  302.     printf("\t\tUse [$|&|%] in place of <flags> for output format.\n");
  303.     printf("\tThe commands below only use the + flag value:\n");
  304.     printf("\tset   : set given flags to ON state\n");
  305.     printf("\tclear : set given flags to OFF state\n");
  306.     printf("\ttog   : toggle given flags\n");
  307.     printf("\t=     : set entire 32-bit register equal to given flags\n");
  308.     printf("\tFile option(s):\n");
  309.     printf("\t-f    : use a different register file (<file> required)\n");
  310.     printf("\tfile  : path and filename of the register file to use\n");
  311.     exit(10);
  312. } /* print_usage() */
  313.