home *** CD-ROM | disk | FTP | other *** search
-
- /* touch.c Modify the date/time of last write on the specified
- * files. If the file to be touched doesn't exist, create
- * it.
- *
- * options -d date use the specified date instead of the
- * current system date
- * -t time use the specified time instead of the
- * current system time
- * -v list the touched files on stdout
- * -c turn off auto-create
- *
- * OS interface Touch returns the number of specified files for which
- * the touch failed as an exit status for a normal exit or
- * 256 in the case of a fatal error
- *
- * compiler turbo c
- *
- * version hx v1.0 - initial release: 9/26/87 - jrh
- * v1.1 - added -c option: 9/27/87 - jrh
- *
- * author Richard Hargrove
- * Texas Instruments, Inc.
- * P.O. Box 869305, m/s 8473
- * Plano, TX 75076
- * 214/575-4128
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <ctype.h>
- #include <dos.h>
- #include <io.h>
- #include <getopt.h>
- #include <exparg.h>
-
- #ifdef DEBUG
- #define STATIC
- #else
- #define STATIC static
- #endif
-
- #define FALSE 0
- #define TRUE 1
- #define EOS '\0'
- #define ERR (-1)
-
- typedef int BOOLEAN;
-
- STATIC char *usage = "usage: touch [-cv] [-d date] [-t time] filespec...\n";
- STATIC char *credit = "touch 1.1 -- by richard hargrove, sept. 27 1987\n";
-
- STATIC char *optlist = "CcD:d:T:t:Vv";
-
- STATIC struct date date_struct;
- STATIC struct time time_struct;
- STATIC struct ftime fdate_time;
- STATIC BOOLEAN verbose = FALSE;
- STATIC BOOLEAN autocreate = TRUE;
-
- /*****************************************************************************/
-
- STATIC void fatal (char *msg1)
- {
- #define FATAL_EXIT 255
-
- /* Report a fatal error and terminate the process.
- */
-
- fprintf (stderr, "touch error : %s%s", msg1, usage);
- exit (FATAL_EXIT);
- }
-
- /*****************************************************************************/
-
- STATIC void warn (char *fname, char *msg)
- {
- /* Report an non-fatal error and return.
- */
-
- fprintf (stderr, "%s - %s", fname, msg);
- }
-
- /*****************************************************************************/
-
- STATIC int stoi (char **str)
- {
- /* Decode the string pointed to by *str to an integer. Stop
- * decoding upon encountering a non-numeric char. Update *str
- * to point to that char.
- */
-
- unsigned char *tstr = (unsigned char *) *str;
- int retval = 0;
-
- while (isdigit (*tstr)) {
- retval *= 10;
- retval += (*tstr++ & 0x0f);
- }
-
- *str = (char *) tstr;
- return (retval);
- }
- /*****************************************************************************/
-
- STATIC void get_user_date (char *str, struct date *date_struct)
- {
- /* Parse the user supplied date and initialize the date struct
- * pointed to by date_struct.
- */
-
- int mon, day, year;
- static int days [] =
- { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
- /* parse month */
- mon = stoi (&str);
-
- /* parse date */
- str++;
- day = stoi (&str);
-
- /* parse year */
- str++;
- year = stoi (&str);
- if ((year > 79) && (year < 100)) year += 1900;
-
- /* adjust days for non-leap-year (2000 is a leap year) */
- if ((year & 0x03) || (year == 2100)) days [2] = 28;
-
- /* set up return data */
- if ((mon > 0) || (mon < 13) ||
- (day > 0) || (day <= days [mon]) ||
- (year > 1979) || (year < 2101)) {
- date_struct->da_year = year;
- date_struct->da_mon = (char) mon;
- date_struct->da_day = (char) day;
- }
- else {
- warn (" - invalid date : using system date", "\n");
- }
- }
-
- /*****************************************************************************/
-
- STATIC void get_user_time (char *str, struct time *time_struct)
- {
- /* Parse the user supplied time and initialize the time struct
- * pointed to by time_struct.
- */
-
- int hour, min, sec = 0;
- BOOLEAN isok;
-
- /* parse hour */
- if ((isok = isdigit (*str)) != FALSE) {
- hour = stoi (&str);
- }
-
- /* parse minute */
- str++;
- if (isok && ((isok = isdigit (*str)) != FALSE)) {
- min = stoi (&str);
- }
-
- /* parse optional seconds */
- if (isok &&
- (*str != EOS)) {
- str++;
- if ((isok = isdigit (*str)) != FALSE) {
- sec = stoi (&str);
- }
- }
-
- /* setup return data */
- if (isok &&
- (hour >= 0) && (hour < 24) &&
- (min >= 0) && (min < 60) &&
- (sec >= 0) && (sec < 60)) {
- time_struct->ti_hour = hour;
- time_struct->ti_min = min;
- time_struct->ti_sec = sec;
- }
- else {
- warn (" - invalid time : using system time", "\n");
- }
- }
-
- /*****************************************************************************/
-
- main (int argc, char *argv [])
- {
- int c;
- int handle;
- int file_errs = 0;
-
- argv = exparg (&argc, argv); /* expand command line wild-cards */
- getdate (&date_struct); /* get system date and time */
- gettime (&time_struct);
-
- /* handle command line options */
- while ((c = getopt (argc, argv, optlist)) != EOF) {
- c = tolower (c);
- if (c == 'c') {
- autocreate = FALSE;
- }
- else if (c == 'd') {
- get_user_date (optarg, &date_struct);
- }
- else if (c == 't') {
- get_user_time (optarg, &time_struct);
- }
- else if (c == 'v') {
- verbose = TRUE;
- }
- else {
- fatal ("invalid option specifier\n");
- }
- }
-
- /* reconfigure command line parameter support */
- argc -= optind;
- if (argc <= 0) {
- fatal ("no files to touch\n");
- }
- argv = &argv [optind];
-
- /* encode the date and time */
- fdate_time.ft_tsec = time_struct.ti_sec >> 1;
- fdate_time.ft_min = time_struct.ti_min;
- fdate_time.ft_hour = time_struct.ti_hour;
- fdate_time.ft_day = date_struct.da_day;
- fdate_time.ft_month = date_struct.da_mon;
- fdate_time.ft_year = date_struct.da_year - 1980;
-
- /* touch the files */
- while (argc--) {
- if ((handle = open (argv [argc],
- (autocreate ? O_WRONLY | O_CREAT : O_WRONLY),
- S_IWRITE)) != ERR) {
- /* these can't fail */
- (void) setftime (handle, &fdate_time);
- close (handle);
- if (verbose) {
- puts (argv [argc]);
- }
- }
- else {
- switch (errno) {
- case ENOENT: warn (argv [argc], "file not found\n");
- break;
- case EMFILE: warn (argv [argc], "too many open files\n");
- break;
- case EACCES: warn (argv [argc], "access denied\n");
- break;
- case EINVACC: warn (argv [argc], "who changed my code?\n");
- break;
- default: warn (argv [argc], "eh ? unknown error\n");
- fprintf (stderr, "error code : %d\n", errno);
- }
- errno = 0;
- file_errs++;
- }
- }
-
- exit (file_errs);
- }
-