Added my implementation of unixtime.
This implementation has very few reasonable code (call atol() and ctime()), but has some nice standard program stuff (parse options, print help, ...).
This commit is contained in:
138
unixtime.c
Normal file
138
unixtime.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* unixtime.c
|
||||
*/
|
||||
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <time.h>
|
||||
|
||||
/* symbols */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define VERSION "0.1"
|
||||
|
||||
/* prototypes */
|
||||
int print_version(void);
|
||||
int print_help(void);
|
||||
|
||||
/* definition of extern objects */
|
||||
char *progname;
|
||||
const char *version = VERSION;
|
||||
|
||||
/*
|
||||
* main
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
int i;
|
||||
int j;
|
||||
char c;
|
||||
char *p;
|
||||
size_t l;
|
||||
time_t t = 0;
|
||||
struct tm *tm;
|
||||
|
||||
/* Store program name without path
|
||||
* (will be used in e.g. error messages) */
|
||||
if( (progname = strdup(basename(argv[0]))) == NULL ) {
|
||||
fprintf(stderr, "%s: ", basename(argv[0]));
|
||||
perror(NULL);
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
|
||||
/* Parse command line options */
|
||||
for( i = 1 ; i < argc ; i++ ) {
|
||||
if(!strncmp("--", argv[i], 2)) {
|
||||
/* Current argument is a GNU long option */
|
||||
if(!strcmp( "--help", argv[i])) {
|
||||
print_help();
|
||||
exit(EX_OK);
|
||||
} else if(!strcmp("--version", argv[i])) {
|
||||
print_version();
|
||||
exit(EX_OK);
|
||||
} else {
|
||||
fprintf(stderr, "%s: invalid option: %s\n", progname, argv[i]);
|
||||
fprintf(stderr, "Try '%s -h' for help.\n", progname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
} else if(!strncmp("-", argv[i], 1)) {
|
||||
/* Current argument is one or more short options */
|
||||
p = argv[i];
|
||||
for( j = 1 ; (c = p[j]) != '\0' ; j++) {
|
||||
switch(c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(EX_OK);
|
||||
break;
|
||||
case 'V':
|
||||
print_version();
|
||||
exit(EX_OK);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid option: %c\n", progname, c);
|
||||
fprintf(stderr, "Try '%s -h' for help.\n", progname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* This is the first argument, that is not an option.
|
||||
* It will be taken as timestamp. */
|
||||
t = atol(argv[i]);
|
||||
l = strlen(argv[i]);
|
||||
if((p = malloc(l + 1)) != NULL) {
|
||||
snprintf(p, l + 1, "%d", t);
|
||||
if(strcmp(argv[i], p)) {
|
||||
fprintf(stderr, "%s: not numeric: %s\n", progname,
|
||||
argv[i]);
|
||||
exit(EX_DATAERR);
|
||||
}
|
||||
free(p);
|
||||
} else {
|
||||
fprintf(stderr, "%s: Warning: cannot allocate memory"
|
||||
" to do numeric test on input.\n", progname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p = ctime((& t));
|
||||
if(p == NULL) {
|
||||
fprintf(stderr, "%s: unrecognized date '%d'.\n", progname, time);
|
||||
exit(EX_DATAERR);
|
||||
}
|
||||
fputs(p, stdout);
|
||||
exit(EX_OK);
|
||||
}
|
||||
|
||||
int print_version( void ) {
|
||||
printf("%s Version %s\n",progname, version);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int print_help( void ) {
|
||||
time_t t = 0;
|
||||
char *p;
|
||||
char *p2;
|
||||
|
||||
printf("\n");
|
||||
printf("%s converts a unix timestamp into a human readable date.\n",
|
||||
progname);
|
||||
printf("\n");
|
||||
printf("Usage: unixtime [-h, --help] [-V, --version] <TIMESTAMP>\n");
|
||||
printf("\n");
|
||||
printf("Where <TIMESTAMP> is the number of seconds since the Epoch\n");
|
||||
if((p = strdup(ctime(& t))) != NULL) {
|
||||
/* ctime() return the date as string with an appended new line.
|
||||
* Since we do not want the new line to be printed, we terminate
|
||||
* the string at the position of the new line. */
|
||||
if((p2 = strstr(p, "\n")) != NULL)
|
||||
strcpy(p2, "\0");
|
||||
printf("(i.e. %s).\n", p);
|
||||
free(p);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
Reference in New Issue
Block a user