"Fossies" - the Fresh Open Source Software archive 
Member "zlibc-0.9k/open.c" of archive zlibc-0.9k.tar.gz:
/*
* open.c
*
* Copyright (C) 1993 Alain Knaff
*/
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
#include "sysincludes.h"
static char *zlib_compressor[]= { COMPR, 0 };
#ifdef HAVE___LIBC_OPEN
int __libc_open(__const char *pathname, int flags, mode_t mode);
#define open __libc_open
/*ALIASF2(open, __libc_open, int, mode_t);*/
#endif
#include <stdarg.h>
int open(__const char *name, int flags, mode_t mode);
int open64 (__const char *name, int flags, ...)
{
va_list ap;
va_start(ap, flags);
if(flags & O_CREAT) {
mode_t mode = va_arg(ap, mode_t);
return open(name, flags | O_LARGEFILE, mode);
} else {
return open(name, flags | O_LARGEFILE, 0);
}
}
int open(__const char *name, int flags, mode_t mode)
{
int fd;
int zfd;
int pid;
int filetype;
int zflags;
int do_append;
int do_uncompress;
int do_create;
int have_filetype;
int tmp;
int stat_result;
int status;
struct stat buf;
#ifdef SYS_UTIME
struct utimbuf buf2;
#else
# ifdef SYS_UTIMES
struct timeval buf2[2];
# endif
#endif
int pipeout[2];
char newname[MAXPATHLEN + MAXEXTLEN + 1];
char _pname[MAXPATHLEN + MAXEXTLEN + 1];
__const char *pname;
_zlibc_init();
filetype=have_filetype=do_append=do_uncompress=do_create=0;
zflags = flags;
if (flags & O_CREAT){
zlib_initialise();
have_filetype=1;
if ( ! (zlib_mode & CM_DISAB )){
filetype = zlib_getfiletype(name,-1);
if ((flags & O_ACCMODE) == O_WRONLY &&
(flags & (O_TRUNC | O_EXCL)) &&
(filetype & PM_CREATE_COMPR))
do_create = 1;
else if ((flags & O_ACCMODE) == O_WRONLY &&
(flags & O_APPEND) &&
(filetype & PM_APPEND_COMPR))
do_append=1;
else if ((flags & O_ACCMODE ) != O_RDONLY &&
(filetype & PM_UNCOMPR_BEFORE_WRITE))
do_uncompress=1;
if (do_create | do_append | do_uncompress)
zflags &= ~O_CREAT;
}
}
fd = zlib_real_open(name,zflags,mode);
#ifdef DEBUG
fprintf(stderr,"file opened *: %s %d %x %x %d\n", name,fd, flags, zflags,
errno);
#endif
/* success to open uncompressed file */
if ( fd >= 0 || errno != ENOENT )
return fd;
if (!have_filetype)
zlib_initialise();
if ( zlib_mode & CM_DISAB )
return fd;
if (!have_filetype)
filetype = zlib_getfiletype(name,-1);
if ( zlib_mode & CM_VERBOSE )
fprintf(stderr,"opening %s %o\n", name,flags);
strncpy(newname,name,MAXPATHLEN);
strcat(newname,zlib_ext);
/* open compressed file */
zflags = flags;
if ((flags & O_ACCMODE) == O_WRONLY &&
(flags & O_TRUNC) &&
(filetype & PM_CREATE_COMPR))
do_create = 1;
else if ((flags & O_ACCMODE) == O_WRONLY &&
(flags & O_APPEND) &&
(filetype & PM_APPEND_COMPR))
do_append=1;
else if ((flags & O_ACCMODE ) != O_RDONLY &&
(filetype & PM_UNCOMPR_BEFORE_WRITE)){
zflags = O_RDONLY;
do_uncompress=1;
} else if ((flags & O_ACCMODE) != O_RDONLY)
return fd;
zfd = zlib_real_open(newname,zflags,mode);
if ( zfd < 0 ){
if ( flags & O_CREAT )
return zlib_real_open(name,flags,mode);
if ( errno == EINVAL ) /* don't want to replace perm errors */
errno = ENOENT;
return zfd;
}
if (do_append || do_create){
/* make a pipe */
if(pipe(pipeout) < 0 )
return -1;
/* double fork */
switch(pid=fork()){
case 0: /* son */
switch(fork()){
case 0: /* son of son */
if (zfd == 0){
/* shit happens ... */
tmp = dup(zfd);
close(zfd);
zfd = tmp;
}
if (pipeout[0] != 0){
close(0);
dup(pipeout[0]);
}
if ( zfd != 1 ){
close(1);
dup(zfd); /* compressed file, input */
}
close(pipeout[0]);
close(pipeout[1]);
if(! (zlib_mode & CM_VERBOSE))
close(2);
execvp (zlib_compressor[0], zlib_compressor);
if ( zlib_mode & CM_VERBOSE ){
perror("exec compressor");
exit(1);
}
case -1: /* error */
if ( zlib_mode & CM_VERBOSE )
perror("fork error");
exit(1);
default: /* father */
exit(0); /* son of son will be taken over by init */
}
case -1: /* error */
errno = ENOENT;
return -1;
}
close(pipeout[0]); /* close read end of pipe */
close(zfd); /* close raw compressed file */
fd=dup(pipeout[1]);
close(pipeout[1]);
/*wait4(pid,&status,0,0); wait for son */
wait(&status);
return fd;
}
if (!do_uncompress && (filetype & PM_READ_MASK) >= PM_HIDE_PIPE ){
/* make a pipe */
if(pipe(pipeout) < 0 )
return -1;
/* double fork */
switch(pid=fork()){
case 0: /* son */
switch(fork()){
case 0: /* son of son */
if ( zfd != 0 ){
close(0);
dup(zfd); /* compressed file, input */
}
if ( pipeout[1] != 1 ){
close(1);
dup(pipeout[1]);
}
close(pipeout[0]);
close(pipeout[1]);
if(! (zlib_mode & CM_VERBOSE))
close(2);
execvp ( zlib_uncompressor[0], zlib_uncompressor );
if ( zlib_mode & CM_VERBOSE ){
perror("exec uncompressor");
exit(1);
}
case -1: /* error */
if ( zlib_mode & CM_VERBOSE )
perror("fork error");
exit(1);
default: /* father */
exit(0); /* son of son will be taken over by init */
}
case -1: /* error */
errno = ENOENT;
return -1;
}
close(pipeout[1]); /* close write end of pipe */
close(zfd); /* close raw compressed file */
fd=dup(pipeout[0]);
close(pipeout[0]);
wait(&status);
} else {
stat_result=fstat(zfd, &buf);
mode = 0400;
if ( !do_uncompress){
sprintf(_pname,"%s/pipe.%d",zlib_tmp,(int)getpid());
pname = _pname;
} else {
mode = 0;
pname = name;
}
zlib_real_unlink(pname);
pipeout[0]=zlib_real_open(pname, O_RDWR | O_CREAT | O_EXCL, mode);
/* temporary output file */
if ( pipeout[0] < 0 ){
if ( zlib_mode & CM_VERBOSE )
perror("could not create uncompressed file");
errno = ENOENT;
return -1;
}
switch(pid=fork()){
case 0: /* son */
if ( zfd != 0 ){
close(0);
dup(zfd); /* compressed file, input */
}
if ( pipeout[0] != 1 ){
close(1);
dup(pipeout[0]);
}
if(! (zlib_mode & CM_VERBOSE))
close(2);
execvp ( zlib_uncompressor[0], zlib_uncompressor ) ;
if ( zlib_mode & CM_VERBOSE )
perror("exec uncompressor");
exit(1);
case -1: /* error */
errno = ENOENT;
return -1;
}
wait(&status);
/* touch it */
close(pipeout[0]);
if(do_uncompress){
/* restore the original mode */
if ( stat_result >= 0)
mode = buf.st_mode;
else
mode = 0600;
zlib_real_chmod(pname, mode);
}
if ( stat_result >= 0 ){
#ifdef SYS_UTIME
buf2.actime = buf.st_atime;
buf2.modtime = buf.st_mtime;
zlib_real_utime(pname, &buf2);
#else
# ifdef SYS_UTIMES
buf2[0].tv_sec = buf.st_atime;
buf2[0].tv_usec = 0;
buf2[1].tv_sec = buf.st_mtime;
buf2[1].tv_usec = 0;
zlib_real_utimes(pname, buf2);
# endif
#endif
}
close(zfd); /* close raw compressed file */
/* re-open it */
fd=zlib_real_open(pname, flags, mode);
if ( !do_uncompress)
zlib_real_unlink(pname);
else {
if ( fd>=0 && WIFEXITED(status) && WEXITSTATUS(status)==0 )
/* only erase the original file if nothing looks fishy... */
zlib_real_unlink(newname);
}
}
return fd;
}
#undef creat
int creat(__const char *name, mode_t mode)
{
return open(name, O_CREAT | O_WRONLY | O_TRUNC, mode);
}
#ifdef linux
FILE *fopen(const char *path, const char *mode)
{
FILE *f;
int fd;
_zlibc_init();
f=zlib_real_fopen(path, mode);
if(f != NULL)
return f;
if ( zlib_mode & CM_DISAB )
/* ZLIBC disabled */
return NULL;
if(strcmp(mode, "r"))
/* If mode is anything else than read, don't bother */
return NULL;
fd = open(path, O_RDONLY, 0);
if(fd < 0)
return NULL;
return fdopen(fd, mode);
}
FILE *fopen64(const char *path, const char *mode)
{
FILE *f;
int fd;
_zlibc_init();
f=zlib_real_fopen64(path, mode);
if(f != NULL)
return f;
if ( zlib_mode & CM_DISAB )
/* ZLIBC disabled */
return NULL;
if(strcmp(mode, "r"))
/* If mode is anything else than read, don't bother */
return NULL;
fd = open(path, O_RDONLY, 0);
if(fd < 0)
return NULL;
return fdopen(fd, mode);
}
#endif