annotate lib/dirtree.c @ 237:7cb15eae1664

Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS() macros in each C file, and making generated/globals.h from that. Rename "toy" to "this" along the way to avoid toy/toys confusion.
author Rob Landley <rob@landley.net>
date Sun, 20 Jan 2008 17:25:44 -0600
parents 1e8f4b05cb65
children e64dec29965d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* vi: set sw=4 ts=4 :*/
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
2 /* dirtree.c - Functions for dealing with directory trees.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
3 *
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
4 * Copyright 2007 Rob Landley <rob@landley.net>
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
5 */
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
6
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
7 #include "toys.h"
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
8
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
9 // Create a dirtree node from a path.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
10
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
11 struct dirtree *dirtree_add_node(char *path)
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
12 {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
13 struct dirtree *dt;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
14 char *name;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
15
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
16 // Find last chunk of name.
156
1e8f4b05cb65 Remove trailing whitespace (thanks to Charlie Shepherd), and a couple comment
Rob Landley <rob@landley.net>
parents: 143
diff changeset
17
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
18 for (;;) {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
19 name = strrchr(path, '/');
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
20
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
21 if (!name) name = path;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
22 else {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
23 if (*(name+1)) name++;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
24 else {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
25 *name=0;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
26 continue;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
27 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
28 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
29 break;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
30 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
31
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
32 dt = xzalloc(sizeof(struct dirtree)+strlen(name)+1);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
33 xstat(path, &(dt->st));
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
34 strcpy(dt->name, name);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
35
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
36 return dt;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
37 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
38
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
39 // Given a directory (in a writeable PATH_MAX buffer), recursively read in a
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
40 // directory tree.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
41 //
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
42 // If callback==NULL, allocate tree of struct dirtree and
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
43 // return root of tree. Otherwise call callback(node) on each hit, free
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
44 // structures after use, and return NULL.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
45
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
46 struct dirtree *dirtree_read(char *path, struct dirtree *parent,
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
47 int (*callback)(struct dirtree *node))
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
48 {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
49 struct dirtree *dt = NULL, **ddt = &dt;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
50 DIR *dir;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
51 int len = strlen(path);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
52
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
53 if (!(dir = opendir(path))) perror_msg("No %s", path);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
54
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
55 for (;;) {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
56 struct dirent *entry = readdir(dir);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
57 if (!entry) break;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
58
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
59 // Skip "." and ".."
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
60 if (entry->d_name[0]=='.') {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
61 if (!entry->d_name[1]) continue;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
62 if (entry->d_name[1]=='.' && !entry->d_name[2]) continue;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
63 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
64
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
65 snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
66 *ddt = dirtree_add_node(path);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
67 (*ddt)->parent = parent;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
68 if (callback) callback(*ddt);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
69 if (entry->d_type == DT_DIR)
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
70 (*ddt)->child = dirtree_read(path, *ddt, callback);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
71 if (callback) free(*ddt);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
72 else ddt = &((*ddt)->next);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
73 path[len]=0;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
74 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
75
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
76 return dt;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
77 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
78
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
79