home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
utility
/
misc
/
bootflag.lzh
/
BootFlag22
/
source
/
BootFlag.c
Wrap
C/C++ Source or Header
|
1992-09-19
|
9KB
|
313 lines
/*
** FreeWare! by John Edward Mosley, jem3@engr.uark.edu
** BootFlag.c - Allows manipulation of an 32-bit flag register in a file on a
** given disk (usually a Workbench disk) so that bit pattern comparisons of
** flags can set the Shell script condition to Warn of the patterns match.
*/
#include <stdio.h>
#include <ctype.h>
#define DEF_STAT_FILE "sys:s/BootFlags"
#define VERSION_INFO "BootFlag version 2.2 for the Amiga (FreeWare) by John Mosley 9-19-1992\n"
#define ENV_VARNAME "ENV:BF_ENV"
typedef char *CHARPTR;
void parse_flags(char *, unsigned int *, unsigned int *);
int return_status(unsigned int, unsigned int);
void print_flags(char *);
void set_status(char *, unsigned int);
unsigned int read_status(void);
void update_status(unsigned int *);
unsigned int atoui(CHARPTR *, int);
void print_usage(void);
char STAT_FILE[41];
void main(int argc, char *argv[]) {
unsigned int ONflags, OFFflags;
if(*argv[argc - 1] == '-' && *(argv[argc - 1] + 1) == 'f') {
strcpy(STAT_FILE, argv[argc - 1] + 2);
argc--;
} /* if */
else strcpy(STAT_FILE, DEF_STAT_FILE);
switch(argc) {
case 3:
if(strcmp(argv[1], "check") == 0) {
parse_flags(argv[2], &ONflags, &OFFflags);
if(return_status(ONflags, OFFflags))
exit(5);
else
exit(0);
} /* if */
else if(*argv[1] == 'p' || *argv[1] == 'P')
print_flags(argv[2]);
else {
parse_flags(argv[2], &ONflags, &OFFflags);
set_status(argv[1], ONflags);
} /* else */
break;
case 2:
if(*argv[1] == 'p' || *argv[1] == 'P')
print_flags(NULL);
break;
default:
printf("BootFlag: Wrong number of arguments\n");
print_usage();
} /* switch */
} /* main() */
void parse_flags(char *strptr, unsigned int *ONflags, unsigned int *OFFflags) {
int sign;
unsigned int temp;
char num[41], *numptr;
*ONflags = *OFFflags = 0;
while(*strptr) {
sign = 1;
/* check for a sign on the flags */
if(*strptr == '+')
strptr++;
else if(*strptr == '-') {
sign = 0;
strptr++;
} /* else if */
/* check to see if it's just a decimal value */
if(isdigit(*strptr)) {
numptr = num;
while(isdigit(*strptr)) *(numptr++) = *(strptr++);
*numptr = NULL;
temp = (unsigned int)atol(num);
} /* if */
/* check for a $hex, &oct, or %binary number & convert */
else switch(*strptr) {
case '$': /* hexadecimal number */
strptr++;
temp = atoui(&strptr, 4);
break;
case '&': /* octal number */
strptr++;
temp = atoui(&strptr, 3);
break;
case '%': /* binary number */
strptr++;
temp = atoui(&strptr, 1);
break;
default:
printf("BootFlag: Unknown number system \"%c\"\n",
*strptr);
print_usage();
} /* else switch */
if(sign) *ONflags = temp;
else *OFFflags = temp;
} /* while */
} /* parse_flags() */
int return_status(unsigned int ONflags, unsigned int OFFflags) {
unsigned int status;
int check_result;
status = read_status();
check_result = 1;
if(ONflags) check_result = ((status & ONflags) == ONflags);
if(OFFflags) check_result &= ((~status & OFFflags) == OFFflags);
return(check_result);
} /* return_status() */
void print_flags(char *format) {
unsigned int status, bit;
char printing_zeros = 0;
status = read_status();
if(format) { /* determine format specification */
switch(*format) {
case '$':
printf("Boot flags are set at $%x.\n", status);
break;
case '&':
printf("Boot flags are set at &%o.\n", status);
break;
case '%':
printf("Boot flags are set at %%");
for(bit = 0x80000000; bit; bit >>= 1)
if(status & bit) {
printf("1");
printing_zeros = 1;
} /* if */
else if(printing_zeros || bit == 1)
printf("0");
printf(".\n");
break;
default:
printf("pmod: Unknown display format \"%c\"\n", *format);
} /* switch */
} /* if */
else
printf("Boot flags are set at %u.\n", status);
} /* print_flags() */
void set_status(char *operation, unsigned int flags) {
unsigned int status;
if(flags < 0 || flags > 0xffffffff) {
printf("BootFlag: Given flag out of range\n");
print_usage();
} /* if */
if(*operation != '=') status = read_status();
switch(*operation) {
case 's':
case 'S':
status |= flags;
break;
case 'c':
case 'C':
status &= ~flags;
break;
case 't':
case 'T':
status ^= flags;
break;
case '=':
status = flags;
break;
default:
printf("BootFlag: Unknown command \"%s\"\n", operation);
print_usage();
} /* switch */
update_status(&status);
} /* set_status() */
unsigned int read_status(void) {
unsigned int status;
FILE *fptr;
char env_doesnt_exist = 0;
if((fptr = fopen(ENV_VARNAME, "rb")) == NULL) {
if((fptr = fopen(STAT_FILE, "rb")) == NULL) {
printf("BootFlag: Cannot access status file\n");
exit(10);
} /* if */
env_doesnt_exist = 1;
} /* if */
if(fread((char *)&status, sizeof(unsigned int), 1, fptr) == EOF) {
fclose(fptr);
printf("BootFlag: Status file corrupt?\n");
exit(10);
} /* if */
fclose(fptr);
if(env_doesnt_exist) { /* create the sukka */
if((fptr = fopen(ENV_VARNAME, "wb")) == NULL) {
printf("BootFlag: Cannot access status file\n");
exit(10);
} /* if */
if(fwrite((char *)&status, sizeof(unsigned int), 1, fptr) == NULL)
printf("BootFlag: Unable to place flags in ENV:\n");
fclose(fptr);
} /* if */
return(status);
} /* read_status() */
void update_status(unsigned int *status) {
FILE *fptr;
if((fptr = fopen(STAT_FILE, "wb")) == NULL) {
printf("BootFlag: Cannot access status file\n");
exit(10);
} /* if */
if(fwrite((char *)status, sizeof(unsigned int), 1, fptr) == NULL) {
fclose(fptr);
printf("BootFlag: Unable to update flags in status file\n");
exit(10);
} /* if */
fclose(fptr);
if((fptr = fopen(ENV_VARNAME, "wb")) == NULL) {
printf("BootFlag: Cannot access status file\n");
exit(10);
} /* if */
if(fwrite((char *)status, sizeof(unsigned int), 1, fptr) == NULL) {
fclose(fptr);
printf("BootFlag: Unable to update flags in ENV:\n");
exit(10);
} /* if */
fclose(fptr);
} /* update_status() */
unsigned int atoui(CHARPTR *lineptr, int shift_base) {
int digit, place = 1;
unsigned int value, sum = 0;
char num[41], *ptr;
/* place the current number from the command-line string into num[] */
ptr = num;
while(**lineptr && **lineptr != '+' && **lineptr != '-')
*(ptr++) = *((*lineptr)++);
*ptr = NULL;
ptr = num;
/* reverse string to start conversion from Least Sig digit */
strrev(ptr);
/* loop through each digit and convert to integer */
while(*ptr) {
*ptr = toupper(*ptr);
switch(shift_base) {
case 4:
if(!isxdigit(*ptr)) {
printf("BootFlag: Bad hexadecimal digit \"%c\"\n", *ptr);
print_usage();
} /* if */
digit = (isdigit(*ptr) != 0)*(*ptr - '0') + (isalpha(*ptr))*(*ptr - 'A' + 10);
break;
case 3:
if(!isdigit(*ptr) || *ptr < '0' || *ptr > '7') {
printf("BootFlag: Bad octal digit \"%c\"\n", *ptr);
print_usage();
} /* if */
digit = (*ptr - '0');
break;
case 1:
if(*ptr != '0' && *ptr != '1') {
printf("BootFlag: Bad binary digit \"%c\"\n", *ptr);
print_usage();
} /* if */
digit = (*ptr - '0');
break;
default:
printf("BootFlag: atoui: Unknown base %d\n", shift_base);
print_usage();
} /* switch */
value = digit*place;
place <<= shift_base;
sum += value;
ptr++;
} /* while */
return(sum);
} /* atoui() */
void print_usage(void) {
printf(VERSION_INFO);
printf("USAGE: BootFlag <check|print|set|clear|tog|=> <flags> [-f<file>]\n");
printf("\tflags : specifier representing 32 binary flags to manipulate\n");
printf("\t\tSyntax: [+|-][$|&|%]<digits>[<+|->[$|&|%]<digits>]\n");
printf("\t\t+: check if flags are ON, -: check if flags are OFF\n");
printf("\t\t$hexadecimal#, &octal#, %binary#, or (none)decimal#\n");
printf("\tcheck : compare flags, return Warn if the given pattern matches\n");
printf("\tprint : print out current flag settings\n");
printf("\t\tUse [$|&|%] in place of <flags> for output format.\n");
printf("\tThe commands below only use the + flag value:\n");
printf("\tset : set given flags to ON state\n");
printf("\tclear : set given flags to OFF state\n");
printf("\ttog : toggle given flags\n");
printf("\t= : set entire 32-bit register equal to given flags\n");
printf("\tFile option(s):\n");
printf("\t-f : use a different register file (<file> required)\n");
printf("\tfile : path and filename of the register file to use\n");
exit(10);
} /* print_usage() */