/* byteswap.c */ /* Byte swapping utility for converting binary data files between */ /* big-endian and little-endian formats. */ /* Revised 2 August 2002, Curtis W. Chen */ /* Copyright 2002 Board of Trustees, Leland Stanford Jr. University */ /* No warranty. */ #include #include #include #include #include #define MAXSTRLEN 4096 #define MAXNELEM (LONG_MAX-1) #define MAXNBYTES 32768 #define MAXINFILES 8192 #define BLOCKSIZE 8192 #define TRUE 1 #define FALSE 0 /* prototype for function called when program receives a signal */ void SigHandler(int signum); /* main program */ int main(int argc, char *argv[]){ FILE *fp, *outfp; unsigned char *chunk1, *chunk2; long i, j, chunksize, chunksize2, nbytes, headerlength; long elemread, extrabytes, keepgoing, filenum, nfiles; long ielem, nelem; char *infilearr[MAXINFILES]; char *filename, *outfilename; char *endptr; /* parse input */ nfiles=0; headerlength=0; outfp=NULL; outfilename=NULL; nelem=MAXNELEM; nbytes=0; if(argc<3){ fprintf(stderr, "usage: byteswap [options] bytes_per_element filename(s)\n"); fprintf(stderr,"options:\n"); fprintf(stderr," -h Don't swap first H bytes\n"); fprintf(stderr," -n Stop after swapping N elements\n"); fprintf(stderr," -o Write to outfile instead of" " swapping in place\n"); exit(1); } for(i=1;i=++i+1){ headerlength=strtol(argv[i],&endptr,10); if(headerlength<0 || strlen(endptr)){ fprintf(stderr,"argument to -h must be nonnegative integer\n"); exit(1); } }else{ fprintf(stderr,"option %s specified with no argument\n",argv[i-1]); exit(1); } }else if(!strcmp(argv[i],"-n")){ if(argc>=++i+1){ nelem=strtol(argv[i],&endptr,10); if(nelem<0 || strlen(endptr)){ fprintf(stderr,"argument to -n must be nonnegative integer\n"); exit(1); } if(nelem>MAXNELEM){ fprintf(stderr,"argument to -n too large\n"); exit(1); } }else{ fprintf(stderr,"option %s specified with no argument\n",argv[i-1]); exit(1); } }else if(!strcmp(argv[i],"-o")){ if(argc>=++i+1){ outfilename=argv[i]; }else{ fprintf(stderr,"option %s specified with no argument\n",argv[i-1]); exit(1); } }else{ fprintf(stderr,"unrecogized option %s\n",argv[i]); exit(1); } }else{ if(nbytes<=0){ nbytes=strtol(argv[i],&endptr,10); if(nbytes<=0 || nbytes>MAXNBYTES || strlen(endptr)){ fprintf(stderr,"illegal number of bytes per element\n"); fprintf(stderr, "usage: byteswap [options] bytes_per_element filename(s)\n"); exit(1); } }else{ if(nfiles>=MAXINFILES){ fprintf(stderr,"too many input files\n"); exit(1); } infilearr[nfiles++]=argv[i]; } } } /* make sure we have required inputs */ if(!nbytes || !nfiles){ fprintf(stderr,"not enough input arguments\n"); exit(1); } /* see if output file passed in */ if(outfilename!=NULL){ /* output file cannot be given with multiple input files */ if(nfiles>1){ fprintf(stderr, "output file cannot be specified with multiple input files\n"); exit(1); } /* refuse to overwrite input file with output file */ /* (may still be overwritten if specified with different relative path) */ if(!strcmp(outfilename,infilearr[0])){ fprintf(stderr,"output file cannot be same as input file\n"); exit(1); } /* open output file */ if((outfp=fopen(outfilename,"w"))==NULL){ fprintf(stderr,"couldn't open file %s for writing\n",outfilename); exit(1); } } /* get memory for chunk buffers */ if((chunk1=malloc(BLOCKSIZE*nbytes*sizeof(unsigned char)))==NULL || (chunk2=malloc(BLOCKSIZE*nbytes*sizeof(unsigned char)))==NULL){ fprintf(stderr,"Out of memory.\n"); exit(1); } /* trap the interrupt signal if swapping in place */ if(outfp==NULL){ signal(SIGINT,SigHandler); } /* loop over all input files */ for(filenum=0;filenumnelem){ elemread=nelem-(ielem-elemread); ielem=nelem; keepgoing=FALSE; } /* swap the bytes */ chunksize2=elemread*nbytes; for(i=0;i