/* * Returns < 0 if dira includes dirb or dira == dirb; * Returns 0 if no inclusive relationship; * Returns > 0 if dirb includes dira. */ static int check_dir_inclusiveness (const char *dira, const char *dirb) { char *a, *b; char *p1, *p2; int ret = 0; a = g_strdup(dira); b = g_strdup(dirb); remove_trail_slash (a); remove_trail_slash (b); p1 = a; p2 = b; while (*p1 != 0 && *p2 != 0) { /* Go to the last one in a path separator sequence. */ while (is_separator(*p1) && is_separator(p1[1])) ++p1; while (is_separator(*p2) && is_separator(p2[1])) ++p2; if (!(is_separator(*p1) && is_separator(*p2)) && *p1 != *p2) goto out; ++p1; ++p2; } /* Example: * p1 * a: /abc/def/ghi * p2 * b: /abc/def */ if (*p1 == 0 && *p2 == 0) ret = -1; else if (*p1 != 0 && is_separator(*p1)) ret = 1; else if (*p2 != 0 && is_separator(*p2)) ret = -1; out: g_free (a); g_free (b); return ret; }
static char * make_worktree (SeafCloneManager *mgr, const char *worktree, gboolean dry_run, GError **error) { char *wt = g_strdup (worktree); struct stat st; int rc; char *ret; remove_trail_slash (wt); rc = g_lstat (wt, &st); if (rc < 0 && errno == ENOENT) { ret = wt; goto mk_dir; } else if (rc < 0 || !S_ISDIR(st.st_mode)) { if (!dry_run) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Invalid local directory"); g_free (wt); return NULL; } ret = try_worktree (wt); g_free (wt); goto mk_dir; } /* OK, wt is an existing dir. Let's see if it's the worktree for * another repo. */ if (is_worktree_of_repo (mgr, wt)) { if (!dry_run) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Already in sync"); g_free (wt); return NULL; } ret = try_worktree (wt); g_free (wt); } else { return wt; } mk_dir: if (!dry_run && g_mkdir_with_parents (ret, 0777) < 0) { seaf_warning ("[clone mgr] Failed to create dir %s.\n", ret); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to create worktree"); g_free (ret); return NULL; } return ret; }
static char * make_worktree (SeafCloneManager *mgr, const char *worktree, gboolean dry_run, GError **error) { char *wt = g_strdup (worktree); SeafStat st; int rc; char *ret; remove_trail_slash (wt); rc = seaf_stat (wt, &st); if (rc < 0 && errno == ENOENT) { ret = wt; return ret; } else if (rc < 0 || !S_ISDIR(st.st_mode)) { if (!dry_run) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Invalid local directory"); g_free (wt); return NULL; } ret = try_worktree (wt); g_free (wt); return ret; } /* OK, wt is an existing dir. Let's see if it's the worktree for * another repo. */ if (is_worktree_of_repo (mgr, wt)) { if (!dry_run) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Already in sync"); g_free (wt); return NULL; } ret = try_worktree (wt); g_free (wt); } else { return wt; } return ret; }