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