PageRenderTime 46ms CodeModel.GetById 13ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/RdFToI.c

#
C | 273 lines | 206 code | 20 blank | 47 comment | 40 complexity | 644f80994afd701998b7c7f5811a677b MD5 | raw file
  1/*
  2 * Copyright (C) 1989-95 GROUPE BULL
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a copy
  5 * of this software and associated documentation files (the "Software"), to
  6 * deal in the Software without restriction, including without limitation the
  7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8 * sell copies of the Software, and to permit persons to whom the Software is
  9 * furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 20 *
 21 * Except as contained in this notice, the name of GROUPE BULL shall not be
 22 * used in advertising or otherwise to promote the sale, use or other dealings
 23 * in this Software without prior written authorization from GROUPE BULL.
 24 */
 25
 26/*****************************************************************************\
 27*  RdFToI.c:                                                                  *
 28*                                                                             *
 29*  XPM library                                                                *
 30*  Parse an XPM file and create the image and possibly its mask               *
 31*                                                                             *
 32*  Developed by Arnaud Le Hors                                                *
 33\*****************************************************************************/
 34
 35/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
 36
 37#ifdef HAVE_CONFIG_H
 38#include <config.h>
 39#endif
 40#include "XpmI.h"
 41#ifndef NO_ZPIPE
 42#include <fcntl.h>
 43#include <errno.h>
 44#include <sys/types.h>
 45#include <sys/wait.h>
 46#else
 47#ifdef FOR_MSW
 48#include <fcntl.h>
 49#endif
 50#endif
 51
 52LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
 53LFUNC(xpmDataClose, void, (xpmData *mdata));
 54
 55FUNC(xpmPipeThrough, FILE*, (int fd,
 56			     const char *cmd,
 57			     const char *arg1,
 58			     const char *mode));
 59
 60#ifndef CXPMPROG
 61int
 62XpmReadFileToImage(
 63    Display		 *display,
 64    char		 *filename,
 65    XImage		**image_return,
 66    XImage		**shapeimage_return,
 67    XpmAttributes	 *attributes)
 68{
 69    XpmImage image;
 70    XpmInfo info;
 71    int ErrorStatus;
 72    xpmData mdata;
 73
 74    xpmInitXpmImage(&image);
 75    xpmInitXpmInfo(&info);
 76
 77    /* open file to read */
 78    if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
 79	return (ErrorStatus);
 80
 81    /* create the XImage from the XpmData */
 82    if (attributes) {
 83	xpmInitAttributes(attributes);
 84	xpmSetInfoMask(&info, attributes);
 85	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
 86					    image_return, shapeimage_return,
 87					    &image, &info, attributes);
 88    } else
 89	ErrorStatus = xpmParseDataAndCreate(display, &mdata,
 90					    image_return, shapeimage_return,
 91					    &image, NULL, attributes);
 92    if (attributes) {
 93	if (ErrorStatus >= 0)		/* no fatal error */
 94	    xpmSetAttributes(attributes, &image, &info);
 95	XpmFreeXpmInfo(&info);
 96    }
 97
 98    xpmDataClose(&mdata);
 99    /* free the XpmImage */
100    XpmFreeXpmImage(&image);
101
102    return (ErrorStatus);
103}
104
105int
106XpmReadFileToXpmImage(
107    char	*filename,
108    XpmImage	*image,
109    XpmInfo	*info)
110{
111    xpmData mdata;
112    int ErrorStatus;
113
114    /* init returned values */
115    xpmInitXpmImage(image);
116    xpmInitXpmInfo(info);
117
118    /* open file to read */
119    if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
120	return (ErrorStatus);
121
122    /* create the XpmImage from the XpmData */
123    ErrorStatus = xpmParseData(&mdata, image, info);
124
125    xpmDataClose(&mdata);
126
127    return (ErrorStatus);
128}
129#endif /* CXPMPROG */
130
131#ifndef NO_ZPIPE
132/* Do not depend on errno after read_through */
133FILE*
134xpmPipeThrough(
135    int		 fd,
136    const char	*cmd,
137    const char	*arg1,
138    const char	*mode)
139{
140    FILE* fp;
141    int status, fds[2], in = 0, out = 1;
142    pid_t pid;
143    if ( 'w' == *mode )
144	out = 0, in = 1;
145    if ( pipe(fds) < 0 )
146	return NULL;
147    pid = fork();
148    if ( pid < 0 )
149	goto fail1;
150    if ( 0 == pid )
151    {
152	close(fds[in]);
153	if ( dup2(fds[out], out) < 0 )
154	    goto err;
155	close(fds[out]);
156	if ( dup2(fd, in) < 0 )
157	    goto err;
158	close(fd);
159	pid = fork();
160	if ( pid < 0 )
161	    goto err;
162	if ( 0 == pid )
163	{
164	    execlp(cmd, cmd, arg1, (char *)NULL);
165	    perror(cmd);
166	    goto err;
167	}
168	_exit(0);
169    err:
170	_exit(1);
171    }
172    close(fds[out]);
173    /* calling process: wait for first child */
174    while ( waitpid(pid, &status, 0) < 0 && EINTR == errno )
175	;
176    if ( WIFSIGNALED(status) ||
177	 (WIFEXITED(status) && WEXITSTATUS(status) != 0) )
178	goto fail2;
179    fp = fdopen(fds[in], mode);
180    if ( !fp )
181	goto fail2;
182    close(fd); /* still open in 2nd child */
183    return fp;
184fail1:
185    close(fds[out]);
186fail2:
187    close(fds[in]);
188    return NULL;
189}
190#endif
191
192/*
193 * open the given file to be read as an xpmData which is returned.
194 */
195static int
196OpenReadFile(
197    char	*filename,
198    xpmData	*mdata)
199{
200    if (!filename) {
201	mdata->stream.file = (stdin);
202	mdata->type = XPMFILE;
203    } else {
204	int fd = open(filename, O_RDONLY);
205#if defined(NO_ZPIPE)
206	if ( fd < 0 )
207	    return XpmOpenFailed;
208#else
209	const char* ext = NULL;
210	if ( fd >= 0 )
211	    ext = strrchr(filename, '.');
212#ifdef STAT_ZFILE /* searching for z-files if the given name not found */
213	else
214	{
215	    size_t len = strlen(filename);
216	    char *compressfile = (char *) XpmMalloc(len + 4);
217	    if ( !compressfile )
218		return (XpmNoMemory);
219	    strcpy(compressfile, filename);
220	    strcpy(compressfile + len, ext = ".Z");
221	    fd = open(compressfile, O_RDONLY);
222	    if ( fd < 0 )
223	    {
224		strcpy(compressfile + len, ext = ".gz");
225		fd = open(compressfile, O_RDONLY);
226		if ( fd < 0 )
227		{
228		    XpmFree(compressfile);
229		    return XpmOpenFailed;
230		}
231	    }
232	    XpmFree(compressfile);
233	}
234#endif
235	if ( ext && !strcmp(ext, ".Z") )
236	{
237	    mdata->type = XPMPIPE;
238	    mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
239	}
240	else if ( ext && !strcmp(ext, ".gz") )
241	{
242	    mdata->type = XPMPIPE;
243	    mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
244	}
245	else
246#endif /* z-files */
247	{
248	    mdata->type = XPMFILE;
249	    mdata->stream.file = fdopen(fd, "r");
250	}
251	if (!mdata->stream.file)
252	{
253	    close(fd);
254	    return (XpmOpenFailed);
255	}
256    }
257    mdata->CommentLength = 0;
258#ifdef CXPMPROG
259    mdata->lineNum = 0;
260    mdata->charNum = 0;
261#endif
262    return (XpmSuccess);
263}
264
265/*
266 * close the file related to the xpmData if any
267 */
268static void
269xpmDataClose(xpmData *mdata)
270{
271    if (mdata->stream.file != (stdin))
272	fclose(mdata->stream.file);
273}