libisoburn/xorriso/xorriso.c

9053 lines
239 KiB
C
Raw Normal View History

2007-10-12 20:39:29 +00:00
/*
( cd .. ; libisoburn-develop/xorriso/compile_xorriso.sh -g )
or
2007-10-12 20:39:29 +00:00
cc -g -DXorriso_with_maiN -DXorriso_with_regeX -DXorriso_with_readlinE \
2007-11-26 19:22:38 +00:00
-DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \
2007-10-12 20:39:29 +00:00
-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_regeX -DXorriso_with_readlinE \
2007-11-26 19:22:38 +00:00
-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
2007-10-12 20:39:29 +00:00
*/
/* 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>
2007-10-12 20:39:29 +00:00
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
2007-10-12 20:39:29 +00:00
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.
2007-10-12 20:39:29 +00:00
*/
#define PROG_VERSION "0.1.0"
2007-10-12 20:39:29 +00:00
/** The source code release timestamp */
#include "xorriso_timestamp.h"
#ifndef Xorriso_timestamP
#define Xorriso_timestamP "-none-given-"
#endif
/** The binary build timestamp is to be set externally by the compiler */
#ifndef Xorriso_build_timestamP
#define Xorriso_build_timestamP "-none-given-"
#endif
2007-10-12 20:39:29 +00:00
#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>
2007-10-12 20:39:29 +00:00
/* eventually, this is done in xorriso_private.h : #include <regex.h> */
2007-10-12 20:39:29 +00:00
#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" */
2007-10-12 20:39:29 +00:00
#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"
2007-10-12 20:39:29 +00:00
/* ------------------------------------------------------------------------ */
#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_fclose(FILE *fp)
{
if(fp!=stdout && fp!=stdin && fp!=NULL)
fclose(fp);
return(1);
}
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);
}
2007-12-25 16:02:06 +00:00
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);
}
2007-10-12 20:39:29 +00:00
int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag)
{
int l;
l= strlen(path);
2007-10-21 15:10:41 +00:00
if(l+1>=SfileadrL)
return(0);
2007-10-12 20:39:29 +00:00
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, "SORRY", 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);
}
2007-10-12 20:39:29 +00:00
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);
}
int Sfile_lookup_permissions(char *fname, int *perms, mode_t *st_mode,int flag)
/* @param perms bit0= r , bit1= w , bit2= x */
2007-10-12 20:39:29 +00:00
/* return: <0 fatal error, 0= file nonexistent, 1=owner, 2=group, 3=other */
{
struct stat stbuf;
int is_root;
2007-10-12 20:39:29 +00:00
*perms= 0;
if(stat(fname,&stbuf)==-1)
return(0);
*st_mode= stbuf.st_mode;
is_root= (geteuid()==0);
if(is_root) /* root can always read and write */
*perms= 3;
if(is_root || geteuid()==stbuf.st_uid) {
2007-10-12 20:39:29 +00:00
if(stbuf.st_mode & S_IRUSR)
(*perms)|= 1;
if(stbuf.st_mode & S_IWUSR)
(*perms)|= 2;
if(stbuf.st_mode & S_IXUSR)
(*perms)|= 4;
if(!is_root)
return(1);
2007-10-12 20:39:29 +00:00
}
/* group membership is a complicated thing */
if(is_root || Sfile_being_group_member(&stbuf,0)>0) {
2007-10-12 20:39:29 +00:00
if(stbuf.st_mode & S_IRGRP)
(*perms)|= 1;
if(stbuf.st_mode & S_IWGRP)
(*perms)|= 2;
if(stbuf.st_mode & S_IXGRP)
(*perms)|= 4;
if(!is_root)
return(2);
2007-10-12 20:39:29 +00:00
}
if(stbuf.st_mode & S_IROTH)
(*perms)|= 1;
if(stbuf.st_mode & S_IWOTH)
(*perms)|= 2;
if(stbuf.st_mode & S_IXOTH)
(*perms)|= 4;
if(is_root)
return(1);
2007-10-12 20:39:29 +00:00
return(3);
}
int Sfile_select(int *fds, int fdcount, int fdidx[3], unsigned int microsec,
int flag)
/*
bit0= check for reading (and choose one into fdidx[0])
bit1= check for writing (and choose one into fdidx[1])
bit2= check for exception (and choose one into fdidx[2])
bit3= initialize fdidx
return-bits are set according to matching flag-bits
*/
{
struct timeval wt;
fd_set rds,wts,exs,*s;
int ready,ret,i,j,max_fd= -1;
if(flag&8)
for(j=0;j<3;j++)
fdidx[j]= 0;
wt.tv_sec= microsec/1000000;
wt.tv_usec= microsec%1000000;
FD_ZERO(&rds);
FD_ZERO(&wts);
FD_ZERO(&exs);
for(i= 0;i<fdcount;i++) {
if(fds[i]<0)
continue;
if(flag&1)
FD_SET(fds[i],&rds);
if(flag&2)
FD_SET(fds[i],&wts);
if(flag&4)
FD_SET(fds[i],&exs);
if(fds[i]>max_fd)
max_fd= fds[i];
}
ready= select(max_fd+1,&rds,&wts,&exs,&wt);
if(ready<=0)
return(0);
ret= 0;
if(fdcount>0)
for(j=0;j<2;j++)
fdidx[j]= (fdidx[j]+1)%fdcount;
for(i= 0;i<fdcount;i++) {
for(j=0;j<3;j++) {
if(j==0)
s= &rds;
else if(j==1)
s= &wts;
else
s= &exs;
if((flag&(1<<j)) && !(ret&(1<<j))) {
if(fds[fdidx[j]]<0)
fdidx[j]= (fdidx[j]+1)%fdcount;
else if(FD_ISSET(fds[fdidx[j]],s))
ret|= (1<<j);
else
fdidx[j]= (fdidx[j]+1)%fdcount;
}
}
}
return(ret);
}
int Sfile_identical(char *file1, char *file2, int flag)
/*
bit0= check whether it is the same i-node
*/
{
FILE *fp1,*fp2;
struct stat stbuf;
int ret,c1,c2;
ino_t ino1,ino2;
dev_t dev1,dev2;
ret= 0;
if(flag&1){
if(stat(file1,&stbuf)==-1) return(0);
ino1= stbuf.st_ino;
dev1= stbuf.st_dev;
if(stat(file2,&stbuf)==-1) return(0);
ino2= stbuf.st_ino;
dev2= stbuf.st_dev;
return((ino1==ino2) && (dev1==dev2));
}
fp1= fopen(file1,"rb");
fp2= fopen(file2,"rb");
if(fp1==NULL||fp2==NULL) goto fertig;
while(1){
c1= fgetc(fp1);
c2= fgetc(fp2);
if(c1==EOF && c2==EOF){
ret= 1;
break;
}
if(c1!=c2)
break;
}
fertig:;
if(fp1!=NULL) fclose(fp1);
if(fp2!=NULL) fclose(fp2);
return(ret);
}
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);
2007-10-12 20:39:29 +00:00
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");
2007-10-12 20:39:29 +00:00
else
sprintf(form,"%%%d.f",siz);
2007-10-12 20:39:29 +00:00
sprintf(result,form,value);
} else {
if(flag&2)
sprintf(form,"%%.f%%c");
2007-10-12 20:39:29 +00:00
else if(dec_siz>0)
sprintf(form,"%%%d.%df%%c",avail_siz,dec_siz);
2007-10-12 20:39:29 +00:00
else
sprintf(form,"%%%d.f%%c",siz-1);
2007-10-12 20:39:29 +00:00
sprintf(result,form,value,scale_c);
}
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
2007-10-12 20:39:29 +00:00
*/
{
int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc;
2007-10-12 20:39:29 +00:00
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;
2007-10-12 20:39:29 +00:00
if(pass==0)
maxl= strlen(progname);
else
strcpy((*argv)[0],progname);
} else {
argzaehl= line_start_argc= 0;
2007-10-12 20:39:29 +00:00
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))
2007-10-18 17:14:09 +00:00
if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
l++;
2007-10-12 20:39:29 +00:00
if(l>maxl) maxl= l;
}else{
strcpy((*argv)[argzaehl],buf);
if(argzaehl==line_start_argc && (flag&8))
2007-10-18 17:14:09 +00:00
if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
sprintf((*argv)[argzaehl],"-%s", buf);
2007-10-12 20:39:29 +00:00
}
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(&current_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);
}
2007-10-12 20:39:29 +00:00
#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"};
2007-10-12 20:39:29 +00:00
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 Exec_cmd(char *prog, char *cmd, char *simple_arg, char **argv,
char errmsg[SfileadrL], int flag)
/*
bit0= package mode (!bit0 of Write_to_channel())
*/
{
int wait_status,is_dead= 0,pipes_open= 0,ret,channel_no;
int stdout_pipe[2],stderr_pipe[2],fds[2],fdidx[3];
char **exec_argv,*simple_argv[3],buffer[256];
pid_t pid,dead_pid;
static int debug= 0;
errmsg[0]= 0;
if(debug)
fprintf(stderr,"Exec_cmd():fork\n");
/* create pipes */
if(pipe(stdout_pipe)==-1) {
cannot_make_pipe:;
sprintf(errmsg,"%s : cannot create two pipes\n reason given: %s\n",
prog,strerror(errno));
return(-1);
}
if(pipe(stderr_pipe)==-1) {
close(stdout_pipe[0]);