Initial release

This commit is contained in:
Pierre Pronchery 2005-02-01 00:03:33 +00:00
parent 6f523033ea
commit 3466fd5f24

270
src/touch.c Normal file
View File

@ -0,0 +1,270 @@
/* touch.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
/* Prefs */
#define PREFS_a 1
#define PREFS_m 2
#define PREFS_c 4
#define PREFS_r 8
#define PREFS_t 16
typedef struct _Prefs
{
int flags;
char * time;
} Prefs;
static int _prefs_parse(Prefs * prefs, int argc, char * argv[])
{
int o;
memset(prefs, 0, sizeof(Prefs));
while((o = getopt(argc, argv, "acmr:t:")) != -1)
{
switch(o)
{
case 'a':
prefs->flags |= PREFS_a;
break;
case 'c':
prefs->flags |= PREFS_c;
break;
case 'm':
prefs->flags |= PREFS_m;
break;
case 'r':
prefs->flags -= prefs->flags & PREFS_t;
prefs->flags |= PREFS_r;
prefs->time = optarg;
break;
case 't':
prefs->flags -= prefs->flags & PREFS_r;
prefs->flags |= PREFS_t;
prefs->time = optarg;
break;
default:
return 1;
}
}
if((prefs->flags & PREFS_a) && (prefs->flags & PREFS_m))
prefs->flags |= (PREFS_a | PREFS_m);
return 0;
}
/* touch */
static int _touch_error(char * message, int ret);
static int _touch_rtime(char * filename, time_t * atime, time_t * mtime);
static int _touch_ttime(char * string, time_t * time);
static int _touch_do(Prefs * prefs, char * filename,
time_t atime, time_t mtime);
static int _touch(Prefs * prefs, int argc, char * argv[])
{
int res = 0;
time_t atime = 0;
time_t mtime = 0;
int i;
if(prefs->flags & PREFS_r
&& _touch_rtime(prefs->time, &atime, &mtime) != 0)
return 2;
else if(prefs->flags & PREFS_t)
{
if(_touch_ttime(prefs->time, &atime) != 0)
return 2;
mtime = atime;
}
for(i = 0; i < argc; i++)
res += _touch_do(prefs, argv[i], atime, mtime);
return res > 0 ? 2 : 0;
}
static int _touch_error(char * message, int ret)
{
fprintf(stderr, "%s", "touch: ");
perror(message);
return ret;
}
static int _touch_rtime(char * filename, time_t * atime, time_t * mtime)
{
struct stat st;
if(stat(filename, &st) != 0)
return _touch_error(filename, 1);
*atime = st.st_atime;
*mtime = st.st_mtime;
return 0;
}
static int _ttime_century(char ** p, time_t * time);
static int _ttime_year(char ** p, time_t * time);
static int _ttime_month(char ** p, time_t * time);
static int _ttime_day(char ** p, time_t * time);
static int _ttime_hour(char ** p, time_t * time);
static int _ttime_minut(char ** p, time_t * time);
static int _ttime_second(char ** p, time_t * time);
static int _touch_ttime(char * string, time_t * time)
{
time_t t = 0;
char ** p = &string;
int ret = 0;
int len;
switch((len = strlen(string)))
{
case 15:
case 12:
ret +=_ttime_century(p, &t);
case 13:
case 10:
ret += _ttime_year(p, &t);
case 11:
case 8:
ret += _ttime_month(p, &t);
ret += _ttime_day(p, &t);
ret += _ttime_hour(p, &t);
ret += _ttime_minut(p, &t);
if(len % 2)
ret += _ttime_second(p, &t);
break;
default:
/* FIXME call usage() instead */
fprintf(stderr, "%s", "touch: -t: invalid time\n");
return 1;
}
if(ret != 0)
return 1;
*time = t;
return 0;
}
static int _ttime_number(char ** p, unsigned int * res);
static int _ttime_century(char ** p, time_t * time)
{
/* FIXME */
return 1;
}
static int _ttime_number(char ** p, unsigned int * res)
{
if(**p >= '0' && **p <= '9')
{
*res = (**p - '0') * 10;
(*p)++;
if(**p >= '0' && **p <= '9')
{
*res += (**p - '0');
#ifdef DEBUG
fprintf(stderr, "DEBUG: %u\n", *res);
#endif
(*p)++;
return 0;
}
}
return 1;
}
static int _ttime_year(char ** p, time_t * time)
{
int res;
if(_ttime_number(p, &res) != 0)
return 1;
*time = res * 60 * 60 * 24 * 365; /* FIXME */
return 0;
}
static int _ttime_month(char ** p, time_t * time)
{
int res;
if(_ttime_number(p, &res) != 0)
return 1;
*time = res * 60 * 60 * 24 * 30; /* FIXME */
return 0;
}
static int _ttime_day(char ** p, time_t * time)
{
int res;
if(_ttime_number(p, &res) != 0)
return 1;
*time = res * 60 * 60 * 24;
return 0;
}
static int _ttime_hour(char ** p, time_t * time)
{
int res;
if(_ttime_number(p, &res) != 0)
return 1;
*time += res * 60 * 60;
return 0;
}
static int _ttime_minut(char ** p, time_t * time)
{
unsigned int res;
if(_ttime_number(p, &res) != 0 || res >= 60)
return 1;
*time += res * 60;
return 0;
}
static int _ttime_second(char ** p, time_t * time)
{
unsigned int res;
if(**p != '.')
return 1;
(*p)++;
if(_ttime_number(p, &res) != 0 || res >= 60)
return 1;
*time += res;
return 0;
}
static int _touch_do(Prefs * prefs, char * filename, time_t atime, time_t mtime)
{
#ifdef DEBUG
fprintf(stderr, "%s%d%s%s%s%ld%s%ld%s", "_touch_do(", prefs->flags,
", ", filename, ", ", atime, ", ", mtime, ");\n");
#endif
return 1;
}
/* usage */
static int _usage(void)
{
fprintf(stderr, "%s", "Usage: touch [-acm][-r ref_file|-t time]\
file...\n\
-a change the access time\n\
-c do not create file if it doesn't exist\n\
-m change the modification time\n\
-r use the file of the given file\n\
-t use the specified time as [[CC]YY]MMDDhhmm[.SS]\n");
return 1;
}
/* main */
int main(int argc, char * argv[])
{
Prefs prefs;
if(_prefs_parse(&prefs, argc, argv) != 0 || argc - optind == 0)
return _usage();
return _touch(&prefs, argc - optind, &argv[optind]);
}