/* * touch: create or update times on files */ #include #include #include #include #include /* for DosSetFileInfo() - aka utime */ #include "glob.h" extern int getopt(); /* getopt() */ extern int opterr, optind; extern char *optarg; char touch_access=1; /* flags of interest */ char touch_modified=1; char create_file=1; char force_touch=0; /* * badboy() complains and dies */ badboy(msg) char *msg; { if (msg) fprintf(stderr, "touch: %s\n", msg); fprintf(stderr, "usage: touch [-amcf] [mmddhhmm[yy]] file [...]\n"); exit(1); } /* badboy */ /* * digarg() looks to see if a string is all digits */ digarg(arg) register char *arg; { while (*arg) if (!isdigit(*arg++)) return 0; return 1; } /* digarg */ /* * get_today() gets the timestamp for today */ get_today(dt,tm) FDATE *dt; FTIME *tm; { DATETIME now; DosGetDateTime(&now); dt->year = now.year-1980; dt->month= now.month; dt->day = now.day; tm->twosecs = now.seconds/2; tm->minutes = now.minutes; tm->hours = now.hours; } /* get_today */ /* * set_timestamp() sets the date and time to a user-defined value */ set_timestamp(argument, dt, tm) char *argument; FDATE *dt; FTIME *tm; { register len = strlen(argument); register long stime = atol(argument); if (len != 8 && len != 10) badboy("invalid time-setting"); if (len == 10) { dt->year = (stime % 100L) - 80; stime /= 100L; } tm->twosecs= 0; tm->minutes= (stime % 100L); stime /= 100L; tm->hours = (stime % 100L); stime /= 100L; dt->day = (stime % 100L); stime /= 100L; dt->month = (stime % 100L); } /* set_timestamp */ /* * touch_a_file() does the work of touching a file */ touch_a_file(file, dt, tm) char *file; FDATE *dt; FTIME *tm; { char file_exists; /* does the file already exist? */ short attrib; /* original attributes of file */ register fd; /* file descriptor */ register mode; /* open() mode */ FILESTATUS dta; /* for updating date and time */ /* get the attributes of the file if it exists */ file_exists = (DosQFileMode(file, &attrib, 0L) == 0); /* if we're forcing readonly files, reset the attributes * to not-readonly */ if (force_touch && file_exists && (attrib & F_RDONLY)) DosSetFileMode(file, attrib & (F_AMASK^F_RDONLY), 0L); /* if -c was specified, we don't want to make new files */ mode = create_file ? (O_RDWR|O_BINARY|O_CREAT) : (O_RDWR|O_BINARY); /* open the file, set the date, then restore the file attributes * if we'd changed them */ if ((fd=open(file, mode, 0666)) >= 0) { memset(&dta, 0, sizeof dta); /* don't set anything unexpected */ if (touch_access && _osmode != DOS_MODE) { /* access times are not supported under DOS */ dta.fdateLastAccess = *dt; dta.ftimeLastAccess = *tm; } if (touch_modified) { dta.fdateLastWrite = *dt; dta.ftimeLastWrite = *tm; } if (DosSetFileInfo(fd, 0x01, (PBYTE)&dta, sizeof dta) != 0) fprintf(stderr, "can't touch %s\n", file); close(fd); if (file_exists && (attrib & F_RDONLY)) DosSetFileMode(file, attrib & F_AMASK, 0L); } else if (!force_touch) perror(file); } /* touch_a_file */ /* * touch, in mortal flesh */ main(argc, argv) char **argv; { FDATE tdate; FTIME ttime; register opt; register i, fd; opterr = 1; /* getopt will complain about missing things */ while ((opt=getopt(argc, argv, "amcf")) != EOF) switch (opt) { case 'a': touch_modified = 0; break; case 'm': touch_access = 0; break; case 'c': create_file = 0; break; case 'f': force_touch = 1; break; default: badboy((char*)0); } if (touch_modified == 0 && touch_access == 0) badboy("can't set both -a and -m"); get_today(&tdate, &ttime); /* check if we're setting an explicit date & time */ if (optind < argc && digarg(argv[optind])) set_timestamp(argv[optind++], &tdate, &ttime); optind--; expand_arglist(argc-optind, argv+optind, (struct args_t*)0); if (myargc < 1) badboy((char*)0); for (i=0; i