Break out dirtree.c and let it call a function instead of returning the data.
authorRob Landley <rob@landley.net>
Thu, 4 Oct 2007 07:04:10 +0000 (02:04 -0500)
committerRob Landley <rob@landley.net>
Thu, 4 Oct 2007 07:04:10 +0000 (02:04 -0500)
lib/dirtree.c [new file with mode: 0644]
lib/lib.c
lib/lib.h
toys/mke2fs.c

diff --git a/lib/dirtree.c b/lib/dirtree.c
new file mode 100644 (file)
index 0000000..b64dfaf
--- /dev/null
@@ -0,0 +1,79 @@
+/* vi: set sw=4 ts=4 :*/
+/* dirtree.c - Functions for dealing with directory trees.
+ *
+ * Copyright 2007 Rob Landley <rob@landley.net>
+ */
+
+#include "toys.h"
+
+// Create a dirtree node from a path.
+
+struct dirtree *dirtree_add_node(char *path)
+{
+       struct dirtree *dt;
+       char *name;
+
+       // Find last chunk of name.
+       
+       for (;;) {
+               name = strrchr(path, '/');
+
+               if (!name) name = path;
+               else {
+                       if (*(name+1)) name++;
+                       else {
+                               *name=0;
+                               continue;
+                       }
+               }
+               break;
+       }
+
+       dt = xzalloc(sizeof(struct dirtree)+strlen(name)+1);
+       xstat(path, &(dt->st));
+       strcpy(dt->name, name);
+
+       return dt;
+}
+
+// Given a directory (in a writeable PATH_MAX buffer), recursively read in a
+// directory tree.
+//
+// If callback==NULL, allocate tree of struct dirtree and
+// return root of tree.  Otherwise call callback(node) on each hit, free
+// structures after use, and return NULL.
+
+struct dirtree *dirtree_read(char *path, struct dirtree *parent,
+                                       int (*callback)(struct dirtree *node))
+{
+       struct dirtree *dt = NULL, **ddt = &dt;
+       DIR *dir;
+       int len = strlen(path);
+
+       if (!(dir = opendir(path))) perror_msg("No %s", path);
+
+       for (;;) {
+               struct dirent *entry = readdir(dir);
+               if (!entry) break;
+
+               // Skip "." and ".."
+               if (entry->d_name[0]=='.') {
+                       if (!entry->d_name[1]) continue;
+                       if (entry->d_name[1]=='.' && !entry->d_name[2]) continue;
+               }
+
+               snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name);
+               *ddt = dirtree_add_node(path);
+               (*ddt)->parent = parent;
+               if (callback) callback(*ddt);
+               if (entry->d_type == DT_DIR)
+                       (*ddt)->child = dirtree_read(path, *ddt, callback);
+               if (callback) free(*ddt);
+               else ddt = &((*ddt)->next);
+               path[len]=0;
+       }
+
+       return dt;
+}
+
+
index 64c8569..7cb29f8 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -549,65 +549,3 @@ void xpidfile(char *name)
        xwrite(fd, spid, sprintf(spid, "%ld\n", (long)getpid()));
        close(fd);
 }
-
-// Create a dirtree node from a path.
-
-struct dirtree *read_dirtree_node(char *path)
-{
-       struct dirtree *dt;
-       char *name;
-
-       // Find last chunk of name.
-       
-       for (;;) {
-               name = strrchr(path, '/');
-
-               if (!name) name = path;
-               else {
-                       if (*(name+1)) name++;
-                       else {
-                               *name=0;
-                               continue;
-                       }
-               }
-               break;
-       }
-
-       dt = xzalloc(sizeof(struct dirtree)+strlen(name)+1);
-       xstat(path, &(dt->st));
-       strcpy(dt->name, name);
-
-       return dt;
-}
-
-// Given a directory (in a writeable PATH_MAX buffer), recursively read in a
-// directory tree.
-
-struct dirtree *read_dirtree(char *path, struct dirtree *parent)
-{
-       struct dirtree *dt = NULL, **ddt = &dt;
-       DIR *dir;
-       int len = strlen(path);
-
-       if (!(dir = opendir(path))) perror_msg("No %s", path);
-
-       for (;;) {
-               struct dirent *entry = readdir(dir);
-               if (!entry) break;
-
-               // Skip "." and ".."
-               if (entry->d_name[0]=='.') {
-                       if (!entry->d_name[1]) continue;
-                       if (entry->d_name[1]=='.' && !entry->d_name[2]) continue;
-               }
-
-               snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name);
-               *ddt = read_dirtree_node(path);
-               (*ddt)->parent = parent;
-               if (entry->d_type == DT_DIR) (*ddt)->child = read_dirtree(path, *ddt);
-               ddt = &((*ddt)->next);
-               path[len]=0;
-       }
-
-       return dt;
-}
index 37a94a5..4cc2dac 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -21,16 +21,21 @@ struct arg_list {
        char *arg;
 };
 
+// args.c
+void get_optflags(void);
+
+// dirtree.c
 struct dirtree {
        struct dirtree *next, *child, *parent;
        struct stat st;
        char name[];
 };
 
-// args.c
-void get_optflags(void);
+struct dirtree *dirtree_add_node(char *path);
+struct dirtree *dirtree_read(char *path, struct dirtree *parent,
+                    int (*callback)(struct dirtree *node));
 
-// functions.c
+// lib.c
 #if !defined(__UCLIBC__) && !defined(__KLIBC__)
 void strlcpy(char *dest, char *src, size_t size);
 #endif
@@ -72,8 +77,6 @@ char *itoa(int n);
 long atolx(char *c);
 off_t fdlength(int fd);
 char *xreadlink(char *name);
-struct dirtree *read_dirtree_node(char *path);
-struct dirtree *read_dirtree(char *path, struct dirtree *parent);
 
 // getmountlist.c
 struct mtab_list {
index 30612ee..b102a2f 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "toys.h"
 
+// Shortcut to our global data structure, since we use it so much.
 #define TT toy.mke2fs
 
 #define INODES_RESERVED 10
@@ -26,13 +27,16 @@ static uint32_t file_blocks_used(uint64_t size, uint32_t *blocklist)
        uint32_t dblocks = (uint32_t)((size+(TT.blocksize-1))/TT.blocksize);
        uint32_t idx=TT.blocksize/4, iblocks=0, diblocks=0, tiblocks=0;
 
-       // Fill out index blocks.
+       // Fill out index blocks in inode.
 
        if (blocklist) {
                int i;
 
+               // Direct index blocks
                for (i=0; i<13 && i<dblocks; i++) blocklist[i] = i;
+               // Singly indirect index blocks
                if (dblocks > 13+idx) blocklist[13] = 13+idx;
+               // Doubly indirect index blocks
                idx = 13 + idx + (idx*idx);
                if (dblocks > idx) blocklist[14] = idx;
 
@@ -131,7 +135,7 @@ static void check_treelinks(struct dirtree *tree)
 // On the other hand, we have 128 bits to come up with a unique identifier, of
 // which 6 have a defined value.  /dev/urandom it is.
 
-static void fake_uuid(char *uuid)
+static void create_uuid(char *uuid)
 {
        // Read 128 random bits
        int fd = xopen("/dev/urandom", O_RDONLY);
@@ -206,7 +210,7 @@ static void init_superblock(struct ext2_superblock *sb)
        sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE);
        sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);
 
-       fake_uuid(sb->uuid);
+       create_uuid(sb->uuid);
        
        // TODO If we're called as mke3fs or mkfs.ext3, do a journal.
 
@@ -331,13 +335,17 @@ static void fill_inode(struct ext2_inode *in, struct dirtree *this)
        // in->faddr
 }
 
+// Works like an archiver.
+// The first argument is the name of the file to create.  If it already
+// exists, that size will be used.
+
 int mke2fs_main(void)
 {
        int i, temp;
        off_t length;
        uint32_t usedblocks, usedinodes, dtiblk, dtbblk;
        struct dirtree *dti, *dtb;
-       
+
        // Handle command line arguments.
 
        if (toys.optargs[1]) {
@@ -363,7 +371,7 @@ int mke2fs_main(void)
 
        if (TT.gendir) {
                strncpy(toybuf, TT.gendir, sizeof(toybuf));
-               dti = read_dirtree(toybuf, NULL);
+               dti = dirtree_read(toybuf, NULL, NULL);
        } else {
                dti = xzalloc(sizeof(struct dirtree)+11);
                strcpy(dti->name, "lost+found");