touch.c revision eaacacc0c33d7b79a8156d9b3e07dbb4354eb2d6
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* Copyright (c) 1987, 1988 Microsoft Corporation */
/* All Rights Reserved */
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
#include <libgen.h>
#include <fcntl.h>
#include <pwd.h>
#include <time.h>
#include <unistd.h>
#include <locale.h>
#include <errno.h>
#define BADTIME "bad time specification"
static char *myname;
static int isnumber(char *);
static int atoi_for2(char *);
static void usage(const int);
static void touchabort(const char *);
static void parse_time(char *, timestruc_t *);
static void parse_datetime(char *, timestruc_t *);
int
{
int c;
int aflag = 0;
int cflag = 0;
int rflag = 0;
int mflag = 0;
int tflag = 0;
int stflag = 0;
int status = 0;
int usecurrenttime = 1;
int timespecified;
int optc;
int fd;
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
cflag++;
stflag++;
switch (optc) {
case 'f':
rflag++;
usecurrenttime = 0;
return (2);
}
break;
case '?':
break;
};
} else
switch (optc) {
case 'a':
aflag++;
usecurrenttime = 0;
break;
case 'c':
cflag++;
break;
case 'f': /* silently ignore for UCB compat */
break;
case 'm':
mflag++;
usecurrenttime = 0;
break;
case 'r': /* same as settime's -f option */
rflag++;
usecurrenttime = 0;
return (2);
}
break;
case 't':
tflag++;
usecurrenttime = 0;
break;
case '?':
break;
}
aflag = 1;
mflag = 1;
}
/*
* If either -r or -t has been specified,
* use the specified time.
*/
if (timespecified == 0) {
/*
* time is specified as an operand.
* use it.
*/
usecurrenttime = 0;
timespecified = 1;
argc--;
} else {
/*
* no time information is specified.
* use the current time.
*/
}
}
for (c = 0; c < argc; c++) {
/*
* If stat failed for reasons other than EOVERFLOW or
* ENOENT, the file should not be created, since this
* can clobber the contents of an existing file.
*/
gettext("%s: %s: current timestamps"
" unavailable:\n%s"),
gettext("consider trying again"
" without -a option\n") :
gettext("consider trying again"
" without -m option\n"));
status++;
continue;
}
/*
* Since we have EOVERFLOW, we know the file
* exists. Since both atime and mtime are being
* changed to known values, we don't care that
* st_atime and st_mtime from the file aren't
* available.
*/
gettext("%s: cannot stat %s: %s\n"),
status++;
continue;
} else if (cflag) {
continue;
< 0) {
gettext("%s: cannot create %s: %s\n"),
status++;
continue;
} else {
gettext("%s: cannot stat %s: %s\n"),
status++;
continue;
}
}
}
if (mflag == 0) {
/* Keep the mtime of the file */
} else {
if (timespecified) {
/* Set the specified time */
times + 1);
}
/* Otherwise, use the current time by gettimeofday */
}
if (aflag == 0) {
/* Keep the atime of the file */
} else {
if (timespecified) {
/* Set the specified time */
}
/* Otherwise, use the current time by gettimeofday */
}
gettext("%s: cannot change times on %s: %s\n"),
status++;
continue;
}
}
return (status);
}
static int
isnumber(char *s)
{
int c;
while ((c = *s++) != '\0')
if (!isdigit(c))
return (0);
return (1);
}
static void
{
int century = 0;
int seconds = 0;
char *p;
/*
* time in the following format (defined by the touch(1) spec):
* [[CC]YY]MMDDhhmm[.SS]
*/
*p = '\0';
}
switch (strlen(t)) {
case 12: /* CCYYMMDDhhmm */
t += 2;
/* FALLTHROUGH */
case 10: /* YYMMDDhhmm */
t += 2;
if (century == 0) {
} else
/* FALLTHROUGH */
case 8: /* MMDDhhmm */
t += 2;
t += 2;
t += 2;
break;
default:
}
}
static void
{
/*
* time in the following format (defined by the touch(1) spec):
* MMDDhhmm[yy]
*/
switch (strlen(t)) {
case 10: /* MMDDhhmmyy */
/* FALLTHROUGH */
case 8: /* MMDDhhmm */
t += 2;
t += 2;
t += 2;
break;
default:
}
}
static int
atoi_for2(char *p)
{
int value;
return (value);
}
static void
touchabort(const char *message)
{
exit(1);
}
static void
{
if (settime)
"usage: %s [-f file] [mmddhhmm[yy]] file...\n"), myname);
else
"usage: %s [-acm] [-r ref_file] file...\n"
" %s [-acm] [MMDDhhmm[yy]] file...\n"
" %s [-acm] [-t [[CC]YY]MMDDhhmm[.SS]] file...\n"),
exit(2);
}
/*
* nanoseconds are rounded off to microseconds by flooring.
*/
static void
{
}