This is os2os.c in view mode; [Download] [Up]
/* (C) Copyright 1993,1994 by Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice * appear in supporting documentation, and that the name of Carnegie * Mellon University not be used in advertising or publicity * pertaining to distribution of the software without specific, * written prior permission. Carnegie Mellon University makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #define INCL_DOSFILEMGR #define INCL_DOSERRORS #include <os2.h> #include <stdio.h> #include <io.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include "xmalloc.h" #include "common.h" #ifdef __EMX__ /* This is for EMX + GCC */ #define EACCESS EACCES #else /* This is for IBM C++ */ #include <direct.h> #define ENAMETOOLONG EOS2ERR #endif /* EMX or IBM CSet++ */ int overwrite_files = 0; int didchat; int mime_eas = 0; /* The name of the file we're writing */ static char *output_fname = 0; /* Characters that can be in filenames */ #define GOODCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \ "0123456789-_^$~!#%&{}@`'()" int my_mkdir(char *filename) { PEAOP2 EABuf; APIRET rc; EABuf = 0; rc = DosCreateDir(filename,EABuf); switch (rc) { case NO_ERROR: return 0; case ERROR_FILENAME_EXCED_RANGE: errno = EACCESS; return 1; case ERROR_PATH_NOT_FOUND: errno = ENOENT; return -1; default: errno = EACCESS; return -1; } } void crunch_file(char *p, char **q) { int len, sawdot; for (*q=p, len=sawdot=0; *p; p++) { if (*p == '.') { if (!sawdot) { *(*q)++ = '.'; sawdot++; len = 0; } } else if (len < (sawdot ? 3:8)) { *(*q)++ = *p; len++; } } **q = '\0'; } typedef struct { ULONG cbList; ULONG oNext; BYTE fEA; BYTE cbName; USHORT cbValue; BYTE NameBuffer[CCHMAXPATH*2+8]; } FEALST; void EA_attach(int fd, char *name, char *value) { EAOP2 eaop; FEALST fealst; int len; eaop.fpFEA2List = (PFEA2LIST) &fealst; eaop.fpGEA2List = NULL; eaop.oError = 0; fealst.oNext = 0; fealst.fEA = 0; fealst.cbName = strlen(name) ; fealst.cbValue = strlen(value) +4; len = fealst.cbName +1; strcpy(fealst.NameBuffer,name); *((USHORT *) &(fealst.NameBuffer [len])) = 0xFFFD; len += sizeof(USHORT); *((USHORT *) &(fealst.NameBuffer [len])) = strlen(value); len += sizeof(USHORT); strcpy(&(fealst.NameBuffer[len]), value); fealst.cbList = fealst.cbName+fealst.cbValue+9; DosSetFileInfo(fd, FIL_QUERYEASIZE, &eaop, sizeof(eaop)); } /* Generate a message-id */ char *os_genid() { static time_t curtime; static char *hostname; static char *domain; char *result; if (curtime == 0) { time(&curtime); hostname = getenv("HOSTNAME"); if (!hostname) hostname="random-pc"; domain = getenv("DOMAINNAME"); if (!domain) domain="random-domain"; } if (strchr(hostname,'.')) { result = xmalloc(25+strlen(hostname)); sprintf(result, "%lu@%s", curtime++, hostname); } else { if (domain[0] == '.') domain++; result = xmalloc(25+strlen(hostname)+strlen(domain)); sprintf(result, "%lu@%s.%s", curtime++, hostname, domain); } return result; } /* Create and return directory for a message-id */ char *os_idtodir(id) char *id; { static char buf[512]; int len = 0; int cs = 0; int rc; char *p, *q; if (p = getenv("TMP")) { strncpy(buf, p, 201); p[200] = '\0'; /* Ensure sufficiently short */ } else { strcpy(buf, "\\tmp"); (void)my_mkdir(buf); } if (buf[strlen(buf)-1] != '\\') strcat(buf, "\\"); strcat(buf, "parts"); (void)my_mkdir(buf); p = buf + strlen(buf); *p++ = '\\'; q = p; while (*id && len < 200) { if (strchr(GOODCHARS, *id)) { *p++ = *id; len++; cs += *id * len; } id++; } *p = '\0'; rc = my_mkdir(buf); if (rc == 1) { char csarr[] = GOODCHARS; /* maybe 8.3 restriction. Take 8 char + 3 checksum */ p = q; len = 0; while ( *p && len < 8) { len++; p++; } *p++ = '.'; *p++ = csarr[cs % sizeof(csarr)]; cs = cs / sizeof(csarr); *p++ = csarr[cs % sizeof(csarr)]; cs = cs / sizeof(csarr); *p++ = csarr[cs % sizeof(csarr)]; *p = '\0'; rc = my_mkdir(buf); } if ((rc == -1) && (errno != EACCESS)) { perror(buf); return 0; } *p++ = '\\'; *p = '\0'; return buf; } /* * We are done with the directory returned by os_idtodir() * Remove it */ os_donewithdir(dir) char *dir; { char *p; /* Remove trailing slash */ p = dir + strlen(dir) - 1; *p = '\0'; rmdir(dir); } /* * Create a new file, with suggested filename "fname". * "fname" may have come from an insecure source, so clean it up first. * It may also be null. * "contentType" is passed in for use by systems that have typed filesystems. * "flags" contains a bit pattern describing attributes of the new file. */ FILE *os_newtypedfile(fname, contentType, flags, contentParams) char *fname; char *contentType; int flags; params contentParams; { char *p, *q, *r; int len=0; int fd=0; int filesuffix=0; int uselong=0; static int partno=0; char buf[256], lbuf[256]; char *descfname=0; FILE *outfile = 0; FILESTATUS3 FileInfoBuf; if (!fname) fname = ""; /* Chop off any drive specifier, convert / to \ */ if (*fname && fname[1] == ':') fname +=2; for (p = fname; *p; p++) if (*p == '/') *p = '\\'; /* If absolute path name, chop to tail */ if (*fname == '\\') { p = strrchr(fname, '\\'); fname = p+1; } /* Clean out bad characters, create directories along path */ for (p=q=r=fname; *p; p++) { if (*p == '\\') { if (!strncmp(p, "\\..\\", 4)) { p[1] = p[2] = 'X'; } *q = '\0'; if (my_mkdir(fname) == 1) { crunch_file(r,&q); (void) my_mkdir(fname); } *q++ = '\\'; r = q; } else if ( (len < 200) && strchr(GOODCHARS ".", *p)) { *q++ = *p; len++; } } *q = '\0'; if (!fname[0]) { sprintf(buf, "part%d",++partno); fname = buf; } do { errno = 0; fd = open(fname, O_CREAT | O_RDWR | (overwrite_files ? O_TRUNC : O_EXCL) | ((flags & FILE_BINARY) ? O_BINARY : O_TEXT), S_IREAD | S_IWRITE); if ((fd == -1) && (errno == ENAMETOOLONG)) { r = strrchr(fname, '\\'); if (!r) r = fname; strcpy(lbuf,r); uselong=1; crunch_file(r,&q); fd = open(fname, O_CREAT | O_RDWR | (overwrite_files ? O_TRUNC : O_EXCL) | ((flags & FILE_BINARY) ? O_BINARY : O_TEXT), S_IREAD | S_IWRITE); } /* simulate sharing violation, if character device found */ if (fd != -1) { if (DosQueryFileInfo(fd, FIL_STANDARD, &FileInfoBuf, sizeof(FILESTATUS3))) { close(fd); fd = -1; errno = EACCESS; } } if ((fd == -1) && ((errno == EEXIST) || (errno == EACCESS))) { /* chop off suffix */ if (fname != buf) { strcpy(buf,fname); fname=buf; } r = strrchr(fname, '\\'); if (!r) r = fname; q = strchr(r, '.'); if (q) { if (*q) *q = '\0'; } q = fname + strlen(fname); sprintf(q, ".%d", ++filesuffix); errno = 0; } } while ((fd == -1) && (!errno)); if (fd == -1) { perror(fname); } else { if (uselong) EA_attach(fd,".LONGNAME",lbuf); if (mime_eas) EA_attach(fd,"MIME-TYPE",contentType); outfile = fdopen(fd, (flags & FILE_BINARY) ? "wb" : "w"); if (!outfile) { close(fd); perror(fname); } } if (output_fname) free(output_fname); output_fname = strsave(fname); if (strlen(fname) > sizeof(buf)-6) { descfname = xmalloc(strlen(fname)+6); } else { descfname = buf; } strcpy(descfname, fname); p = strrchr(descfname, '\\'); if (!p) p = descfname; if (p = strrchr(p, '.')) *p = '\0'; strcat(descfname, ".dsc"); (void) rename(TEMPFILENAME, descfname); if (descfname != buf) free(descfname); fprintf(stdout, "%s (%s)\n", output_fname, contentType); didchat = 1; return outfile; } /* * Close a file opened by os_newTypedFile() */ os_closetypedfile(outfile) FILE *outfile; { fclose(outfile); } /* * (Don't) Handle a BinHex'ed file */ int os_binhex(infile, part, nparts) FILE *infile; int part; int nparts; { return 1; } /* * Warn user that the MD5 digest of the last file created by os_newtypedfile() * did not match that supplied in the Content-MD5: header. */ os_warnMD5mismatch() { char *warning; warning = xmalloc(strlen(output_fname) + 100); sprintf(warning, "%s was corrupted in transit", output_fname); warn(warning); free(warning); } /* * Report an error (in errno) concerning a filename */ os_perror(file) char *file; { perror(file); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.