/* For MSC 5.0/QuickC: cl touch.c setargv /link /NOE */ #include #include #include #include #include #include #include #include #include #include #ifndef ERROR #define ERROR -1 #endif main(argc,argv) int argc; char **argv; { int i, hdl; char *date = NULL,*time = NULL; struct utimbuf datetimes, *tptr; extern int errno; if(argc < 2) /* if no filenames passed, print usage message */ { printf("\nUsage: touch [/Dmm/dd/yy /Thh:mm:ss] [filename...]"); exit(1); /* set errorlevel to 1 */ } /* process any switches, only allowed in argv[1] and argv[2]*/ for( i = 1; i < 3; i++) if(argv[i][0] == '/') /* slash found? */ if(toupper(argv[i][1]) == 'D') /* if Date string */ date = &argv[i][2]; else if(toupper(argv[i][1]) == 'T') /* if Time string */ time = &argv[i][2]; /* if date or time switch set, set ptr to times structure */ if(date || time) { convert_date_time(&datetimes,date,time); tptr = &datetimes; } else tptr = (struct utimbuf *)NULL; /* else to NULL */ /* increment argv and decrement argc if either date or time switches are on */ if(date) { argv++; argc--; } if(time) { argv++; argc--; } /* process each filename passed */ for( i = 1; i < argc; ) { if(utime(argv[i],tptr) == ERROR) /* unable to update the time */ { switch(errno) /* print appropriate error message */ { case EACCES: printf("\ntouch: Directory or Read-only file: %s",argv[i]); break; case EINVAL: printf("\ntouch: Bad time argument changing %s",argv[i]); exit(1); case EMFILE: printf("\ntouch: Too many open files (check FILES= in CONFIG.SYS)"); exit(1); case ENOENT: /* if file doesn't exist, create it */ if((hdl = open(argv[i], (O_WRONLY | O_CREAT),S_IWRITE)) == -1) printf("\ntouch: Unable to create %s",argv[i]); else { close(hdl); continue; } break; } } i++; } exit(0); /* set errorlevel to 0 */ } /* * This function places date and time values in the datestr and timestr * pointers into a tm structure, overriding the current time. */ convert_date_time(struct utimbuf *datetimes, char *datestr, char *timestr) { struct tm *current_time; time((time_t *)&datetimes->modtime); /* get current time */ current_time = localtime(&datetimes->modtime); /* get pointer to it */ if(datestr) /* if date passed, put it into place */ { current_time->tm_mon = (get_date_time(&datestr) - 1); current_time->tm_mday = get_date_time(&datestr); if((current_time->tm_year = get_date_time(&datestr)) > 1900) current_time->tm_year -= 1900; } if(timestr) /* if time passed, put into place */ { current_time->tm_hour = get_date_time(×tr); current_time->tm_min = get_date_time(×tr); current_time->tm_sec = get_date_time(×tr); } datetimes->modtime = mktime(current_time); /* place in time_t */ } /* * This function takes a pointer to a date or time pointer, gets the * next piece of the date or time string and returns it as an integer * value. It advances the date or time pointer to point to the next * piece available. */ int get_date_time(char **ptr) { char phrase[15]; char *p; strcpy(phrase,*ptr); /* copy the current string */ if(p = strchr(phrase,'/')) /* find next separator and set to NULL */ *p = NULL; else if(p = strchr(phrase,':')) *p = NULL; (*ptr) += strlen(phrase); /* advance pointer to next component */ if(**ptr == '/' || **ptr == ':') /* if a separator, move past it */ (*ptr)++; return atoi(phrase); /* return the current component */ }