Permalink
Browse files

Implement reading of ._rdup_. files

These hold user/group info and wil get written when chowning
a file fails.
  • Loading branch information...
1 parent 755f750 commit 306946244f2d31b489ee7f4a207c40cbc9219bd1 @miekg committed May 25, 2012
Showing with 52 additions and 9 deletions.
  1. +35 −5 chown.c
  2. +16 −4 crawler.c
  3. +1 −0 rdup.h.in
View
40 chown.c
@@ -13,21 +13,51 @@ void
chown_write(gchar *dir, gchar *base, uid_t u, gchar *user, gid_t g, gchar *group)
{
FILE *f;
- gchar *path = g_strdup_printf("%s/%s%s", dir, USRGRPINFO, base);
+ gchar *path;
+ if (base == NULL) {
+ /* a directory, i.e. /tmp/._rdup_. */
+ path = g_strdup_printf("%s/%s", dir, USRGRPINFO);
+ } else {
+ path = g_strdup_printf("%s/%s%s", dir, USRGRPINFO, base);
+ }
if ( ! ( f = fopen(path, "r"))) {
/* no file found or failure to open */
g_free(path);
return;
}
g_free(path);
- fprintf(f, "%s:%d/%s:%d", user, u, group, g);
+ fprintf(f, "%s:%d/%s:%d\n", user, u, group, g);
fclose(f);
}
/* parse the chown help file */
-chown_pack
+struct chown_pack *
chown_parse(gchar *dir, gchar *base)
{
- dir = dir; base = base;
- return NULL;
+ FILE *f;
+ gchar *path;
+ if (base == NULL) {
+ /* a directory */
+ path = g_strdup_printf("%s/%s", dir, USRGRPINFO);
+ } else {
+ path = g_strdup_printf("%s/%s%s", dir, USRGRPINFO, base);
+ }
+ if ( ! ( f = fopen(path, "r"))) {
+ /* no file found or failure to open */
+ g_free(path);
+ return NULL;
+ }
+ long int u, g;
+ gchar *user = g_malloc(17);
+ gchar *group = g_malloc(17);
+ struct chown_pack *cp = g_malloc(sizeof(struct chown_pack));
+ if ( fscanf(f, "%16[^:]:%ld/%16[^:]:%ld\n", user, &u, group, &g) != 4) {
+ /* failure to parse the file */
+ return NULL;
+ }
+ cp->u = (uid_t)u;
+ cp->g = (gid_t)g;
+ cp->user = user;
+ cp->group = group;
+ return cp;
}
View
@@ -95,6 +95,7 @@ dir_crawl(GTree *t, GHashTable *linkhash, GHashTable *userhash,
DIR *dir;
struct dirent *dent;
struct rdup *directory;
+ struct chown_pack *cp;
char *curpath;
gchar *lnk;
struct stat s;
@@ -219,10 +220,13 @@ dir_crawl(GTree *t, GHashTable *linkhash, GHashTable *userhash,
pop.f_size = pop.f_name_size;
pop.f_name_size += 4 + strlen(pop.f_target);
}
- /* check if there exists a USRGRPINFO + 'curfile' file and if so parse it's
- * contents and set uid:user/gid:group */
-
-
+ /* check for USRGRPINFO file */
+ if ( (cp = chown_parse(path, dent->d_name)) != NULL ) {
+ pop.f_uid = cp->u;
+ pop.f_gid = cp->g;
+ pop.f_user = cp->user;
+ pop.f_group = cp->group;
+ }
g_tree_insert(t, (gpointer) entry_dup(&pop), VALUE);
if (pop.f_target != NULL)
@@ -259,6 +263,14 @@ dir_crawl(GTree *t, GHashTable *linkhash, GHashTable *userhash,
dirstack[d]->f_ino = s.st_ino;
dirstack[d]->f_lnk = 0;
+ /* check for USRGRPINFO file */
+ if ( (cp = chown_parse(curpath, NULL)) != NULL ) {
+ dirstack[d]->f_uid = cp->u;
+ dirstack[d]->f_gid = cp->g;
+ dirstack[d]->f_user = cp->user;
+ dirstack[d]->f_group = cp->group;
+ }
+
if (d++ % D_STACKSIZE == 0) {
dirstack = g_realloc(dirstack,
++dstack_cnt * D_STACKSIZE *
View
@@ -91,6 +91,7 @@ struct chown_pack {
};
void chown_write(gchar *dir, gchar *base, uid_t u, gchar *user, gid_t g, gchar *group);
+struct chown_pack * chown_parse(gchar *dir, gchar *base);
/* chown_parse */
/* child.c */

0 comments on commit 3069462

Please sign in to comment.