[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    resend: SUSv3 touch
From:       walter harms <wharms () bfs ! de>
Date:       2009-02-16 17:02:44
Message-ID: 49999C34.4030306 () bfs ! de
[Download RAW message or body]

Hi List,
this is the busybox version of a SUSv3 touch.
The code is basicly indentical to the last version
i posted some time ago. I have removed some deadcode
and a debug printf statement

re,
 wh

   text    data     bss     dec     hex filename
    940       0       0     940     3ac touch.o

["touch.c" (text/x-csrc)]

/* vi: set sw=4 ts=4: */
/*
 * SUSv3 touch implementation for busybox
 *
 * Copyright (C) 2008 by  Walter Harms
 * http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html
 *
 * no long option support yet
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include "libbb.h"

/* This is a NOFORK applet. Be very careful! */

/* coreutils implements:
 * -a   change only the access time
 * -c, --no-create
 *      do not create any files
 * -d, --date=STRING
 *      parse STRING and use it instead of current time
 * -f   (ignored, BSD compat)
 * -m   change only the modification time
 * -r, --reference=FILE
 *      use this file's times instead of current time
 * -t STAMP
 *      use [[CC]YY]MMDDhhmm[.ss] instead of current time
 * --time=WORD
 *      change the specified time: WORD is access, atime, or use
 */

#define TOUCH_CREATE_PERM    (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )   /* -rw-r--r--*/

#define OPT_C  1
#define OPT_F  2
#define OPT_M  4
#define OPT_A  8
#define MMDDhhmm     8
//#define YYMMDDhhmm   10
//#define CCYYMMDDhhmm 12
#define CCYYMMDDhhmmSS 15


static int a2i(char a,char b)
{

  a=a-'0';
  b=b-'0';
  return a+b*10;
}

static int  parse_timestamp(char *stamp, time_t *t)
{
	int i,n=strlen(stamp);
	size_t off;
	struct tm *tm=xmalloc(sizeof(*tm));
	char *tx;

	if ( n< MMDDhhmm || n>CCYYMMDDhhmmSS )
		return -1;

	*t=time(0);
	localtime_r(t,tm);

	tm->tm_wday=0;
	tx=(char*)tm;
	off=offsetof(struct tm,tm_min);

	/*
	  check for .ss
	  if found readjust n
	*/

	if (stamp[n-3]=='.')
	{  
		// tm_sec
		*tx=a2i(stamp[n-1],stamp[n-2]);
		n=n-3;
	}
	else
		*tx=0;

	for(i=n;0<i;i=i-2)
	{
		tx+=off;
		*tx=a2i(stamp[i-1],stamp[i-2]);

	}
	/* mon is from 0 to 11 */
	tm->tm_mon--;
	if (tm->tm_wday != 0 )  /* CC will end here */
	{
		tm->tm_year+=(tm->tm_wday*100)-1900;
		tm->tm_wday=0;
	}
	else
	{
		/*
		  69-99 have to be 19xx but 00-68 2000-2068
		*/
		if (tm->tm_year<69) tm->tm_year+=100;
	}


	*t=mktime(tm);
	if (ENABLE_FEATURE_CLEAN_UP)
		free(tm);
	return 0;
}

/*
  actualy touch a file
*/

static int touch ( char *name,struct utimbuf *timebuf, int create )
{
	int fd;

	/* Try to create the file. */
	if (!create) 
		create=O_CREAT;

	fd = open(name, O_RDWR | create ,TOUCH_CREATE_PERM );
	if ((fd >= 0) && !close(fd)) {
		utime(name, timebuf);
		return EXIT_SUCCESS;		
	}		
	bb_simple_perror_msg(name);
	return EXIT_FAILURE;
}


int touch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int touch_main(int argc UNUSED_PARAM, char **argv)
{
	struct utimbuf timebuf;
	char *reference_file = NULL;
	char *time_str       = NULL;
	int status = EXIT_SUCCESS;
	struct stat stbuf;

        int flags = getopt32(argv, "cfmar:t:", &reference_file, &time_str);
	time_t now=time(0);

	argv += optind;
	if (!*argv) {
		bb_show_usage();
	}

	timebuf.actime=timebuf.modtime = now;
	stbuf.st_atime=stbuf.st_mtime  = now;
	if (reference_file) {
		xstat(reference_file, &stbuf);
	} 
	if (time_str){
		if ( parse_timestamp(time_str,&stbuf.st_mtime) < 0 ) {
			bb_error_msg_and_die("can not parse %s",time_str);
		} 
		stbuf.st_atime=stbuf.st_mtime;
//		printf("%s -> %ld\n",time_str,stbuf.st_mtime);
	}

	if ( flags & OPT_A) timebuf.actime = stbuf.st_atime;
	if ( flags & OPT_M) timebuf.modtime = stbuf.st_mtime;

	do {
		status|=touch(*argv,&timebuf,flags&OPT_C);
	} while (*++argv);

	return status;
}


_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic