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:
5
Makefile
Normal file
5
Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
help:
|
||||
@echo "Run ./configure first!"
|
||||
@echo "Or even better: take a look at the file README."
|
||||
install: help
|
||||
all: help
|
||||
5
Makefile.dist
Normal file
5
Makefile.dist
Normal file
@@ -0,0 +1,5 @@
|
||||
help:
|
||||
@echo "Run ./configure first!"
|
||||
@echo "Or even better: take a look at the file README."
|
||||
install: help
|
||||
all: help
|
||||
72
Makefile.in
Normal file
72
Makefile.in
Normal file
@@ -0,0 +1,72 @@
|
||||
# @Makefile.in@
|
||||
|
||||
PREFIX := @PREFIX@
|
||||
BINDIR := @BINDIR@
|
||||
MAN1DIR := @MAN1DIR@
|
||||
|
||||
MAIN := unixtime
|
||||
OBJS := unixtime.o
|
||||
#LIBS :=
|
||||
MAN1 := unixtime.1
|
||||
|
||||
MANGZ := @MANGZ@
|
||||
ifeq ($(MANGZ), 1)
|
||||
MAN1 := $(addsuffix .gz, $(MAN1))
|
||||
endif
|
||||
|
||||
CC := @CC@
|
||||
CP := @CP@
|
||||
GZIP := @GZIP@
|
||||
INSTALL := @INSTALL@
|
||||
RM := @RM@
|
||||
STRIP := @STRIP@
|
||||
TAR := @TAR@
|
||||
|
||||
.PHONY: help strip install install-bin install-man install-man1 uninstall \
|
||||
clean distclean mrproper dist
|
||||
.DEFAULT: $(MAIN)
|
||||
|
||||
$(MAIN): $(OBJS)
|
||||
ifeq (@STATIC@, 1)
|
||||
$(CC) --static -g -o $(MAIN) $(LIBS) $(OBJS)
|
||||
else
|
||||
$(CC) -g -o $(MAIN) $(LIBS) $(OBJS)
|
||||
endif
|
||||
|
||||
%.o : %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
help:
|
||||
@echo "There is no help."
|
||||
|
||||
strip: $(MAIN)
|
||||
$(STRIP) $(MAIN)
|
||||
|
||||
install: install-bin install-man
|
||||
|
||||
install-bin: strip
|
||||
$(INSTALL) $(MAIN) $(BINDIR)
|
||||
|
||||
install-man: install-man1
|
||||
|
||||
install-man1: $(MAN1)
|
||||
$(INSTALL) $^ $(MAN1DIR)
|
||||
|
||||
%.gz : %
|
||||
$(GZIP) -c $< > $@
|
||||
|
||||
uninstall:
|
||||
-$(RM) $(BINDIR)/$(MAIN)
|
||||
cd $(MAN1DIR) ; -$(RM) $(MAN1)
|
||||
|
||||
clean:
|
||||
$(RM) -f *.o $(MAIN)
|
||||
|
||||
distclean: clean
|
||||
$(CP) Makefile.dist Makefile
|
||||
mrproper: distclean
|
||||
|
||||
dist: distclean
|
||||
cd .. ; $(TAR) -czf $(notdir $(PWD)).tar.gz $(notdir $(PWD))
|
||||
|
||||
#end
|
||||
9
README
Normal file
9
README
Normal file
@@ -0,0 +1,9 @@
|
||||
unixtime(1) converts a unix timestamp (number of seconds since epoch)
|
||||
into a human readable date.
|
||||
|
||||
INSTALL
|
||||
=======
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
291
configure
vendored
Executable file
291
configure
vendored
Executable file
@@ -0,0 +1,291 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# configure
|
||||
#
|
||||
# A simple script to configure Makefiles
|
||||
# (i.e. read Makefile.in, replace strings and write Makefile).
|
||||
#
|
||||
# heinzel <heinzel@heinzelwelt.de>
|
||||
#
|
||||
# $Id: configure,v 1.1 2008/02/19 14:12:59 heinzel Exp $
|
||||
#
|
||||
VERSION='configure Version 0.1 $Revision: 1.1 $ ($Date: 2008/02/19 14:12:59 $ $Author: heinzel $)'
|
||||
|
||||
### config ###
|
||||
FILES=""
|
||||
FILES_DEF="configure.files"
|
||||
|
||||
TEMPLATE_SUFFIX=".in"
|
||||
MACROS_DEF="configure.macros"
|
||||
|
||||
MACROS="CTEMPLATE"
|
||||
MACRO_CTEMPLATE="@CFILE@ (created by configure script)"
|
||||
|
||||
### functions ###
|
||||
function print_help() {
|
||||
cat <<EOH
|
||||
configure create files by processing templates and replace macros.
|
||||
For now macros are simple name-value pairs. Use strings like @NAME@ within
|
||||
the template files and configure will replace those strings by the named
|
||||
value while creating the resulting files.
|
||||
|
||||
Usage: ./configure [OPTIONS]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
-V, --version
|
||||
|
||||
Generic Options (and default values):
|
||||
EOH
|
||||
for m in $MACROS ; do
|
||||
case "$m" in
|
||||
CFILE|CTEMPLATE)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
name="`echo $m | tr [[:upper:]] [[:lower:]]`"
|
||||
text="`eval_macro $m`"
|
||||
case "$text" in
|
||||
0)
|
||||
output=" --without-${name}"
|
||||
;;
|
||||
1)
|
||||
output=" --with-${name}"
|
||||
;;
|
||||
*)
|
||||
output=" --${name} $text"
|
||||
;;
|
||||
esac
|
||||
echo "$output"
|
||||
done
|
||||
echo ""
|
||||
cat <<EOH
|
||||
Files:
|
||||
This script will create following files: $FILES
|
||||
or read file names to create from '$FILES_DEF'
|
||||
The templates have to end with '$TEMPLATE_SUFFIX'
|
||||
The macros can be defined in '$MACROS_DEF'
|
||||
EOH
|
||||
}
|
||||
|
||||
function print_version() {
|
||||
echo "$VERSION"
|
||||
}
|
||||
|
||||
function set_macro() {
|
||||
case "$1" in
|
||||
'')
|
||||
return 1
|
||||
;;
|
||||
--with-*|--enable-*)
|
||||
name="`echo $1 | cut -f1 -d= | cut -f4- -d- | tr [[:lower:]] [[:upper:]]`"
|
||||
text="1"
|
||||
;;
|
||||
--without-*|--disable-*)
|
||||
name="`echo $1 | cut -f1 -d= | cut -f4- -d- | tr [[:lower:]] [[:upper:]]`"
|
||||
text="0"
|
||||
;;
|
||||
--*=*)
|
||||
name="`echo $1 | cut -f1 -d= | cut -c3- | tr [[:lower:]] [[:upper:]]`"
|
||||
text="`echo $1 | cut -f2- -d=`"
|
||||
;;
|
||||
--*)
|
||||
name="`echo $1 | cut -c3- | tr [[:lower:]] [[:upper:]]`"
|
||||
text="$2"
|
||||
;;
|
||||
*=*)
|
||||
name="`echo $1 | cut -f1 -d= | tr [[:lower:]] [[:upper:]]`"
|
||||
text="`echo $1 | cut -f2- -d=`"
|
||||
;;
|
||||
*)
|
||||
name="`echo $1 | tr [[:lower:]] [[:upper:]]`"
|
||||
text=""
|
||||
;;
|
||||
esac
|
||||
eval MACRO_${name}=${text}
|
||||
if ! expr " $MACROS " : ".* $name .*" >/dev/null ; then
|
||||
MACROS="$MACROS ${name}"
|
||||
fi
|
||||
}
|
||||
|
||||
function eval_macro() {
|
||||
local name="$1"
|
||||
local text=""
|
||||
local return=""
|
||||
|
||||
eval text="\$MACRO_${name}"
|
||||
while : ; do
|
||||
# Test if text contains more macros.
|
||||
echo "$text" | grep -E "@[A-Z][A-Z0-9]*@" >/dev/null
|
||||
r=$?
|
||||
if test "1${r}" != "10" ; then
|
||||
# Text is macro free.
|
||||
return="$text"
|
||||
break
|
||||
else
|
||||
# Get the last macro name from text...
|
||||
sm_name="`echo $text | sed -e 's=^.*@\([A-Z][A-Z0-9]*\)@.*$=\1='`"
|
||||
# Resolve it...
|
||||
sm_text="`eval_macro $sm_name`"
|
||||
# Substitute macro...
|
||||
text="`echo $text | sed -e 's=@'${sm_name}'@='${sm_text}'=g'`"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$return"
|
||||
}
|
||||
|
||||
function load_defaults() {
|
||||
local inc="${MACROS_DEF:-configure.macros}"
|
||||
local i=0
|
||||
local line=""
|
||||
|
||||
if test "X${inc}" = "X" ; then
|
||||
return 1
|
||||
fi
|
||||
if test ! -r "$inc" -o -d "$inc" ; then
|
||||
echo "${inc}: not a readable file." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
while read line ; do
|
||||
i="`expr $i + 1`"
|
||||
case "$line" in
|
||||
\#*|\ *|'')
|
||||
continue
|
||||
;;
|
||||
*=*)
|
||||
set_macro "$line"
|
||||
;;
|
||||
*)
|
||||
echo "Warning: $inc: unexpected line ($i)." >&2
|
||||
;;
|
||||
esac
|
||||
done < "$inc"
|
||||
}
|
||||
|
||||
function configure() {
|
||||
local file="$1"
|
||||
local ext="${TEMPLATE_SUFFIX:-.in}"
|
||||
local template=""
|
||||
|
||||
local static_file=""
|
||||
|
||||
local expr=""
|
||||
local name=""
|
||||
local text=""
|
||||
|
||||
if test "X${file}" = "X" ; then
|
||||
echo "No filename given." >&2
|
||||
return 1
|
||||
fi
|
||||
template="${file}${ext}"
|
||||
if test ! -r "$template" -o -d "$template" ; then
|
||||
echo "$file: cannot read template ($template)."
|
||||
return 1
|
||||
fi
|
||||
|
||||
set_macro CFILE="$file"
|
||||
ctext="`eval_macro CTEMPLATE`"
|
||||
cexpr="s=@${template}@=${ctext}=g"
|
||||
|
||||
if test "X${CONFIGURE_STATIC_FILE}" != "X" ; then
|
||||
static_file="$CONFIGURE_STATIC_FILE"
|
||||
read expr < "$static_file"
|
||||
else
|
||||
static_file="`mktemp configure.tmp.XXXXXX`"
|
||||
if test "1$?" -ne "10" -o "X${static_file}" = "X" \
|
||||
-o ! -w "$static_file" ; then
|
||||
echo "Cannot create temp file." >&2
|
||||
return 1
|
||||
fi
|
||||
CONFIGURE_STATIC_FILE="$static_file"
|
||||
|
||||
expr=""
|
||||
for name in $MACROS ; do
|
||||
case "$name" in
|
||||
CFILE|CTEMPLATE)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
text="`eval_macro $name`"
|
||||
expr="s=@$name@=$text=g
|
||||
$expr"
|
||||
done
|
||||
|
||||
echo "$expr" > "$static_file"
|
||||
fi
|
||||
|
||||
sed -e "$cexpr" -e "$expr" "$template" > "$file"
|
||||
}
|
||||
|
||||
function clean_up() {
|
||||
if test "X${CONFIGURE_STATIC_FILE}" != "X" -a -f "$CONFIGURE_STATIC_FILE" ; then
|
||||
rm "$CONFIGURE_STATIC_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
### set options ###
|
||||
load_defaults
|
||||
|
||||
while test "1$#" -gt "10" ; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
-V|--version)
|
||||
print_version
|
||||
exit 0
|
||||
;;
|
||||
--with-*|--without-*)
|
||||
set_macro "$1"
|
||||
shift
|
||||
;;
|
||||
--enable-*|--disable-*)
|
||||
set_macro "$1"
|
||||
shift
|
||||
;;
|
||||
--*=*)
|
||||
set_macro "$1"
|
||||
shift
|
||||
;;
|
||||
--*)
|
||||
case "$2" in
|
||||
''|-*)
|
||||
set_macro "${1}=1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set_macro "$1" "$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
### action ###
|
||||
|
||||
files="$FILES"
|
||||
if test "X${FILES_DEF}" != "X" -a -f "$FILES_DEF" ; then
|
||||
read buf < "$FILES_DEF"
|
||||
files="$files $buf"
|
||||
fi
|
||||
|
||||
|
||||
if test "X${files}" = "X" ; then
|
||||
echo "No files to configure." >&2
|
||||
echo " Make sure '$FILES_DEF' is there and readable." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for f in $files ; do
|
||||
echo "Creating file $f..."
|
||||
configure $f
|
||||
done
|
||||
|
||||
clean_up
|
||||
### end ###
|
||||
1
configure.files
Normal file
1
configure.files
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
35
configure.macros
Normal file
35
configure.macros
Normal file
@@ -0,0 +1,35 @@
|
||||
# configure.macros
|
||||
|
||||
# Directories
|
||||
PREFIX="/usr/local"
|
||||
BINDIR="@PREFIX@/bin"
|
||||
SBINDIR="@PREFIX@/sbin"
|
||||
MANDIR="@PREFIX@/share/man"
|
||||
MAN1DIR="@MANDIR@/man1"
|
||||
MAN2DIR="@MANDIR@/man2"
|
||||
MAN3DIR="@MANDIR@/man3"
|
||||
MAN4DIR="@MANDIR@/man4"
|
||||
MAN5DIR="@MANDIR@/man5"
|
||||
MAN6DIR="@MANDIR@/man6"
|
||||
MAN7DIR="@MANDIR@/man7"
|
||||
MAN8DIR="@MANDIR@/man8"
|
||||
MAN9DIR="@MANDIR@/man9"
|
||||
|
||||
# Programms
|
||||
CAT="cat"
|
||||
CC="cc"
|
||||
CP="cp"
|
||||
GZIP="gzip"
|
||||
INSTALL="install"
|
||||
RM="rm"
|
||||
SHELL="/bin/sh"
|
||||
STRIP="strip"
|
||||
TAR="tar"
|
||||
ZCAT="zcat"
|
||||
|
||||
# Magic macros
|
||||
# @CFILE@ will be expanded to the name of the file, that will be created.
|
||||
# Also the current template name (e.g. @Makefile.in@) can be used as a macro
|
||||
# that will be expanded to another macro named CTEMPLATE (which can be
|
||||
# defined here or will default to a buildin text).
|
||||
#end
|
||||
25
unixtime.1
Normal file
25
unixtime.1
Normal file
@@ -0,0 +1,25 @@
|
||||
.\" unixtime.1
|
||||
.TH UNIXTIME 1 "Feb. 2008" "heinzel"
|
||||
|
||||
.SH NAME
|
||||
unixtime \- converts a unix timestamp into a human readable date
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B unixtime [-h, --help] [-V, --version] <TIMESTAMP>
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBunixtime\fP is similar to the standard c library function \fBctime()\fP
|
||||
|
||||
.SH OPTIONS
|
||||
An integer <TIMESTAMP>, which is a number of seconds since the Epoch.
|
||||
|
||||
.SH "BUGS"
|
||||
Since I have no real understanding of C, I am sure, there are.
|
||||
|
||||
.SH "AUTHOR"
|
||||
heinzel <heinzel@heinzelwelt.de>
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR time (2),
|
||||
.BR ctime (3)
|
||||
|
||||
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