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