diff --git a/bin/makefile-dos b/bin/makefile-dos index 98668365..225a6481 100644 --- a/bin/makefile-dos +++ b/bin/makefile-dos @@ -18,7 +18,7 @@ SRCFILES = conspage.c gcoflow.c shift.c dbgtool.c gcr.c gcrcell.c llstk. OFILES = conspage.obj gcoflow.obj shift.obj dbgtool.obj gcr.obj gcrcell.obj llstk.obj gcscan.obj loopsops.obj storage.obj allocmds.obj dir.obj gvar2.obj lowlev1.obj subr.obj arithops.obj lowlev2.obj subr0374.obj doscomm.obj hardrtn.obj lsthandl.obj sxhash.obj draw.obj main.obj testtool.obj array.obj dsk.obj inet.obj misc7.obj timer.obj array2.obj dspif.obj initdsp.obj miscn.obj typeof.obj array3.obj initkbd.obj ubf1.obj array4.obj dspsubrs.obj initsout.obj mkatom.obj ubf2.obj array5.obj eqf.obj intcall.obj mkcell.obj ubf3.obj array6.obj ether.obj ufn.obj atom.obj findkey.obj kbdsubrs.obj mouseif.obj ufs.obj bbtsub.obj foreign.obj keyevent.obj unixcomm.obj bin.obj fp.obj binds.obj fvar.obj mvs.obj unwind.obj bitblt.obj gc.obj uraid.obj blt.obj gc2.obj kprint.obj osmsg.obj usrsubr.obj byteswap.obj gcarray.obj perrno.obj uutils.obj carcdr.obj asmbbt.obj gccode.obj vars3.obj gcfinal.obj ldsout.obj return.obj vmemsave.obj chardev.obj gchtfind.obj lineblt8.obj rpc.obj xc.obj common.obj gcmain3.obj lisp2c.obj rplcons.obj z2.obj vdate.obj $(COLORFILES) $(ARCHFILES) $(LPFILES) -HFILES = address.h adr68k.h arithopsdefs.h arith.h cell.h dbprint.h display.h dspif.h ifpage.h iopage.h lispemul.h lispmap.h lsptypes.h miscstat.h lspglob.h array.h bb.h bbtmacro.h debug.h devconf.h dspdata.h fast_dsp.h gcdata.h initatms.h inlinec.h keyboard.h lispver1.h lispver2.h lldsp.h locfile.h medleyfp.h mouseif.h my.h opcodes.h osmsgprint.h pilotbbt.h print.h retmacro.h stack.h stream.h subrs.h timeout.h tos1defs.h tosfns.h tosret.h xdefs.h xbitmaps.h xkeymap.h +HFILES = address.h adr68k.h arithopsdefs.h arith.h cell.h dbprint.h display.h dspif.h ifpage.h iopage.h lispemul.h lispmap.h lsptypes.h miscstat.h lspglob.h array.h bb.h bbtmacro.h debug.h devconf.h dspdata.h fast_dsp.h gcdata.h initatms.h inlinec.h keyboard.h lldsp.h locfile.h medleyfp.h mouseif.h my.h opcodes.h osmsgprint.h pilotbbt.h print.h retmacro.h stack.h stream.h subrs.h timeout.h tos1defs.h tosfns.h tosret.h xdefs.h xbitmaps.h xkeymap.h diff --git a/bin/makefile-tail b/bin/makefile-tail index d6277f70..a11cdda6 100644 --- a/bin/makefile-tail +++ b/bin/makefile-tail @@ -340,7 +340,7 @@ $(OBJECTDIR)car-cdr.o: $(SRCDIR)car-cdr.c $(REQUIRED-INCS) \ $(OBJECTDIR)chardev.o: $(SRCDIR)chardev.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)adr68k.h $(INCDIR)lsptypes.h $(INCDIR)arith.h $(INCDIR)timeout.h \ - $(INCDIR)locfile.h $(INCDIR)lispver2.h $(INCDIR)dbprint.h \ + $(INCDIR)locfile.h $(INCDIR)dbprint.h \ $(INCDIR)chardevdefs.h $(INCDIR)byteswapdefs.h $(INCDIR)commondefs.h \ $(INCDIR)perrnodefs.h $(CC) $(RFLAGS) $(SRCDIR)chardev.c -o $(OBJECTDIR)chardev.o @@ -505,7 +505,7 @@ $(OBJECTDIR)dsk.o: $(SRCDIR)dsk.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)adr68k.h $(INCDIR)lsptypes.h $(INCDIR)lspglob.h $(INCDIR)ifpage.h \ $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)arith.h $(INCDIR)stream.h \ - $(INCDIR)timeout.h $(INCDIR)locfile.h $(INCDIR)lispver2.h \ + $(INCDIR)timeout.h $(INCDIR)locfile.h \ $(INCDIR)dbprint.h $(INCDIR)dskdefs.h $(INCDIR)byteswapdefs.h \ $(INCDIR)car-cdrdefs.h $(INCDIR)cell.h $(INCDIR)commondefs.h \ $(INCDIR)ufsdefs.h @@ -515,7 +515,7 @@ $(OBJECTDIR)ufs.o: $(SRCDIR)ufs.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)adr68k.h $(INCDIR)lsptypes.h $(INCDIR)lspglob.h $(INCDIR)ifpage.h \ $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)arith.h $(INCDIR)stream.h \ - $(INCDIR)timeout.h $(INCDIR)locfile.h $(INCDIR)lispver2.h $(INCDIR)dbprint.h \ + $(INCDIR)timeout.h $(INCDIR)locfile.h $(INCDIR)dbprint.h \ $(INCDIR)ufsdefs.h $(INCDIR)commondefs.h $(INCDIR)dskdefs.h $(CC) $(RFLAGS) $(SRCDIR)ufs.c -o $(OBJECTDIR)ufs.o @@ -523,7 +523,7 @@ $(OBJECTDIR)dir.o: $(SRCDIR)dir.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)adr68k.h $(INCDIR)lsptypes.h $(INCDIR)arith.h $(INCDIR)lspglob.h \ $(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)timeout.h \ - $(INCDIR)locfile.h $(INCDIR)lispver2.h $(INCDIR)dirdefs.h \ + $(INCDIR)locfile.h $(INCDIR)dirdefs.h \ $(INCDIR)commondefs.h $(INCDIR)dskdefs.h $(INCDIR)ufsdefs.h $(CC) $(RFLAGS) $(SRCDIR)dir.c -o $(OBJECTDIR)dir.o @@ -640,7 +640,7 @@ $(OBJECTDIR)inet.o: $(SRCDIR)inet.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)lsptypes.h $(INCDIR)arith.h $(INCDIR)emlglob.h $(INCDIR)lspglob.h \ $(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h $(INCDIR)adr68k.h \ - $(INCDIR)dbprint.h $(INCDIR)locfile.h $(INCDIR)lispver2.h \ + $(INCDIR)dbprint.h $(INCDIR)locfile.h \ $(INCDIR)inetdefs.h $(INCDIR)byteswapdefs.h $(INCDIR)commondefs.h \ $(INCDIR)mkcelldefs.h $(CC) $(RFLAGS) $(SRCDIR)inet.c -o $(OBJECTDIR)inet.o @@ -758,7 +758,7 @@ $(OBJECTDIR)osmsg.o: $(SRCDIR)osmsg.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)adr68k.h $(INCDIR)lsptypes.h $(INCDIR)arith.h $(INCDIR)stream.h \ $(INCDIR)lspglob.h $(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h \ - $(INCDIR)timeout.h $(INCDIR)locfile.h $(INCDIR)lispver2.h $(INCDIR)osmsgprint.h \ + $(INCDIR)timeout.h $(INCDIR)locfile.h $(INCDIR)osmsgprint.h \ $(INCDIR)dbprint.h $(INCDIR)commondefs.h $(INCDIR)osmsgdefs.h $(CC) $(RFLAGS) $(SRCDIR)osmsg.c -o $(OBJECTDIR)osmsg.o @@ -865,7 +865,7 @@ $(OBJECTDIR)unixcomm.o: $(SRCDIR)unixcomm.c $(REQUIRED-INCS) \ $(INCDIR)lspglob.h $(INCDIR)ifpage.h $(INCDIR)iopage.h $(INCDIR)miscstat.h \ $(INCDIR)cell.h $(INCDIR)stack.h $(INCDIR)arith.h $(INCDIR)dbprint.h \ $(INCDIR)timeout.h $(INCDIR)unixcommdefs.h $(INCDIR)byteswapdefs.h \ - $(INCDIR)commondefs.h $(INCDIR)locfile.h $(INCDIR)lispver2.h + $(INCDIR)commondefs.h $(INCDIR)locfile.h $(CC) $(RFLAGS) $(SRCDIR)unixcomm.c -o $(OBJECTDIR)unixcomm.o $(OBJECTDIR)unixfork.o: $(SRCDIR)unixfork.c $(REQUIRED-INCS) \ @@ -888,7 +888,7 @@ $(OBJECTDIR)rpc.o: $(SRCDIR)rpc.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)lispmap.h \ $(INCDIR)lsptypes.h $(INCDIR)lspglob.h $(INCDIR)ifpage.h $(INCDIR)iopage.h \ $(INCDIR)miscstat.h $(INCDIR)emlglob.h $(INCDIR)adr68k.h $(INCDIR)arith.h \ - $(INCDIR)locfile.h $(INCDIR)lispver2.h $(INCDIR)rpcdefs.h \ + $(INCDIR)locfile.h $(INCDIR)rpcdefs.h \ $(INCDIR)commondefs.h $(CC) $(RFLAGS) $(SRCDIR)rpc.c -o $(OBJECTDIR)rpc.o @@ -909,7 +909,7 @@ $(OBJECTDIR)vmemsave.o: $(SRCDIR)vmemsave.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h \ $(INCDIR)lispmap.h $(INCDIR)lspglob.h $(INCDIR)ifpage.h $(INCDIR)iopage.h \ $(INCDIR)miscstat.h $(INCDIR)timeout.h $(INCDIR)adr68k.h \ - $(INCDIR)lsptypes.h $(INCDIR)locfile.h $(INCDIR)lispver2.h $(INCDIR)dbprint.h \ + $(INCDIR)lsptypes.h $(INCDIR)locfile.h $(INCDIR)dbprint.h \ $(INCDIR)devif.h $(INCDIR)vmemsavedefs.h $(INCDIR)byteswapdefs.h $(INCDIR)commondefs.h \ $(INCDIR)dskdefs.h $(INCDIR)initkbddefs.h $(INCDIR)perrnodefs.h \ $(INCDIR)ufsdefs.h diff --git a/inc/dirdefs.h b/inc/dirdefs.h index f46f3896..582bffb4 100644 --- a/inc/dirdefs.h +++ b/inc/dirdefs.h @@ -58,7 +58,7 @@ typedef struct dfinfo { } DFINFO; #ifdef DOS -int make_old_version(char *old, char *file); +int make_old_version(char *old, size_t oldsize, char *file); #endif #ifdef FSDEBUG void print_finfo(FINFO *fp); diff --git a/inc/dskdefs.h b/inc/dskdefs.h index f5cfa94c..ffe1f1d4 100644 --- a/inc/dskdefs.h +++ b/inc/dskdefs.h @@ -19,7 +19,9 @@ LispPTR COM_writepage(LispPTR *args); LispPTR COM_truncatefile(LispPTR *args); LispPTR COM_changedir(LispPTR *args); LispPTR COM_getfreeblock(LispPTR *args); -void separate_version(char *name, char *ver, int checkp); +void conc_dir_and_name(char *dir, char *name, char *fname, size_t fname_size); +void conc_name_and_version(char *name, char *ver, char *rname, size_t rname_size); +void separate_version(char *name, size_t namesize, char *ver, size_t versize, int checkp); int unpack_filename(char *file, char *dir, char *name, char *ver, int checkp); -int true_name(char *path); +int true_name(char *path, size_t pathsize); #endif diff --git a/inc/lispver1.h b/inc/lispver1.h deleted file mode 100644 index a50e67d4..00000000 --- a/inc/lispver1.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef LISPVER1_H -#define LISPVER1_H 1 -/* $Id: lispver1.h,v 1.2 1999/01/03 02:06:08 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */ - -/* DOS version of LispVersionToUnixVersion */ -#define LispVersionToUnixVersion(pathname, ver) \ - do { \ - \ - char *cp; \ - char *vp; \ - char ver_buf[VERSIONLEN]; \ - \ - cp = pathname; \ - vp = NULL; \ - while (*cp) \ - { \ - switch (*cp) \ - { \ - \ - case ';': \ - *cp = 0; \ - cp++; \ - vp = cp; \ - break; \ - \ - case '\'': \ - if (*(cp + 1) != 0) cp += 2; \ - else cp++; \ - break; \ - \ - default: \ - cp++; \ - break; \ - } \ - } \ - \ - if (vp) \ - { \ - NumericStringP(vp, YES, NO); \ - NO: *vp = 0; \ - YES: \ - if ((*vp)) ver = strtol(vp, (char **)NULL, 10); \ - else ver = -1; \ - } \ - else ver = -1; \ - } while (0) -#endif /* LISPVER1_H */ diff --git a/inc/lispver2.h b/inc/lispver2.h deleted file mode 100644 index 7e180091..00000000 --- a/inc/lispver2.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef LISPVER2_H -#define LISPVER2_H 1 -/* $Id: lispver2.h,v 1.2 1999/01/03 02:06:09 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */ - -/* non-DOS version of LispVersionToUnixVersion */ - -#define LispVersionToUnixVersion(pathname) do { \ - \ - char *lv_cp; \ - char *lv_vp; \ - unsigned lv_ver; \ - char lv_ver_buf[VERSIONLEN]; \ - \ - lv_cp = pathname; \ - lv_vp = NULL; \ - while (*lv_cp) { \ - switch (*lv_cp) { \ - \ - case ';': \ - lv_vp = lv_cp; \ - lv_cp++; \ - break; \ - \ - case '\'': \ - if (*(lv_cp + 1) != 0) lv_cp += 2; \ - else lv_cp++; \ - break; \ - \ - default: \ - lv_cp++; \ - break; \ - } \ - } \ - \ - if (lv_vp != NULL) { \ - /* \ - * A semicolon which is not quoted has been found. \ - */ \ - if (*(lv_vp + 1) == 0) { \ - /* \ - * The empty version field. \ - * This is regarded as a versionless file. \ - */ \ - *lv_vp = 0; \ - } else { \ - NumericStringP((lv_vp + 1), YES, NO); \ - YES: \ - /* \ - * Convert the remaining field to digit. \ - */ \ - lv_ver = strtoul(lv_vp + 1, (char **)NULL, 10); \ - if (lv_ver == 0) { \ - /* versionless */ \ - *lv_vp = 0; \ - } else { \ - sprintf(lv_ver_buf, ".~%u~", lv_ver); \ - *lv_vp = 0; \ - strcat(pathname, lv_ver_buf); \ - } \ - goto CONT; \ - \ - NO: \ - strcpy(lv_ver_buf, lv_vp + 1); \ - strcat(lv_ver_buf, "~"); \ - *lv_vp++ = '.'; \ - *lv_vp++ = '~'; \ - *lv_vp = 0; \ - strcat(pathname, lv_ver_buf); \ - CONT: \ - lv_vp--; /* Just for label */ \ - } \ - } \ -} while (0) -#endif /* LISPVER2_H */ diff --git a/inc/locfile.h b/inc/locfile.h index 856c23d6..c1aa0ad3 100644 --- a/inc/locfile.h +++ b/inc/locfile.h @@ -281,219 +281,6 @@ do { \ #define SPECIALFILEMARK (-1) -#define NumericStringP(str, truetag, falsetag) do { \ - char *lfn_cp; \ - \ - /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \ - if (*(str) == '\0') goto falsetag; \ - \ - for(lfn_cp = str; *lfn_cp!='\0'; ++lfn_cp) \ - if(*lfn_cp < '0' || '9' < *lfn_cp) \ - goto falsetag; /* NOLINT(bugprone-macro-parentheses) */ \ - goto truetag; /* NOLINT(bugprone-macro-parentheses) */ \ - } while (0) - -/* - * Name: LispVersionToUnixVersion - * - * Argument: char *pathname - * Xerox Lisp syntax pathname. - * - * Value: If succeed, returns 1, otherwise 0. - * - * Side Effect: The version part of pathname is destructively modified. - * - * Description: - * - * Destructively modify the version part of pathname which is following the - * Xerox Lisp file naming convention to UNIX one. - * If the file name which is passed from Lisp has the version part, it must be - * a valid one (i.e. constructed with only number). This is guaranteed by Lisp - * code. - * This macro should be called at the top of the routines which accept the - * file name from lisp before converting it into UNIX file name, because - * locating the version part, the informations about quoted characters are needed. - * They might be lost in the course of the conversion. - * - */ -#ifdef DOS - -/* DOS version of LispVersionToUnixVersion */ -/* * * * * This is done this way because DOS can't handle the non-DOS version -- */ -/* * * * * it gave "Too many characters in a character constant" errors! */ -#include "lispver1.h" -#else /* DOS */ -/* NON-DOS version of the macro LispVersionToUnixVersion */ -#include "lispver2.h" -#endif /* DOS */ - - -/* - * Name: UnixVersionToLispVersion - * - * Argument: char *pathname - * UNIX syntax pathname. - * int vlessp - * If 0, versionless file is converted to version 1. - * Otherwise, remains as versionless. - * - * Value: If succeed, returns 1, otherwise 0. - * - * Side Effect: The version part of pathname is destructively modified. - * - * Description: - * - * Destructively modify the version part of pathname which is following the - * UNIX file naming convention to Xerox Lisp one. - * This macro should be called, in the routines which convert the UNIX pathname - * to Lisp one, just before it returns the result to Lisp, because converting - * version field will append a semicolon and it might make the routine be - * confused. - * The file which has not a valid version field, that is ".~##~" form, is - * dealt with as version 1. - */ - -#define UnixVersionToLispVersion(pathname, vlessp) do { \ - \ - char *start; \ - char *end; \ - char *lf_cp; \ - int ver_no; \ - size_t len; \ - char ver_buf[VERSIONLEN]; \ - \ - if ((start = strchr(pathname, '~')) != NULL) { \ - /* First of all, find the version field in pathname. */ \ - end = start; \ - lf_cp = start + 1; \ - while (*lf_cp) { \ - if (*lf_cp == '~') { \ - start = end; \ - end = lf_cp; \ - lf_cp++; \ - } else { \ - lf_cp++; \ - } \ - } \ - \ - if (start != end && *(start - 1) == '.' && end == (lf_cp - 1)) { \ - /* \ - * pathname ends in the form ".~###~". But we \ - * check ### is a valid number or not. \ - */ \ - len = (end - start) - 1; \ - strncpy(ver_buf, start + 1, len); \ - ver_buf[len] = '\0'; \ - NumericStringP(ver_buf, YES, NO); \ - YES: \ - *(start - 1) = ';'; \ - *start = '\0'; \ - *end = '\0'; \ - /* call strtoul() to eliminate leading 0s. */ \ - ver_no = strtoul(start + 1, (char **)NULL, 10); \ - sprintf(ver_buf, "%u", ver_no); \ - strcat(pathname, ver_buf); \ - goto CONT; \ - \ - NO: \ - /* Dealt with as version 1 unless vlessp */ \ - if (!(vlessp)) strcat(pathname, ";1"); \ - CONT: \ - lf_cp--; /* Just for label */ \ - } else { \ - /* Dealt with as version 1 unless vlessp. */ \ - if (!(vlessp)) strcat(pathname, ";1"); \ - } \ - } else { \ - /* Dealt with as version 1 unless vlessp. */ \ - if (!(vlessp)) strcat(pathname, ";1"); \ - } \ - } while (0) - -/* - * Name: ConcDirAndName - * - * Argument: char *dir The name of the directory. - * char *name The name of a file. - * char *fname The place where the full file name should be - * stored. - * Value: N/A - * - * Side Effect: fname is replaced with the full file name. - * - * Description: - * - * Concatenate the directory name and root file name. Checks if dir contains - * the trail directory delimiter or not. - * - */ - -#define ConcDirAndName(dir, name, fname) do { \ - \ - char *lf_cp1, *lf_cp2; \ - \ - lf_cp1 = dir; \ - lf_cp2 = dir; \ - \ - while (*lf_cp2 != '\0') { \ - switch (*lf_cp2) { \ - \ - case '/': \ - lf_cp1 = lf_cp2; \ - lf_cp2++; \ - break; \ - \ - default: \ - lf_cp2++; \ - break; \ - } \ - } \ - if (lf_cp1 == (lf_cp2 - 1)) { \ - if (lf_cp1 == (dir)) { \ - /* dir is a root directory. */ \ - strcpy(fname, "/"); \ - strcat(fname, name); \ - } else { \ - /* The trail directory is included. */ \ - strcpy(fname, dir); \ - strcat(fname, name); \ - } \ - } else { \ - /* The trail directory is not included */ \ - strcpy(fname, dir); \ - strcat(fname, "/"); \ - strcat(fname, name); \ - } \ - } while (0) - -/* - * Name: ConcNameAndVersion - * - * Argument: char *name The root file name. - * char *ver The file version. - * char *rname The place where the concatenated file name will be - * stored. - * Value: N/A - * - * Side Effect: rname is replaced with the concatenated file name. - * - * Description: - * - * Concatenate the root file name and its version in UNIX format. - * - */ - -#define ConcNameAndVersion(name, ver, rname) do { \ - if (*(ver) != '\0') { \ - strcpy(rname, name); \ - strcat(rname, ".~"); \ - strcat(rname, ver); \ - strcat(rname, "~"); \ - } else { \ - strcpy(rname, name); \ - } \ -} while (0) - #define VERSIONLEN 16 #define MAXVERSION 999999999 diff --git a/inc/timeout.h b/inc/timeout.h index 9499b39b..8760d494 100644 --- a/inc/timeout.h +++ b/inc/timeout.h @@ -38,9 +38,8 @@ extern unsigned int TIMEOUT_TIME; } while (0) #define S_TOUT(exp) \ - alarm(TIMEOUT_TIME), \ - (exp), \ - alarm(0) + alarm(TIMEOUT_TIME), \ + (exp) #define ERRSETJMP(rval) \ do { \ diff --git a/inc/ufsdefs.h b/inc/ufsdefs.h index e90cda75..40500fed 100644 --- a/inc/ufsdefs.h +++ b/inc/ufsdefs.h @@ -5,15 +5,13 @@ LispPTR UFS_getfilename(LispPTR *args); LispPTR UFS_deletefile(LispPTR *args); LispPTR UFS_renamefile(LispPTR *args); LispPTR UFS_directorynamep(LispPTR *args); +void UnixVersionToLispVersion(char *pathname, size_t pathsize, int vlessp); #ifdef DOS -int unixpathname(char *src, char *dst, int versionp, int genp, char *drive, int *extlenptr, char *rawname); +int unixpathname(char *src, char *dst, int dstlen, int versionp, int genp, char *drive, int *extlenptr, char *rawname); #else -int unixpathname(char *src, char *dst, int versionp, int genp); +int unixpathname(char *src, char *dst, size_t dstlen, int versionp, int genp); #endif -int lisppathname(char *fullname, char *lispname, int dirp, int versionp); -int quote_fname(char *file); -int quote_fname_ufs(char *file); -int quote_dname(char *dir); +int lisppathname(char *fullname, char *lispname, size_t lispnamesize, int dirp, int versionp); #ifdef DOS init_host_filesystem(void); exit_host_filesystem(void); diff --git a/src/dir.c b/src/dir.c index 5b31c4d5..098174f0 100644 --- a/src/dir.c +++ b/src/dir.c @@ -20,9 +20,9 @@ #define alarm(x) 1 #endif /* DOS */ #include // for errno, EINTR, ENOENT -#include // for NULL, sprintf, size_t +#include // for NULL, snprintf, size_t #include // for calloc, free, strtoul, malloc, qsort -#include // for strcpy, strcmp, strlen, strrchr, strcat +#include // for strlcpy, strcmp, strlen, strrchr, strlcat #include // for stat, S_ISDIR, st_atime, st_mtime #include // for timespec_t #include "adr68k.h" // for NativeAligned4FromLAddr @@ -34,12 +34,12 @@ #include "lspglob.h" #include "lsptypes.h" #include "timeout.h" // for S_TOUT, TIMEOUT0, TIMEOUT, ERRSETJMP -#include "ufsdefs.h" // for quote_dname, quote_fname, quote_fname_ufs - +#include "ufsdefs.h" // for unixpathname extern int *Lisp_errno; extern int Dummy_errno; -#define DIRCHAR '>' +#define LISPDIRCHAR '>' +#define LISPDIRSTR ">" /************************************************************************ SUBROUTINES @@ -72,20 +72,20 @@ extern int Dummy_errno; do { \ char *pp; \ \ - separate_version(tname, tver, 0); \ + separate_version(tname, sizeof(tname), tver, sizeof(tver), 0); \ \ if ((pp = (char *)strrchr(tname, '.')) == NULL) { \ *(text) = '\0'; \ } else { \ *pp = '\0'; \ - strcpy(text, pp + 1); \ + strlcpy(text, pp + 1, sizeof(text)); \ } \ \ if ((pp = (char *)strrchr(pname, '.')) == NULL) { \ *(pext) = '\0'; \ } else { \ *pp = '\0'; \ - strcpy(pext, pp + 1); \ + strlcpy(pext, pp + 1, sizeof(pext)); \ } \ } while (0) @@ -94,9 +94,9 @@ extern int Dummy_errno; char tname[MAXNAMLEN], text[MAXNAMLEN], tver[VERSIONLEN]; \ char pname[MAXNAMLEN], pext[MAXNAMLEN]; \ \ - strcpy(tname, target); \ + strlcpy(tname, target, sizeof(tname)); \ DOWNCASE(tname); \ - strcpy(pname, name); \ + strlcpy(pname, name, sizeof(pname)); \ DOWNCASE(pname); \ \ SetupMatch(tname, pname, text, pext, tver); \ @@ -112,8 +112,8 @@ extern int Dummy_errno; char tname[MAXNAMLEN], text[MAXNAMLEN], tver[VERSIONLEN]; \ char pname[MAXNAMLEN], pext[MAXNAMLEN]; \ \ - strcpy(tname, target); \ - strcpy(pname, name); \ + strlcpy(tname, target, sizeof(tname)); \ + strlcpy(pname, name, sizeof(pname)); \ \ SetupMatch(tname, pname, text, pext, tver); \ \ @@ -191,23 +191,23 @@ static int match_pattern(char *tp, char *pp) #ifdef DOS -int make_old_version(char *old, char *file) +int make_old_version(char *old, size_t oldsize, char *file) { int len = (int)strlen(file) - 1; - if (file[len] == DIRCHAR) return 0; + if (file[len] == LISPDIRCHAR) return 0; /* look up old versions of files for version # 0's */ - strcpy(old, file); + strlcpy(old, file, oldsize); if (old[len] == '.') - strcat(old, "%"); + strlcat(old, "%", oldsize); else if ((len > 0) && old[len - 1] == '.') - strcat(old, "%"); + strlcat(old, "%", oldsize); else if ((len > 1) && old[len - 2] == '.') - strcat(old, "%"); + strlcat(old, "%", oldsize); else if ((len > 2) && old[len - 3] == '.') old[len] = '%'; else - strcat(old, ".%"); + strlcat(old, ".%", oldsize); return 1; } #endif /* DOS */ @@ -216,6 +216,232 @@ int make_old_version(char *old, char *file) /******** E N D O F P A T T E R N - M A T C H I N G C O D E *******/ /************************************************************************/ +/************************************************************************/ +/************** B E G I N O F Q U O T I N G C O D E ****************/ +/************************************************************************/ + +/* + * Name: quote_fname + * + * Argument: char *file The root file name in UNIX format. "Root" + * file name contains the name, extension and + * version fields. A valid version field is in a + * form as ".~##~". + * size_t filesize size of storage allocated for (name of) file + * + * Value: If succeed, returns 1, otherwise 0. + * + * Side Effect: If succeed, file is replaced with the file name in Xerox Lisp format + * in which special characters are quoted. + * + * Description: + * + * Converts a UNIX root file name to Xerox Lisp one. This routine only quotes special + * characters in Xerox file naming convention, does not care about the "true" name + * which might be specified directly by the user as like lisppathname. Thus, this + * routine can be invoked when you don't know how to escape the period character. This + * is the case when you convert a file name in the course of the directory enumeration. + * + * This routine is used when file is a "FILE" name and being converted to {DSK} name. + * + * The special characters which is quoted include "<", ">", ";", and "'" itself. Notice + * again that "." is not quoted, because we don't know it is a extension separator in + * Lisp sense or not. + */ + +static int quote_fname(char *file, size_t filesize) +{ + char *cp, *dp; + int extensionp; + char fbuf[MAXNAMLEN + 1], namebuf[MAXNAMLEN + 1], ver[VERSIONLEN]; + + cp = file; + dp = fbuf; + + while (*cp) { + switch (*cp) { + case '>': + case ';': + case '\'': + *dp++ = '\''; + *dp++ = *cp++; + break; + + default: *dp++ = *cp++; break; + } + } + *dp = '\0'; + + /* + * extensionp indicates whether extension field is included in a file + * name or not. If extension field is not included, we have to add a + * period to specify empty extension field. + */ + separate_version(fbuf, sizeof(fbuf), ver, sizeof(ver), 1); + cp = fbuf; + extensionp = 0; + while (*cp && !extensionp) { + switch (*cp) { + case '.': + if (*(cp + 1)) extensionp = 1; + cp++; + break; + + case '\'': + if (*(cp + 1) != '\0') + cp += 2; + else + cp++; + break; + + default: cp++; break; + } + } + if (!extensionp) { + if (*(cp - 1) == '.') { + *(cp - 1) = '\''; + *cp++ = '.'; + } + *cp++ = '.'; + *cp = '\0'; + } + if (*ver != '\0') { + conc_name_and_version(fbuf, ver, namebuf, sizeof(namebuf)); + } else { + strlcpy(namebuf, fbuf, sizeof(namebuf)); + } + UnixVersionToLispVersion(namebuf, sizeof(namebuf), 1); + strlcpy(file, namebuf, filesize); + return (1); +} + +/* + * Name: quote_fname_ufs + * + * Argument: char *file The root file name in UNIX format. "Root" + * file name contains the name, extension and + * version fields. A valid version field is in a + * form as ".~##~". + * + * Value: If succeed, returns 1, otherwise 0. + * + * Side Effect: If succeed, file is replaced with the file name in Xerox Lisp format + * in which special characters are quoted. + * + * Description: + * + * Similar to quote_fname, but this routine is only used when file is a "FILE" name + * and being converted to {UNIX} name. + */ + +static int quote_fname_ufs(char *file, size_t filesize) +{ + char *cp, *dp; + int extensionp; + char fbuf[MAXNAMLEN + 1]; + + cp = file; + dp = fbuf; + + while (*cp) { + switch (*cp) { + case '>': + case ';': + case '\'': + *dp++ = '\''; + *dp++ = *cp++; + break; + + default: *dp++ = *cp++; break; + } + } + *dp = '\0'; + + /* + * extensionp indicates whether extension field is included in a file + * name or not. If extension field is not included, we have to add a + * period to specify empty extension field. + */ + cp = fbuf; + extensionp = 0; + while (*cp && !extensionp) { + switch (*cp) { + case '.': + if (*(cp + 1)) extensionp = 1; + cp++; + break; + + case '\'': + if (*(cp + 1) != '\0') + cp += 2; + else + cp++; + break; + + default: cp++; break; + } + } + if (!extensionp) { + if (*(cp - 1) == '.') { + *(cp - 1) = '\''; + *cp++ = '.'; + } + *cp++ = '.'; + *cp = '\0'; + } + strlcpy(file, fbuf, filesize); + return (1); +} + +/* + * Name: quote_dname + * + * Argument: char *dir The directory name in UNIX format. Does not + * include its parent name. + * + * Value: If succeed, returns 1, otherwise 0. + * + * Side Effect: If succeed, dir is replaced with the directory name in Xerox Lisp + * format in which special characters are quoted. + * + * Description: + * + * Similar to quote_fname, but this routine is only used when dir is a "DIRECTORY" + * name. Both {DSK} and {UNIX} uses this routine. + */ + +static int quote_dname(char *dir, size_t dirsize) +{ + char *cp, *dp; + char fbuf[MAXNAMLEN + 1]; + + cp = dir; + dp = fbuf; + + while (*cp) { + switch (*cp) { + case '>': + case ';': + case '\'': + *dp++ = '\''; + *dp++ = *cp++; + break; + + default: *dp++ = *cp++; break; + } + } + *dp = '\0'; + + if (*(dp - 1) == '.') { + /* Trail period should be quoted. */ + *(dp - 1) = '\''; + *dp++ = '.'; + } + + strlcpy(dir, fbuf, dirsize); + return (1); +} + /************************************************************************/ /************ B E G I N O F F I L E - I N F O C O D E **************/ /************************************************************************/ @@ -408,7 +634,7 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) isslash = 1; if (!isslash) - strcpy(namebuf, dir); /* Only add the dir if it's real */ + strlcpy(namebuf, dir, sizeof(namebuf)); /* Only add the dir if it's real */ else if (drive) { namebuf[0] = drive; namebuf[1] = DRIVESEP; @@ -416,8 +642,8 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) } else *namebuf = '\0'; - strcat(namebuf, DIRSEPSTR); - strcat(namebuf, name); + strlcat(namebuf, DIRSEPSTR, sizeof(namebuf)); + strlcat(namebuf, name, sizeof(namebuf)); TIMEOUT(res = _dos_findfirst(namebuf, _A_NORMAL | _A_SUBDIR, &dirp)); if (res < 0) { @@ -436,16 +662,17 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); return (-1); } nextp->next = prevp; if (isslash) { if (drive) - sprintf(namebuf, "%c:\\%s", drive, dirp.name); + snprintf(namebuf, sizeof(namebuf), "%c:\\%s", drive, dirp.name); else - sprintf(namebuf, "\\%s", dirp.name); + snprintf(namebuf, sizeof(namebuf), "\\%s", dirp.name); } else - sprintf(namebuf, "%s\\%s", dir, dirp.name); + snprintf(namebuf, sizeof(namebuf), "%s\\%s", dir, dirp.name); TIMEOUT(rval = stat(namebuf, &sbuf)); if (rval == -1 && errno != ENOENT) { @@ -458,30 +685,24 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) return (-1); } - strcpy(namebuf, dirp.name); + strlcpy(namebuf, dirp.name, sizeof(namebuf)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(namebuf, sizeof(namebuf)); + strlcpy(nextp->lname, namebuf, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRSTR, sizeof(nextp->lname)); + nextp->lname_len = strlen(nextp->lname); } else { /* All other types than directory. */ nextp->dirp = 0; - strcat(namebuf, ".~1~"); - quote_fname(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + strlcat(namebuf, ".~1~", sizeof(namebuf)); + quote_fname(namebuf, sizeof(namebuf)); + strlcpy(nextp->lname, namebuf, sizeof(nextp->lname)); + nextp->lname_len = strlen(nextp->lname); } - strcpy(namebuf, dirp.name); - len = strlen(namebuf); - DOWNCASE(namebuf); - strcpy(nextp->no_ver_name, namebuf); + strlcpy(nextp->no_ver_name, dirp.name, sizeof(nextp->no_ver_name)); + DOWNCASE(nextp->no_ver_name); nextp->version = 1; nextp->ino = sbuf.st_ino; nextp->prop->length = (unsigned)sbuf.st_size; @@ -492,14 +713,13 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) if (pwd == (struct passwd *)NULL) { nextp->prop->au_len = 0; } else { - len = strlen(pwd->pw_name); - strcpy(nextp->prop->author, pwd->pw_name); - *(nextp->prop->author + len) = '\0'; - nextp->prop->au_len = len; + strlcpy(nextp->prop->author, pwd->pw_name, sizeof(nextp->prop->author)); + nextp->prop->au_len = strlen(nextp->prop->author); } */ n++; } - + alarm(0); // cancel alarm from S_TOUT + /***********************/ /* Now go looking for version-0 entries */ /***********************/ @@ -507,15 +727,15 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) for (nextp = prevp; nextp; nextp = nextp->next) { FINFO *newp; - if (!make_old_version(old, nextp->no_ver_name)) continue; + if (!make_old_version(old, sizeof(old), nextp->no_ver_name)) continue; if (isslash) { if (drive) - sprintf(namebuf, "%c:\\%s", drive, old); + snprintf(namebuf, sizeof(namebuf), "%c:\\%s", drive, old); else - sprintf(namebuf, "\\%s", old); + snprintf(namebuf, sizeof(namebuf), "\\%s", old); } else - sprintf(namebuf, "%s\\%s", dir, old); + snprintf(namebuf, sizeof(namebuf), "%s\\%s", dir, old); TIMEOUT(rval = stat(namebuf, &sbuf)); if (rval == -1) continue; @@ -524,14 +744,12 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) newp->next = prevp; /* All other types than directory. */ newp->dirp = 0; - sprintf(namebuf, "%s.~00~", nextp->no_ver_name); - quote_fname(namebuf); - len = strlen(namebuf); - strcpy(newp->lname, namebuf); - *(newp->lname + len) = '\0'; - newp->lname_len = len; + snprintf(namebuf, sizeof(namebuf), "%s.~00~", nextp->no_ver_name); + quote_fname(namebuf, sizeof(namebuf)); + strlcpy(newp->lname, namebuf, sizeof(newp->lname)); + newp->lname_len = strlen(newp->lname); - strcpy(newp->no_ver_name, old); + strlcpy(newp->no_ver_name, old, sizeof(newp->no_ver_name)); newp->version = 0; newp->ino = sbuf.st_ino; newp->prop->length = (unsigned)sbuf.st_size; @@ -577,12 +795,12 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) AllocFinfo(nextp); if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (-1); } nextp->next = prevp; - sprintf(namebuf, "%s/%s", dir, dp->d_name); + snprintf(namebuf, sizeof(namebuf), "%s/%s", dir, dp->d_name); TIMEOUT(rval = stat(namebuf, &sbuf)); if (rval == -1 && errno != ENOENT) { /* @@ -590,35 +808,26 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) * link. We should ignore such error here. */ FreeFinfo(nextp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (-1); } - strcpy(namebuf, dp->d_name); + strlcpy(nextp->lname, dp->d_name, sizeof(nextp->lname)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(nextp->lname, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRSTR, sizeof(nextp->lname)); } else { /* All other types than directory. */ nextp->dirp = 0; - quote_fname(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + quote_fname(nextp->lname, sizeof(nextp->lname)); } + nextp->lname_len = strlen(nextp->lname); - strcpy(namebuf, dp->d_name); - len = strlen(namebuf); - separate_version(namebuf, fver, 1); - DOWNCASE(namebuf); - strcpy(nextp->no_ver_name, namebuf); + strlcpy(nextp->no_ver_name, dp->d_name, sizeof(nextp->no_ver_name)); + separate_version(nextp->no_ver_name, sizeof(nextp->no_ver_name), fver, sizeof(fver), 1); + DOWNCASE(nextp->no_ver_name); if (*fver == '\0') nextp->version = 0; else @@ -632,14 +841,12 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) if (pwd == (struct passwd *)NULL) { nextp->prop->au_len = 0; } else { - len = strlen(pwd->pw_name); - strcpy(nextp->prop->author, pwd->pw_name); - *(nextp->prop->author + len) = '\0'; - nextp->prop->au_len = len; + strlcpy(nextp->prop->author, pwd->pw_name, sizeof(nextp->prop->author)); + nextp->prop->au_len = strlen(nextp->prop->author); } n++; } - closedir(dirp); + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT if (n > 0) *finfo_buf = prevp; return (n); } @@ -687,7 +894,7 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) isslash = 1; if (!isslash) - strcpy(namebuf, dir); /* Only add the dir if it's real */ + strlcpy(namebuf, dir, sizeof(namebuf)); /* Only add the dir if it's real */ else if (drive) { namebuf[0] = drive; namebuf[1] = DRIVESEP; @@ -695,8 +902,8 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) } else *namebuf = '\0'; - strcat(namebuf, DIRSEPSTR); - strcat(namebuf, name); + strlcat(namebuf, DIRSEPSTR, sizeof(namebuf)); + strlcat(namebuf, name, sizeof(namebuf)); TIMEOUT(rval = _dos_findfirst(namebuf, _A_NORMAL | _A_SUBDIR, &dirp)); if (rval != 0) { @@ -715,17 +922,18 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); *Lisp_errno = errno; + alarm(0); // cancel alarm from S_TOUT return (-1); } nextp->next = prevp; if (isslash) { if (drive) - sprintf(namebuf, "%c:\\%s", drive, dirp.name); + snprintf(namebuf, sizeof(namebuf), "%c:\\%s", drive, dirp.name); else - sprintf(namebuf, "\\%s", dirp.name); + snprintf(namebuf, sizeof(namebuf), "\\%s", dirp.name); } else - sprintf(namebuf, "%s\\%s", dir, dirp.name); - TIMEOUT(rval = stat(namebuf, &sbuf)); + snprintf(namebuf, sizeof(namebuf), "%s\\%s", dir, dirp.name); + TIMEOUT(rval = stat(namebuf, &sbuf)); // will cancel S_TOUT alarm if (rval == -1 && errno != ENOENT) { /* * ENOENT error might be caused by missing symbolic @@ -736,35 +944,32 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) return (-1); } - strcpy(namebuf, dirp.name); /* moved from below 2/26/93 */ + + strlcpy(namebuf, dirp.name, sizeof(namebuf)); /* moved from below 2/26/93 */ if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(namebuf, sizeof(namebuf)); + strlcpy(nextp->lname, namebuf, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRCHAR, sizeof(nextp->lname)); + nextp->lname_len = strlen(nextp->lname); } else { /* All other types than directory. */ nextp->dirp = 0; - strcat(namebuf, ".~1~"); - quote_fname(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + strlcat(namebuf, ".~1~", sizeof(namebuf)); + quote_fname(namebuf, sizeof(namebuf)); + strlcpy(nextp->lname, namebuf, sizeof(nextp->lname)); + nextp->lname_len = strlen(nextp->lname); } - strcpy(namebuf, dirp.name); /* to get real versionless name */ - len = strlen(namebuf); + strlcpy(namebuf, dirp.name, sizeof(namebuf)); /* to get real versionless name */ DOWNCASE(namebuf); - strcpy(nextp->no_ver_name, namebuf); + strlcpy(nextp->no_ver_name, namebuf, sizeof(nextp->no_ver_name)); nextp->version = 1; nextp->ino = sbuf.st_ino; n++; } - + alarm(0); // ensure alarm from S_TOUT is cancelled + /***********************/ /* Now go looking for version-0 entries */ /***********************/ @@ -772,15 +977,15 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) for (nextp = prevp; nextp; nextp = nextp->next) { FINFO *newp; - if (!make_old_version(old, nextp->no_ver_name)) continue; + if (!make_old_version(old, sizeof(old), nextp->no_ver_name)) continue; if (isslash) { if (drive) - sprintf(namebuf, "%c:\\%s", drive, old); + snprintf(namebuf, sizeof(namebuf), "%c:\\%s", drive, old); else - sprintf(namebuf, "\\%s", old); + snprintf(namebuf, sizeof(namebuf), "\\%s", old); } else - sprintf(namebuf, "%s\\%s", dir, old); + snprintf(namebuf, sizeof(namebuf), "%s\\%s", dir, old); TIMEOUT(rval = stat(namebuf, &sbuf)); if (rval == -1) continue; @@ -789,14 +994,14 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) newp->next = prevp; /* All other types than directory. */ newp->dirp = 0; - sprintf(namebuf, "%s.~00~", nextp->no_ver_name); - quote_fname(namebuf); + snprintf(namebuf, sizeof(namebuf), "%s.~00~", nextp->no_ver_name); + quote_fname(namebuf, sizeof(namebuf)); len = strlen(namebuf); - strcpy(newp->lname, namebuf); + strlcpy(newp->lname, namebuf, sizeof(newp->lname)); *(newp->lname + len) = '\0'; newp->lname_len = len; - strcpy(newp->no_ver_name, old); + strlcpy(newp->no_ver_name, old, sizeof(newp->no_ver_name)); newp->version = 0; newp->ino = sbuf.st_ino; n++; @@ -840,12 +1045,12 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) AllocFinfo(nextp); if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (-1); } nextp->next = prevp; - sprintf(namebuf, "%s/%s", dir, dp->d_name); + snprintf(namebuf, sizeof(namebuf), "%s/%s", dir, dp->d_name); TIMEOUT(rval = stat(namebuf, &sbuf)); if (rval == -1 && errno != ENOENT) { /* @@ -853,35 +1058,26 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) * link. We should ignore such error here. */ FreeFinfo(nextp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); return (-1); } - strcpy(namebuf, dp->d_name); + strlcpy(nextp->lname, dp->d_name, sizeof(nextp->lname)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(nextp->lname, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRSTR, sizeof(nextp->lname)); } else { /* All other types than directory. */ nextp->dirp = 0; - quote_fname(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + quote_fname(nextp->lname, sizeof(nextp->lname)); } + nextp->lname_len = strlen(nextp->lname); - strcpy(namebuf, dp->d_name); - len = strlen(namebuf); - separate_version(namebuf, fver, 1); - DOWNCASE(namebuf); - strcpy(nextp->no_ver_name, namebuf); + strlcpy(nextp->no_ver_name, dp->d_name, sizeof(nextp->no_ver_name)); + separate_version(nextp->no_ver_name, sizeof(nextp->no_ver_name), fver, sizeof(fver), 1); + DOWNCASE(nextp->no_ver_name); if (*fver == '\0') nextp->version = 0; else @@ -889,7 +1085,7 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) nextp->ino = sbuf.st_ino; n++; } - closedir(dirp); + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT if (n > 0) *finfo_buf = prevp; return (n); } @@ -946,11 +1142,12 @@ static int enum_ufs_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); *Lisp_errno = errno; + alarm(0); // cancel alarm from S_TOUT return (-1); } nextp->next = prevp; - sprintf(namebuf, "%s\\%s", dir, dirp.name); - TIMEOUT(rval = stat(namebuf, &sbuf)); + snprintf(namebuf, sizeof(namebuf), "%s\\%s", dir, dirp.name); + TIMEOUT(rval = stat(namebuf, &sbuf)); // cancels alarm set by S_TOUT if (rval == -1 && errno != ENOENT) { /* * ENOENT error might be caused by missing symbolic @@ -961,45 +1158,26 @@ static int enum_ufs_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) return (-1); } - strcpy(namebuf, dirp.name); + strlcpy(nextp->lname, dp->d_name, sizeof(nextp->lname)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(nextp->lname, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRSTR, sizeof(nextp->lname)); } else { /* All other types than directory. */ nextp->dirp = 0; - quote_fname_ufs(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + quote_fname_ufs(nextp->lname, sizeof(nextp->lname)); } + nextp->lname_len = strlen(nextp->lname); - strcpy(namebuf, dirp.name); - len = strlen(namebuf); nextp->ino = sbuf.st_ino; nextp->prop->length = (unsigned)sbuf.st_size; nextp->prop->wdate = (unsigned)ToLispTime(sbuf.st_mtime); nextp->prop->rdate = (unsigned)ToLispTime(sbuf.st_atime); nextp->prop->protect = (unsigned)sbuf.st_mode; - /* - TIMEOUT(pwd = getpwuid(sbuf.st_uid)); - if (pwd == (struct passwd *)NULL) { - nextp->prop->au_len = 0; - } else { - len = strlen(pwd->pw_name); - strcpy(nextp->prop->author, pwd->pw_name); - *(nextp->prop->author + len) = '\0'; - nextp->prop->au_len = len; - } - */ n++; } + alarm(0); // ensure alarm set by S_TOUT is cancelled if (n > 0) *finfo_buf = prevp; return (n); } @@ -1035,64 +1213,43 @@ static int enum_ufs_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) AllocFinfo(nextp); if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (-1); } nextp->next = prevp; - sprintf(namebuf, "%s/%s", dir, dp->d_name); - TIMEOUT(rval = stat(namebuf, &sbuf)); + snprintf(namebuf, sizeof(namebuf), "%s/%s", dir, dp->d_name); + TIMEOUT(rval = stat(namebuf, &sbuf)); // cancels alarm set by S_TOUT if (rval == -1 && errno != ENOENT) { /* * ENOENT error might be caused by missing symbolic * link. We should ignore such error here. */ FreeFinfo(nextp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); return (-1); } - strcpy(namebuf, dp->d_name); + strlcpy(nextp->lname, dp->d_name, sizeof(nextp->lname)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(nextp->lname, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRSTR, sizeof(nextp->lname)); } else { - /* All other types than directory. */ nextp->dirp = 0; - quote_fname_ufs(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + quote_fname_ufs(nextp->lname, sizeof(nextp->lname)); } + nextp->lname_len = strlen(nextp->lname); - strcpy(namebuf, dp->d_name); - len = strlen(namebuf); nextp->ino = sbuf.st_ino; nextp->prop->length = (unsigned)sbuf.st_size; nextp->prop->wdate = (unsigned)ToLispTime(sbuf.st_mtime); nextp->prop->rdate = (unsigned)ToLispTime(sbuf.st_atime); nextp->prop->protect = (unsigned)sbuf.st_mode; - /* - TIMEOUT(pwd = getpwuid(sbuf.st_uid)); - if (pwd == (struct passwd *)NULL) { - nextp->prop->au_len = 0; - } else { - len = strlen(pwd->pw_name); - strcpy(nextp->prop->author, pwd->pw_name); - *(nextp->prop->author + len) = '\0'; - nextp->prop->au_len = len; - } - */ n++; } - closedir(dirp); + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT if (n > 0) *finfo_buf = prevp; return (n); } @@ -1145,10 +1302,11 @@ static int enum_ufs(char *dir, char *name, char *ver, FINFO **finfo_buf) if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); *Lisp_errno = errno; + alarm(0); // cancel alarm from S_TOUT return (-1); } nextp->next = prevp; - sprintf(namebuf, "%s\\%s", dir, dirp.name); + snprintf(namebuf, sizeof(namebuf), "%s\\%s", dir, dirp.name); TIMEOUT(rval = stat(namebuf, &sbuf)); if (rval == -1 && errno != ENOENT) { /* @@ -1160,26 +1318,26 @@ static int enum_ufs(char *dir, char *name, char *ver, FINFO **finfo_buf) return (-1); } - strcpy(namebuf, dirp.name); + strlcpy(namebuf, dirp.name, sizeof(namebuf)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); + quote_dname(namebuf, sizeof(namebuf)); + strlcpy(nextp->lname, namebuf, sizeof(nextp->lname)); len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; + *(nextp->lname + len) = LISPDIRCHAR; *(nextp->lname + len + 1) = '\0'; nextp->lname_len = len + 1; } else { /* All other types than directory. */ nextp->dirp = 0; - quote_fname_ufs(namebuf); + quote_fname_ufs(namebuf, sizeof(namebuf)); len = strlen(namebuf); - strcpy(nextp->lname, namebuf); + strlcpy(nextp->lname, namebuf, sizeof(nextp->lname)); *(nextp->lname + len) = '\0'; nextp->lname_len = len; } - strcpy(namebuf, dirp.name); + strlcpy(namebuf, dirp.name, sizeof(namebuf)); len = strlen(namebuf); nextp->ino = sbuf.st_ino; n++; @@ -1218,49 +1376,38 @@ static int enum_ufs(char *dir, char *name, char *ver, FINFO **finfo_buf) AllocFinfo(nextp); if (nextp == (FINFO *)NULL) { FreeFinfo(prevp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (-1); } nextp->next = prevp; - sprintf(namebuf, "%s/%s", dir, dp->d_name); - TIMEOUT(rval = stat(namebuf, &sbuf)); + snprintf(namebuf, sizeof(namebuf), "%s/%s", dir, dp->d_name); + TIMEOUT(rval = stat(namebuf, &sbuf)); // cancels alarm from S_TOUT if (rval == -1 && errno != ENOENT) { /* * ENOENT error might be caused by missing symbolic * link. We should ignore such error here. */ FreeFinfo(nextp); - closedir(dirp); *Lisp_errno = errno; + TIMEOUT(closedir(dirp)); return (-1); } - strcpy(namebuf, dp->d_name); + strlcpy(nextp->lname, dp->d_name, sizeof(nextp->lname)); if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; - quote_dname(namebuf); - strcpy(nextp->lname, namebuf); - len = strlen(namebuf); - *(nextp->lname + len) = DIRCHAR; - *(nextp->lname + len + 1) = '\0'; - nextp->lname_len = len + 1; + quote_dname(nextp->lname, sizeof(nextp->lname)); + strlcat(nextp->lname, LISPDIRSTR, sizeof(nextp->lname)); } else { - /* All other types than directory. */ nextp->dirp = 0; - quote_fname_ufs(namebuf); - len = strlen(namebuf); - strcpy(nextp->lname, namebuf); - *(nextp->lname + len) = '\0'; - nextp->lname_len = len; + quote_fname_ufs(nextp->lname, sizeof(nextp->lname)); } - - strcpy(namebuf, dp->d_name); - len = strlen(namebuf); + nextp->lname_len = strlen(nextp->lname); nextp->ino = sbuf.st_ino; n++; } - closedir(dirp); + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT if (n > 0) *finfo_buf = prevp; return (n); } @@ -1336,8 +1483,8 @@ static int trim_finfo(FINFO **fp) * Versionless is not linked to any versioned * file. */ - sprintf(ver, ";%u", mp->version + 1); - strcat(sp->lname, ver); + snprintf(ver, sizeof(ver), ";%u", mp->version + 1); + strlcat(sp->lname, ver, sizeof(sp->lname)); sp->lname_len = strlen(sp->lname); pnum = ++num; pp = cp; @@ -1362,7 +1509,7 @@ static int trim_finfo(FINFO **fp) * Only versionless file exists. It is regarded as * version 1. */ - strcat(cp->lname, ";1"); + strlcat(cp->lname, ";1", sizeof(cp->lname)); cp->lname_len += 2; pp = cp; sp = cp = cp->next; @@ -1464,8 +1611,8 @@ static int trim_finfo_highest(FINFO **fp, int highestp) * Versionless is not linked to any versioned * file. */ - sprintf(ver, ";%u", mp->version + 1); - strcat(sp->lname, ver); + snprintf(ver, sizeof(ver), ";%u", mp->version + 1); + strlcat(sp->lname, ver, sizeof(sp->lname)); sp->lname_len = strlen(sp->lname); /* * Lower versioned files, mp to cp @@ -1504,7 +1651,7 @@ static int trim_finfo_highest(FINFO **fp, int highestp) * Only versionless file exists. It is regarded as * version 1. */ - strcat(cp->lname, ";1"); + strlcat(cp->lname, ";1", sizeof(cp->lname)); cp->lname_len += 2; pp = cp; sp = cp = cp->next; @@ -1646,8 +1793,8 @@ static int trim_finfo_version(FINFO **fp, unsigned rver) * file. */ if (mp->version + 1 == rver) { - sprintf(ver, ";%u", rver); - strcat(sp->lname, ver); + snprintf(ver, sizeof(ver), ";%u", rver); + strlcat(sp->lname, ver, sizeof(sp->lname)); sp->lname_len = strlen(sp->lname); /* * Lower versioned files, mp to cp @@ -1703,7 +1850,7 @@ static int trim_finfo_version(FINFO **fp, unsigned rver) FreeFinfo(sp); sp = cp; } else { - strcat(cp->lname, ";1"); + strlcat(cp->lname, ";1", sizeof(cp->lname)); cp->lname_len += 2; pp = cp; sp = cp = cp->next; @@ -2034,9 +2181,9 @@ LispPTR COM_gen_files(LispPTR *args) */ #ifdef DOS - if (!unixpathname(fbuf, pattern, 1, 1, drive, 0, 0)) { + if (!unixpathname(fbuf, pattern, sizeof(pattern), 1, 1, drive, 0, 0)) { #else - if (!unixpathname(fbuf, pattern, 1, 1)) { + if (!unixpathname(fbuf, pattern, sizeof(pattern), 1, 1)) { #endif /* DOS */ /* Yes, always dskp is on */ return (SMALLP_MINUSONE); @@ -2049,12 +2196,12 @@ LispPTR COM_gen_files(LispPTR *args) * On {DSK}, we have to make sure dir is case insensitively existing * directory. */ - if (true_name(dir) != -1) return (SMALLP_MINUSONE); + if (true_name(dir, sizeof(dir)) != -1) return (SMALLP_MINUSONE); if (*ver != '\0') { highestp = 0; version = strtoul(ver, (char **)NULL, 10); - if (version > 0) strcpy(ver, "*"); + if (version > 0) strlcpy(ver, "*", sizeof(ver)); } else { version = 0; for (cp = fbuf; *cp; cp++) {} @@ -2065,7 +2212,7 @@ LispPTR COM_gen_files(LispPTR *args) * all version. trim_finfo_highest will get rid of * lower versions. */ - strcpy(ver, "*"); + strlcpy(ver, "*", sizeof(ver)); highestp = 1; } else { highestp = 0; @@ -2077,7 +2224,7 @@ LispPTR COM_gen_files(LispPTR *args) count = enum_dsk(dir, name, ver, &fp); } else { /* Makes UNIX device matches any version. */ - strcpy(ver, "*"); + strlcpy(ver, "*", sizeof(ver)); if (propp) count = enum_ufs_prop(dir, name, ver, &fp); diff --git a/src/dsk.c b/src/dsk.c index a96a0f43..84ed2b20 100644 --- a/src/dsk.c +++ b/src/dsk.c @@ -9,12 +9,13 @@ #include "version.h" +#include // for isdigit #include // for errno, EINTR, ENOENT, ENFILE, EPERM #include // for O_RDWR, O_CREAT, open, O_RDONLY, O_TRUNC -#include // for NULL, sprintf, size_t, rename, SEEK_SET +#include // for NULL, snprintf, size_t, rename, SEEK_SET #include // for ptrdiff_t #include // for strtoul, qsort -#include // for strcpy, strcmp, strlen, strncpy, strchr +#include // for strlcpy, strcmp, strlen, strncpy, strchr #include // for stat, fstat, mkdir, S_ISREG, st_atime, chmod #include // for ino_t, time_t, off_t #include // for unlink, close, link, lseek, access, chdir @@ -27,7 +28,7 @@ #include "car-cdrdefs.h" // for cdr, car #include "dskdefs.h" // for COM_changedir, COM_closefile, COM_getfile... #include "lispemul.h" // for NIL, LispPTR, ATOM_T -#include "locfile.h" // for ConcDirAndName, LASTVERSIONARRAY, ConcNam... +#include "locfile.h" // for LASTVERSIONARRAY #include "lspglob.h" #include "lsptypes.h" #include "timeout.h" // for TIMEOUT, ERRSETJMP, S_TOUT, TIMEOUT0 @@ -73,8 +74,8 @@ static struct { FileName *files; /* array of files */ } VA = {0}; -static int locate_file(char *dir, char *name); -static int make_directory(char *dir); +static int locate_file(char *dir, size_t dirsize, char *name); +static int make_directory(char *dir, size_t dirsize); static int maintain_version(char *file, int forcep); static int compare_file_versions(const void *a, const void *b); static int get_versionless(FileName *varray, char *file, char *dir); @@ -84,7 +85,6 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile); static int get_new(char *dir, FileName *varray, char *afile, char *vfile); static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile); static int get_version_array(char *dir, char *file); - #ifdef DOS static void separate_drive(char *lfname, char *drive) { @@ -206,7 +206,7 @@ void separate_host(char *lfname, char *host) * args[5] The place where the error number should be * stored. * - * Value: If succeed, returns the Lisp smallp which represents the open + * Value: If succeeds, returns the Lisp smallp which represents the open * file descriptor, otherwise Lisp NIL. * * Side Effect: If succeed, cdate(args[3]) and size(args[4]) will hold the @@ -265,9 +265,9 @@ LispPTR COM_openfile(LispPTR *args) * convert a version field. */ #ifdef DOS - unixpathname(lfname, file, dskp, 0, drive, &extlen, rawname); + unixpathname(lfname, file, sizeof(file), dskp, 0, drive, &extlen, rawname); #else - unixpathname(lfname, file, dskp, 0); + unixpathname(lfname, file, sizeof(file), dskp, 0); #endif /* @@ -332,21 +332,21 @@ LispPTR COM_openfile(LispPTR *args) case ACCESS_OUTPUT: flags = O_RDWR | O_TRUNC | O_CREAT; unpack_filename(file, dir, name, ver, 1); - if (make_directory(dir) == 0) return (NIL); + if (make_directory(dir, sizeof(dir)) == 0) return (NIL); if (dskp) link_check_flg = 1; break; case ACCESS_BOTH: flags = O_RDWR | O_CREAT; unpack_filename(file, dir, name, ver, 1); - if (make_directory(dir) == 0) return (NIL); + if (make_directory(dir, sizeof(dir)) == 0) return (NIL); if (dskp) link_check_flg = 1; break; case ACCESS_APPEND: flags = O_RDWR | O_CREAT; unpack_filename(file, dir, name, ver, 1); - if (make_directory(dir) == 0) return (NIL); + if (make_directory(dir, sizeof(dir)) == 0) return (NIL); if (dskp) link_check_flg = 1; break; } @@ -374,9 +374,9 @@ LispPTR COM_openfile(LispPTR *args) if (dskp) { if (unpack_filename(file, dir, name, ver, 1) == 0) return (NIL); - if (true_name(dir) != -1) return (0); + if (true_name(dir, sizeof(dir)) != -1) return (0); if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, file); + conc_name_and_version(name, ver, file, sizeof(file)); switch (args[1]) { case RECOG_OLD: @@ -467,7 +467,7 @@ LispPTR COM_openfile(LispPTR *args) #ifdef DOS if (args[1] == RECOG_NEW) { char old[MAXPATHLEN]; - make_old_version(old, file); + make_old_version(old, sizeof(old), file); unlink(old); rename(file, old); /* make old version */ } @@ -599,8 +599,7 @@ LispPTR COM_closefile(LispPTR *args) * Convert a Lisp file name to UNIX one. If host is DSK, we also have to * convert a version field. */ - dskp ? unixpathname(lfname, file, 1, 0, drive, &extlen, rawname) - : unixpathname(lfname, file, 0, 0, drive, &extlen, rawname); + unixpathname(lfname, file, sizeof(file), dskp, drive, &extlen, rawname); fd = LispNumToCInt(args[1]); cdate = (time_t)LispNumToCInt(args[2]); if (!dskp) { @@ -639,7 +638,7 @@ LispPTR COM_closefile(LispPTR *args) * On {DSK}, we have to make sure dir is case sensitively existing * directory. */ - if (true_name(dir) != -1) return (NIL); + if (true_name(dir, sizeof(dir)) != -1) return (NIL); /* * There is a very troublesome problem here. The file name Lisp @@ -664,7 +663,7 @@ LispPTR COM_closefile(LispPTR *args) } for (; rval == 0; S_TOUT(rval = _dos_findnext(&dirp))) { - sprintf(file, "%s\\%s", dir, dirp.name); + snprintf(file, sizeof(file), "%s\\%s", dir, dirp.name); } } #ifndef DOS /* effectively NEVER, since we're in an ifdef DOS */ @@ -673,7 +672,7 @@ LispPTR COM_closefile(LispPTR *args) time[1].tv_sec = (long)ToUnixTime(cdate); time[1].tv_usec = 0L; #endif /* DOS */ - TIMEOUT(rval = close(fd)); + TIMEOUT(rval = close(fd)); // cancels alarm from S_TOUT if (rval == -1) { *Lisp_errno = errno; return (NIL); @@ -722,8 +721,7 @@ LispPTR COM_closefile(LispPTR *args) * Convert a Lisp file name to UNIX one. If host is DSK, we also have to * convert a version field. */ - dskp ? unixpathname(lfname, file, 1, 0) : unixpathname(lfname, file, 0, 0); - + unixpathname(lfname, file, sizeof(file), dskp, 0); fd = LispNumToCInt(args[1]); cdate = (time_t)LispNumToCInt(args[2]); @@ -850,9 +848,9 @@ LispPTR DSK_getfilename(LispPTR *args) * unixpathname specifies it. */ #ifdef DOS - if (unixpathname(lfname, file, 1, 0, drive, &extlen, rawname) == 0) return (NIL); + if (unixpathname(lfname, file, sizeof(file), 1, 0, drive, &extlen, rawname) == 0) return (NIL); #else - if (unixpathname(lfname, file, 1, 0) == 0) return (NIL); + if (unixpathname(lfname, file, sizeof(file), 1, 0) == 0) return (NIL); #endif if (unpack_filename(file, dir, name, ver, 1) == 0) return (NIL); @@ -865,7 +863,7 @@ LispPTR DSK_getfilename(LispPTR *args) * be done in case insensitive manner. true_name does this work. */ - if (true_name(dir) != -1) { + if (true_name(dir, sizeof(dir)) != -1) { /* No such directory. */ return (NIL); } @@ -878,8 +876,8 @@ LispPTR DSK_getfilename(LispPTR *args) * The file name is specified with a trail directory delimiter. * We should recognize it as a directory. */ - strcpy(aname, dir); - strcpy(vname, dir); + strlcpy(aname, dir, sizeof(aname)); + strlcpy(vname, dir, sizeof(vname)); dirp = 1; } else { /* @@ -888,19 +886,19 @@ LispPTR DSK_getfilename(LispPTR *args) */ if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, aname); + conc_name_and_version(name, ver, aname, sizeof(aname)); if (get_old(dir, VA.files, aname, vname) == 0) return (NIL); - if ((rval = true_name(aname)) == 0) return (NIL); + if ((rval = true_name(aname, sizeof(aname))) == 0) return (NIL); if (rval == -1) { /* * The specified file is a directory file. */ - strcpy(vname, aname); + strlcpy(vname, aname, sizeof(vname)); dirp = 1; } else { #ifdef DOS - strcpy(vname, aname); + strlcpy(vname, aname, sizeof(vname)); #endif dirp = 0; } @@ -913,7 +911,7 @@ LispPTR DSK_getfilename(LispPTR *args) * "Oldest" file means the "oldest existing" file. Thus, we have to * check dir is an existing directory or not. */ - if (true_name(dir) != -1) { + if (true_name(dir, sizeof(dir)) != -1) { /* No such directory. */ return (NIL); } @@ -922,25 +920,25 @@ LispPTR DSK_getfilename(LispPTR *args) * The file name is specified with a trail directory delimiter. * We should recognize it as a directory. */ - strcpy(aname, dir); - strcpy(vname, dir); + strlcpy(aname, dir, sizeof(aname)); + strlcpy(vname, dir, sizeof(vname)); dirp = 1; } else { if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, aname); + conc_name_and_version(name, ver, aname, sizeof(aname)); if (get_oldest(dir, VA.files, aname, vname) == 0) return (NIL); - if ((rval = true_name(aname)) == 0) return (NIL); + if ((rval = true_name(aname, sizeof(aname))) == 0) return (NIL); if (rval == -1) { /* * The specified file is a directory file. */ - strcpy(vname, aname); + strlcpy(vname, aname, sizeof(vname)); dirp = 1; } else { #ifdef DOS - strcpy(vname, aname); + strlcpy(vname, aname, sizeof(vname)); #endif dirp = 0; } @@ -952,23 +950,23 @@ LispPTR DSK_getfilename(LispPTR *args) * "New" file means the "not existing" file. Thus it is not * necessary that dir is an existing directory. If dir is not * an existing directory, we returns the specified file name - * as if, the subsequent OPENFILE will find the truth. + * as is, the subsequent OPENFILE will find the truth. */ - if (true_name(dir) != -1) { - strcpy(vname, file); + if (true_name(dir, sizeof(dir)) != -1) { + strlcpy(vname, file, sizeof(vname)); dirp = 0; } else if (strcmp(name, "") == 0) { /* * The file name is specified with a trail directory delimiter. * We should recognize it as a directory. */ - strcpy(aname, dir); - strcpy(vname, dir); + strlcpy(aname, dir, sizeof(aname)); + strlcpy(vname, dir, sizeof(vname)); dirp = 1; } else { - ConcDirAndName(dir, name, aname); - if ((rval = true_name(aname)) == -1) { - strcpy(vname, aname); + conc_dir_and_name(dir, name, aname, sizeof(aname)); + if ((rval = true_name(aname, sizeof(aname))) == -1) { + strlcpy(vname, aname, sizeof(vname)); dirp = 1; } else { /* @@ -977,7 +975,7 @@ LispPTR DSK_getfilename(LispPTR *args) */ if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, aname); + conc_name_and_version(name, ver, aname, sizeof(aname)); if (get_new(dir, VA.files, aname, vname) == 0) return (NIL); dirp = 0; } @@ -992,18 +990,18 @@ LispPTR DSK_getfilename(LispPTR *args) * try "old" recognition on the directory first. If the recognition * fails, we try "new" recognition. */ - if (true_name(dir) != -1) { - strcpy(vname, file); + if (true_name(dir, sizeof(dir)) != -1) { + strlcpy(vname, file, sizeof(vname)); dirp = 0; } else { - ConcDirAndName(dir, name, aname); - if ((rval = true_name(aname)) == -1) { - strcpy(vname, aname); + conc_dir_and_name(dir, name, aname, sizeof(aname)); + if ((rval = true_name(aname, sizeof(aname))) == -1) { + strlcpy(vname, aname, sizeof(vname)); dirp = 1; } else { if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, aname); + conc_name_and_version(name, ver, aname, sizeof(aname)); if (get_old_new(dir, VA.files, aname, vname) == 0) return (NIL); dirp = 0; } @@ -1016,18 +1014,18 @@ LispPTR DSK_getfilename(LispPTR *args) * file is dealt with specially, it does not have any version, even * if it is on {DSK} device. Only we have to do here is to make * sure the path to reach to the specified file is an existing - * directories. The file name itself is recognized as if. + * directories. The file name itself is recognized as is. */ - if (true_name(dir) != -1) return (NIL); - ConcDirAndName(dir, name, vname); - strcpy(aname, vname); - if (true_name(aname) == -1) { - strcpy(vname, aname); + if (true_name(dir, sizeof(dir)) != -1) return (NIL); + conc_dir_and_name(dir, name, vname, sizeof(vname)); + strlcpy(aname, vname, sizeof(aname)); + if (true_name(aname, sizeof(aname)) == -1) { + strlcpy(vname, aname, sizeof(vname)); dirp = 1; } else { dirp = 0; } - if (lisppathname(vname, lfname, dirp, 0) == 0) return (NIL); + if (lisppathname(vname, lfname, sizeof(lfname), dirp, 0) == 0) return (NIL); STRING_BASE(args[2], base); len = strlen(lfname); @@ -1049,20 +1047,20 @@ LispPTR DSK_getfilename(LispPTR *args) /* * Now, vname holds the "versioned" full name of the recognized file in UNIX * format. We have to convert it back to Lisp format. The version field - * have to be converted. The fourth argument for lisppathname specifies it. + * have to be converted. The fifth argument for lisppathname specifies it. */ #ifdef DOS /* For DOS, have to assure we use the name asked for, not the */ /* faked-up oversion-0 name, so reported names match. */ { char dver[VERSIONLEN]; - separate_version(vname, dver, 0); - ConcDirAndName(dir, name, aname); - ConcNameAndVersion(aname, dver, vname); + separate_version(vname, sizeof(vname), dver, sizeof(dver), 0); + conc_dir_and_name(dir, name, aname, sizeof(aname)); + conc_name_and_version(aname, dver, vname, sizeof(vname)); } #endif /* DOS */ - if (lisppathname(vname, lfname, dirp, (dirp ? 0 : 1)) == 0) return (NIL); + if (lisppathname(vname, lfname, sizeof(lfname), dirp, (dirp ? 0 : 1)) == 0) return (NIL); STRING_BASE(args[2], base); len = strlen(lfname); @@ -1121,9 +1119,9 @@ LispPTR DSK_deletefile(LispPTR *args) LispStringToCString(args[0], fbuf, MAXPATHLEN); #ifdef DOS separate_drive(fbuf, drive); - unixpathname(fbuf, file, 1, 0, drive, &extlen, rawname); + unixpathname(fbuf, file, sizeof(file), 1, 0, drive, &extlen, rawname); #else - unixpathname(fbuf, file, 1, 0); + unixpathname(fbuf, file, sizeof(file), 1, 0); #endif if (unpack_filename(file, dir, fbuf, ver, 1) == 0) return (NIL); @@ -1143,7 +1141,7 @@ LispPTR DSK_deletefile(LispPTR *args) * of it. */ - ConcNameAndVersion(fbuf, ver, file); + conc_name_and_version(fbuf, ver, file, sizeof(file)); if (get_oldest(dir, VA.files, file, fbuf) == 0) return (NIL); if (get_versionless(VA.files, vless, dir) == 0) { @@ -1272,17 +1270,17 @@ LispPTR DSK_renamefile(LispPTR *args) LispStringToCString(args[0], fbuf, MAXPATHLEN); #ifdef DOS separate_drive(fbuf, drive1); - unixpathname(fbuf, src, 1, 0, drive1, &extlen1, rawname1); + unixpathname(fbuf, src, sizeof(src), 1, 0, drive1, &extlen1, rawname1); #else /* DOS */ - unixpathname(fbuf, src, 1, 0); + unixpathname(fbuf, src, sizeof(src), 1, 0); #endif /* DOS */ LispStringToCString(args[1], fbuf, MAXPATHLEN); #ifdef DOS separate_drive(fbuf, drive2); - unixpathname(fbuf, dst, 1, 0, drive2, &extlen2, rawname2); + unixpathname(fbuf, dst, sizeof(dst), 1, 0, drive2, &extlen2, rawname2); #else /* DOS */ - unixpathname(fbuf, dst, 1, 0); + unixpathname(fbuf, dst, sizeof(dst), 1, 0); #endif /* DOS */ if (unpack_filename(dst, dir, fbuf, ver, 1) == 0) return (NIL); @@ -1290,12 +1288,12 @@ LispPTR DSK_renamefile(LispPTR *args) * The destination file has been recognized as new file. Thus we have * to make sure that the directory exists. */ - if (make_directory(dir) == 0) return (NIL); + if (make_directory(dir, sizeof(dir)) == 0) return (NIL); /* * We maintain the destination to handle the link damaged case correctly. */ - ConcDirAndName(dir, fbuf, dst); + conc_dir_and_name(dir, fbuf, dst, sizeof(dst)); if (maintain_version(dst, 0) == 0) return (NIL); if (get_version_array(dir, fbuf) == 0) return (NIL); @@ -1306,7 +1304,7 @@ LispPTR DSK_renamefile(LispPTR *args) * of it. */ - ConcNameAndVersion(fbuf, ver, dst); + conc_name_and_version(fbuf, ver, dst, sizeof(dst)); if (get_new(dir, VA.files, dst, fbuf) == 0) return (NIL); /* @@ -1321,7 +1319,7 @@ LispPTR DSK_renamefile(LispPTR *args) if (OnlyVersionlessP(VA.files)) { get_versionless(VA.files, vless, dir); if (strcmp(dst, vless) != 0) { - ConcNameAndVersion(vless, "1", fbuf); + conc_name_and_version(vless, "1", fbuf, sizeof(fbuf)); TIMEOUT(rval = rename(vless, fbuf)); if (rval == -1) { *Lisp_errno = errno; @@ -1361,7 +1359,7 @@ LispPTR DSK_renamefile(LispPTR *args) * code, we have to recognize it again to know the "real" accessible name * of it. */ - ConcNameAndVersion(fbuf, ver, src); + conc_name_and_version(fbuf, ver, src, sizeof(src)); if (get_old(dir, VA.files, src, fbuf) == 0) return (NIL); if (get_versionless(VA.files, vless, dir) == 0) { @@ -1401,7 +1399,7 @@ LispPTR DSK_renamefile(LispPTR *args) } else { need_maintain_flg = 0; } - strcpy(svless, vless); + strlcpy(svless, vless, sizeof(svless)); } /* @@ -1489,19 +1487,18 @@ LispPTR DSK_directorynamep(LispPTR *args) if (len > MAXPATHLEN - 2) FileNameTooLong(NIL); LispStringToCString(args[0], dirname, MAXPATHLEN); - /* Convert Xerox Lisp file naming convention to Unix one. */ #ifdef DOS separate_drive(dirname, drive); - if (unixpathname(dirname, fullname, 1, 0, drive, 0, 0) == 0) return (NIL); + if (unixpathname(dirname, fullname, sizeof(fullname), 1, 0, drive, 0, 0) == 0) return (NIL); #else /* DOS*/ - if (unixpathname(dirname, fullname, 1, 0) == 0) return (NIL); + if (unixpathname(dirname, fullname, sizeof(fullname), 1, 0) == 0) return (NIL); #endif /* DOS */ - if (true_name(fullname) != -1) return (NIL); + if (true_name(fullname, sizeof(fullname)) != -1) return (NIL); /* Convert Unix file naming convention to Xerox Lisp one. */ - if (lisppathname(fullname, dirname, 1, 0) == 0) return (NIL); + if (lisppathname(fullname, dirname, sizeof(dirname), 1, 0) == 0) return (NIL); len = strlen(dirname); STRING_BASE(args[1], base); @@ -1600,9 +1597,9 @@ LispPTR COM_getfileinfo(LispPTR *args) * convert a version field. */ #ifdef DOS - unixpathname(lfname, file, dskp, 0, drive, &extlen, rawname); + unixpathname(lfname, file, sizeof(file), dskp, 0, drive, &extlen, rawname); #else /* DOS */ - unixpathname(lfname, file, dskp, 0); + unixpathname(lfname, file, sizeof(file), dskp, 0); #endif /* DOS */ /* @@ -1615,15 +1612,15 @@ LispPTR COM_getfileinfo(LispPTR *args) */ if (dskp) { if (unpack_filename(file, dir, name, ver, 1) == 0) return (NIL); - if (true_name(dir) != -1) return (0); + if (true_name(dir, sizeof(dir)) != -1) return (0); if (strcmp(name, "") == 0) { /* * The directory is specified. */ - strcpy(file, dir); + strlcpy(file, dir, sizeof(file)); } else { if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, file); + conc_name_and_version(name, ver, file, sizeof(file)); if (get_old(dir, VA.files, file, name) == 0) return (NIL); } } @@ -1795,9 +1792,9 @@ LispPTR COM_setfileinfo(LispPTR *args) * convert a version field. */ #ifdef DOS - unixpathname(lfname, file, dskp, 0, drive, &extlen, rawname); + unixpathname(lfname, file, sizeof(file), dskp, 0, drive, &extlen, rawname); #else /* DOS */ - unixpathname(lfname, file, dskp, 0); + unixpathname(lfname, file, sizeof(file), dskp, 0); #endif /* DOS */ /* @@ -1810,9 +1807,9 @@ LispPTR COM_setfileinfo(LispPTR *args) */ if (dskp) { if (unpack_filename(file, dir, name, ver, 1) == 0) return (NIL); - if (true_name(dir) != -1) return (0); + if (true_name(dir, sizeof(dir)) != -1) return (0); if (get_version_array(dir, name) == 0) return (NIL); - ConcNameAndVersion(name, ver, file); + conc_name_and_version(name, ver, file, sizeof(file)); if (get_old(dir, VA.files, file, name) == 0) return (NIL); } @@ -2142,9 +2139,9 @@ LispPTR COM_changedir(LispPTR *args) return (NIL); #ifdef DOS - if (!unixpathname(lfname, dir, 0, 0, drive, 0, 0)) return (NIL); + if (!unixpathname(lfname, dir, sizeof(dir), 0, 0, drive, 0, 0)) return (NIL); #else /* DOS */ - if (!unixpathname(lfname, dir, 0, 0)) return (NIL); + if (!unixpathname(lfname, dir, sizeof(dir), 0, 0)) return (NIL); #endif /* DOS */ if (dskp) { @@ -2152,7 +2149,7 @@ LispPTR COM_changedir(LispPTR *args) * If {DSK} device, the directory name can be specified in a case * insensitive manner. We have to convert it into a right case. */ - if (true_name(dir) != -1) return (NIL); + if (true_name(dir, sizeof(dir)) != -1) return (NIL); } TIMEOUT(rval = chdir(dir)); @@ -2242,9 +2239,9 @@ LispPTR COM_getfreeblock(LispPTR *args) return (NIL); #ifdef DOS - if (!unixpathname(lfname, file, 0, 0, drive, 0, 0)) return (NIL); + if (!unixpathname(lfname, file, sizeof(file), 0, 0, drive, 0, 0)) return (NIL); #else /* DOS */ - if (!unixpathname(lfname, file, 0, 0)) return (NIL); + if (!unixpathname(lfname, file, sizeof(file), 0, 0)) return (NIL); #endif /* DOS */ if (!unpack_filename(file, dir, name, ver, 0)) return (NIL); @@ -2254,7 +2251,7 @@ LispPTR COM_getfreeblock(LispPTR *args) * Although Lisp code guarantees the directory is an existing one, * by calling DSK_getfilename, we check it again for safety. */ - if (true_name(dir) != -1) return (NIL); + if (true_name(dir, sizeof(dir)) != -1) return (NIL); } /* @@ -2292,7 +2289,6 @@ LispPTR COM_getfreeblock(LispPTR *args) /******************************************** Subroutines ********************************************/ - /* * Name: separate_version * @@ -2300,7 +2296,9 @@ LispPTR COM_getfreeblock(LispPTR *args) * "root file name" (i.e. without directory) as * name argument, but full file name is also * acceptable. + * size_t namesize sizeof the name storage * char *ver The place where extracted version will be stored. + * size_t versize sizeof the ver storage * init checkp If 1, whether the version field contains only * numbers or not is checked. If 0, anything in the * version field is stored in ver. If GENERATEFILE @@ -2322,61 +2320,29 @@ LispPTR COM_getfreeblock(LispPTR *args) * regarded valid. * */ - -void separate_version(char *name, char *ver, int checkp) -{ - char *start, *end, *cp; - unsigned ver_no; +void separate_version(char *name, size_t namesize, char *ver, size_t versize, int checkp) { + char *ep = &name[strlen(name) - 1]; + char *lp = ep; size_t len; - char ver_buf[VERSIONLEN]; - if ((end = (char *)strchr(name, '~')) != (char *)NULL) { - start = end; - cp = end + 1; - while (*cp) { - if (*cp == '~') { - start = end; - end = cp; - } - cp++; - } - - if (start != end && *(start - 1) == '.' && end == (cp - 1)) { - /* - * name ends in the form ".~###~". But we have to check - * ### are all numbers or not, if checkp is 1. - */ - len = (end - start) - 1; - strncpy(ver_buf, start + 1, len); - ver_buf[len] = '\0'; - if (checkp) { - NumericStringP(ver_buf, YES, NO); - YES: - /* - * name contains a valid version field. - */ - *(start - 1) = '\0'; - *end = '\0'; - /* - * Use strtoul() to eliminate leading 0s. - */ - ver_no = strtoul(start + 1, (char **)NULL, 10); - sprintf(ver_buf, "%u", ver_no); - strcpy(ver, ver_buf); - return; - } else { - *(start - 1) = '\0'; - strcpy(ver, ver_buf); - return; - } - } - } else if (strchr(name, '%')) { - strcpy(ver, "0"); + *ver = '\0'; /* set up in case of failure */ + if (*ep == '%') { /* original code did this, is it necessary? */ + strlcpy(ver, "0", versize); /* a backup file is version 0 - DOS? */ return; } -NO: - /* name does not contain a valid version field. */ - *ver = '\0'; + if (*ep-- != '~') return; /* not a well-formed Unix-style version */ + if (checkp) { /* all numeric version required */ + while(isdigit(*ep) && (ep > (name + 1))) ep--; /* walk back, but not too far */ + } else { + while(*ep != '~' && (ep > (name + 1))) ep--; /* walk back, but not too far */ + } + /* is it a well-formed version, "name.~nnn~" */ + if ((ep == name) || (*ep != '~') || (*(ep - 1) != '.')) return; + len = lp - (ep + 1); /* how long is the found version */ + if (len >= versize) return; /* give up if it won't fit */ + memcpy(ver, ep + 1, len); /* copy it back */ + ver[len] = '\0'; /* and terminate the string */ + *(ep - 1) = '\0'; /* and truncate the original name at the "." */ } /* @@ -2430,8 +2396,8 @@ int unpack_filename(char *file, char *dir, char *name, char *ver, int checkp) *dir = '\0'; } - strcpy(name, cp + 1); - separate_version(name, ver, checkp); + strlcpy(name, cp + 1, MAXNAMLEN); + separate_version(name, MAXNAMLEN, ver, VERSIONLEN, checkp); return (1); } @@ -2444,6 +2410,8 @@ int unpack_filename(char *file, char *dir, char *name, char *ver, int checkp) * in path or not is not a matter. true_name handles * both case correctly. * + * size_t pathsize The amount of storage allocated for path + * * Value: If the pathname is recognized as an existing directory, returns * -1, recognized as an existing file, returns 1, otherwise 0. * @@ -2456,7 +2424,7 @@ int unpack_filename(char *file, char *dir, char *name, char *ver, int checkp) * */ -int true_name(char *path) +int true_name(char *path, size_t pathsize) { char dir[MAXPATHLEN]; char name[MAXNAMLEN]; @@ -2508,7 +2476,7 @@ int true_name(char *path) } /* Try to locate name on dir*/ - if ((type = locate_file(dir, name)) == 0) { + if ((type = locate_file(dir, sizeof(dir), name)) == 0) { /* * No directory or file named name has been found on * dir. @@ -2520,16 +2488,104 @@ int true_name(char *path) * to dir by locate_file. */ } - strcpy(path, dir); + strlcpy(path, dir, pathsize); return (type); } +/* + * Name: conc_dir_and_name + * + * Argument: char *dir The name of the directory. + * char *name The name of a file. + * char *fname The place where the full file name should be + * stored. + * Value: N/A + * + * Side Effect: fname is replaced with the full file name. + * + * Description: + * + * Concatenate the directory name and root file name. Checks if dir contains + * the trail directory delimiter or not. + * + */ + +void conc_dir_and_name(char *dir, char *name, char *fname, size_t fname_size) +{ + char *lf_cp1, *lf_cp2; + + lf_cp1 = dir; + lf_cp2 = dir; + + while (*lf_cp2 != '\0') { + switch (*lf_cp2) { + + case '/': + lf_cp1 = lf_cp2; + lf_cp2++; + break; + + default: + lf_cp2++; + break; + } + } + if (lf_cp1 == (lf_cp2 - 1)) { + if (lf_cp1 == (dir)) { + /* dir is a root directory. */ + strlcpy(fname, "/", fname_size); + strlcat(fname, name, fname_size); + } else { + /* The trail directory is included. */ + strlcpy(fname, dir, fname_size); + strlcat(fname, name, fname_size); + } + } else { + /* The trail directory is not included */ + strlcpy(fname, dir, fname_size); + strlcat(fname, "/", fname_size); + strlcat(fname, name, fname_size); + } +} + +/* + * Name: conc_name_and_version + * + * Argument: char *name The root file name. + * char *ver The file version. + * char *rname The place where the concatenated file name will be + * stored. + * size_t rname_size The size of the storage allocated for rname + * Value: N/A + * + * Side Effect: rname is replaced with the concatenated file name. + * + * Description: + * + * Concatenate the root file name and its version in UNIX format. + * + */ + +void conc_name_and_version(char *name, char *ver, char *rname, size_t rname_size) +{ + if (*ver != '\0') { + strlcpy(rname, name, rname_size); + strlcat(rname, ".~", rname_size); + strlcat(rname, ver, rname_size); + strlcat(rname, "~", rname_size); + } else { + strlcpy(rname, name, rname_size); + } +} + /* * Name: locate_file * * Argument: char *dir The existing directory name. Does not include * the trail delimiter. * + * size_t dirsize The number of bytes allocated for dir + * * char *name The name which is searched on dir. * * Value: If name is recognized as an existing directory, returns -1, @@ -2545,7 +2601,7 @@ int true_name(char *path) * */ -static int locate_file(char *dir, char *name) +static int locate_file(char *dir, size_t dirsize, char *name) { #ifdef DOS char path[MAXPATHLEN]; @@ -2554,11 +2610,11 @@ static int locate_file(char *dir, char *name) struct find_t dirp; struct direct *dp; - /* First of all, recognize as if. */ - sprintf(path, "%s\\%s", dir, name); + /* First of all, recognize as is. */ + snprintf(path, sizeof(path), "%s\\%s", dir, name); DIR_OR_FILE_P(path, type); if (type != 0) { - strcpy(dir, path); + strlcpy(dir, path, dirsize); return (type); } @@ -2573,30 +2629,30 @@ static int locate_file(char *dir, char *name) DIR *dirp; struct dirent *dp; - /* First of all, recognize as if. */ - sprintf(path, "%s/%s", dir, name); + /* First of all, recognize as is. */ + snprintf(path, sizeof(path), "%s/%s", dir, name); DIR_OR_FILE_P(path, type); if (type != 0) { - strcpy(dir, path); + strlcpy(dir, path, dirsize); return (type); } /* Next try with all lower case name. */ - strcpy(nb1, name); + strlcpy(nb1, name, sizeof(nb1)); DOWNCASE(nb1); - sprintf(path, "%s/%s", dir, nb1); + snprintf(path, sizeof(path), "%s/%s", dir, nb1); DIR_OR_FILE_P(path, type); if (type != 0) { - strcpy(dir, path); + strlcpy(dir, path, dirsize); return (type); } /* Next try with all upper case name. */ UPCASE(nb1); - sprintf(path, "%s/%s", dir, nb1); + snprintf(path, sizeof(path), "%s/%s", dir, nb1); DIR_OR_FILE_P(path, type); if (type != 0) { - strcpy(dir, path); + strlcpy(dir, path, dirsize); return (type); } @@ -2612,20 +2668,20 @@ static int locate_file(char *dir, char *name) errno = 0, S_TOUT(dp = readdir(dirp))) if (dp) { if (strlen(dp->d_name) == len) { - strcpy(nb2, dp->d_name); + strlcpy(nb2, dp->d_name, sizeof(nb2)); UPCASE(nb2); if (strcmp(nb1, nb2) == 0) { - sprintf(path, "%s/%s", dir, dp->d_name); + snprintf(path, sizeof(path), "%s/%s", dir, dp->d_name); DIR_OR_FILE_P(path, type); if (type != 0) { - strcpy(dir, path); - TIMEOUT(closedir(dirp)); + strlcpy(dir, path, dirsize); + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (type); } } } } - TIMEOUT(closedir(dirp)); + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (0); #endif /* DOS */ } @@ -2647,7 +2703,7 @@ static int locate_file(char *dir, char *name) * */ -static int make_directory(char *dir) +static int make_directory(char *dir, size_t dirsize) { char *cp, *dp; int maked, rval; @@ -2695,17 +2751,17 @@ static int make_directory(char *dir) return (0); } if (*cp == '\0') { - strcpy(dir, dir_buf); + strlcpy(dir, dir_buf, dirsize); return (1); } *dp++ = DIRSEP; cp++; } else { - switch (true_name(dir_buf)) { + switch (true_name(dir_buf, sizeof(dir_buf))) { case -1: /* Directory */ if (*cp == '\0') { /* Every subdirectories are examined. */ - strcpy(dir, dir_buf); + strlcpy(dir, dir_buf, dirsize); return (1); } else { dp = dir_buf; @@ -2933,7 +2989,7 @@ static int get_version_array(char *dir, char *file) isslash = 1; if (!isslash) - strcpy(lcased_file, dir); /* Only add the dir if it's real */ + strlcpy(lcased_file, dir, sizeof(lcased_file)); /* Only add the dir if it's real */ else if (drive) { lcased_file[0] = drive; lcased_file[1] = DRIVESEP; @@ -2941,10 +2997,10 @@ static int get_version_array(char *dir, char *file) } else *lcased_file = '\0'; - /* strcpy(lcased_file, dir); removed when above code added 3/4/93 */ - strcat(lcased_file, DIRSEPSTR); - strcat(lcased_file, file); - separate_version(lcased_file, ver, 1); + /* strlcpy(lcased_file, dir, sizeof(lcased_file)); removed when above code added 3/4/93 */ + strlcat(lcased_file, DIRSEPSTR, sizeof(lcased_file)); + strlcat(lcased_file, file, sizeof(lcased_file)); + separate_version(lcased_file, sizeof(lcased_file), ver, sizeof(ver), 1); DOWNCASE(lcased_file); /*************************************************/ @@ -2953,12 +3009,12 @@ static int get_version_array(char *dir, char *file) /* First, make the "backup-file-name" for this file */ - make_old_version(old_file, lcased_file); + make_old_version(old_file, sizeof(old_file), lcased_file); TIMEOUT(res = _dos_findfirst(old_file, _A_NORMAL | _A_SUBDIR, &dirp)); if (res == 0) { - strcpy(name, dirp.name); - strcpy(VA.files[varray_index].name, name); + strlcpy(name, dirp.name, sizeof(name)); + strlcpy(VA.files[varray_index].name, name, sizeof(VA.files[0].name)); VA.files[varray_index].version_no = 0; varray_index++; } @@ -2975,11 +3031,11 @@ static int get_version_array(char *dir, char *file) } */ for (; res == 0; S_TOUT(res = _dos_findnext(&dirp))) { - strcpy(name, dirp.name); - separate_version(name, ver, 1); + strlcpy(name, dirp.name, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); DOWNCASE(name); - strcpy(VA.files[varray_index].name, dirp.name); + strlcpy(VA.files[varray_index].name, dirp.name, sizeof(VA.files[0].name)); if (*ver == '\0') { /* Versionless file */ VA.files[varray_index].version_no = 1; @@ -2992,6 +3048,7 @@ static int get_version_array(char *dir, char *file) varray_index++; if (varray_index >= VERSIONARRAYMAXLENGTH) { *Lisp_errno = EIO; + alarm(0); // cancel alarm from S_TOUT return (0); } else if (varray_index >= VA.allocated) { VA.allocated += VERSIONARRAYCHUNKLENGTH; @@ -2999,7 +3056,7 @@ static int get_version_array(char *dir, char *file) sizeof(*VA.files) * VA.allocated); } } - + alarm(0); // cancel alarm from S_TOUT /* * The last entry of VA.files is indicated by setting LASTVERSIONARRAY into * version_no field. @@ -3015,9 +3072,9 @@ static int get_version_array(char *dir, char *file) * untouched by the sort, which is intentional. */ if (!NoFileP(VA.files)) { - strcpy(name, VA.files[0].name); - separate_version(name, ver, 1); - strcpy(VA.files[varray_index].name, name); + strlcpy(name, VA.files[0].name, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); + strlcpy(VA.files[varray_index].name, name, sizeof(VA.files[0].name)); if (varray_index > 1) { qsort(VA.files, varray_index, sizeof(*VA.files), compare_file_versions); } @@ -3040,8 +3097,8 @@ static int get_version_array(char *dir, char *file) * First of all, prepare a lower cased file name for the case insensitive * search. Also we have to separate file name from its version field. */ - strcpy(lcased_file, file); - separate_version(lcased_file, ver, 1); + strlcpy(lcased_file, file, sizeof(lcased_file)); + separate_version(lcased_file, sizeof(lcased_file), ver, sizeof(ver), 1); DOWNCASE(lcased_file); /* Cache for VA.files reinstated using nanosecond timestamps which many @@ -3064,7 +3121,7 @@ static int get_version_array(char *dir, char *file) } else { VA.dir_ino = sbuf.st_ino; VA.lastMTime = sbuf.st_mtim; - strcpy(VA.name, lcased_file); + strlcpy(VA.name, lcased_file, sizeof(VA.name)); } errno = 0; @@ -3083,14 +3140,14 @@ static int get_version_array(char *dir, char *file) for (S_TOUT(dp = readdir(dirp)); dp != NULL || errno == EINTR; errno = 0, S_TOUT(dp = readdir(dirp))) if (dp) { - strcpy(name, dp->d_name); - separate_version(name, ver, 1); + strlcpy(name, dp->d_name, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); DOWNCASE(name); if (strcmp(name, lcased_file) == 0) { /* * This file can be regarded as a same file in Lisp sense. */ - strcpy(VA.files[varray_index].name, dp->d_name); + strlcpy(VA.files[varray_index].name, dp->d_name, sizeof(VA.files[0].name)); if (*ver == '\0') { /* Versionless file */ VA.files[varray_index].version_no = 0; @@ -3103,6 +3160,7 @@ static int get_version_array(char *dir, char *file) varray_index++; if (varray_index >= VERSIONARRAYMAXLENGTH) { *Lisp_errno = EIO; + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT return (0); } else if (varray_index >= VA.allocated) { VA.allocated += VERSIONARRAYCHUNKLENGTH; @@ -3111,6 +3169,8 @@ static int get_version_array(char *dir, char *file) } } } + TIMEOUT(closedir(dirp)); // cancels alarm from S_TOUT + /* * The last entry of varray is indicated by setting LASTVERSIONARRAY into * version_no field. @@ -3126,15 +3186,14 @@ static int get_version_array(char *dir, char *file) * untouched by the sort, which is intentional. */ if (!NoFileP(VA.files)) { - strcpy(name, VA.files[0].name); - separate_version(name, ver, 1); - strcpy(VA.files[varray_index].name, name); + strlcpy(name, VA.files[0].name, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); + strlcpy(VA.files[varray_index].name, name, sizeof(VA.files[0].name)); if (varray_index > 1) { qsort(VA.files, varray_index, sizeof(*VA.files), compare_file_versions); } } - TIMEOUT(closedir(dirp)); return (1); #endif /* DOS */ } @@ -3177,7 +3236,7 @@ static int maintain_version(char *file, int forcep) /* * We have to make sure that dir is the existing directory. */ - if (true_name(dir) != -1) return (0); + if (true_name(dir, sizeof(dir)) != -1) return (0); if (get_version_array(dir, fname) == 0) return (0); if (NoFileP(VA.files)) { @@ -3196,7 +3255,7 @@ static int maintain_version(char *file, int forcep) */ #ifndef DOS get_versionless(VA.files, vless, dir); - ConcNameAndVersion(vless, "1", fname); + conc_name_and_version(vless, "1", fname, sizeof(fname)); TIMEOUT(rval = link(vless, fname)); if (rval == -1) { *Lisp_errno = errno; @@ -3219,15 +3278,15 @@ static int maintain_version(char *file, int forcep) * to the existing highest versioned file. */ FindHighestVersion(VA.files, entry, max_no); - ConcDirAndName(dir, entry->name, old_file); + conc_dir_and_name(dir, entry->name, old_file, sizeof(old_file)); /* * The versionless file should have the same case name as the old * file. */ #ifndef DOS - strcpy(fname, entry->name); - separate_version(fname, ver, 1); - ConcDirAndName(dir, fname, vless); + strlcpy(fname, entry->name, sizeof(fname)); + separate_version(fname, sizeof(fname), ver, sizeof(ver), 1); + conc_dir_and_name(dir, fname, vless, sizeof(vless)); TIMEOUT(rval = link(old_file, vless)); if (rval == -1) { *Lisp_errno = errno; @@ -3246,13 +3305,13 @@ static int maintain_version(char *file, int forcep) * is versioned one higher than the existing highest version. */ FindHighestVersion(VA.files, entry, max_no); - sprintf(ver, "%u", max_no + 1); + snprintf(ver, sizeof(ver), "%u", max_no + 1); /* * The old file should have the same case name as the versionless * file. */ #ifndef DOS - ConcNameAndVersion(vless, ver, old_file); + conc_name_and_version(vless, ver, old_file, sizeof(old_file)); TIMEOUT(rval = link(vless, old_file)); if (rval == -1) { *Lisp_errno = errno; @@ -3281,15 +3340,15 @@ static int maintain_version(char *file, int forcep) return (0); } FindHighestVersion(VA.files, entry, max_no); - ConcDirAndName(dir, entry->name, old_file); + conc_dir_and_name(dir, entry->name, old_file, sizeof(old_file)); /* * The versionless file should have the same case name as the old * file. */ #ifndef DOS - strcpy(fname, entry->name); - separate_version(fname, ver, 1); - ConcDirAndName(dir, fname, vless); + strlcpy(fname, entry->name, sizeof(fname)); + separate_version(fname, sizeof(fname), ver, sizeof(ver), 1); + conc_dir_and_name(dir, fname, vless, sizeof(vless)); TIMEOUT(rval = link(old_file, vless)); if (rval == -1) { *Lisp_errno = errno; @@ -3332,7 +3391,7 @@ static int get_versionless(FileName *varray, char *file, char *dir) while (varray->version_no != LASTVERSIONARRAY) { if (varray->version_no == 0) { - ConcDirAndName(dir, varray->name, file); + conc_dir_and_name(dir, varray->name, file, MAXPATHLEN); return (1); } else varray++; @@ -3411,7 +3470,7 @@ static int check_vless_link(char *vless, FileName *varray, char *to_file, int *h max_entry = varray; } if (!found && varray->version_no != 0) { - ConcDirAndName(dir, varray->name, name); + conc_dir_and_name(dir, varray->name, name, sizeof(name)); TIMEOUT(rval = stat(name, &sbuf)); if (rval != 0) { *Lisp_errno = errno; @@ -3431,7 +3490,7 @@ static int check_vless_link(char *vless, FileName *varray, char *to_file, int *h } else { *highest_p = 0; } - strcpy(to_file, name); + strlcpy(to_file, name, MAXPATHLEN); } else { *to_file = '\0'; } @@ -3489,8 +3548,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) /* "Old" file have to be existing, thus varray should not be empty. */ if (NoFileP(varray)) return (0); - strcpy(name, afile); - separate_version(name, ver, 1); + strlcpy(name, afile, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); if (get_versionless(varray, vless, dir) == 0) { /* @@ -3503,8 +3562,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) * is an old file. */ FindHighestVersion(varray, entry, max_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* @@ -3515,8 +3574,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else return (0); @@ -3532,8 +3591,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) * No version is specified. The versionless file is dealt * with as version 1. */ - ConcNameAndVersion(vless, "1", vfile); - strcpy(afile, vless); + conc_name_and_version(vless, "1", vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { ver_no = strtoul(ver, (char **)NULL, 10); @@ -3542,9 +3601,9 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) * Version 1 is specified. The versionless file is * dealt with as a version 1 file. */ - ConcNameAndVersion(name, "1", afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vless); + conc_name_and_version(name, "1", afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* @@ -3570,9 +3629,9 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) * link missing versionless file. */ FindHighestVersion(varray, entry, max_no); - sprintf(vbuf, "%u", max_no + 1); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vless); + snprintf(vbuf, sizeof(vbuf), "%u", max_no + 1); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* A version is specified. */ @@ -3585,9 +3644,9 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) * is dealt with as a version of the link * missing versionless file. */ - sprintf(vbuf, "%u", ver_no); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vless); + snprintf(vbuf, sizeof(vbuf), "%u", ver_no); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* @@ -3596,8 +3655,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) */ FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else return (0); @@ -3615,8 +3674,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) * in varray is an old file. */ FindHighestVersion(varray, entry, max_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* @@ -3627,8 +3686,8 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else return (0); @@ -3638,7 +3697,7 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile) } /* - * Name: get_oldeset + * Name: get_oldest * * Argument: char *dir Directory absolute path following the UNIX * file naming convention on which varray @@ -3688,8 +3747,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) /* "Oldest" file have to be existing, thus varray should not be empty. */ if (NoFileP(varray)) return (0); - strcpy(name, afile); - separate_version(name, ver, 1); + strlcpy(name, afile, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); if (get_versionless(varray, vless, dir) == 0) { /* @@ -3702,8 +3761,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) * is an oldest file. */ FindLowestVersion(varray, entry, min_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* @@ -3714,8 +3773,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else return (0); @@ -3731,8 +3790,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) * No version is specified. The versionless file is dealt * with as version 1. */ - ConcNameAndVersion(vless, "1", vfile); - strcpy(afile, vless); + conc_name_and_version(vless, "1", vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { ver_no = strtoul(ver, (char **)NULL, 10); @@ -3741,9 +3800,9 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) * Version 1 is specified. The versionless file is * dealt with as a version 1 file. */ - ConcNameAndVersion(name, "1", afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vless); + conc_name_and_version(name, "1", afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* @@ -3767,8 +3826,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) * dealt with as the oldest version. */ FindLowestVersion(varray, entry, min_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* A version is specified. */ @@ -3781,9 +3840,9 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) * is dealt with as a version of the link * missing versionless file. */ - sprintf(vbuf, "%u", ver_no); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vless); + snprintf(vbuf, sizeof(vbuf), "%u", ver_no); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* @@ -3792,8 +3851,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) */ FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else return (0); @@ -3811,8 +3870,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) * in varray is an old file. */ FindLowestVersion(varray, entry, min_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* @@ -3823,8 +3882,8 @@ static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else return (0); @@ -3882,8 +3941,8 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) int highest_p; FileName *entry; - strcpy(name, afile); - separate_version(name, ver, 1); + strlcpy(name, afile, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); #ifndef DOS if (NoFileP(varray)) { @@ -3898,19 +3957,19 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * If version is not specified or 1 is specified, * we can return versionless file as afile. */ - ConcNameAndVersion(name, "1", afile); - ConcDirAndName(dir, afile, vfile); - ConcDirAndName(dir, name, afile); + conc_name_and_version(name, "1", afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + conc_dir_and_name(dir, name, afile, MAXPATHLEN); return (1); } #ifndef DOS else { /* * A version other than 1 is specified. "New" file - * is recognized as if. + * is recognized as is. */ - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -3926,17 +3985,17 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * the existing highest version. */ FindHighestVersion(varray, entry, max_no); - sprintf(vbuf, "%u", max_no + 1); + snprintf(vbuf, sizeof(vbuf), "%u", max_no + 1); /* * We will use the file name of the existing highest * versioned file as the name of the new file, so that * new file is as the same case as old. */ - strcpy(name, entry->name); - separate_version(name, ver, 1); - ConcDirAndName(dir, name, afile); - ConcNameAndVersion(afile, vbuf, vfile); - strcpy(afile, vfile); + strlcpy(name, entry->name, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); + conc_dir_and_name(dir, name, afile, MAXPATHLEN); + conc_name_and_version(afile, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } else { /* @@ -3947,13 +4006,13 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } /* * There is not a file with the specified version in varray. - * The specified file can be recognized as if. + * The specified file can be recognized as is. * Most user will hope to create a new file in same case as * old. One of case sensitive names in the files are stored * in the trail marker entry in varray by get_version_array @@ -3962,9 +4021,9 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * files has the name in same case. */ while (varray->version_no != LASTVERSIONARRAY) varray++; - ConcNameAndVersion(varray->name, ver, afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_name_and_version(varray->name, ver, afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } else if (OnlyVersionlessP(varray)) { @@ -3978,8 +4037,8 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * No version is specified. The versionless file is dealt * with as version 1. Thus new version is 2. */ - ConcNameAndVersion(vless, "2", vfile); - strcpy(afile, vfile); + conc_name_and_version(vless, "2", vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } else { ver_no = strtoul(ver, (char **)NULL, 10); @@ -3988,16 +4047,16 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * Version 1 is specified. The versionless file is * dealt with as a version 1 file. */ - ConcNameAndVersion(name, "1", afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vless); + conc_name_and_version(name, "1", afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* - * Other versions than 1 are recognized as if. + * Other versions than 1 are recognized as is. */ - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -4018,9 +4077,9 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * missing versionless file. */ FindHighestVersion(varray, entry, max_no); - sprintf(vbuf, "%u", max_no + 2); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vfile); + snprintf(vbuf, sizeof(vbuf), "%u", max_no + 2); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } else { /* A version is specified. */ @@ -4033,9 +4092,9 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * is dealt with as a version of the link * missing versionless file. */ - sprintf(vbuf, "%u", ver_no); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vless); + snprintf(vbuf, sizeof(vbuf), "%u", ver_no); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* @@ -4044,14 +4103,14 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) */ FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } /* * There is not a file with the specified * version in varray. The specified file can - * be recognized as if. + * be recognized as is. * Most user will hope to create a new file in * same case as old. One of case sensitive * names in the files are stored in the trail @@ -4062,9 +4121,9 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * case. */ while (varray->version_no != LASTVERSIONARRAY) varray++; - ConcNameAndVersion(varray->name, ver, afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_name_and_version(varray->name, ver, afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -4081,16 +4140,16 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) * new file. */ FindHighestVersion(varray, entry, max_no); - sprintf(vbuf, "%u", max_no + 1); + snprintf(vbuf, sizeof(vbuf), "%u", max_no + 1); /* * We will use the name of the highest versioned file * as the name of the new file. */ - strcpy(vless, entry->name); - separate_version(vless, ver, 1); - ConcDirAndName(dir, vless, afile); - ConcNameAndVersion(afile, vbuf, vfile); - strcpy(afile, vfile); + strlcpy(vless, entry->name, sizeof(vless)); + separate_version(vless, sizeof(vless), ver, sizeof(ver), 1); + conc_dir_and_name(dir, vless, afile, MAXPATHLEN); + conc_name_and_version(afile, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } else { /* @@ -4101,25 +4160,25 @@ static int get_new(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } /* * There is not a file with the specified * version in varray. The specified file can - * be recognized as if. + * be recognized as is. * Most user will hope to create a new file in * same case as old. We will use the name of * the highest versioned file as the name of the * new file. */ FindHighestVersion(varray, entry, max_no); - strcpy(vless, entry->name); - separate_version(vless, vbuf, 1); - ConcDirAndName(dir, vless, afile); - ConcNameAndVersion(afile, ver, vfile); - strcpy(afile, vfile); + strlcpy(vless, entry->name, sizeof(vless)); + separate_version(vless, sizeof(vless), vbuf, sizeof(vbuf), 1); + conc_dir_and_name(dir, vless, afile, MAXPATHLEN); + conc_name_and_version(afile, ver, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -4176,8 +4235,8 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) int highest_p; FileName *entry; - strcpy(name, afile); - separate_version(name, ver, 1); + strlcpy(name, afile, sizeof(name)); + separate_version(name, sizeof(name), ver, sizeof(ver), 1); if (NoFileP(varray)) { /* @@ -4189,17 +4248,17 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * If version is not specified or 1 is specified, * we can return versionless file as afile. */ - ConcNameAndVersion(name, "1", afile); - ConcDirAndName(dir, afile, vfile); - ConcDirAndName(dir, name, afile); + conc_name_and_version(name, "1", afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + conc_dir_and_name(dir, name, afile, MAXPATHLEN); return (1); } else { /* * A version other than 1 is specified. "New" file - * is recognized as if. + * is recognized as is. */ - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -4215,8 +4274,8 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * is an old file. */ FindHighestVersion(varray, entry, max_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* @@ -4227,13 +4286,13 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } /* * There is not a file with the specified version in varray. - * The specified file can be recognized as if. + * The specified file can be recognized as is. * Most user will hope to create a new file in same case as * old. One of case sensitive names in the files are stored * in the trail marker entry in varray by get_version_array @@ -4242,9 +4301,9 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * files has the name in same case. */ while (varray->version_no != LASTVERSIONARRAY) varray++; - ConcNameAndVersion(varray->name, ver, afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_name_and_version(varray->name, ver, afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } else if (OnlyVersionlessP(varray)) { @@ -4258,8 +4317,8 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * No version is specified. The versionless file is dealt * with as version 1. */ - ConcNameAndVersion(vless, "1", vfile); - strcpy(afile, vless); + conc_name_and_version(vless, "1", vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { ver_no = strtoul(ver, (char **)NULL, 10); @@ -4268,16 +4327,16 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * Version 1 is specified. The versionless file is * dealt with as a version 1 file. */ - ConcNameAndVersion(name, "1", afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vless); + conc_name_and_version(name, "1", afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* - * Other versions than 1 are recognized as if. + * Other versions than 1 are recognized as is. */ - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -4297,9 +4356,9 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * link missing versionless file. */ FindHighestVersion(varray, entry, max_no); - sprintf(vbuf, "%u", max_no + 1); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vless); + snprintf(vbuf, sizeof(vbuf), "%u", max_no + 1); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* A version is specified. */ @@ -4312,9 +4371,9 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * is dealt with as a version of the link * missing versionless file. */ - sprintf(vbuf, "%u", ver_no); - ConcNameAndVersion(vless, vbuf, vfile); - strcpy(afile, vless); + snprintf(vbuf, sizeof(vbuf), "%u", ver_no); + conc_name_and_version(vless, vbuf, vfile, MAXPATHLEN); + strlcpy(afile, vless, MAXPATHLEN); return (1); } else { /* @@ -4323,14 +4382,14 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) */ FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } /* * There is not a file with the specified * version in varray. The specified file can - * be recognized as if. + * be recognized as is. * Most user will hope to create a new file in * same case as old. One of case sensitive * names in the files are stored in the trail @@ -4341,9 +4400,9 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * case. */ while (varray->version_no != LASTVERSIONARRAY) varray++; - ConcNameAndVersion(varray->name, ver, afile); - ConcDirAndName(dir, afile, vfile); - strcpy(afile, vfile); + conc_name_and_version(varray->name, ver, afile, MAXPATHLEN); + conc_dir_and_name(dir, afile, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } @@ -4359,8 +4418,8 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) * in varray is an old file. */ FindHighestVersion(varray, entry, max_no); - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } else { /* @@ -4371,25 +4430,25 @@ static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile) ver_no = strtoul(ver, (char **)NULL, 10); FindSpecifiedVersion(varray, entry, ver_no); if (entry != NULL) { - ConcDirAndName(dir, entry->name, afile); - strcpy(vfile, afile); + conc_dir_and_name(dir, entry->name, afile, MAXPATHLEN); + strlcpy(vfile, afile, MAXPATHLEN); return (1); } /* * There is not a file with the specified * version in varray. The specified file can - * be recognized as if. + * be recognized as is. * Most user will hope to create a new file in * same case as old. We will use the name of * the highest versioned file as the name of the * new file. */ FindHighestVersion(varray, entry, max_no); - strcpy(vless, entry->name); - separate_version(vless, vbuf, 1); - ConcDirAndName(dir, vless, afile); - ConcNameAndVersion(afile, ver, vfile); - strcpy(afile, vfile); + strlcpy(vless, entry->name, sizeof(vless)); + separate_version(vless, sizeof(vless), vbuf, sizeof(vbuf), 1); + conc_dir_and_name(dir, vless, afile, MAXPATHLEN); + conc_name_and_version(afile, ver, vfile, MAXPATHLEN); + strlcpy(afile, vfile, MAXPATHLEN); return (1); } } diff --git a/src/ldeether.c b/src/ldeether.c index 6d4eaa57..998d0a8a 100644 --- a/src/ldeether.c +++ b/src/ldeether.c @@ -200,7 +200,7 @@ int main(int argc, char *argv[]) { goto I_Give_Up; } bcopy(if_data.ifc_req[0].ifr_addr.sa_data, ether_host, 6); - strcpy(Ename, if_data.ifc_req[0].ifr_name); + strlcpy(Ename, if_data.ifc_req[0].ifr_name, sizeof(Ename)); fcntl(ether_fd, F_SETFL, fcntl(ether_fd, F_GETFL, 0) | O_ASYNC | O_NONBLOCK); diff --git a/src/ufs.c b/src/ufs.c index b5173cd4..bd311f31 100644 --- a/src/ufs.c +++ b/src/ufs.c @@ -9,6 +9,7 @@ #include "version.h" +#include /* for isdigit */ #include #include #include @@ -128,6 +129,134 @@ exit_host_filesystem(void) { #endif /* DOS */ +/* + * Name: LispVersionToUnixVersion + * + * Argument: char *pathname + * Xerox Lisp syntax pathname. + * + * Value: If succeed, returns 1, otherwise 0. + * + * Side Effect: The version part of pathname is destructively modified. + * + * Description: + * + * Destructively modifies the version part of pathname which follows the + * Xerox Lisp file naming convention to the UNIX one. + * + * If the file name which is passed from Lisp has the version part, it must be + * a valid one (i.e. all numeric). This is guaranteed by Lisp code. + * + * This function should be called at the top of the routines which accept the + * file name from Lisp before converting it into a UNIX file name, because + * quoted characters, which might be removed during the conversion, may be + * needed to identify the version part. + * + */ + +/* + * Unix version destructively replaces the Lisp ";version" with ".~version~" while the + * DOS version truncates the Lisp version at the ";" and stores an integer. + * Why are they different? + */ +#ifdef DOS +static void LispVersionToUnixVersion(char *pathname, int *ver) +{ + char version[VERSIONLEN + 4] = {0}; + char *vp = NULL; + char *ep = &pathname[strlen(pathname) - 1]; /* from the end */ + while (ep >= pathname) { /* until the beginning */ + if (*ep == ';' && /* found a semicolon */ + (ep == pathname || *(ep - 1) != '\'')) {/* at the beginning or not quoted */ + vp = ep; /* version starts at unquoted semicolon */ + break; /* stop when found version */ + } + ep--; /* previous character */ + } + + *ver = -1; + if (vp == NULL) return; /* there was no version field */ + + *vp++ = '\0'; /* end name at the semicolon */ + if (*vp == '\0') return; /* empty version field */ + + *ver = strtol(vp, NULL, 10); +} +#else +static void LispVersionToUnixVersion(char *pathname, size_t pathsize) +{ + char version[VERSIONLEN + 4] = {0}; + char *vp = NULL; + char *ep = &pathname[strlen(pathname) - 1]; /* from the end */ + while (ep >= pathname) { /* until the beginning */ + if (*ep == ';' && /* found a semicolon */ + (ep == pathname || *(ep - 1) != '\'')) {/* at the beginning or not quoted */ + vp = ep; /* version starts at unquoted semicolon */ + break; /* stop when found version */ + } + ep--; /* previous character */ + } + + if (vp == NULL) return; /* there was no version field */ + + *vp++ = '\0'; /* end name at the semicolon */ + if (*vp == '\0') return; /* empty version field */ + + while (*vp == '0') vp++; /* skip leading zeros */ + if (*vp == '\0') return; /* all zero version is no version */ + version[0] = '.'; /* leading version marker */ + version[1] = '~'; /* leading version marker */ + strlcat(version, vp, VERSIONLEN); /* the trimmed version from the source */ + strlcat(version, "~", VERSIONLEN); /* trailing version marker */ + strlcat(pathname, version, pathsize); /* concatenate version to pathname */ +} +#endif + +/* + * Name: UnixVersionToLispVersion + * + * Argument: char *pathname UNIX syntax pathname. + * size_t pathsize size of storage of pathname + * int vlessp If 0, versionless file is converted to version 1. + * Otherwise, remains as versionless. + * + * Side Effect: The version part of pathname is destructively modified. + * + * Description: + * + * Destructively modify the version part of pathname which follows the + * UNIX file naming convention to the Xerox Lisp one. + * This procedure should be called, in the routines which convert the UNIX pathname + * to Lisp one, just before it returns the result to Lisp, because converting + * version field will append a semicolon and it might make the routine be + * confused. + * + * A name which does not have a valid version field, that is ".~##~" form, is + * dealt with as version 1. + * + * A Lisp version is guaranteed to take less storage than a Unix version, however + * an invalid/missing version field will increase the storage used. + */ + +void UnixVersionToLispVersion(char *pathname, size_t pathsize, int vlessp) +{ + char *uvp; + char *ep = &pathname[strlen(pathname) - 1]; + + if (*ep-- != '~') goto badversion; /* well-formed name with version ending with "~" */ + while (isdigit(*ep) && (ep > (pathname + 1))) ep--; /* walk back, not too far */ + /* well-formed name with version starting ".~" */ + if ((ep == pathname) || (*ep != '~') || (*(ep - 1) != '.')) goto badversion; + /* must end .~###~ and ep points at the initial tilde */ + *(ep - 1) = ';'; /* smash . to ; */ + for (uvp = ep + 1; *uvp == '0' && *(uvp + 1) != '~'; uvp++); /* after ~, skip zeros */ + while (*uvp != '~') *ep++ = *uvp++; /* copy remaining digits, guaranteed shorter */ + *ep = '\0'; /* and terminate string */ + return; + badversion: + if (!vlessp) strlcat(pathname, ";1", pathsize); +} + /* * Name: UFS_getfilename * @@ -172,13 +301,13 @@ LispPTR UFS_getfilename(LispPTR *args) LispStringToCString(args[0], lfname, MAXPATHLEN); /* * Convert a Lisp file name to UNIX one. This is a UNIX device method. - * Thus we don't need to convert a version field. Third argument for + * Thus we don't need to convert a version field. Fourth argument for * unixpathname specifies it. */ #ifdef DOS - if (unixpathname(lfname, file, 0, 0, 0, 0, 0) == 0) return (NIL); + if (unixpathname(lfname, file, sizeof(file), 0, 0, 0, 0, 0) == 0) return (NIL); #else - if (unixpathname(lfname, file, 0, 0) == 0) return (NIL); + if (unixpathname(lfname, file, sizeof(file), 0, 0) == 0) return (NIL); #endif /* DOS */ switch (args[1]) { @@ -200,7 +329,7 @@ LispPTR UFS_getfilename(LispPTR *args) case RECOG_NON: /* * "New" file means the "not existing" file. UNIX device always - * recognizes a not existing file as if, the subsequent OPENFILE will + * recognizes a not existing file as is, the subsequent OPENFILE will * find the truth. * "Non" recognition is used to recognize a sysout file. */ @@ -208,9 +337,9 @@ LispPTR UFS_getfilename(LispPTR *args) } /* * Now, we convert a file name back to Lisp format. The version field have not - * to be converted. The fourth argument for lisppathname specifies it. + * to be converted. The fifth argument for lisppathname specifies it. */ - if (lisppathname(file, lfname, 0, 0) == 0) return (NIL); + if (lisppathname(file, lfname, sizeof(lfname), 0, 0) == 0) return (NIL); STRING_BASE(args[2], base); len = strlen(lfname); @@ -259,9 +388,9 @@ LispPTR UFS_deletefile(LispPTR *args) LispStringToCString(args[0], fbuf, MAXPATHLEN); #ifdef DOS - if (unixpathname(fbuf, file, 0, 0, 0, 0, 0) == 0) return (NIL); + if (unixpathname(fbuf, file, sizeof(file), 0, 0, 0, 0, 0) == 0) return (NIL); #else - if (unixpathname(fbuf, file, 0, 0) == 0) return (NIL); + if (unixpathname(fbuf, file, sizeof(file), 0, 0) == 0) return (NIL); #endif /* DOS */ /* check if we're operating on directory or file */ TIMEOUT(rval = stat(file, &sbuf)); @@ -327,15 +456,15 @@ LispPTR UFS_renamefile(LispPTR *args) LispStringToCString(args[0], fbuf, MAXPATHLEN); #ifdef DOS - if (unixpathname(fbuf, src, 0, 0, 0, 0, 0) == 0) return (NIL); + if (unixpathname(fbuf, src, sizeof(src), 0, 0, 0, 0, 0) == 0) return (NIL); #else - if (unixpathname(fbuf, src, 0, 0) == 0) return (NIL); + if (unixpathname(fbuf, src, sizeof(src), 0, 0) == 0) return (NIL); #endif /* DOS */ LispStringToCString(args[1], fbuf, MAXPATHLEN); #ifdef DOS - if (unixpathname(fbuf, dst, 0, 0, 0, 0, 0) == 0) return (NIL); + if (unixpathname(fbuf, dst, sizeof(dst), 0, 0, 0, 0, 0) == 0) return (NIL); #else - if (unixpathname(fbuf, dst, 0, 0) == 0) return (NIL); + if (unixpathname(fbuf, dst, sizeof(dst), 0, 0) == 0) return (NIL); #endif /* DOS */ TIMEOUT(rval = rename(src, dst)); @@ -400,9 +529,9 @@ LispPTR UFS_directorynamep(LispPTR *args) /* Convert Xerox Lisp file naming convention to Unix one. */ #ifdef DOS - if (unixpathname(dirname, fullname, 0, 0, 0, 0, 0) == 0) return (NIL); + if (unixpathname(dirname, fullname, sizeof(fullname), 0, 0, 0, 0, 0) == 0) return (NIL); #else - if (unixpathname(dirname, fullname, 0, 0) == 0) return (NIL); + if (unixpathname(dirname, fullname, sizeof(fullname), 0, 0) == 0) return (NIL); #endif /* DOS */ TIMEOUT(rval = stat(fullname, &sbuf)); @@ -414,7 +543,7 @@ LispPTR UFS_directorynamep(LispPTR *args) if (!S_ISDIR(sbuf.st_mode)) return (NIL); /* Convert Unix file naming convention to Xerox Lisp one. */ - if (lisppathname(fullname, dirname, 1, 0) == 0) return (NIL); + if (lisppathname(fullname, dirname, sizeof(dirname), 1, 0) == 0) return (NIL); len = strlen(dirname); STRING_BASE(args[1], base); @@ -437,6 +566,7 @@ LispPTR UFS_directorynamep(LispPTR *args) * if the pathname is passed as a directory, the * tail delimiter may be included. * char *dst The buffer to which the converted pathname is stored. + * int dstlen The size of the dst buffer * int versionp * If 1, version field in src is converted to UNIX * version form. {DSK} device invokes unixpathname @@ -463,9 +593,9 @@ LispPTR UFS_directorynamep(LispPTR *args) * */ #ifdef DOS -int unixpathname(char *src, char *dst, int versionp, int genp, char *drive, int *extlenptr, char *rawname) +int unixpathname(char *src, char *dst, int dstlen, int versionp, int genp, char *drive, int *extlenptr, char *rawname) #else -int unixpathname(char *src, char *dst, int versionp, int genp) +int unixpathname(char *src, char *dst, size_t dstlen, int versionp, int genp) #endif /* DOS */ { char *cp, *dp, *np; @@ -495,12 +625,12 @@ int unixpathname(char *src, char *dst, int versionp, int genp) * file system code. */ if (strcmp(src, "<") == 0) { - strcpy(dst, DIRSEPSTR); + strlcpy(dst, DIRSEPSTR, dstlen); return (1); } /* Copy src to protect it from destructive modification. */ - strcpy(lfname, src); + strlcpy(lfname, src, sizeof(lfname)); /* * If versionp is specified, we have to deal with the version field first, @@ -508,9 +638,9 @@ int unixpathname(char *src, char *dst, int versionp, int genp) * in the course of the following conversion. */ #ifdef DOS - if (versionp) LispVersionToUnixVersion(lfname, version); else version = -1; + if (versionp) LispVersionToUnixVersion(lfname, &version); else version = -1; #else - if (versionp) LispVersionToUnixVersion(lfname); + if (versionp) LispVersionToUnixVersion(lfname, sizeof(lfname)); #endif /* DOS */ cp = lfname; @@ -582,7 +712,7 @@ int unixpathname(char *src, char *dst, int versionp, int genp) TIMEOUT0(pwd = getpwuid(getuid())); if (pwd == NULL) return (0); - strcpy(dst, pwd->pw_dir); + strlcpy(dst, pwd->pw_dir, dstlen); while (*dp != '\0') dp++; if (*(dp - 1) != DIRSEP) { /* @@ -606,7 +736,7 @@ int unixpathname(char *src, char *dst, int versionp, int genp) TIMEOUT0(pwd = getpwnam(name)); if (pwd == NULL) return (0); - strcpy(dst, pwd->pw_dir); + strlcpy(dst, pwd->pw_dir, dstlen); while (*dp != '\0') dp++; if (*(dp - 1) != DIRSEP) { /* @@ -769,6 +899,8 @@ int unixpathname(char *src, char *dst, int versionp, int genp) #ifdef DOS if (NameValid) *dp++ = *(cp + 1); CountNameChars; +#else + *dp++ = *(cp + 1); #endif /* DOS */ cp += 2; break; @@ -807,10 +939,10 @@ int unixpathname(char *src, char *dst, int versionp, int genp) * for the convenience of the pattern matching routines, we don't * care about the last period character. */ - strcpy(fbuf1, lfname); - strcpy(fbuf2, dst); - separate_version(fbuf1, ver1, 1); - separate_version(fbuf2, ver2, 1); + strlcpy(fbuf1, lfname, sizeof(fbuf1)); + strlcpy(fbuf2, dst, sizeof(fbuf2)); + separate_version(fbuf1, sizeof(fbuf1), ver1, sizeof(ver1), 1); + separate_version(fbuf2, sizeof(fbuf2), ver2, sizeof(ver2), 1); for (cp = fbuf1; *cp; cp++) {} for (dp = fbuf2; *dp; dp++) {} if (*(cp - 1) == '.') { @@ -825,11 +957,11 @@ int unixpathname(char *src, char *dst, int versionp, int genp) } #ifdef DOS if (version >= 0) - sprintf(ver2, "%d", version); + snprintf(ver2, sizeof(ver2), "%d", version); else *ver2 = '\0'; #endif /* DOS */ - ConcNameAndVersion(fbuf2, ver2, dst); + conc_name_and_version(fbuf2, ver2, dst, MAXPATHLEN); } return (1); } @@ -845,6 +977,7 @@ int unixpathname(char *src, char *dst, int versionp, int genp) * The lispname is used to determine which * character should be quoted in the result * Xerox Lisp pathname representation. + * size_t lispnamesize size of storage available for lispname * int dirp If 1, fullname is a directory. If 0, * fullname is a file. * int versionp If 1, version field is also converted @@ -871,14 +1004,14 @@ int unixpathname(char *src, char *dst, int versionp, int genp) * */ -int lisppathname(char *fullname, char *lispname, int dirp, int versionp) +int lisppathname(char *fullname, char *lispname, size_t lispnamesize, int dirp, int versionp) { char *cp, *dp, *lnamep, *cnamep; char namebuf[MAXPATHLEN], fbuf[MAXPATHLEN], ver[VERSIONLEN]; int i, mask, extensionp; if (strcmp(fullname, DIRSEPSTR) == 0) { - strcpy(lispname, "<"); + strlcpy(lispname, "<", lispnamesize); return (1); } @@ -889,7 +1022,7 @@ int lisppathname(char *fullname, char *lispname, int dirp, int versionp) *lispname++ = *fullname++; } #endif - + if (!dirp) { /* * The characters which are dealt with specially (i.e. are quoted) @@ -940,7 +1073,7 @@ int lisppathname(char *fullname, char *lispname, int dirp, int versionp) * ' '' * . '. only if it is used as a part of the extension * field. - * others as if + * others as is */ cp = fullname + 1; @@ -982,7 +1115,7 @@ int lisppathname(char *fullname, char *lispname, int dirp, int versionp) if (dirp) { if (*(dp - 1) != '>' || *(dp - 2) == '\'') *dp++ = '>'; *dp = '\0'; - strcpy(lispname, namebuf); + strlcpy(lispname, namebuf, lispnamesize); return (1); } @@ -1046,7 +1179,7 @@ int lisppathname(char *fullname, char *lispname, int dirp, int versionp) * or not. If extension field is not included, we have to add a period * to specify empty extension field. */ - strcpy(fbuf, namebuf); + strlcpy(fbuf, namebuf, sizeof(fbuf)); dp = cp = fbuf; while (*cp) { switch (*cp) { @@ -1066,7 +1199,7 @@ int lisppathname(char *fullname, char *lispname, int dirp, int versionp) } } cp = dp + 1; - if (versionp) separate_version(fbuf, ver, 1); + if (versionp) separate_version(fbuf, sizeof(fbuf), ver, sizeof(ver), 1); extensionp = 0; while (*cp && !extensionp) { switch (*cp) { @@ -1087,237 +1220,16 @@ int lisppathname(char *fullname, char *lispname, int dirp, int versionp) *cp = '\0'; } if (versionp && *ver != '\0') { - ConcNameAndVersion(fbuf, ver, namebuf); + conc_name_and_version(fbuf, ver, namebuf, MAXPATHLEN); } else { - strcpy(namebuf, fbuf); + strlcpy(namebuf, fbuf, sizeof(namebuf)); } /* * Now, it's time to convert the version field. */ - if (!dirp && versionp) UnixVersionToLispVersion(namebuf, 0); - - strcpy(lispname, namebuf); - return (1); -} - -/* - * Name: quote_fname - * - * Argument: char *file The root file name in UNIX format. "Root" - * file name contains the name, extension and - * version fields. A valid version field is in a - * form as ".~##~". - * - * Value: If succeed, returns 1, otherwise 0. - * - * Side Effect: If succeed, file is replaced with the file name in Xerox Lisp format - * in which special characters are quoted. - * - * Description: - * - * Converts a UNIX root file name to Xerox Lisp one. This routine only quotes special - * characters in Xerox file naming convention, does not care about the "true" name - * which might be specified directly by the user as like lisppathname. Thus, this - * routine can be invoked when you don't know how to escape the period character. This - * is the case when you convert a file name in the course of the directory enumeration. - * - * This routine is used when file is a "FILE" name and being converted to {DSK} name. - * - * The special characters which is quoted include "<", ">", ";", and "'" itself. Notice - * again that "." is not quoted, because we don't know it is a extension separator in - * Lisp sense or not. - */ - -int quote_fname(char *file) -{ - char *cp, *dp; - int extensionp; - char fbuf[MAXNAMLEN + 1], namebuf[MAXNAMLEN + 1], ver[VERSIONLEN]; - - cp = file; - dp = fbuf; - - while (*cp) { - switch (*cp) { - case '>': - case ';': - case '\'': - *dp++ = '\''; - *dp++ = *cp++; - break; - - default: *dp++ = *cp++; break; - } - } - *dp = '\0'; - - /* - * extensionp indicates whether extension field is included in a file - * name or not. If extension field is not included, we have to add a - * period to specify empty extension field. - */ - separate_version(fbuf, ver, 1); - cp = fbuf; - extensionp = 0; - while (*cp && !extensionp) { - switch (*cp) { - case '.': - if (*(cp + 1)) extensionp = 1; - cp++; - break; - - case '\'': - if (*(cp + 1) != '\0') - cp += 2; - else - cp++; - break; - - default: cp++; break; - } - } - if (!extensionp) { - if (*(cp - 1) == '.') { - *(cp - 1) = '\''; - *cp++ = '.'; - } - *cp++ = '.'; - *cp = '\0'; - } - if (*ver != '\0') { - ConcNameAndVersion(fbuf, ver, namebuf); - } else { - strcpy(namebuf, fbuf); - } - UnixVersionToLispVersion(namebuf, 1); - strcpy(file, namebuf); - return (1); -} - -/* - * Name: quote_fname_ufs - * - * Argument: char *file The root file name in UNIX format. "Root" - * file name contains the name, extension and - * version fields. A valid version field is in a - * form as ".~##~". - * - * Value: If succeed, returns 1, otherwise 0. - * - * Side Effect: If succeed, file is replaced with the file name in Xerox Lisp format - * in which special characters are quoted. - * - * Description: - * - * Similar to quote_fname, but this routine is only used when file is a "FILE" name - * and being converted to {UNIX} name. - */ - -int quote_fname_ufs(char *file) -{ - char *cp, *dp; - int extensionp; - char fbuf[MAXNAMLEN + 1]; - - cp = file; - dp = fbuf; - - while (*cp) { - switch (*cp) { - case '>': - case ';': - case '\'': - *dp++ = '\''; - *dp++ = *cp++; - break; - - default: *dp++ = *cp++; break; - } - } - *dp = '\0'; - - /* - * extensionp indicates whether extension field is included in a file - * name or not. If extension field is not included, we have to add a - * period to specify empty extension field. - */ - cp = fbuf; - extensionp = 0; - while (*cp && !extensionp) { - switch (*cp) { - case '.': - if (*(cp + 1)) extensionp = 1; - cp++; - break; - - case '\'': - if (*(cp + 1) != '\0') - cp += 2; - else - cp++; - break; - - default: cp++; break; - } - } - if (!extensionp) { - if (*(cp - 1) == '.') { - *(cp - 1) = '\''; - *cp++ = '.'; - } - *cp++ = '.'; - *cp = '\0'; - } - strcpy(file, fbuf); - return (1); -} - -/* - * Name: quote_dname - * - * Argument: char *dir The directory name in UNIX format. Does not - * include its parent name. - * - * Value: If succeed, returns 1, otherwise 0. - * - * Side Effect: If succeed, dir is replaced with the directory name in Xerox Lisp - * format in which special characters are quoted. - * - * Description: - * - * Similar to quote_fname, but this routine is only used when dir is a "DIRECTORY" - * name. Both {DSK} and {UNIX} uses this routine. - */ - -int quote_dname(char *dir) -{ - char *cp, *dp; - char fbuf[MAXNAMLEN + 1]; - - cp = dir; - dp = fbuf; - - while (*cp) { - switch (*cp) { - case '>': - case ';': - case '\'': - *dp++ = '\''; - *dp++ = *cp++; - break; - - default: *dp++ = *cp++; break; - } - } - *dp = '\0'; - - if (*(dp - 1) == '.') { - /* Trail period should be quoted. */ - *(dp - 1) = '\''; - *dp++ = '.'; - } + if (!dirp && versionp) UnixVersionToLispVersion(namebuf, sizeof(namebuf), 0); - strcpy(dir, fbuf); + strlcpy(lispname, namebuf, lispnamesize); return (1); } diff --git a/src/unixcomm.c b/src/unixcomm.c index 856b3817..03cefde2 100644 --- a/src/unixcomm.c +++ b/src/unixcomm.c @@ -303,7 +303,7 @@ int FindUnixPipes(void) { /* */ /************************************************************************/ -static int FindAvailablePty(char *Slave) { +static int FindAvailablePty(char *Slave, size_t SlaveLen) { int res; res = posix_openpt(O_RDWR); @@ -313,7 +313,7 @@ static int FindAvailablePty(char *Slave) { } grantpt(res); unlockpt(res); - strcpy(Slave, ptsname(res)); + strlcpy(Slave, ptsname(res), SlaveLen); DBPRINT(("slave pty name is %s.\n", Slave)); if (res != -1) { @@ -392,7 +392,7 @@ LispPTR Unix_handlecomm(LispPTR *args) { PipeName = build_socket_pathname(sockFD); memset(&sock, 0, sizeof(sock)); sock.sun_family = AF_UNIX; - strcpy(sock.sun_path, PipeName); + strlcpy(sock.sun_path, PipeName, sizeof(sock.sun_path)); if (bind(sockFD, (struct sockaddr *)&sock, sizeof(struct sockaddr_un)) < 0) { close(sockFD); perror("binding sockets"); @@ -570,7 +570,7 @@ LispPTR Unix_handlecomm(LispPTR *args) { int Master; unsigned short len; - Master = FindAvailablePty(SlavePTY); + Master = FindAvailablePty(SlavePTY, sizeof(SlavePTY)); DBPRINT(("Fork Shell; Master PTY = %d. Slave=%c%c.\n", Master, SlavePTY[0], SlavePTY[1])); if (Master < 0) { printf("Open of lisp side of PTY failed.\n"); @@ -771,6 +771,7 @@ LispPTR Unix_handlecomm(LispPTR *args) { { int sockFD; struct sockaddr_un sock; + size_t pathsize; /* First open the socket */ sockFD = socket(AF_UNIX, SOCK_STREAM, 0); @@ -782,12 +783,13 @@ LispPTR Unix_handlecomm(LispPTR *args) { socket into it */ /* need to type-check the string here */ LispStringToCString(args[1], shcom, 2048); - UJ[sockFD].pathname = malloc(strlen(shcom) + 1); - strcpy(UJ[sockFD].pathname, shcom); + pathsize = strlen(shcom) + 1; + UJ[sockFD].pathname = malloc(pathsize); + strlcpy(UJ[sockFD].pathname, shcom, pathsize); /* Then bind it to the pathname, and get it listening properly */ sock.sun_family = AF_UNIX; - strcpy(sock.sun_path, shcom); + strlcpy(sock.sun_path, shcom, sizeof(sock.sun_path)); if (bind(sockFD, (struct sockaddr *)&sock, sizeof(struct sockaddr_un)) < 0) { close(sockFD); free(UJ[sockFD].pathname); diff --git a/src/unixfork.c b/src/unixfork.c index 1292a90f..92bc9f0e 100644 --- a/src/unixfork.c +++ b/src/unixfork.c @@ -358,7 +358,7 @@ int fork_Unix(void) { (void)snprintf(PipeName, sizeof(PipeName), "/tmp/LPU%ld-%d", StartTime, slot); memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, PipeName); + strlcpy(addr.sun_path, PipeName, sizeof(addr.sun_path)); status = connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)); if (status < 0) { diff --git a/src/vmemsave.c b/src/vmemsave.c index e77af0f6..4a38a422 100644 --- a/src/vmemsave.c +++ b/src/vmemsave.c @@ -156,36 +156,36 @@ LispPTR vmem_save0(LispPTR *args) LispStringToCString(args[0], pathname, MAXPATHLEN); separate_host(pathname, host); #ifdef DOS - if (!unixpathname(pathname, sysout, 0, 0, drive, 0, 0)) return (BADFILENAME); + if (!unixpathname(pathname, sysout, sizeof(sysout), 0, 0, drive, 0, 0)) return (BADFILENAME); #else - if (!unixpathname(pathname, sysout, 0, 0)) return (BADFILENAME); + if (!unixpathname(pathname, sysout, sizeof(sysout), 0, 0)) return (BADFILENAME); #endif /* DOS */ return (vmem_save(sysout)); } else { if ((def = getenv("LDEDESTSYSOUT")) == 0) { #ifdef DOS if (getcwd(pwd, MAXNAMLEN) == NULL) return (FILETIMEOUT); - strcpy(sysout, pwd); - strcat(sysout, "/lisp.vm"); + strlcpy(sysout, pwd, sizeof(sysout)); + strlcat(sysout, "/lisp.vm", sizeof(sysout)); #else pwd = getpwuid(getuid()); /* NEED TIMEOUT */ if (pwd == (struct passwd *)NULL) return (FILETIMEOUT); - strcpy(sysout, pwd->pw_dir); - strcat(sysout, "/lisp.virtualmem"); + strlcpy(sysout, pwd->pw_dir, sizeof(sysout)); + strlcat(sysout, "/lisp.virtualmem", sizeof(sysout)); #endif /* DOS */ } else { if (*def == '~' && (*(def + 1) == '/' || *(def + 1) == '\0')) { #ifdef DOS if (getcwd(pwd, MAXNAMLEN) == NULL) return (FILETIMEOUT); - strcpy(sysout, pwd); + strlcpy(sysout, pwd, sizeof(sysout)); #else pwd = getpwuid(getuid()); /* NEED TIMEOUT */ if (pwd == (struct passwd *)NULL) return (FILETIMEOUT); - strcpy(sysout, pwd->pw_dir); + strlcpy(sysout, pwd->pw_dir, sizeof(sysout)); #endif /* DOS */ - strcat(sysout, def + 1); + strlcat(sysout, def + 1, sizeof(sysout)); } else { - strcpy(sysout, def); + strlcpy(sysout, def, sizeof(sysout)); } } return (vmem_save(sysout)); @@ -349,9 +349,9 @@ LispPTR vmem_save(char *sysout_file_name) SETJMP(FILETIMEOUT); #ifdef DOS /* Bloddy 8 char filenames in dos ... /jarl */ - make_old_version(tempname, sysout_file_name); + make_old_version(tempname, sizeof(tempname), sysout_file_name); #else /* DOS */ - sprintf(tempname, "%s-temp", sysout_file_name); + snprintf(tempname, sizeof(tempname), "%s-temp", sysout_file_name); #endif /* DOS */ /* Confirm protection of specified file by open/close */ diff --git a/src/xrdopt.c b/src/xrdopt.c index f3098579..43e3de3a 100644 --- a/src/xrdopt.c +++ b/src/xrdopt.c @@ -17,7 +17,7 @@ #include // for PATH_MAX #include // for fprintf, NULL, stderr, sscanf #include // for getenv, exit, strtol -#include // for strncpy, strcat, strcpy, strcmp +#include // for strncpy, strlcat, strlcpy, strcmp #include // for u_char #include // for access, R_OK #include "xdefs.h" // for WINDOW_NAME @@ -211,13 +211,13 @@ void read_Xoption(int *argc, char *argv[]) print_Xusage(argv[0]); } else { envname = getenv("DISPLAY"); - (void)strcpy(Display_Name, envname); + (void)strlcpy(Display_Name, envname, sizeof(Display_Name)); } if ((xdisplay = XOpenDisplay(Display_Name)) != NULL) { /* read the other databases */ /* Start with app-defaults/medley */ - (void)strcpy(tmp, "/usr/lib/X11/app-defaults/"); - (void)strcat(tmp, "medley"); + (void)strlcpy(tmp, "/usr/lib/X11/app-defaults/", sizeof(tmp)); + (void)strlcat(tmp, "medley", sizeof(tmp)); applicationDB = XrmGetFileDatabase(tmp); if (applicationDB != NULL) { (void)XrmMergeDatabases(applicationDB, &rDB); } /* Then try the displays defaults */ @@ -232,8 +232,8 @@ void read_Xoption(int *argc, char *argv[]) } envname = getenv("HOME"); - (void)strcat(tmp, envname); - (void)strcat(tmp, "/.Xdefaults"); + (void)strlcpy(tmp, envname, sizeof(tmp)); + (void)strlcat(tmp, "/.Xdefaults", sizeof(tmp)); if (access(tmp, R_OK) != 0) { serverDB = XrmGetFileDatabase(tmp); if (serverDB != NULL) { (void)XrmMergeDatabases(serverDB, &rDB); } @@ -255,7 +255,7 @@ void read_Xoption(int *argc, char *argv[]) if (XrmGetResource(rDB, "ldex.icontitle", "Ldex.icontitle", str_type, &value) == True) { (void)strncpy(iconTitle, value.addr, value.size); } else { - (void)strcpy(iconTitle, "Medley"); + (void)strlcpy(iconTitle, "Medley", sizeof(iconTitle)); } if (XrmGetResource(rDB, "ldex.iconbitmap", "Ldex.Iconbitmap", str_type, &value) == True) { @@ -276,8 +276,6 @@ void read_Xoption(int *argc, char *argv[]) &LispDisplayRequestedWidth, &LispDisplayRequestedHeight); } - (void)strcpy(tmp, ""); /* Clear the string */ - if (XrmGetResource(rDB, "ldex.cursorColor", "Ldex.cursorColor", str_type, &value) == True) { (void)strncpy(cursorColor, value.addr, sizeof(cursorColor) - 1); }