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 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 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 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 193 void conv_init(void) 194 { 195 if ((readconv(_path_cvt)) <= 0) 196 return; 197 parseconv(); 198 }