#include "cfgopts.h" void switch_type_and_write (struct Config_Tag ptr[], int count, FILE *outfile); long fcopy(char *dest, char *source); // copy one file to another static unsigned char line[1000], line_bak[1000]; static char *true_false[]={ "ERROR","FALSE","TRUE" }; /*---------------------------------------------------------------------/ / reads from an input configuration (INI) file. /---------------------------------------------------------------------*/ /*>>------[ input_config() ]-------------[ 08-02-95 14:02PM ]------/ / return value: / int ; number of records read or -1 on error / parameters: / char *filename ; filename of INI style file / struct Config_Tag configs[]; Configuration structure / char *header ; INI header name (i.e. "[TEST]") /-------------------------------------------------------------------<<*/ int input_config(char *filename, struct Config_Tag configs[], char *header) { struct Config_Tag *ptr; int count=0,lineno=0,temp; FILE *file; char *fptr,*tok,*next; file=fopen(filename,"r"); if ( file==NULL ) return ERROR; // return error designation. if ( header!=NULL ) do { fptr=fgets(line,sizeof(line)-2,file); // get input line } while ( memcasecmp(line,header,strlen(header)) && !feof(file)); if ( !feof(file) ) do { fptr=fgets(line,sizeof(line)-2,file); // get input line if ( fptr==NULL ) continue; lineno++; if ( line[0]=='#' || line[0]==';' || line[0]=='/') continue; // skip comments if ( line[0]=='[' ) continue; // skip next header tok=strtok(line,"=\n\r"); // get first token if ( tok!=NULL ) { next=strtok(NULL,"=\n\r"); // get actual config information for ( ptr=configs;ptr->buf;++ptr ) // scan for token { if ( !strcasecmp( tok , ptr->code ) ) // got a match? { if(!next) break; switch ( ptr->type ) // check type { case Boolean_Tag: if (!strcasecmp(next,"FALSE")) *((Boolean_T *)(ptr->buf)) = FALSE; else if (!strcasecmp(next,"TRUE")) *((Boolean_T *)(ptr->buf)) = TRUE; ++count; break; case Byte_Tag: sscanf(next, "%d", &temp); *((char *)(ptr->buf))=(char)temp; ++count; break; case Word_Tag: sscanf(next, "%hd", (short *)(ptr->buf)); ++count; break; case DWord_Tag: sscanf(next, "%ld", (long *)(ptr->buf)); ++count; break; case OctWord_Tag: sscanf(next, "%ho", (short *)(ptr->buf)); ++count; break; case DOctWord_Tag: sscanf(next, "%lo", (long *)(ptr->buf)); ++count; break; case HexWord_Tag: sscanf(next, "%hx", (short *)(ptr->buf)); ++count; break; case DHexWord_Tag: sscanf(next, "%lx", (long *)(ptr->buf)); ++count; break; case Float_Tag: sscanf(next, "%g", (float *)ptr->buf); ++count; break; case Double_Tag: sscanf(next, "%lg", (double *)ptr->buf); ++count; break; case String_Tag: if(ptr->size_buf <= strlen(next)) strcpy((char *)ptr->buf, "\0\0"); else strcpy((char *)ptr->buf, next); ++count; break; case Function_Tag: case Error_Tag: default: printf("Error in Config file %s on line %d\n",filename,lineno); break; } } } } } while ( fptr!=NULL && line[0]!='['); fclose(file); return count; } /*---------------------------------------------------------------------/ / updates an input configuration (INI) file from a structure. /---------------------------------------------------------------------*/ /*>>------[ update_config() ]-------------[ 08-02-95 14:02PM ]------/ / return value: / int ; Number of records read & updated / parameters: / char *filename ; filename of INI file / struct Config_Tag configs[]; Configuration structure / char *header ; INI header name (i.e. "[TEST]") /-------------------------------------------------------------------<<*/ int update_config(char *filename, struct Config_Tag configs[], char *header) { int count=0,lineno=0, section_not_found; FILE *infile,*outfile; char *fptr,*tok; infile=fopen(filename,"r"); if ( infile==NULL ) { // file not found, creating new onw outfile=fopen("temp_PHX.$$$","w"); if ( outfile==NULL ) return ERROR; // return error designation. if ( header!=NULL ) fprintf(outfile,"%s\n",header); switch_type_and_write(configs, count, outfile); fclose(outfile); fcopy(filename,"temp_PHX.$$$"); remove("temp_PHX.$$$"); return count; } outfile=fopen("temp_PHX.$$$","w"); if ( outfile==NULL ) { fclose(infile); return ERROR; // return error designation. } if ( header!=NULL ) { do { fptr=fgets(line,sizeof(line)-2,infile); // get input line if(fptr) fprintf(outfile,"%s",line); section_not_found=memcasecmp(line,header,strlen(header)); } while ( section_not_found && !feof(infile)); } if ( feof(infile) ) { fprintf(outfile,"\n"); if ( header!=NULL && section_not_found ) fprintf(outfile,"\n%s\n",header); switch_type_and_write(configs, count, outfile); } else { do { fptr=fgets(line,sizeof(line)-2,infile); // get input line if ( fptr==NULL ) { // eof reached, lets write it switch_type_and_write(configs, count, outfile); break; } lineno++; if ( line[0]=='#' || line[0]=='\r' || line[0]=='\n' || line[0]==';' || line[0]=='/') { fprintf(outfile,"%s",line); continue; // skip comments } else if ( line[0]=='[' ) { // new section found, last section was empty switch_type_and_write(configs, count, outfile); fprintf(outfile,"%s",line); do { // write the rest of the file fptr=fgets(line,sizeof(line)-2,infile); if (fptr) fprintf(outfile,"%s",line); } while (!feof(infile)); break; } strcpy(line_bak, line); tok=strtok(line,"=\n\r"); // get first token if ( tok!=NULL ) { if ( !strcasecmp( tok , configs->code ) ) // got a match? { switch_type_and_write(configs, count, outfile); do { // write the rest of the file fptr=fgets(line,sizeof(line)-2,infile); if (fptr) fprintf(outfile,"%s",line); } while (!feof(infile)); break; } fprintf(outfile,"%s",line_bak); } } while ( fptr!=NULL ); } fclose(infile); fclose(outfile); fcopy(filename,"temp_PHX.$$$"); remove("temp_PHX.$$$"); return count; } void GetPrivateProfileString(char *INIsection, char *INIkey, char *INIdefault, char *INIbuffer, int INIbuflen, char *INIpath) { struct Config_Tag cfgStr[] = { { INIkey, String_Tag, INIbuffer, INIbuflen }, { NULL, Error_Tag, NULL, 0 } /* Terminating record */ }; unsigned char INIsect2[250]; INIbuffer[0]=0; INIsect2[0]='['; strcpy(INIsect2+1, INIsection); strcat(INIsect2, "]"); input_config(INIpath, cfgStr, INIsect2); if(INIbuffer[0]==0) strcpy(INIbuffer, INIdefault); if(INIbuffer[0]==0x22 && INIbuffer[strlen(INIbuffer)-1]==0x22) // kill "" { INIbuffer[strlen(INIbuffer)-1]=0; strcpy(INIbuffer, INIbuffer+1); } } void WritePrivateProfileString(char *INIsection, char *INIkey, char *INIvalue, char *INIpath) { unsigned char INIsect2[250]; struct Config_Tag cfgStr[] = { { INIkey, String_Tag, INIvalue } }; INIsect2[0]='['; strcpy(INIsect2+1, INIsection); strcat(INIsect2, "]"); update_config(INIpath, cfgStr, INIsect2); } /* * copy one file to another. Returns the (positive) * number of bytes copied, or -1 if an error occurred. */ #define BUFFER_SIZE 1024 /*---------------------------------------------------------------------/ / copy one file to another. /---------------------------------------------------------------------*/ /*>>------[ fcopy() ]-------------[ 08-02-95 14:02PM ]------/ / return value: / long ; Number of bytes copied or -1 on error / parameters: / char *dest ; Destination file name / char *source ; Source file name /-------------------------------------------------------------------<<*/ long fcopy(char *dest, char *source) { FILE *d, *s; char *buffer; size_t incount; long totcount = 0L; s = fopen(source, "rb"); if(s == NULL) return -1L; d = fopen(dest, "wb"); if(d == NULL) { fclose(s); return -1L; } buffer = (char *)malloc(BUFFER_SIZE); if(buffer == NULL) { fclose(s); fclose(d); return -1L; } incount = fread(buffer, sizeof(char), BUFFER_SIZE, s); while(!feof(s)) { totcount += (long)incount; fwrite(buffer, sizeof(char), incount, d); incount = fread(buffer, sizeof(char), BUFFER_SIZE, s); } totcount += (long)incount; fwrite(buffer, sizeof(char), incount, d); free(buffer); fclose(s); fclose(d); return totcount; } int memcasecmp (const void *vs1, const void *vs2, size_t n) { unsigned int i; unsigned char const *s1 = (unsigned char const *) vs1; unsigned char const *s2 = (unsigned char const *) vs2; for (i = 0; i < n; i++) { unsigned char u1 = *s1++; unsigned char u2 = *s2++; if (TOUPPER (u1) != TOUPPER (u2)) return TOUPPER (u1) - TOUPPER (u2); } return 0; } void switch_type_and_write (struct Config_Tag ptr[], int count, FILE *outfile) { int temp; fprintf(outfile,"%s=",ptr->code); switch ( ptr->type ) // check type { case Boolean_Tag: fprintf(outfile,"%s\n", true_false[*((Boolean_T *)(ptr->buf))+1]); ++count; return; case Byte_Tag: temp=(int)*((char *)(ptr->buf)); fprintf(outfile, "%hd\n", temp); ++count; return; case Word_Tag: fprintf(outfile, "%hd\n", *((short *)(ptr->buf))); ++count; return; case DWord_Tag: fprintf(outfile, "%ld\n", *((long *)(ptr->buf))); ++count; return; case OctWord_Tag: fprintf(outfile, "%ho\n", *((short *)(ptr->buf))); ++count; return; case DOctWord_Tag: fprintf(outfile, "%lo\n", *((long *)(ptr->buf))); ++count; return; case HexWord_Tag: fprintf(outfile, "%hx\n", *((short *)(ptr->buf))); ++count; return; case DHexWord_Tag: fprintf(outfile, "%lx\n", *((long *)(ptr->buf))); ++count; return; case Float_Tag: fprintf(outfile, "%hg\n", *((float *)ptr->buf)); ++count; return; case Double_Tag: fprintf(outfile, "%lg\n", *((double *)ptr->buf)); ++count; return; case String_Tag: fprintf(outfile, "%s\n",(char *)ptr->buf); ++count; return; } }