home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
dirutl
/
touch.arc
/
TOUCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-09-27
|
7KB
|
270 lines
/* 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);
}