[comp.sys.ibm.pc] lattice-c source of touch.c for ibm-pc dos

jchvr@ihlpg.ATT.COM (Hartong) (09/23/87)

No garantees but here is the lattice c source for touch.c (see your local unix
system on what touch is supposed to do).

#include	<stdio.h>
#include	<dos.h>

#define	CARRY	1
#ifdef min
#undef min
#endif
static union REGS rg;
static int	flags;
static char	ar[256];

int	create=0;	/* 0= create, !=0 is do not create file */
int	notdone=0;	/* number of files not done */

struct	TIME { int day;
	       int wkday;
	       int month;
	       int year;
	       int hour;
	       int min;
	       int sec;
	    };

doit(name,day,month,year,hour,min,sec)
char	name[];
int	day,month,year,hour,min,sec;
{	int	handle;
	byte	hi,lo;

	/* check date */
	year = year - 1980;
	sec = 0;
	if ( (year < 0) || (year > 199)) goto error;
	if ( (month< 0) || (month> 12 )) goto error;
	if ( (day  < 0) || (day  > 31 )) goto error;
	if ( (hour < 0) || (hour > 23 )) goto error;
	if ( (min  < 0) || (min  > 59 )) goto error;
	goto okay;
error:
	fprintf(stderr,"touch : ERROR : illegal date\n");
	exit(1);
okay:
	strcpy(ar,name);

	/* Open file Handle pg:7-120 */
	rg.h.ah = 0x3d;		/* open file handle */
	rg.h.al = 0;		/* open for read */
	rg.x.dx = &(ar[0]);	/* pointer to pathname */
	flags = intdos(&rg, &rg);
	handle = rg.x.ax;

	if ( (flags & CARRY) != 0) {
		switch (handle) {
			case 2  :	fprintf(stderr,"%s not found\n",name); break;
			case 4  :	fprintf(stderr,"Too many open files\n"); break;
			case 5  :	fprintf(stderr,"Access denied on %s\n",name); break;
			case 12 :	fprintf(stderr,"Invalid access on %s\n",name); break;
			default :	fprintf(stderr,"Unknown error on %s\n",name); break;
		}
		notdone++;
		return(-1);
	}

	/* compute values for DX */
	lo = month & 7 ; /* take 3 right most bits */
	lo = lo << 5;
	lo = lo | day;
	hi = year & 0x7f;
	hi = hi << 1;
	hi = hi | ( (month>>3) & 0xff);
	rg.h.dl = lo;
	rg.h.dh = hi;

	lo = min & 7;
	lo = lo << 5;
	lo = lo | sec;
	hi = hour & 31;
	hi = hi << 3;
	hi = hi | ( (min>>3) & 0xff);
	rg.h.cl = lo;
	rg.h.ch = hi;

	/* set date and time */
	rg.h.ah = 0x57;		/* get/set date/time of file */
	rg.h.al = 1;		/* set time/date */
	rg.x.bx = handle;
	flags = intdos(&rg, &rg);
	if ( (flags & CARRY) != 0 ) {
		fprintf(stderr,"Cannot touch %s\n",name);
		notdone++;
	}
	/* close file handle */
	rg.h.ah = 0x3e;		/* close file */
	rg.x.bx = handle;
	intdos(&rg, &rg);
}/*doit*/

gettime(ptr)
struct TIME	*ptr;
{
	rg.h.ah = 0x2a;		/* get date */
	intdos(&rg, &rg);
	ptr->year = rg.x.cx;
	ptr->month= rg.h.dh;
	ptr->day = rg.h.dl;
	ptr->wkday= rg.h.al;

	rg.h.ah = 0x2c;		/* get time */
	intdos(&rg, &rg);
	ptr->hour = rg.h.ch;
	ptr->min = rg.h.cl;
	ptr->sec = rg.h.dh;
}/*gettime*/

#define	length(i)	strlen(i)
#define	add(i,j)	((s[(i)]-'0')*10 + (s[(j)]-'0'))

getarg(s,t)
char	s[];
struct	TIME	*t;
{	int	i;

	if ( (length(s) != 10) && (length(s) != 8) ) {
		fprintf(stderr,"Illegal date\n");
		exit(1);
	}
	for (i=0; i<length(s); i++) {
		if ( (s[i] < '0') || (s[i] > '9') ) {
			fprintf(stderr,"Illegal date\n");
			exit(1);
		}
	}
	gettime(t);
	if ( length(s) == 10 ) {
		t->year = 1900 + add(8,9);
	}
	t->month = add(0,1);
	t->day   = add(2,3);
	t->hour  = add(4,5);
	t->min   = add(6,7);
}/*getarg*/

main(argc,argv)
int	argc;
char	*argv[];
{	int	i;
	struct TIME	t;
	FILE	*f;
	char	c;
	int	start;

#if MSDOS
	_parseall(&argc,argv,1);
#endif
	if ( argc <= 1 ) {
		fprintf(stderr,"Usage: touch file [file ...]\n");
		exit(0);
	}
	start = 1;
	/* check for -c option ignore all others */
	c = argv[start][0];	/* take first char */
	if (c == '-') {
		start++;
		if (argv[start][1] == 'c') create++;
	}

	/* check for MMddhhmm[yy]  any digit will do */
	c = argv[start][0];	/* take first char */
	if ( (c >= '0') && (c <= '9') ) {
		start++;
		getarg(argv[start],&t);
	} else {
		gettime(&t);
	}

	for (i=start; i<argc; i++) {
		if (create == 0 ) {
			f = fopen(argv[i],"a");
			fclose(f);
		}
		doit(argv[i],t.day,t.month,t.year,t.hour,t.min,t.sec);
	}
	exit(notdone);
}/*main*/

swh@hpsmtc1.HP.COM (Steve Harrold) (09/24/87)

Re: Lattice-C for 'touch'

Seems like a lot of finagling to actually update the file's timestamp.
Just use Microsoft C and the 'utime' library function to do it.

---------------------
Steve Harrold			...hplabs!hpsmtc1!swh
				HPG200/13
				(408) 447-5580
---------------------

martyl@rocksvax.UUCP (10/03/87)

Wow -- I was impressed at how code can expand to fill available
space.

When I found I needed to have a copy of touch on a ms-dos system when
I first needed one, I whipped this up in a few minutes (it has no c or f
options) --

/* File: touch.c - created by Marty Leisner */
/* leisner.Henr        14-Mar-87 15:11:35 */
 
/* Copyright (C) 1987 by Martin Leisner. All rights reserved. */
/* something like unix touch */

#include <stdio.h>
 
main(argc, argv)
int argc;
char *argv[];
{
        while(--argc) {
                argv++;
                if(utime(*argv, NULL))
                        printf("can't update file %s\n", *argv);
        }
}

I first used open and close on the files (which I believe forces a dos 
timestamp, but then I found out Aztec supports the utime function.

It did the job.


-- 
marty leisner
xerox corp
leisner.henr@xerox.com
martyl@rocksvax.uucp