Be more careful about tree entry modes.
authorLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 5 May 2005 23:18:48 +0000 (16:18 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 5 May 2005 23:18:48 +0000 (16:18 -0700)
The tree object parsing used to get the executable bit wrong,
and didn't know about symlinks. Also, fsck really wants the
full mode value so that it can verify the other bits for sanity,
so save it all in struct tree_entry.

fsck-cache.c
tree.c
tree.h

index 301cc67..abdec92 100644 (file)
@@ -100,6 +100,28 @@ static int fsck_tree(struct tree *item)
                if (strchr(entry->name, '/'))
                        has_full_path = 1;
 
+               switch (entry->mode) {
+               /*
+                * Standard modes.. 
+                */
+               case S_IFREG | 0755:
+               case S_IFREG | 0644:
+               case S_IFLNK:
+               case S_IFDIR:
+                       break;
+               /*
+                * This is nonstandard, but we had a few of these
+                * early on when we honored the full set of mode
+                * bits..
+                */
+               case S_IFREG | 0664:
+                       break;
+               default:
+                       printf("tree %s has entry %o %s\n",
+                               sha1_to_hex(item->object.sha1),
+                               entry->mode, entry->name);
+               }
+
                if (last) {
                        if (verify_ordered(last, entry) < 0) {
                                fprintf(stderr, "tree %s not ordered\n",
diff --git a/tree.c b/tree.c
index 4a26603..468f99e 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -122,8 +122,10 @@ int parse_tree(struct tree *item)
 
                entry = xmalloc(sizeof(struct tree_entry_list));
                entry->name = strdup(path + 1);
-               entry->directory = S_ISDIR(mode);
-               entry->executable = mode & S_IXUSR;
+               entry->directory = S_ISDIR(mode) != 0;
+               entry->executable = (mode & S_IXUSR) != 0;
+               entry->symlink = S_ISLNK(mode) != 0;
+               entry->mode = mode;
                entry->next = NULL;
 
                bufptr += len + 20;
diff --git a/tree.h b/tree.h
index 96cf429..e1c94c0 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -9,6 +9,8 @@ struct tree_entry_list {
        struct tree_entry_list *next;
        unsigned directory : 1;
        unsigned executable : 1;
+       unsigned symlink : 1;
+       unsigned int mode;
        char *name;
        union {
                struct tree *tree;