root@hobbes.UUCP (John Plocher) (07/16/87)
This is a note to report a few (more) problems with the System5 ARC
which was posted back before May 87. These problems may also be in
the BSD and MS-DOS versions.
The reason I got into ARC again was that I wanted to add handling for PKarc's
SCRUNCHING (compression type 9). I have not added the compression/decompression
routines; all I did was modify arclst.c and arcunp.c to spit out helpful notes
upon encountering type 9 headers.
I also made System5 14 char filenames OPTIONAL and DOS 12 char filenames the
DEFAULT! This program is primarily used to handle DOS stuff...
Anyways, here is the stuff I found:
To repeat:
/usr/src/dos/ls> ls
LS.C LS.OBJ LS.EXE LS.arc
/usr/src/dos/ls> arc ai LS.arc LS*
Segmentation violation core dumped
/usr/src/dos/ls>
Reason: Boundry condition!
The file LS.arc is the LAST member of the arg[] list sent to
sortarg(). Since LS.arc is the name of the *archive*, it is
removed by:
while (strcmp(arg[top],arcname) == 0) {
for (seek = top; seek < num;seek++)
arg[seek] = arg[seek + 1];
arg[--num] = '\0';
dups++;
}
When the loop goes into pass 2 after 'removing' LS.arc it does
a strcmp(0, arcname).
BTW: Change arg[--num] = '\0'; to arg[--num] = NULL;
arg is declared as char *arg[]; An array of POINTERS to
chars! The way it is coded is WRONG.
The following loop which checks for duplicate names has the
same problem.
Fix:
/*
* arcmisc.c 1.2
...
sortarg(num,arg) /* sort argument list, remove dups */
int num;
char *arg[];
{
...
/* find any occurences of 'arcname', and remove them */
for (top = 0;top < num;top++) {
! while (arg[top] && strcmp(arg[top],arcname) == 0) {
for (seek = top; seek < num;seek++)
arg[seek] = arg[seek + 1];
! arg[--num] = NULL;
dups++;
}
}
/* find any other duplicate arguments (ignoring pathnames), */
/* and remove the second and subsequent occurences */
for (top = 0;top < num-1;top++) {
buf1 = arg[top];
buf2 = arg[top + 1];
if (i = strrchr(arg[top],'/')) buf1 = i + 1;
if (i = strrchr(arg[top + 1],'/')) buf2 = i + 1;
! while (buf1 && buf2 && strcmp(buf1,buf2) == 0) {
for (seek = top + 1;seek < num;seek++)
arg[seek] = arg[seek + 1];
! arg[--num] = NULL;
buf2 = arg[top + 1];
if (i = strrchr(arg[top + 1],'/')) buf2 = i + 1;
dups++;
}
}
...
--
John Plocher uwvax!geowhiz!uwspan!plocher plocher%uwspan.UUCP@uwvax.CS.WISC.EDU