Nit in compress about filenames; backup patched to use opendir() and

readdir() (old dir format didn't work)
This commit is contained in:
Ben Gras 2005-07-18 09:33:27 +00:00
parent dfc51728b7
commit 5cd673c5ba
2 changed files with 37 additions and 37 deletions

View file

@ -41,22 +41,21 @@
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <stdio.h> #include <stdio.h>
#include <dirent.h>
#define NAME_SIZE _DIRENT_NAME_LEN
#undef NARROW /* Width of verbose output */ #undef NARROW /* Width of verbose output */
#define COPY_SIZE 4096 #define COPY_SIZE 4096
#define MAX_ENTRIES 512 #define MAX_ENTRIES 512
#define DIR_ENT_SIZE 16
#define NAME_SIZE 14
#define MAX_PATH 256 #define MAX_PATH 256
#define NONFATAL 0 #define NONFATAL 0
#define FATAL 1 #define FATAL 1
#define NO_SAVINGS 512 /* compress can return code 2 */ #define NO_SAVINGS 512 /* compress can return code 2 */
#define OUT_OF_SPACE 2 #define OUT_OF_SPACE 2
struct dir_buf { /* list of the src directory */ struct dirent dir_ent[MAX_ENTRIES];
unsigned short ino; int entries = 0;
char name[NAME_SIZE];
} dir_buf[MAX_ENTRIES];
struct sorted { struct sorted {
int mode; /* file mode */ int mode; /* file mode */
@ -93,6 +92,8 @@ char *argv[];
int ct, n, m, fd; int ct, n, m, fd;
char *dir1, *dir2, *cp, c; char *dir1, *dir2, *cp, c;
struct stat s; struct stat s;
struct dirent *e;
DIR *DIR1, *DIR2;
(void) sync(); (void) sync();
@ -133,18 +134,21 @@ char *argv[];
if ((s.st_mode & S_IFMT) != S_IFDIR) error(FATAL, "non-directory ", dir1, ""); if ((s.st_mode & S_IFMT) != S_IFDIR) error(FATAL, "non-directory ", dir1, "");
/* Read in the source directory */ /* Read in the source directory */
fd = open(dir1, O_RDONLY); if(!(DIR1 = opendir(dir1))) {
if (fd < 0) error(FATAL, "cannot open ", dir1, ""); perror(dir1);
ct = read(fd, (char *)&dir_buf[0], MAX_ENTRIES * DIR_ENT_SIZE); return 1;
close(fd); }
if (ct == MAX_ENTRIES * DIR_ENT_SIZE) while(entries < MAX_ENTRIES && (e=readdir(DIR1)))
memcpy(&dir_ent[entries++], e, sizeof(*e));
closedir(DIR1);
if (entries == MAX_ENTRIES)
error(FATAL, "directory ", dir1, " is too large"); error(FATAL, "directory ", dir1, " is too large");
/* Create the target directory. */ /* Create the target directory. */
maketarget(dir2); maketarget(dir2);
/* Stat all the entries. */ /* Stat all the entries. */
n = ct / DIR_ENT_SIZE; n = entries;
m = stat_all(dir1, n); m = stat_all(dir1, n);
/* Remove non-entries and sort what's left. */ /* Remove non-entries and sort what's left. */
@ -218,29 +222,28 @@ int n;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
/* Mark "." and ".." as null entries, as well as unstatable ones. */ /* Mark "." and ".." as null entries, as well as unstatable ones. */
if (strcmp(dir_buf[i].name, ".") == 0) dir_buf[i].ino = 0; if (strcmp(dir_ent[i].d_name, ".") == 0) dir_ent[i].d_ino = 0;
if (strcmp(dir_buf[i].name, "..") == 0) dir_buf[i].ino = 0; if (strcmp(dir_ent[i].d_name, "..") == 0) dir_ent[i].d_ino = 0;
if (dir_buf[i].ino == 0) continue; if (dir_ent[i].d_ino == 0) continue;
/* Stat the file. */ /* Stat the file. */
strcpy(cbuf, dir1); snprintf(cbuf, sizeof(cbuf), "%s/%s", dir1, dir_ent[i].d_name);
strncat(cbuf, "/", (size_t)1);
strncat(cbuf, dir_buf[i].name, (size_t)NAME_SIZE);
if (stat(cbuf, &s) < 0) { if (stat(cbuf, &s) < 0) {
error(NONFATAL, "cannot stat ", cbuf, ""); error(NONFATAL, "cannot stat ", cbuf, "");
dir_buf[i].ino = 0; /* mark as unusable */ dir_ent[i].d_ino = 0; /* mark as unusable */
continue; continue;
} }
sorted[i].mode = s.st_mode; sorted[i].mode = s.st_mode;
sorted[i].acctime = s.st_atime; sorted[i].acctime = s.st_atime;
sorted[i].modtime = s.st_mtime; sorted[i].modtime = s.st_mtime;
sorted[i].namep = dir_buf[i].name; sorted[i].namep = dir_ent[i].d_name;
sorted[i].namep[NAME_SIZE-1] = '\0';
} }
/* Squeeze out all the entries whose ino field is 0. */ /* Squeeze out all the entries whose ino field is 0. */
j = 0; j = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (dir_buf[i].ino != 0) { if (dir_ent[i].d_ino != 0) {
sorted[j] = sorted[i]; sorted[j] = sorted[i];
j++; j++;
} }
@ -258,7 +261,7 @@ int m;
for (sp1 = &sorted[0]; sp1 < &sorted[m - 1]; sp1++) { for (sp1 = &sorted[0]; sp1 < &sorted[m - 1]; sp1++) {
for (sp2 = sp1 + 1; sp2 < &sorted[m]; sp2++) { for (sp2 = sp1 + 1; sp2 < &sorted[m]; sp2++) {
if (strncmp(sp1->namep, sp2->namep, (size_t)NAME_SIZE) > 0) if (strcmp(sp1->namep, sp2->namep) > 0)
swap(sp1, sp2); swap(sp1, sp2);
} }
} }
@ -274,21 +277,18 @@ char *dir1, *dir2;
* recursively call the entire program to process the directory. * recursively call the entire program to process the directory.
*/ */
int er, fmode, res, namlen; int er, fmode, res;
struct sorted *sp; struct sorted *sp;
struct stat s; struct stat s;
char cbuf[MAX_PATH]; char cbuf[MAX_PATH];
for (sp = &sorted[0]; sp < &sorted[m]; sp++) { for (sp = &sorted[0]; sp < &sorted[m]; sp++) {
int namlen;
fmode = sp->mode & S_IFMT; fmode = sp->mode & S_IFMT;
if (fmode == S_IFREG) { if (fmode == S_IFREG) {
/* Regular file. Construct target name and stat it. */ /* Regular file. Construct target name and stat it. */
strcpy(cbuf, dir2); snprintf(cbuf, sizeof(cbuf), "%s/%s", dir2, sp->namep);
strncat(cbuf, "/", (size_t)1);
strncat(cbuf, sp->namep, (size_t)NAME_SIZE);
namlen = strlen(sp->namep); namlen = strlen(sp->namep);
if (namlen > NAME_SIZE)
namlen = NAME_SIZE; /* no terminating null here */
/* Switch between compressed and uncompressed file names */ /* Switch between compressed and uncompressed file names */
if (zflag && !rflag && strncmp((sp->namep + namlen - 2), ".Z", (size_t)2) if (zflag && !rflag && strncmp((sp->namep + namlen - 2), ".Z", (size_t)2)
&& (namlen <= (NAME_SIZE - 2))) && (namlen <= (NAME_SIZE - 2)))
@ -319,7 +319,7 @@ char *dir1, *dir2;
copydir(dir1, dir2, sp->namep); copydir(dir1, dir2, sp->namep);
} else if (fmode == S_IFBLK || fmode == S_IFCHR) { } else if (fmode == S_IFBLK || fmode == S_IFCHR) {
/* Special file. */ /* Special file. */
strncpy(cbuf, sp->namep, (size_t)NAME_SIZE); strncpy(cbuf, sp->namep, sizeof(cbuf));
printf("%s is special file. Not backed up.\n", cbuf); printf("%s is special file. Not backed up.\n", cbuf);
} }
} }
@ -467,6 +467,7 @@ char *src, *targ;
int pid, status, res, s; int pid, status, res, s;
char fbuf[20]; char fbuf[20];
/* These flags go for compress and gzip. */
strcpy(fbuf, "-c"); strcpy(fbuf, "-c");
if (rflag) if (rflag)
strcat(fbuf, "d"); strcat(fbuf, "d");
@ -485,9 +486,11 @@ char *src, *targ;
close(1); close(1);
s = open(targ, O_RDWR); s = open(targ, O_RDWR);
if (s < 0) error(FATAL, "cannot write on ", "targ", ""); if (s < 0) error(FATAL, "cannot write on ", "targ", "");
execle("/usr/bin/gzip", "gzip", fbuf, src, (char *)0, environ);
execle("/usr/local/bin/gzip", "gzip", fbuf, src, (char *)0, environ);
execle("/bin/compress", "compress", fbuf, src, (char *)0, environ); execle("/bin/compress", "compress", fbuf, src, (char *)0, environ);
execle("/usr/bin/compress", "compress", fbuf, src, (char *)0, environ); execle("/usr/bin/compress", "compress", fbuf, src, (char *)0, environ);
error(FATAL, "cannot exec compress", "", ""); error(FATAL, "cannot exec gzip or compress", "", "");
} }
return(0); return(0);
} }
@ -516,12 +519,8 @@ char *dir1, *dir2, *namep;
if (tflag) strcat(fbuf, "t"); if (tflag) strcat(fbuf, "t");
if (vflag) strcat(fbuf, "v"); if (vflag) strcat(fbuf, "v");
if (zflag) strcat(fbuf, "z"); if (zflag) strcat(fbuf, "z");
strcpy(d1buf, dir1); snprintf(d1buf, sizeof(d1buf), "%s/%s", dir1, namep);
strcat(d1buf, "/"); snprintf(d2buf, sizeof(d2buf), "%s/%s", dir2, namep);
strncat(d1buf, namep, (size_t)NAME_SIZE);
strcpy(d2buf, dir2);
strcat(d2buf, "/");
strncat(d2buf, namep, (size_t)NAME_SIZE);
if ((pid = fork()) < 0) error(FATAL, "cannot fork", "", ""); if ((pid = fork()) < 0) error(FATAL, "cannot fork", "", "");
if (pid > 0) { if (pid > 0) {

View file

@ -73,6 +73,7 @@
#define DOTZ ".Z" #define DOTZ ".Z"
#include <limits.h> #include <limits.h>
#include <dirent.h>
/* The default for Minix is -b13, but we can do -b16 if the machine can. */ /* The default for Minix is -b13, but we can do -b16 if the machine can. */
#define DEFAULTBITS 13 #define DEFAULTBITS 13
@ -574,7 +575,7 @@ char **argv;
cp++; cp++;
else else
cp = ofname; cp = ofname;
if (strlen(cp) > 12) if (strlen(cp) >= _DIRENT_NAME_LEN-3)
{ {
fprintf(stderr,"%s: filename too long to tack on .Z\n",cp); fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
continue; continue;