|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
( cd .. ; libisoburn-develop/xorriso/compile_xorriso.sh -g )
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
cc -g -DXorriso_with_maiN -DXorriso_with_readlinE \
|
|
|
|
-DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \
|
|
|
|
-Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
|
|
|
|
-o xorriso/xorriso \
|
|
|
|
xorriso/xorriso.c xorriso/xorrisoburn.c \
|
|
|
|
-lpthread -lreadline -lburn -lisofs -lisoburn
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
cc -g -DXorriso_with_readlinE \
|
|
|
|
-DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \
|
|
|
|
-Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
|
|
|
|
-c \
|
|
|
|
xorriso/xorriso.c xorriso/xorrisoburn.c
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Command line oriented batch and dialog tool which creates, loads,
|
|
|
|
manipulates and burns ISO 9660 filesystem images.
|
|
|
|
|
|
|
|
Copyright 2007-2008 Thomas Schmitt, <scdbackup@gmx.net>
|
|
|
|
|
|
|
|
Initial code of this program was derived from program src/askme.c out
|
|
|
|
of scdbackup-0.8.8, Copyright 2007 Thomas Schmitt, BSD-License.
|
|
|
|
|
|
|
|
Provided under GPL version 2, with the announcement that this might
|
|
|
|
get changed in future. I would prefer BSD or a modified LGPL with no
|
|
|
|
option to choose any kind of future GPL version.
|
|
|
|
(This announcement affects only future releases of xorriso.
|
|
|
|
If you obtain a copy licensed as "GPL version 2" then this license is
|
|
|
|
not revocable for that particular copy, of course.)
|
|
|
|
|
|
|
|
|
|
|
|
Overview of xorriso architecture:
|
|
|
|
|
|
|
|
libburn provides the ability to read and write data.
|
|
|
|
|
|
|
|
libisofs interprets and manipulates ISO 9660 directory trees. It generates
|
|
|
|
the output stream which is handed over to libburn.
|
|
|
|
|
|
|
|
libisoburn encapsulates the connectivity issues between libburn and
|
|
|
|
libisofs. It also enables multi-session emulation on overwritable media
|
|
|
|
and random access file objects.
|
|
|
|
xorriso is intended as reference application of libisoburn.
|
|
|
|
|
|
|
|
xorrisoburn.[ch] encapsulate any usage of the libraries by xorriso.
|
|
|
|
|
|
|
|
xorriso.h exposes the public functions of xorriso which are intended
|
|
|
|
to be used by programs which link with xorriso.o. These functions are
|
|
|
|
direct equivalents of the xorriso interpreter commands.
|
|
|
|
There is also the API for handling event messages.
|
|
|
|
|
|
|
|
xorriso_private.h is not to be included by other software. It encapsulates
|
|
|
|
the inner interfaces of xorriso.
|
|
|
|
|
|
|
|
xorriso.c provides the command interpreter as described in xorriso.1.
|
|
|
|
It performs any activity that does not demand a reference to a symbol
|
|
|
|
of the library APIs. This includes:
|
|
|
|
- Interpretation of user input from arguments, dialog, and scripting.
|
|
|
|
- Output of result text and event messages.
|
|
|
|
- POSIX filesystem operations.
|
|
|
|
- Public functions which perform the particular xorriso commands.
|
|
|
|
- The main() function, if enabled by #define Xorriso_with_maiN.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <utime.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <grp.h>
|
|
|
|
|
|
|
|
/* eventually, this is done in xorriso_private.h : #include <regex.h> */
|
|
|
|
|
|
|
|
#ifdef Xorriso_with_readlinE
|
|
|
|
#ifdef Xorriso_with_old_readlinE
|
|
|
|
#include <readline.h>
|
|
|
|
#include <history.h>
|
|
|
|
#else /* Xorriso_with_old_readlinE */
|
|
|
|
#include <readline/readline.h>
|
|
|
|
#include <readline/history.h>
|
|
|
|
#endif /* ! Xorriso_with_old_readlinE */
|
|
|
|
#endif /* Xorriso_with_readlinE */
|
|
|
|
|
|
|
|
#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ));
|
|
|
|
|
|
|
|
|
|
|
|
/* Diet facility: exclude help texts from binaries */
|
|
|
|
/* This will eventually be redefined to eat up its content */
|
|
|
|
#define AlN(x) x
|
|
|
|
|
|
|
|
|
|
|
|
/* There is only one stage of diet: Xorriso_no_helP */
|
|
|
|
#ifdef Xorriso_no_helP
|
|
|
|
#undef AlN
|
|
|
|
#define AlN(x)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
|
|
|
|
/* The official xorriso options API. "No shortcuts" */
|
|
|
|
#include "xorriso.h"
|
|
|
|
|
|
|
|
/* The inner isofs- and burn-library interface */
|
|
|
|
#include "xorrisoburn.h"
|
|
|
|
|
|
|
|
/* The inner description of XorrisO */
|
|
|
|
#define Xorriso_is_xorriso_selF 1
|
|
|
|
#include "xorriso_private.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef Xorriso_sfile_externaL
|
|
|
|
|
|
|
|
|
|
|
|
char *Sfile_fgets(char *line, int maxl, FILE *fp)
|
|
|
|
{
|
|
|
|
int l;
|
|
|
|
char *ret;
|
|
|
|
|
|
|
|
ret= fgets(line,maxl,fp);
|
|
|
|
if(ret==NULL)
|
|
|
|
return(NULL);
|
|
|
|
l= strlen(line);
|
|
|
|
if(l>0) if(line[l-1]=='\r') line[--l]= 0;
|
|
|
|
if(l>0) if(line[l-1]=='\n') line[--l]= 0;
|
|
|
|
if(l>0) if(line[l-1]=='\r') line[--l]= 0;
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_count_components(char *path, int flag)
|
|
|
|
/*
|
|
|
|
bit0= do not ignore trailing slash
|
|
|
|
bit1= do not ignore empty components (other than the empty root name)
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int l,count= 0;
|
|
|
|
char *cpt;
|
|
|
|
|
|
|
|
l= strlen(path);
|
|
|
|
if(l==0)
|
|
|
|
return(0);
|
|
|
|
count= 1;
|
|
|
|
for(cpt= path+l-1;cpt>=path;cpt--) {
|
|
|
|
if(*cpt=='/') {
|
|
|
|
if(*(cpt+1)==0 && !(flag&1))
|
|
|
|
continue;
|
|
|
|
if(*(cpt+1)=='/' && !(flag&2))
|
|
|
|
continue;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(count);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_component_pointer(char *path, char **sourcept, int idx, int flag)
|
|
|
|
/*
|
|
|
|
bit0= do not ignore trailing slash
|
|
|
|
bit1= do not ignore empty components (other than the empty root name)
|
|
|
|
bit2= accept 0 as '/'
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int count= 0;
|
|
|
|
char *spt;
|
|
|
|
|
|
|
|
for(spt= path;*spt!=0 || (flag&4);spt++) {
|
|
|
|
if(count>=idx) {
|
|
|
|
*sourcept= spt;
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
if(*spt=='/' || *spt==0) {
|
|
|
|
if(*(spt+1)=='/' && !(flag&2))
|
|
|
|
continue;
|
|
|
|
if(*(spt+1)==0 && !(flag&1))
|
|
|
|
continue;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if((flag&1) && count>=idx)
|
|
|
|
return(1);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_leafname(char *path, char leafname[SfileadrL], int flag)
|
|
|
|
{
|
|
|
|
int count, ret;
|
|
|
|
char *lpt;
|
|
|
|
|
|
|
|
leafname[0]= 0;
|
|
|
|
count= Sfile_count_components(path, 0);
|
|
|
|
if(count==0)
|
|
|
|
return(0);
|
|
|
|
ret= Sfile_component_pointer(path, &lpt, count-1, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
return(ret);
|
|
|
|
if(Sfile_str(leafname, lpt, 0)<=0)
|
|
|
|
return(0);
|
|
|
|
lpt= strchr(leafname, '/');
|
|
|
|
if(lpt!=NULL)
|
|
|
|
*lpt= 0;
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag)
|
|
|
|
{
|
|
|
|
int l;
|
|
|
|
|
|
|
|
l= strlen(path);
|
|
|
|
if(l+1>=SfileadrL)
|
|
|
|
return(0);
|
|
|
|
if(l==0) {
|
|
|
|
strcpy(path,"/");
|
|
|
|
l= 1;
|
|
|
|
} else if(path[l-1]!='/') {
|
|
|
|
path[l++]= '/';
|
|
|
|
path[l]= 0;
|
|
|
|
}
|
|
|
|
if(l+strlen(addon)>=SfileadrL)
|
|
|
|
return(0);
|
|
|
|
if(addon[0]=='/')
|
|
|
|
strcpy(path+l,addon+1);
|
|
|
|
else
|
|
|
|
strcpy(path+l,addon);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag)
|
|
|
|
{
|
|
|
|
int l, i;
|
|
|
|
|
|
|
|
l= strlen(path)+strlen(prefix)+1;
|
|
|
|
if(l>=SfileadrL) {
|
|
|
|
|
|
|
|
#ifdef Not_yeT
|
|
|
|
/* >>> ??? how to transport messages to xorriso ? */
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Combination of wd and relative address too long (%d > %d)",
|
|
|
|
l,SfileadrL-1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
l-= strlen(path);
|
|
|
|
for(i= strlen(path)+1; i>=0; i--)
|
|
|
|
path[i+l]= path[i];
|
|
|
|
strcpy(path,prefix);
|
|
|
|
path[l-1]= '/';
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Sfile_being_group_member(struct stat *stbuf, int flag)
|
|
|
|
{
|
|
|
|
int i, suppl_groups;
|
|
|
|
gid_t *suppl_glist;
|
|
|
|
|
|
|
|
if (getegid()==stbuf->st_gid)
|
|
|
|
return(1);
|
|
|
|
suppl_groups= getgroups(0, NULL);
|
|
|
|
suppl_glist= (gid_t *) malloc((suppl_groups + 1) * sizeof(gid_t));
|
|
|
|
if (suppl_glist==NULL)
|
|
|
|
return(-1);
|
|
|
|
suppl_groups= getgroups(suppl_groups+1,suppl_glist);
|
|
|
|
for (i= 0; i<suppl_groups; i++) {
|
|
|
|
if (suppl_glist[i]==stbuf->st_gid) {
|
|
|
|
free((char *) suppl_glist);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free((char *) suppl_glist);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_type(char *filename, int flag)
|
|
|
|
/*
|
|
|
|
bit0= return -1 if file is missing
|
|
|
|
bit1= return a hardlink with siblings as type 5
|
|
|
|
bit2= evaluate eventual link target rather than the link object itself
|
|
|
|
bit3= return a socket or a char device as types 7 or 8 rather than 0
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
return:
|
|
|
|
0=unknown
|
|
|
|
1=regular
|
|
|
|
2=directory
|
|
|
|
3=symbolic link
|
|
|
|
4=named pipe
|
|
|
|
5=multiple hardlink (with bit1)
|
|
|
|
6=block device
|
|
|
|
7=socket (with bit3)
|
|
|
|
8=character device (with bit3)
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
struct stat stbuf;
|
|
|
|
if(flag&4) {
|
|
|
|
if(stat(filename,&stbuf)==-1) {
|
|
|
|
if(flag&1) return(-1);
|
|
|
|
else return(0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(lstat(filename,&stbuf)==-1) {
|
|
|
|
if(flag&1) return(-1);
|
|
|
|
else return(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(S_ISREG(stbuf.st_mode)) {
|
|
|
|
if(flag&2)
|
|
|
|
if(stbuf.st_nlink>1)
|
|
|
|
return(5);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
if(S_ISDIR(stbuf.st_mode))
|
|
|
|
return(2);
|
|
|
|
if((stbuf.st_mode&S_IFMT)==S_IFLNK)
|
|
|
|
return(3);
|
|
|
|
if(S_ISFIFO(stbuf.st_mode))
|
|
|
|
return(4);
|
|
|
|
if(S_ISBLK(stbuf.st_mode))
|
|
|
|
return(6);
|
|
|
|
if(flag&8)
|
|
|
|
if((stbuf.st_mode&S_IFMT)==S_IFSOCK)
|
|
|
|
return(7);
|
|
|
|
if(flag&8)
|
|
|
|
if(S_ISCHR(stbuf.st_mode))
|
|
|
|
return(8);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *Sfile_datestr(time_t tim, short int flag)
|
|
|
|
/*
|
|
|
|
bit0=with hours+minutes
|
|
|
|
bit1=with seconds
|
|
|
|
|
|
|
|
bit8= local time rather than UTC
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
static char zeitcode[80]={"000000"};
|
|
|
|
char puff[80];
|
|
|
|
struct tm *azt;
|
|
|
|
|
|
|
|
if(flag&256)
|
|
|
|
azt = localtime(&tim);
|
|
|
|
else
|
|
|
|
azt = gmtime(&tim);
|
|
|
|
|
|
|
|
if(azt->tm_year>99)
|
|
|
|
sprintf(zeitcode,"%c%1.1d%2.2d%2.2d",
|
|
|
|
'A'+(azt->tm_year-100)/10,azt->tm_year%10,
|
|
|
|
azt->tm_mon+1,azt->tm_mday);
|
|
|
|
else
|
|
|
|
sprintf(zeitcode,"%2.2d%2.2d%2.2d",
|
|
|
|
azt->tm_year,azt->tm_mon+1,azt->tm_mday);
|
|
|
|
if(flag&1){
|
|
|
|
sprintf(puff,".%2.2d%2.2d",azt->tm_hour,azt->tm_min);
|
|
|
|
strcat(zeitcode,puff);
|
|
|
|
}
|
|
|
|
if(flag&2){
|
|
|
|
sprintf(puff,"%2.2d",azt->tm_sec);
|
|
|
|
strcat(zeitcode,puff);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(zeitcode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_scale(double value, char *result, int siz, double thresh, int flag)
|
|
|
|
/*
|
|
|
|
bit0= eventually ommit 'b'
|
|
|
|
bit1= make text as short as possible
|
|
|
|
bit2= no fraction (if it would fit at all)
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
char scale_c,scales[6],form[80];
|
|
|
|
int i,dec_siz= 0,avail_siz= 1;
|
|
|
|
|
|
|
|
strcpy(scales,"bkmgtp");
|
|
|
|
scale_c= scales[0];
|
|
|
|
for(i=1;scales[i]!=0;i++) {
|
|
|
|
if(value<thresh-0.5)
|
|
|
|
break;
|
|
|
|
value/= 1024.0;
|
|
|
|
scale_c= scales[i];
|
|
|
|
}
|
|
|
|
if(scale_c!='b' && !(flag&4)) { /* is there room for fractional part ? */
|
|
|
|
avail_siz= siz-1;
|
|
|
|
sprintf(form,"%%.f");
|
|
|
|
sprintf(result,"%.f",value);
|
|
|
|
if(strlen(result)<=avail_siz-2)
|
|
|
|
dec_siz= 1; /* we are very modest */
|
|
|
|
}
|
|
|
|
if(scale_c=='b' && (flag&1)) {
|
|
|
|
if(flag&2)
|
|
|
|
sprintf(form,"%%.f");
|
|
|
|
else
|
|
|
|
sprintf(form,"%%%d.f",siz);
|
|
|
|
sprintf(result,form,value);
|
|
|
|
} else {
|
|
|
|
if(flag&2)
|
|
|
|
sprintf(form,"%%.f%%c");
|
|
|
|
else if(dec_siz>0)
|
|
|
|
sprintf(form,"%%%d.%df%%c",avail_siz,dec_siz);
|
|
|
|
else
|
|
|
|
sprintf(form,"%%%d.f%%c",siz-1);
|
|
|
|
sprintf(result,form,value,scale_c);
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_off_t_text(char text[80], off_t num, int flag)
|
|
|
|
{
|
|
|
|
char *tpt;
|
|
|
|
off_t hnum, scale= 1;
|
|
|
|
int digits= 0, d, i;
|
|
|
|
|
|
|
|
tpt= text;
|
|
|
|
hnum= num;
|
|
|
|
if(hnum<0) {
|
|
|
|
*(tpt++)= '-';
|
|
|
|
hnum= -num;
|
|
|
|
}
|
|
|
|
if(hnum<0) { /* it can stay nastily persistent */
|
|
|
|
strcpy(text, "_overflow_");
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
for(i= 0; i<23; i++) { /* good for up to 70 bit = 10 exp 21.07... */
|
|
|
|
if(hnum==0)
|
|
|
|
break;
|
|
|
|
hnum/= 10;
|
|
|
|
if(hnum)
|
|
|
|
scale*= 10;
|
|
|
|
}
|
|
|
|
if(i==0) {
|
|
|
|
strcpy(text, "0");
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
if(i==23) {
|
|
|
|
strcpy(text, "_overflow_");
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
digits= i;
|
|
|
|
hnum= num;
|
|
|
|
for(; i>0; i--) {
|
|
|
|
d= hnum/scale;
|
|
|
|
tpt[digits-i]= '0'+d;
|
|
|
|
hnum= hnum%scale;
|
|
|
|
scale/= 10;
|
|
|
|
}
|
|
|
|
tpt[digits]= 0;
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_destroy_argv(int *argc, char ***argv, int flag)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if(*argc>0 && *argv!=NULL){
|
|
|
|
for(i=0;i<*argc;i++){
|
|
|
|
if((*argv)[i]!=NULL)
|
|
|
|
Smem_freE((*argv)[i]);
|
|
|
|
}
|
|
|
|
Smem_freE((char *) *argv);
|
|
|
|
}
|
|
|
|
*argc= 0;
|
|
|
|
*argv= NULL;
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
|
|
|
|
int flag)
|
|
|
|
/*
|
|
|
|
bit0= read progname as first argument from line
|
|
|
|
bit1= just release argument list argv and return
|
|
|
|
bit2= abort with return(0) if incomplete quotes are found
|
|
|
|
bit3= eventually prepend missing '-' to first argument read from line
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc;
|
|
|
|
char *cpt,*start;
|
|
|
|
char buf[SfileadrL];
|
|
|
|
|
|
|
|
Sfile_destroy_argv(argc,argv,0);
|
|
|
|
if(flag&2) return(1);
|
|
|
|
|
|
|
|
for(pass=0;pass<2;pass++) {
|
|
|
|
cpt= line-1;
|
|
|
|
if(!(flag&1)){
|
|
|
|
argzaehl= line_start_argc= 1;
|
|
|
|
if(pass==0)
|
|
|
|
maxl= strlen(progname);
|
|
|
|
else
|
|
|
|
strcpy((*argv)[0],progname);
|
|
|
|
} else {
|
|
|
|
argzaehl= line_start_argc= 0;
|
|
|
|
if(pass==0) maxl= 0;
|
|
|
|
}
|
|
|
|
while(*(++cpt)!=0){
|
|
|
|
if(isspace(*cpt)) continue;
|
|
|
|
start= cpt;
|
|
|
|
buf[0]= 0;
|
|
|
|
cpt--;
|
|
|
|
while(*(++cpt)!=0) {
|
|
|
|
if(isspace(*cpt)) break;
|
|
|
|
if(*cpt=='"'){
|
|
|
|
l= cpt-start; bufl= strlen(buf);
|
|
|
|
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
|
|
|
|
l= strlen(buf);
|
|
|
|
start= cpt+1;
|
|
|
|
while(*(++cpt)!=0) if(*cpt=='"') break;
|
|
|
|
if((flag&4) && *cpt==0)
|
|
|
|
return(0);
|
|
|
|
l= cpt-start; bufl= strlen(buf);
|
|
|
|
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
|
|
|
|
start= cpt+1;
|
|
|
|
}else if(*cpt=='\''){
|
|
|
|
l= cpt-start; bufl= strlen(buf);
|
|
|
|
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
|
|
|
|
l= strlen(buf);
|
|
|
|
start= cpt+1;
|
|
|
|
while(*(++cpt)!=0) if(*cpt=='\'') break;
|
|
|
|
if((flag&4) && *cpt==0)
|
|
|
|
return(0);
|
|
|
|
l= cpt-start; bufl= strlen(buf);
|
|
|
|
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
|
|
|
|
start= cpt+1;
|
|
|
|
}
|
|
|
|
if(*cpt==0) break;
|
|
|
|
}
|
|
|
|
l= cpt-start;
|
|
|
|
bufl= strlen(buf);
|
|
|
|
if(l>0) {strncat(buf,start,l);buf[bufl+l]= 0;}
|
|
|
|
l= strlen(buf);
|
|
|
|
if(pass==0){
|
|
|
|
if(argzaehl==line_start_argc && (flag&8))
|
|
|
|
if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
|
|
|
|
l++;
|
|
|
|
if(l>maxl) maxl= l;
|
|
|
|
}else{
|
|
|
|
strcpy((*argv)[argzaehl],buf);
|
|
|
|
if(argzaehl==line_start_argc && (flag&8))
|
|
|
|
if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
|
|
|
|
sprintf((*argv)[argzaehl],"-%s", buf);
|
|
|
|
}
|
|
|
|
argzaehl++;
|
|
|
|
if(*cpt==0) break;
|
|
|
|
}
|
|
|
|
if(pass==0){
|
|
|
|
*argc= argzaehl;
|
|
|
|
if(argzaehl>0) {
|
|
|
|
*argv= (char **) Smem_malloC(argzaehl*sizeof(char *));
|
|
|
|
if(*argv==NULL)
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
for(i=0;i<*argc;i++) {
|
|
|
|
(*argv)[i]= (char *) Smem_malloC((maxl+1));
|
|
|
|
if((*argv)[i]==NULL)
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= append */
|
|
|
|
int Sfile_str(char target[SfileadrL], char *source, int flag)
|
|
|
|
{
|
|
|
|
int l;
|
|
|
|
|
|
|
|
l= strlen(source);
|
|
|
|
if(flag&1)
|
|
|
|
l+= strlen(target);
|
|
|
|
if(l>=SfileadrL) {
|
|
|
|
fprintf(stderr, "--- Path string overflow (%d > %d). Malicious input ?\n",
|
|
|
|
l,SfileadrL-1);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if(flag&1)
|
|
|
|
strcat(target, source);
|
|
|
|
else
|
|
|
|
strcpy(target, source);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Combine environment variable HOME with given filename
|
|
|
|
@param filename Address relative to $HOME
|
|
|
|
@param fileadr Resulting combined address
|
|
|
|
@param fa_size Size of array fileadr
|
|
|
|
@param flag Unused yet
|
|
|
|
@return 1=ok , 0=no HOME variable , -1=result address too long
|
|
|
|
*/
|
|
|
|
int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag)
|
|
|
|
{
|
|
|
|
char *home;
|
|
|
|
|
|
|
|
strcpy(fileadr,filename);
|
|
|
|
home= getenv("HOME");
|
|
|
|
if(home==NULL)
|
|
|
|
return(0);
|
|
|
|
if(strlen(home)+strlen(filename)+1>=fa_size)
|
|
|
|
return(-1);
|
|
|
|
strcpy(fileadr,home);
|
|
|
|
if(filename[0]!=0){
|
|
|
|
strcat(fileadr,"/");
|
|
|
|
strcat(fileadr,filename);
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Return a double representing seconds and microseconds since 1 Jan 1970 */
|
|
|
|
double Sfile_microtime(int flag)
|
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
struct timezone tz;
|
|
|
|
gettimeofday(&tv,&tz);
|
|
|
|
return((double) (tv.tv_sec+1.0e-6*tv.tv_usec));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sfile_decode_datestr(struct tm *reply, char *text, int flag)
|
|
|
|
/* YYMMDD[.hhmm[ss]] */
|
|
|
|
{
|
|
|
|
int i,l;
|
|
|
|
time_t current_time;
|
|
|
|
struct tm *now;
|
|
|
|
|
|
|
|
current_time= time(0);
|
|
|
|
now= localtime(¤t_time);
|
|
|
|
for(i=0;i<sizeof(struct tm);i++)
|
|
|
|
((char *) reply)[i]= ((char *) now)[i];
|
|
|
|
|
|
|
|
if(text[0]<'0'|| (text[0]>'9' && text[0]<'A') || text[0]>'Z')
|
|
|
|
return(0);
|
|
|
|
l= strlen(text);
|
|
|
|
for(i=1;i<l;i++)
|
|
|
|
if(text[i]<'0'||text[i]>'9')
|
|
|
|
break;
|
|
|
|
if(i!=6)
|
|
|
|
return(0);
|
|
|
|
if(text[i]==0)
|
|
|
|
goto decode;
|
|
|
|
if(text[i]!='.' || (l!=11 && l!=13))
|
|
|
|
return(0);
|
|
|
|
for(i++;i<l;i++)
|
|
|
|
if(text[i]<'0'||text[i]>'9')
|
|
|
|
break;
|
|
|
|
if(i!=l)
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
decode:;
|
|
|
|
reply->tm_hour= 0;
|
|
|
|
reply->tm_min= 0;
|
|
|
|
reply->tm_sec= 0;
|
|
|
|
i= 0;
|
|
|
|
if(text[0]>='A')
|
|
|
|
reply->tm_year= 100+(text[i]-'A')*10+text[1]-'0';
|
|
|
|
else
|
|
|
|
reply->tm_year= 10*(text[0]-'0')+text[1]-'0';
|
|
|
|
reply->tm_mon= 10*(text[2]-'0')+text[3]-'0'-1;
|
|
|
|
reply->tm_mday= 10*(text[4]-'0')+text[5]-'0';
|
|
|
|
if(l==6)
|
|
|
|
return(1);
|
|
|
|
reply->tm_hour= 10*(text[7]-'0')+text[8]-'0';
|
|
|
|
reply->tm_min= 10*(text[9]-'0')+text[10]-'0';
|
|
|
|
if(l==11)
|
|
|
|
return(1);
|
|
|
|
reply->tm_sec= 10*(text[11]-'0')+text[12]-'0';
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* Xorriso_sfile_externaL */
|
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------- misc --------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
int Write_to_channel(char *text, int channel_no, int flag)
|
|
|
|
/*
|
|
|
|
bit0= packet write disabled, write to stdin resp. stderr
|
|
|
|
bit1= text is the name of the log file for the given channel
|
|
|
|
bit2= text is the name of the consolidated packet log file for all channels
|
|
|
|
bit15= with bit1 or bit2: close depicted log file
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
char *rpt,*npt,ret= 1;
|
|
|
|
char prefix[16];
|
|
|
|
static int num_channels= 4;
|
|
|
|
static char channel_prefixes[4][4]= {".","R","I","M"};
|
|
|
|
static FILE *logfile_fp[4]= {NULL,NULL,NULL,NULL};
|
|
|
|
static FILE *pktlog_fp= NULL;
|
|
|
|
|
|
|
|
if(channel_no<0 || channel_no>=num_channels)
|
|
|
|
return(-1);
|
|
|
|
|
|
|
|
/* Logfiles */
|
|
|
|
if((flag&2) && logfile_fp[channel_no]!=NULL) {
|
|
|
|
fprintf(logfile_fp[channel_no],
|
|
|
|
"! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n",
|
|
|
|
channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
|
|
|
|
fclose(logfile_fp[channel_no]);
|
|
|
|
logfile_fp[channel_no]= NULL;
|
|
|
|
}
|
|
|
|
if((flag&4) && pktlog_fp!=NULL) {
|
|
|
|
fprintf(pktlog_fp,
|
|
|
|
"I:1:! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n",
|
|
|
|
channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
|
|
|
|
fclose(pktlog_fp);
|
|
|
|
pktlog_fp= NULL;
|
|
|
|
}
|
|
|
|
if(flag&(1<<15))
|
|
|
|
return(1);
|
|
|
|
if((flag&2)) {
|
|
|
|
logfile_fp[channel_no]= fopen(text,"a");
|
|
|
|
if(logfile_fp[channel_no]==NULL)
|
|
|
|
return(0);
|
|
|
|
fprintf(logfile_fp[channel_no],
|
|
|
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n",
|
|
|
|
channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256));
|
|
|
|
fflush(logfile_fp[channel_no]);
|
|
|
|
}
|
|
|
|
if((flag&4)) {
|
|
|
|
pktlog_fp= fopen(text,"a");
|
|
|
|
if(pktlog_fp==NULL)
|
|
|
|
return(0);
|
|
|
|
fprintf(pktlog_fp,
|
|
|
|
"I:1:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : . : %s\n",
|
|
|
|
Sfile_datestr(time(0),1|2|256));
|
|
|
|
fflush(pktlog_fp);
|
|
|
|
}
|
|
|
|
if(flag&(2|4))
|
|
|
|
return(1);
|
|
|
|
if(flag&1) {
|
|
|
|
if(channel_no==1 || channel_no==3)
|
|
|
|
printf("%s",text);
|
|
|
|
if(channel_no==2 || channel_no==3)
|
|
|
|
fprintf(stderr,"%s",text);
|
|
|
|
if(logfile_fp[channel_no]!=NULL) {
|
|
|
|
fprintf(logfile_fp[channel_no],"%s",text);
|
|
|
|
fflush(logfile_fp[channel_no]);
|
|
|
|
}
|
|
|
|
if(pktlog_fp!=NULL)
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
rpt= text;
|
|
|
|
sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]);
|
|
|
|
while(*rpt!=0) {
|
|
|
|
npt= strchr(rpt,'\n');
|
|
|
|
if(npt==NULL)
|
|
|
|
prefix[2]= '0';
|
|
|
|
else
|
|
|
|
prefix[2]= '1';
|
|
|
|
if(!(flag&1)) {
|
|
|
|
ret= fwrite(prefix,5,1,stdout);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if(pktlog_fp!=NULL) {
|
|
|
|
ret= fwrite(prefix,5,1,pktlog_fp);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if(npt==NULL) {
|
|
|
|
if(!(flag&1)) {
|
|
|
|
ret= fwrite(rpt,strlen(rpt),1,stdout);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
ret= fwrite("\n",1,1,stdout);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if(pktlog_fp!=NULL) {
|
|
|
|
ret= fwrite(rpt,strlen(rpt),1,pktlog_fp);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
ret= fwrite("\n",1,1,pktlog_fp);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if(!(flag&1)) {
|
|
|
|
ret= fwrite(rpt,npt+1-rpt,1,stdout);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if(pktlog_fp!=NULL) {
|
|
|
|
ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rpt= npt+1;
|
|
|
|
}
|
|
|
|
if(!(flag&1))
|
|
|
|
fflush(stdout);
|
|
|
|
if(pktlog_fp!=NULL)
|
|
|
|
fflush(pktlog_fp);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Strcmp(const void *pt1, const void *pt2)
|
|
|
|
{
|
|
|
|
return(strcmp(*((char **) pt1), *((char **) pt2)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Sort_argv(int argc, char **argv, int flag)
|
|
|
|
{
|
|
|
|
if(argc<=0)
|
|
|
|
return(2);
|
|
|
|
qsort(argv,(size_t) argc,sizeof(char *),Strcmp);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FILE *Afile_fopen(char *filename, char *mode, int flag)
|
|
|
|
/*
|
|
|
|
bit0= do not print error message on failure
|
|
|
|
bit6= write packeted error messages (see Write_to_channel())
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
FILE *fp= NULL;
|
|
|
|
char errmsg[2*SfileadrL];
|
|
|
|
|
|
|
|
if(strcmp(filename,"-")==0) {
|
|
|
|
if(mode[0]=='a' || mode[0]=='w' ||
|
|
|
|
(mode[0]=='r' && mode[1]=='+') ||
|
|
|
|
(mode[0]=='r' && mode[1]=='b' && mode[2]=='+'))
|
|
|
|
fp= stdout;
|
|
|
|
else
|
|
|
|
fp= stdin;
|
|
|
|
} else if(strncmp(filename,"tcp:",4)==0){
|
|
|
|
sprintf(errmsg,"sorry - TCP/IP service isn't implemented yet.\n");
|
|
|
|
Write_to_channel(errmsg,2,!(flag&64));
|
|
|
|
} else if(strncmp(filename,"file:",5)==0){
|
|
|
|
fp= fopen(filename+5,mode);
|
|
|
|
} else {
|
|
|
|
fp= fopen(filename,mode);
|
|
|
|
}
|
|
|
|
if(fp==NULL){
|
|
|
|
if(!(flag&1)) {
|
|
|
|
sprintf(errmsg,"failed to open file '%s' in %s mode\n",filename,mode);
|
|
|
|
if(errno>0)
|
|
|
|
sprintf(errmsg+strlen(errmsg)," %s\n",strerror(errno));
|
|
|
|
Write_to_channel(errmsg,2,!(flag&64));
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
return(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Convert a text into a number of type double and multiply it by unit code
|
|
|
|
[kmgtpe] (2^10 to 2^60) or [s] (2048). (Also accepts capital letters.)
|
|
|
|
@param text Input like "42", "2k", "3.14m" or "-1g"
|
|
|
|
@param flag Bitfield for control purposes:
|
|
|
|
bit0= return -1 rathern than 0 on failure
|
|
|
|
@return The derived double value
|
|
|
|
*/
|
|
|
|
double Scanf_io_size(char *text, int flag)
|
|
|
|
/*
|
|
|
|
bit0= default value -1 rather than 0
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
double ret= 0.0;
|
|
|
|
|
|
|
|
if(flag&1)
|
|
|
|
ret= -1.0;
|
|
|
|
if(text[0]==0)
|
|
|
|
return(ret);
|
|
|
|
sscanf(text,"%lf",&ret);
|
|
|
|
c= text[strlen(text)-1];
|
|
|
|
if(c=='k' || c=='K') ret*= 1024.0;
|
|
|
|
if(c=='m' || c=='M') ret*= 1024.0*1024.0;
|
|
|
|
if(c=='g' || c=='G') ret*= 1024.0*1024.0*1024.0;
|
|
|
|
if(c=='t' || c=='T') ret*= 1024.0*1024.0*1024.0*1024.0;
|
|
|
|
if(c=='p' || c=='P') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0;
|
|
|
|
if(c=='e' || c=='E') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0*1024.0;
|
|
|
|
if(c=='s' || c=='S') ret*= 2048.0;
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Decode_date_input_format(struct tm *erg, char *text, int flag)
|
|
|
|
/* MMDDhhmm[[CC]YY][.ss]] */
|
|
|
|
{
|
|
|
|
int i,l,year;
|
|
|
|
time_t current_time;
|
|
|
|
struct tm *now;
|
|
|
|
|
|
|
|
current_time= time(0);
|
|
|
|
now= localtime(¤t_time);
|
|
|
|
for(i=0;i<sizeof(struct tm);i++)
|
|
|
|
((char *) erg)[i]= ((char *) now)[i];
|
|
|
|
|
|
|
|
l= strlen(text);
|
|
|
|
for(i=0;i<l;i++)
|
|
|
|
if(text[i]<'0'||text[i]>'9')
|
|
|
|
break;
|
|
|
|
if(i!=8 && i!=10 && i!=12)
|
|
|
|
return(0);
|
|
|
|
if(text[i]==0)
|
|
|
|
goto decode;
|
|
|
|
if(text[i]!='.' || l!=15)
|
|
|
|
return(0);
|
|
|
|
i++;
|
|
|
|
if(text[i]<'0'||text[i]>'9')
|
|
|
|
return(0);
|
|
|
|
i++;
|
|
|
|
if(text[i]<'0'||text[i]>'9')
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
decode:;
|
|
|
|
/* MMDDhhmm[[CC]YY][.ss]] */
|
|
|
|
i= 0;
|
|
|
|
erg->tm_mon= 10*(text[0]-'0')+text[1]-'0'-1;
|
|
|
|
erg->tm_mday= 10*(text[2]-'0')+text[3]-'0';
|
|
|
|
erg->tm_hour= 10*(text[4]-'0')+text[5]-'0';
|
|
|
|
erg->tm_min= 10*(text[6]-'0')+text[7]-'0';
|
|
|
|
erg->tm_sec= 0;
|
|
|
|
if(l==8)
|
|
|
|
return(1);
|
|
|
|
if(l>10){
|
|
|
|
year= 1000*(text[8]-'0')+100*(text[9]-'0')+10*(text[10]-'0')+(text[11]-'0');
|
|
|
|
}else{
|
|
|
|
year= 1900+10*(text[8]-'0')+(text[9]-'0');
|
|
|
|
if(year<1970)
|
|
|
|
year+= 100;
|
|
|
|
}
|
|
|
|
erg->tm_year= year-1900;
|
|
|
|
if(l<=12)
|
|
|
|
return(1);
|
|
|
|
erg->tm_sec= 10*(text[13]-'0')+text[14]-'0';
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Decode_date_weekday(char *text, int flag)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
static char days[][4]= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", ""};
|
|
|
|
|
|
|
|
for(i= 0; days[i][0]!=0; i++)
|
|
|
|
if(strncmp(text,days[i],3)==0)
|
|
|
|
return(i);
|
|
|
|
if((strlen(text)==3 || (strlen(text)==4 && text[3]==',')) &&
|
|
|
|
isalpha(text[0]) && isalpha(text[1]) && isalpha(text[2]))
|
|
|
|
return(7);
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Decode_date_month(char *text, int flag)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
static char months[][4]= {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
|
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
|
|
|
|
|
|
|
|
for(i= 0; months[i][0]!=0; i++)
|
|
|
|
if(strncmp(text,months[i],3)==0)
|
|
|
|
return(i);
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @return -1=not a number, -2=not a day , 1 to 31 day of month */
|
|
|
|
int Decode_date_mday(char *text, int flag)
|
|
|
|
{
|
|
|
|
int ret, i;
|
|
|
|
|
|
|
|
for(i= 0; text[i]!=0; i++)
|
|
|
|
if(!isdigit(text[i]))
|
|
|
|
return(-1);
|
|
|
|
if(strlen(text)>2 || text[0]==0)
|
|
|
|
return(-2);
|
|
|
|
sscanf(text, "%d", &ret);
|
|
|
|
if(ret<=0 || ret>31)
|
|
|
|
return(-2);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Decode_date_hms(char *text, struct tm *erg, int flag)
|
|
|
|
{
|
|
|
|
int i, hour= -1, minute= -1, second= 0;
|
|
|
|
|
|
|
|
for(i= 0; i<9; i+= 3) {
|
|
|
|
if(i==6&&text[i]==0)
|
|
|
|
break;
|
|
|
|
if(!isdigit(text[i]))
|
|
|
|
return(-1);
|
|
|
|
if(!isdigit(text[i+1]))
|
|
|
|
return(-1);
|
|
|
|
if(text[i+2]!=':' && !(text[i+2]==0 && i>=3))
|
|
|
|
return(-1);
|
|
|
|
if(i==0)
|
|
|
|
sscanf(text+i,"%d",&hour);
|
|
|
|
else if(i==3)
|
|
|
|
sscanf(text+i,"%d",&minute);
|
|
|
|
else
|
|
|
|
sscanf(text+i,"%d",&second);
|
|
|
|
}
|
|
|
|
if(hour<0 || hour>23 || minute<0 || minute>59 || second>59)
|
|
|
|
return(-1);
|
|
|
|
erg->tm_hour= hour;
|
|
|
|
erg->tm_min= minute;
|
|
|
|
erg->tm_sec= second;
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @return -1=not a number, -2=not a year , >=0 years AD */
|
|
|
|
int Decode_date_year(char *text, int flag)
|
|
|
|
{
|
|
|
|
int ret, i;
|
|
|
|
|
|
|
|
for(i= 0; text[i]!=0; i++)
|
|
|
|
if(!isdigit(text[i]))
|
|
|
|
return(-1);
|
|
|
|
if(strlen(text)!=4)
|
|
|
|
return(-2);
|
|
|
|
sscanf(text, "%d", &ret);
|
|
|
|
if(ret<0 || ret>3000)
|
|
|
|
return(-2);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Decode_date_timezone(char *text, struct tm *erg, int flag)
|
|
|