#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "XpmI.h"
#ifndef NO_ZPIPE
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#else
#ifdef FOR_MSW
#include <fcntl.h>
#endif
#endif
LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
LFUNC(xpmDataClose, void, (xpmData *mdata));
#ifndef CXPMPROG
int
XpmReadFileToImage(display, filename,
image_return, shapeimage_return, attributes)
Display *display;
char *filename;
XImage **image_return;
XImage **shapeimage_return;
XpmAttributes *attributes;
{
XpmImage image;
XpmInfo info;
int ErrorStatus;
xpmData mdata;
xpmInitXpmImage(&image);
xpmInitXpmInfo(&info);
if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
return (ErrorStatus);
if (attributes) {
xpmInitAttributes(attributes);
xpmSetInfoMask(&info, attributes);
ErrorStatus = xpmParseDataAndCreate(display, &mdata,
image_return, shapeimage_return,
&image, &info, attributes);
} else
ErrorStatus = xpmParseDataAndCreate(display, &mdata,
image_return, shapeimage_return,
&image, NULL, attributes);
if (attributes) {
if (ErrorStatus >= 0)
xpmSetAttributes(attributes, &image, &info);
XpmFreeXpmInfo(&info);
}
xpmDataClose(&mdata);
XpmFreeXpmImage(&image);
return (ErrorStatus);
}
int
XpmReadFileToXpmImage(filename, image, info)
char *filename;
XpmImage *image;
XpmInfo *info;
{
xpmData mdata;
int ErrorStatus;
xpmInitXpmImage(image);
xpmInitXpmInfo(info);
if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
return (ErrorStatus);
ErrorStatus = xpmParseData(&mdata, image, info);
xpmDataClose(&mdata);
return (ErrorStatus);
}
#endif
#ifndef NO_ZPIPE
FILE*
xpmPipeThrough(fd, cmd, arg1, mode)
int fd;
const char* cmd;
const char* arg1;
const char* mode;
{
FILE* fp;
int status, fds[2], in = 0, out = 1;
pid_t pid;
if ( 'w' == *mode )
out = 0, in = 1;
if ( pipe(fds) < 0 )
return NULL;
pid = fork();
if ( pid < 0 )
goto fail1;
if ( 0 == pid )
{
close(fds[in]);
if ( dup2(fds[out], out) < 0 )
goto err;
close(fds[out]);
if ( dup2(fd, in) < 0 )
goto err;
close(fd);
pid = fork();
if ( pid < 0 )
goto err;
if ( 0 == pid )
{
execlp(cmd, cmd, arg1, (char *)NULL);
perror(cmd);
goto err;
}
_exit(0);
err:
_exit(1);
}
close(fds[out]);
while ( waitpid(pid, &status, 0) < 0 && EINTR == errno )
;
if ( WIFSIGNALED(status) ||
(WIFEXITED(status) && WEXITSTATUS(status) != 0) )
goto fail2;
fp = fdopen(fds[in], mode);
if ( !fp )
goto fail2;
close(fd);
return fp;
fail1:
close(fds[out]);
fail2:
close(fds[in]);
return NULL;
}
#endif
static int
OpenReadFile(filename, mdata)
char *filename;
xpmData *mdata;
{
if (!filename) {
mdata->stream.file = (stdin);
mdata->type = XPMFILE;
} else {
int fd = open(filename, O_RDONLY);
#if defined(NO_ZPIPE)
if ( fd < 0 )
return XpmOpenFailed;
#else
const char* ext = NULL;
if ( fd >= 0 )
ext = strrchr(filename, '.');
#ifdef STAT_ZFILE
else
{
size_t len = strlen(filename);
char *compressfile = (char *) XpmMalloc(len + 4);
if ( !compressfile )
return (XpmNoMemory);
strcpy(compressfile, filename);
strcpy(compressfile + len, ext = ".Z");
fd = open(compressfile, O_RDONLY);
if ( fd < 0 )
{
strcpy(compressfile + len, ext = ".gz");
fd = open(compressfile, O_RDONLY);
if ( fd < 0 )
{
XpmFree(compressfile);
return XpmOpenFailed;
}
}
XpmFree(compressfile);
}
#endif
if ( ext && !strcmp(ext, ".Z") )
{
mdata->type = XPMPIPE;
mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
}
else if ( ext && !strcmp(ext, ".gz") )
{
mdata->type = XPMPIPE;
mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
}
else
#endif
{
mdata->type = XPMFILE;
mdata->stream.file = fdopen(fd, "r");
}
if (!mdata->stream.file)
{
close(fd);
return (XpmOpenFailed);
}
}
mdata->CommentLength = 0;
#ifdef CXPMPROG
mdata->lineNum = 0;
mdata->charNum = 0;
#endif
return (XpmSuccess);
}
static void
xpmDataClose(mdata)
xpmData *mdata;
{
if (mdata->stream.file != (stdin))
fclose(mdata->stream.file);
}