Back to home page

MITgcm

 
 

    


File indexing completed on 2018-03-02 18:45:00 UTC

view on githubraw file Latest commit e768bd12 on 2008-02-26 17:05:00 UTC
ec6cf3b09d Ed H*0001 /* (C) Copyright 1993,1994 by Carnegie Mellon University
                0002  * All Rights Reserved.
                0003  *
                0004  * Permission to use, copy, modify, distribute, and sell this software
                0005  * and its documentation for any purpose is hereby granted without
                0006  * fee, provided that the above copyright notice appear in all copies
                0007  * and that both that copyright notice and this permission notice
                0008  * appear in supporting documentation, and that the name of Carnegie
                0009  * Mellon University not be used in advertising or publicity
                0010  * pertaining to distribution of the software without specific,
                0011  * written prior permission.  Carnegie Mellon University makes no
                0012  * representations about the suitability of this software for any
                0013  * purpose.  It is provided "as is" without express or implied
                0014  * warranty.
                0015  *
                0016  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
                0017  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
                0018  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
                0019  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                0020  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
                0021  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                0022  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                0023  * SOFTWARE.
                0024  */
                0025 #include <stdio.h>
e768bd1221 Jean*0026 #include <stdlib.h>
ec6cf3b09d Ed H*0027 #include <ctype.h>
                0028 #include <string.h>
                0029 #include <errno.h>
                0030 #include <sys/types.h>
e768bd1221 Jean*0031 #include <sys/stat.h>
ec6cf3b09d Ed H*0032 #include <sys/param.h>
e768bd1221 Jean*0033 #include <time.h>
ec6cf3b09d Ed H*0034 #include <netdb.h>
                0035 #include <fcntl.h>
e768bd1221 Jean*0036 #include <unistd.h>
ec6cf3b09d Ed H*0037 #include "xmalloc.h"
                0038 #include "common.h"
                0039 #include "part.h"
                0040 
e768bd1221 Jean*0041 extern void warn(char *s);
                0042 
ec6cf3b09d Ed H*0043 #ifndef MAXHOSTNAMELEN
                0044 #define MAXHOSTNAMELEN 64
                0045 #endif
                0046 
e768bd1221 Jean*0047 #ifndef errno
ec6cf3b09d Ed H*0048 extern int errno;
e768bd1221 Jean*0049 #endif
ec6cf3b09d Ed H*0050 
                0051 int overwrite_files = 0;
                0052 int didchat;
                0053 
                0054 /* The name of the file we're writing */
                0055 static char *output_fname = 0;
                0056 
                0057 /* Characters that shouldn't be in filenames */
                0058 #define BADCHARS "!$&*()|\'\";<>[]{}?/`\\ \t"
                0059 
                0060 /* Generate a message-id */
                0061 char *os_genid(void)
                0062 {
                0063     static int pid = 0;
                0064     static time_t curtime;
                0065     static char hostname[MAXHOSTNAMELEN+1];
                0066     char *result;
                0067     struct hostent *hp;
                0068     
                0069 
                0070     if (pid == 0) {
                0071     pid = getpid();
                0072     time(&curtime);
                0073     gethostname(hostname, sizeof(hostname));
                0074 
                0075     /* If we don't have a FQDN, try canonicalizing with gethostbyname */
                0076     if (!strchr(hostname, '.')) {
                0077         hp = gethostbyname(hostname);
                0078         if (hp) {
                0079         strcpy(hostname, hp->h_name);
                0080         }
                0081     }
                0082     }
                0083 
e768bd1221 Jean*0084     result = malloc(25+strlen(hostname));
                0085     sprintf(result, "%d.%lu@%s", pid, (unsigned long) curtime++, hostname);
ec6cf3b09d Ed H*0086     return result;
                0087 }
                0088 
                0089 /* Create and return directory for a message-id */
                0090 char *os_idtodir(char *id)
                0091 {
                0092     static char buf[4096];
                0093     char *p;
                0094 
                0095     if (getenv("TMPDIR")) {
                0096     strcpy(buf, getenv("TMPDIR"));
                0097     }
                0098     else {
e768bd1221 Jean*0099     strcpy(buf, "/var/tmp");
ec6cf3b09d Ed H*0100     }
                0101     strcat(buf, "/m-prts-");
                0102     p = getenv("USER");
                0103     if (!p) p = getenv("LOGNAME");
                0104     if (!p) p = "x";
                0105     strcat(buf, p);
                0106     
                0107     (void)mkdir(buf, 0700);
                0108 
                0109     p = buf + strlen(buf);
                0110     *p++ = '/';
                0111     while (*id && p < buf+sizeof(buf)-10 ) {
                0112     if (isprint(*id) && !strchr(BADCHARS, *id)) *p++ = *id;
                0113     id++;
                0114     }
                0115     *p = '\0';
                0116     if (mkdir(buf, 0700) == -1 && errno != EEXIST) {
                0117     perror(buf);
                0118     return 0;
                0119     }
                0120     *p++ = '/';
                0121     *p = '\0';
                0122     return buf;
                0123 }
                0124 
                0125 /*
                0126  * We are done with the directory returned by os_idtodir()
                0127  * Remove it
                0128  */
                0129 void os_donewithdir(char *dir)
                0130 {
                0131     char *p;
                0132 
                0133     /* Remove trailing slash */
                0134     p = dir + strlen(dir) - 1;
                0135     *p = '\0';
                0136 
                0137     rmdir(dir);
                0138 }
                0139 
                0140 FILE *os_createnewfile(char *fname)
                0141 {
                0142     int fd;
                0143     FILE *ret;
                0144      
                0145 #ifdef O_EXCL
e768bd1221 Jean*0146     struct stat statbuf;
                0147 
                0148     if ((stat(fname, &statbuf) == 0) && (S_ISCHR(statbuf.st_mode))) {
                0149     fd=open(fname, O_RDWR);
                0150     }
                0151     else {
                0152     fd=open(fname, O_RDWR|O_CREAT|O_EXCL, 0644);
                0153     }
ec6cf3b09d Ed H*0154 #else
                0155     fd=open(fname, O_RDWR|O_CREAT|O_TRUNC, 0644);
                0156 #endif
                0157 
                0158     if (fd == -1)
                0159         return NULL;
                0160      
                0161     ret=fdopen(fd, "w");
                0162     return ret;
                0163 }
                0164 
                0165      
                0166 /*
                0167  * Create a new file, with suggested filename "fname".
                0168  * "fname" may have come from an insecure source, so clean it up first.
                0169  * It may also be null.
                0170  * "contentType" is passed in for use by systems that have typed filesystems.
                0171  * "flags" contains a bit pattern describing attributes of the new file.
                0172  */
                0173 FILE *os_newtypedfile(char *fname, char *contentType, int flags, params contentParams)
                0174 {
                0175     char *p;
                0176     static int filesuffix=0;
                0177     char buf[128], *descfname=0;
                0178     FILE *outfile = 0;
                0179 
                0180     if (!fname) fname = "";
                0181 
                0182     /* If absolute path name, chop to tail */
                0183     if (*fname == '/') {
                0184     p = strrchr(fname, '/');
                0185     fname = p+1;
                0186     }
                0187 
                0188     /* Get rid of leading ~ or ~/ */
                0189     while (*fname == '~' || *fname == '/') fname++;
                0190 
                0191     while (!strncmp(fname, "../", 3)) fname += 3;
                0192     
                0193     /* Clean out bad characters, create directories along path */
                0194     for (p=fname; *p; p++) {
                0195     if (*p == '/') {
                0196         if (!strncmp(p, "/../", 4)) {
                0197         p[1] = p[2] = 'X';
                0198         }
                0199         *p = '\0';
                0200         (void) mkdir(fname, 0777);
                0201         *p = '/';
                0202     }
                0203     else if (!isprint(*p) || strchr(BADCHARS, *p)) *p = 'X';
                0204     }
                0205 
                0206     if (!fname[0]) {
                0207     do {
                0208         if (outfile) fclose(outfile);
                0209         sprintf(buf, "part%d", ++filesuffix);
e768bd1221 Jean*0210     } while ((outfile = fopen(buf, "r")));
ec6cf3b09d Ed H*0211     fname = buf;
                0212     }
                0213     else if (!overwrite_files && (outfile = fopen(fname, "r"))) {
                0214     do {
                0215         fclose(outfile);
                0216         sprintf(buf, "%s.%d", fname, ++filesuffix);
                0217      
e768bd1221 Jean*0218     } while ((outfile = fopen(buf, "r")));
ec6cf3b09d Ed H*0219     fname = buf;
                0220     }
                0221 
                0222     if (overwrite_files)
                0223          outfile = fopen(fname, "w");
                0224     else
                0225          outfile = os_createnewfile(fname);
                0226     
                0227     if (!outfile) {
                0228     perror(fname);
                0229     }
                0230 
                0231     if (output_fname) free(output_fname);
                0232     output_fname = strsave(fname);
                0233 
                0234     if (strlen(fname) > sizeof(buf)-6) {
                0235     descfname = xmalloc(strlen(fname)+6);
                0236     }
                0237     else {
                0238     descfname = buf;
                0239     }
                0240     strcpy(descfname, fname);
                0241 
                0242     p = strchr(descfname, '/');
                0243     if (!p) p = descfname;
e768bd1221 Jean*0244     if ((p = strrchr(p, '.'))) *p = '\0';
ec6cf3b09d Ed H*0245 
                0246     strcat(descfname, ".desc");
                0247     (void) rename(TEMPFILENAME, descfname);
                0248     if (descfname != buf) free(descfname);
                0249     
                0250     fprintf(stdout, "%s (%s)\n", output_fname, contentType);
                0251     didchat = 1;
                0252 
                0253     return outfile;
                0254 }
                0255 
                0256 /*
                0257  * Close a file opened by os_newTypedFile()
                0258  */
                0259 void os_closetypedfile(FILE *outfile)
                0260 {
                0261     fclose(outfile);
                0262 }
                0263 
                0264 /*
                0265  * (Don't) Handle a BinHex'ed file
                0266  */
                0267 int
                0268 os_binhex(struct part *inpart, int part, int nparts)
                0269 {
                0270     return 1;
                0271 }
                0272 
                0273 /*
                0274  * Warn user that the MD5 digest of the last file created by os_newtypedfile()
                0275  * did not match that supplied in the Content-MD5: header.
                0276  */
                0277 void os_warnMD5mismatch(void)
                0278 {
                0279     char *warning;
                0280 
                0281     warning = xmalloc(strlen(output_fname) + 100);
                0282     sprintf(warning, "%s was corrupted in transit",
                0283         output_fname);
                0284     warn(warning);
                0285     free(warning);
                0286 }
                0287 
                0288 /*
                0289  * Report an error (in errno) concerning a filename
                0290  */
                0291 void os_perror(char *file)
                0292 {
                0293     perror(file);
                0294 }