1 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2 
3 /****************************************************************************
4 
5   Copyright (c) 1999,2000 WU-FTPD Development Group.
6   All rights reserved.
7 
8   Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
9     The Regents of the University of California.
10   Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.
11   Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
12   Portions Copyright (c) 1989 Massachusetts Institute of Technology.
13   Portions Copyright (c) 1998 Sendmail, Inc.
14   Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P.  Allman.
15   Portions Copyright (c) 1997 by Stan Barber.
16   Portions Copyright (c) 1997 by Kent Landfield.
17   Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
18     Free Software Foundation, Inc.
19 
20   Use and distribution of this software and its source code are governed
21   by the terms and conditions of the WU-FTPD Software License ("LICENSE").
22 
23   If you did not receive a copy of the license, it may be obtained online
24   at http://www.wu-ftpd.org/license.html.
25 
26   $Id: conversions.c,v 1.10 2000/07/01 18:17:38 wuftpd Exp $
27 
28 ****************************************************************************/
29 #include "config.h"
30 
31 #include <stdio.h>
32 #include <errno.h>
33 #ifdef HAVE_SYS_SYSLOG_H
34 #include <sys/syslog.h>
35 #endif
36 #if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H))
37 #include <syslog.h>
38 #endif
39 
40 extern char *strsep(char **, const char *);
41 
42 #include <string.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include "conversions.h"
46 #include "extensions.h"
47 #include "pathnames.h"
48 #include "proto.h"
49 
50 /*************************************************************************/
51 /* FUNCTION  : readconv                                                  */
52 /* PURPOSE   : Read the conversions into memory                          */
53 /* ARGUMENTS : The pathname of the conversion file                       */
54 /* RETURNS   : 0 if error, 1 if no error                                 */
55 /*************************************************************************/
56 
57 char *convbuf = NULL;
58 struct convert *cvtptr;
59 
60 struct str2int {
61     char *string;
62     int value;
63 };
64 
65 struct str2int c_list[] =
66 {
67     {"T_REG", T_REG},
68     {"T_ASCII", T_ASCII},
69     {"T_DIR", T_DIR},
70     {"O_COMPRESS", O_COMPRESS},
71     {"O_UNCOMPRESS", O_UNCOMPRESS},
72     {"O_TAR", O_TAR},
73     {NULL, 0},
74 };
75 
conv(char * str)76 static int conv(char *str)
77 {
78     int rc = 0;
79     int counter;
80 
81     /* check for presence of ALL items in string... */
82 
83     if (str)
84 	for (counter = 0; c_list[counter].string; ++counter)
85 	    if (strstr(str, c_list[counter].string))
86 		rc = rc | c_list[counter].value;
87     return (rc);
88 }
89 
readconv(char * convpath)90 static int readconv(char *convpath)
91 {
92     FILE *convfile;
93     struct stat finfo;
94 
95     if ((convfile = fopen(convpath, "r")) == NULL) {
96 	if (errno != ENOENT)
97 	    syslog(LOG_ERR, "cannot open conversion file %s: %s",
98 		   convpath, strerror(errno));
99 	return (0);
100     }
101     if (fstat(fileno(convfile), &finfo) != 0) {
102 	syslog(LOG_ERR, "cannot fstat conversion file %s: %s", convpath,
103 	       strerror(errno));
104 	(void) fclose(convfile);
105 	return (0);
106     }
107     if (finfo.st_size == 0) {
108 	convbuf = (char *) calloc(1, 1);
109     }
110     else {
111 	if (!(convbuf = (char *) malloc((size_t) finfo.st_size + 1))) {
112 	    syslog(LOG_ERR, "could not malloc convbuf (%d bytes)", (size_t) finfo.st_size + 1);
113 	    (void) fclose(convfile);
114 	    return (0);
115 	}
116 	if (!fread(convbuf, (size_t) finfo.st_size, 1, convfile)) {
117 	    syslog(LOG_ERR, "error reading conv file %s: %s", convpath,
118 		   strerror(errno));
119 	    convbuf = NULL;
120 	    (void) fclose(convfile);
121 	    return (0);
122 	}
123 	*(convbuf + finfo.st_size) = '\0';
124     }
125     (void) fclose(convfile);
126     return (1);
127 }
128 
parseconv(void)129 static void parseconv(void)
130 {
131     char *ptr;
132     char *convptr = convbuf, *line;
133     char *argv[8], *p, *val;
134     struct convert *cptr, *cvttail = (struct convert *) NULL;
135     int n;
136 
137     if (!convbuf || !(*convbuf))
138 	return;
139 
140     /* read through convbuf, stripping comments. */
141     while (*convptr != '\0') {
142 	line = convptr;
143 	while (*convptr && *convptr != '\n')
144 	    convptr++;
145 	*convptr++ = '\0';
146 
147 	/* deal with comments */
148 	if ((ptr = strchr(line, '#')) != NULL)
149 	    *ptr = '\0';
150 
151 	if (*line == '\0')
152 	    continue;
153 
154 	/* parse the lines... */
155 	for (n = 0, p = line; n < 8 && p != NULL; n++) {
156 	    val = (char *) strsep(&p, ":\n");
157 	    argv[n] = val;
158 	    if ((argv[n][0] == ' ') || (argv[n][0] == '\0'))
159 		argv[n] = NULL;
160 	}
161 	/* check their were 8 fields, if not skip the line... */
162 	if (n != 8 || p != NULL)
163 	    continue;
164 
165 	/* make sure the required elements are present */
166 	if ((!argv[0] && !argv[1] && !argv[2] && !argv[3]) || !argv[4] || !argv[7])
167 	    continue;
168 
169 	/* add element to end of list */
170 	cptr = (struct convert *) calloc(1, sizeof(struct convert));
171 
172 	if (cptr == NULL) {
173 	    syslog(LOG_ERR, "calloc error parsing ftpconversions");
174 	    exit(0);
175 	}
176 	if (cvttail)
177 	    cvttail->next = cptr;
178 	cvttail = cptr;
179 	if (!cvtptr)
180 	    cvtptr = cptr;
181 
182 	cptr->stripprefix = (char *) argv[0];
183 	cptr->stripfix = (char *) argv[1];
184 	cptr->prefix = (char *) argv[2];
185 	cptr->postfix = (char *) argv[3];
186 	cptr->external_cmd = (char *) argv[4];
187 	cptr->types = conv((char *) argv[5]);
188 	cptr->options = conv((char *) argv[6]);
189 	cptr->name = (char *) argv[7];
190     }
191 }
192 
conv_init(void)193 void conv_init(void)
194 {
195     if ((readconv(_path_cvt)) <= 0)
196 	return;
197     parseconv();
198 }
199