bool Inkscape::IO::file_is_writable( char const *utf8name) { bool success = true; if ( utf8name) { gchar *filename = NULL; if (utf8name && !g_utf8_validate(utf8name, -1, NULL)) { /* FIXME: Trying to guess whether or not a filename is already in utf8 is unreliable. If any callers pass non-utf8 data (e.g. using g_get_home_dir), then change caller to use simple g_file_test. Then add g_return_val_if_fail(g_utf_validate(...), false) to beginning of this function. */ filename = g_strdup(utf8name); // Looks like g_get_home_dir isn't safe. //g_warning("invalid UTF-8 detected internally. HUNT IT DOWN AND KILL IT!!!"); } else { filename = g_filename_from_utf8 ( utf8name, -1, NULL, NULL, NULL ); } if ( filename ) { struct stat st; if (g_file_test (filename, G_FILE_TEST_EXISTS)){ if (g_lstat (filename, &st) == 0) { success = ((st.st_mode & S_IWRITE) != 0); } } g_free(filename); filename = NULL; } else { g_warning( "Unable to convert filename in IO:file_test" ); } } return success; }
static int rmdir_real (GString *path) { const gchar *dirname; struct stat st; size_t len; GDir *dir; if (!(dir = g_dir_open (path->str, 0, NULL))) return -1; g_string_append_c (path, G_DIR_SEPARATOR); len = path->len; while ((dirname = g_dir_read_name (dir))) { if (!strcmp (dirname, ".") || !strcmp (dirname, "..")) continue; g_string_truncate (path, len); g_string_append (path, dirname); if (g_lstat (path->str, &st) == 0 && S_ISDIR (st.st_mode)) rmdir_real (path); else g_unlink (path->str); } g_dir_close (dir); g_string_truncate (path, len - 1); return g_rmdir (path->str); }
/** * _thunar_vfs_io_ops_get_file_size_and_type: * @path : the #ThunarVfsPath to the file whose size and type * to determine. * @size_return : return location for the file size or %NULL. * @type_return : return location for the file type or %NULL. * @error : return location for errors or %NULL. * * Determines the size and type of the file at @path. * * Return value: %TRUE if the size and type was determined successfully, * %FALSE otherwise. **/ gboolean _thunar_vfs_io_ops_get_file_size_and_type (ThunarVfsPath *path, ThunarVfsFileSize *size_return, ThunarVfsFileType *type_return, GError **error) { struct stat statb; gboolean succeed = FALSE; gchar *absolute_path; gchar *uri; _thunar_vfs_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* determine the absolute local path for the path object */ absolute_path = _thunar_vfs_path_translate_dup_string (path, THUNAR_VFS_PATH_SCHEME_FILE, error); if (G_LIKELY (absolute_path != NULL)) { /* determine the file info for the absolute path */ succeed = (g_lstat (absolute_path, &statb) == 0); if (G_LIKELY (succeed)) { /* return size and type if requested */ if (G_LIKELY (size_return != NULL)) *size_return = statb.st_size; if (G_LIKELY (type_return != NULL)) *type_return = (statb.st_mode & S_IFMT) >> 12; } else {
/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) { struct stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend+1 > pathend_last) return (1); *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return(globextend(pathbuf, pglob, limitp)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; if (q+1 > pathend_last) return (1); *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (*pattern == SEP) { if (pathend+1 > pathend_last) return (1); *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, pglob, limitp)); } /* NOTREACHED */ }
/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2 ( Char *pathbuf, Char *pathend, Char *pattern, glob_t *pglob ) { Stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) /* End of pattern? */ { *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) #ifdef S_ISLNK /* bummer for unixware */ || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)) #endif )) { *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return(globextend(pathbuf, pglob)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; *q++ = *p++; } if (!anymeta) /* No expansion, do next segment. */ { pathend = q; pattern = p; while (*pattern == SEP) *pathend++ = *pattern++; } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathend, pattern, p, pglob)); } /* NOTREACHED */ }
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; }
int main (int argc, char *argv[]) { GError *error = NULL; GOptionContext *context; MetaLookupCache *cache; MetaTree *tree; char *tree_path; struct stat statbuf; int i; context = g_option_context_new ("<tree file> <dir in tree> - list entries"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("option parsing failed: %s\n", error->message); return 1; } cache = meta_lookup_cache_new (); for (i = 1; i < argc; i++) { if (g_lstat (argv[i], &statbuf) != 0) { g_printerr ("can't stat %s\n", argv[i]); return 1; } tree_path = NULL; tree = meta_lookup_cache_lookup_path (cache, argv[i], statbuf.st_dev, FALSE, &tree_path); if (tree) g_print ("tree: %s (exists: %d), tree path: %s\n", meta_tree_get_filename (tree), meta_tree_exists (tree), tree_path); else g_print ("tree lookup failed\n"); if (do_pause) { char buffer[1000]; g_print ("Pausing, press enter\n"); fgets(buffer, sizeof(buffer), stdin); } } return 0; }
static void check_socket_permissions(void) { GStatBuf socket_stat; if (g_lstat(socket_info.file_name, &socket_stat) == 0) { /* If the user id of the process is not the same as the owner of the socket * file, then ignore this socket and start a new session. */ if (socket_stat.st_uid != getuid()) { const gchar *msg = _( /* TODO maybe this message needs a rewording */ "Geany tried to access the Unix Domain socket of another instance running as another user.\n" "This is a fatal error and Geany will now quit."); g_warning("%s", msg); dialogs_show_msgbox(GTK_MESSAGE_ERROR, "%s", msg); exit(1); } } }
/* * Check whether JPilot PDB or PC3 file has changed by comparing * with cached data. * return: TRUE if file has changed. */ static gboolean jpilot_check_files( JPilotFile *pilotFile ) { gboolean retVal = TRUE; GStatBuf filestat; gchar *pcFile; /* Check main file */ if( addrcache_check_file( pilotFile->addressCache, pilotFile->path ) ) return TRUE; /* Test PC3 file */ if( ! pilotFile->havePC3 ) return FALSE; pcFile = jpilot_get_pc3_file( pilotFile ); if( pcFile == NULL ) return FALSE; if( 0 == g_lstat( pcFile, &filestat ) ) { if( filestat.st_mtime == pilotFile->pc3ModifyTime ) retVal = FALSE; } g_free( pcFile ); return retVal; }
/* * Save PC3 file time to cache. * return: TRUE if time marked. */ static gboolean jpilot_mark_files( JPilotFile *pilotFile ) { gboolean retVal = FALSE; GStatBuf filestat; gchar *pcFile; /* Mark PDB file cache */ retVal = addrcache_mark_file( pilotFile->addressCache, pilotFile->path ); /* Now mark PC3 file */ pilotFile->havePC3 = FALSE; pilotFile->pc3ModifyTime = 0; pcFile = jpilot_get_pc3_file( pilotFile ); if( pcFile == NULL ) return retVal; if( 0 == g_lstat( pcFile, &filestat ) ) { pilotFile->havePC3 = TRUE; pilotFile->pc3ModifyTime = filestat.st_mtime; retVal = TRUE; } g_free( pcFile ); return retVal; }
// recursively calculate the size of the specified directory static long get_size (const char *root) { // NOTE: just like Silverlight we give a minimum cost of 1KB for each // directory and file to avoid disk exhaustion by empty files/directories. long result = MOONLIGHT_MINIMUM_FILE_ENTRY_COST; struct stat info; if (g_lstat (root, &info) != 0) return result; // there should be no link in IS but, if any, we're not following them if (S_ISLNK (info.st_mode)) return result; if (S_ISDIR (info.st_mode)) { // scan everythins inside the directory GDir *dir = g_dir_open (root, 0, NULL); if (!dir) return result; // should never happen // note: g_dir_read_name *smartly* skips '.' and '..' const char *entry_name = g_dir_read_name (dir); while (entry_name) { char name [PATH_MAX]; if (g_snprintf (name, PATH_MAX, "%s/%s", root, entry_name) <= PATH_MAX) result += get_size (name); entry_name = g_dir_read_name (dir); } g_dir_close (dir); } else { // file size is computed at 1KB boundaries, minimum of 1KB (fixed cost for a file-system entry) result = (info.st_size & ~MOONLIGHT_FILE_SIZE_MASK); if ((result == 0) || (info.st_size & MOONLIGHT_FILE_SIZE_MASK)) result += MOONLIGHT_MINIMUM_FILE_ENTRY_COST; } return result; }
/** * removes directory recursively. */ void mud_dir_remove (const char * path) { GError * gerr = NULL; GDir * d = g_dir_open (path, 0, &gerr); const char * n = NULL; if (gerr) { fprintf (stderr, "%s\n", gerr->message); g_error_free (gerr); } else { struct stat buf; while ((n = g_dir_read_name (d))) { gchar * x = g_build_path (G_DIR_SEPARATOR_S, path, n, NULL); if (g_lstat (x, &buf)) { fprintf (stderr, "lstat failed on '%s'\n", x); } else { if (S_ISDIR (buf.st_mode)) mud_dir_remove (x); else if (g_remove (x)) fprintf (stderr, "unable to remove file '%s'\n", x); } g_free (x); } g_dir_close (d); } if (g_rmdir (path)) fprintf (stderr, "unable to remove directory '%s'\n", path); }
static int checkout_entry (struct cache_entry *ce, struct unpack_trees_options *o, gboolean recover_merge, const char *conflict_suffix) { int base_len = strlen(o->base); int len = ce_namelen(ce); int full_len; char path[PATH_MAX]; int offset; struct stat st; char file_id[41]; if (!len) { g_warning ("entry name should not be empty.\n"); return -1; } snprintf (path, PATH_MAX, "%s/", o->base); /* first create all leading directories. */ full_len = base_len + len + 1; offset = base_len + 1; while (offset < full_len) { do { path[offset] = ce->name[offset-base_len-1]; offset++; } while (offset < full_len && ce->name[offset-base_len-1] != '/'); if (offset >= full_len) break; path[offset] = 0; if (g_lstat (path, &st) == 0 && S_ISDIR(st.st_mode)) continue; if (ccnet_mkdir (path, 0777) < 0) { g_warning ("Failed to create directory %s.\n", path); return -1; } } path[offset] = 0; if (!S_ISDIR(ce->ce_mode)) { /* In case that we're replacing an empty dir with a file, * we need first to remove the empty dir. */ if (g_lstat (path, &st) == 0 && S_ISDIR(st.st_mode)) { if (g_rmdir (path) < 0) { g_warning ("Failed to remove dir %s: %s\n", path, strerror(errno)); /* Don't quit since we can handle conflict later. */ } } } else { /* For simplicity, we just don't checkout the empty dir if there is * already a file with the same name in the worktree. * This implies, you can't remove a file then create an empty directory * with the same name. But it's a rare requirement. */ if (g_mkdir (path, 0777) < 0) { g_warning ("Failed to create empty dir %s.\n", path); } return 0; } if (!o->reset && g_lstat (path, &st) == 0 && S_ISREG(st.st_mode) && (ce->ce_ctime.sec != st.st_ctime || ce->ce_mtime.sec != st.st_mtime)) { /* If we're recovering an interrupted merge, we don't know whether * the file was changed by checkout or by the user. So we have to * calculate the sha1 for that file and compare it with the one in * cache entry. */ if (!recover_merge || compare_file_content (path, &st, ce->sha1, o->crypt) != 0) { g_warning ("File %s is changed. Skip checking out.\n", path); return -1; } /* Recover merge and file content matches index entry. * We were interrupted before updating the index, update index * entry timestamp now. */ goto update_cache; } /* then checkout the file. */ rawdata_to_hex (ce->sha1, file_id, 20); if (seaf_fs_manager_checkout_file (seaf->fs_mgr, file_id, path, ce->ce_mode, o->crypt, conflict_suffix) < 0) { g_warning ("Failed to checkout file %s.\n", path); return -1; } update_cache: /* finally fill cache_entry info */ g_lstat (path, &st); fill_stat_cache_info (ce, &st); return 0; }
static int unlink_entry (struct cache_entry *ce, struct unpack_trees_options *o) { char path[PATH_MAX]; struct stat st; int base_len = strlen(o->base); int len = ce_namelen(ce); int offset; if (!len) { g_warning ("entry name should not be empty.\n"); return -1; } snprintf (path, PATH_MAX, "%s/%s", o->base, ce->name); if (!S_ISDIR(ce->ce_mode)) { /* file doesn't exist in work tree */ if (g_lstat (path, &st) < 0 || !S_ISREG(st.st_mode)) { return 0; } /* file has been changed. */ if (!o->reset && (ce->ce_ctime.sec != st.st_ctime || ce->ce_mtime.sec != st.st_mtime)) { g_warning ("File %s is changed. Skip removing the file.\n", path); return -1; } /* first unlink the file. */ if (g_unlink (path) < 0) { g_warning ("Failed to remove %s: %s.\n", path, strerror(errno)); return -1; } } else { if (g_lstat (path, &st) < 0 || !S_ISDIR(st.st_mode)) return 0; if (g_rmdir (path) < 0) { g_warning ("Failed to remove %s: %s.\n", path, strerror(errno)); return -1; } } /* then remove all empty directories upwards. */ offset = base_len + len; do { if (path[offset] == '/') { path[offset] = '\0'; int ret = g_rmdir (path); if (ret < 0 && errno == ENOTEMPTY) { break; } else if (ret < 0) { g_warning ("Failed to remove %s: %s.\n", path, strerror(errno)); return -1; } } } while (--offset > base_len); return 0; }
void wt_status_collect_changes_worktree(struct index_state *index, GList **results, const char *worktree, IgnoreFunc ignore_func) { DiffEntry *de; int entries, i; entries = index->cache_nr; for (i = 0; i < entries; i++) { char *realpath; struct stat st; struct cache_entry *ce = index->cache[i]; int changed = 0; if (ce_stage(ce)) { int mask = 0; mask |= 1 << ce_stage(ce); while (i < entries) { struct cache_entry *nce = index->cache[i]; if (strcmp(ce->name, nce->name)) break; mask |= 1 << ce_stage(nce); i++; } /* * Compensate for loop update */ i--; de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_UNMERGED, ce->sha1, ce->name); de->unmerge_state = diff_unmerged_state (mask); *results = g_list_prepend (*results, de); continue; } if (ce_uptodate(ce) || ce_skip_worktree(ce)) continue; realpath = g_build_path (PATH_SEPERATOR, worktree, ce->name, NULL); if (g_lstat(realpath, &st) < 0) { if (errno != ENOENT && errno != ENOTDIR) changed = -1; changed = 1; } if (changed) { if (changed < 0) { g_warning ("Faile to stat %s: %s\n", ce->name, strerror(errno)); g_free (realpath); continue; } de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DELETED, ce->sha1, ce->name); *results = g_list_prepend (*results, de); g_free (realpath); continue; } if (S_ISDIR (ce->ce_mode)) { if (!S_ISDIR (st.st_mode) || !is_empty_dir (realpath, ignore_func)) { de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DIR_DELETED, ce->sha1, ce->name); *results = g_list_prepend (*results, de); } g_free (realpath); continue; } g_free (realpath); changed = ie_match_stat (index, ce, &st, 0); if (!changed) { ce_mark_uptodate (ce); continue; } de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_MODIFIED, ce->sha1, ce->name); *results = g_list_prepend (*results, de); } }
/* destructive copy that will remove dst path if it exists */ gboolean utility_copyAll(const gchar* srcPath, const gchar* dstPath) { if(!dstPath || !srcPath || !g_file_test(srcPath, G_FILE_TEST_EXISTS)) { return FALSE; } /* if destination already exists, delete it */ if(g_file_test(dstPath, G_FILE_TEST_EXISTS) && !utility_removeAll(dstPath)) { return FALSE; } /* get file/dir mode */ struct stat statbuf; memset(&statbuf, 0, sizeof(struct stat)); if(g_lstat(srcPath, &statbuf) != 0) { warning("unable to stat src path '%s': error %i: %s", srcPath, errno, strerror(errno)); return FALSE; } /* now create the dir or copy the file */ if(g_file_test(srcPath, G_FILE_TEST_IS_DIR)) { /* create new dir with same mode as the old */ if(g_mkdir(dstPath, statbuf.st_mode) != 0) { warning("unable to make dst path '%s': error %i: %s", dstPath, errno, strerror(errno)); return FALSE; } else { /* now recurse into this directory */ GError* err = NULL; GDir* dir = g_dir_open(srcPath, 0, &err); if(err) { warning("unable to open directory '%s': error %i: %s", srcPath, err->code, err->message); return FALSE; } else { gboolean isSuccess = TRUE; const gchar* entry = NULL; while((entry = g_dir_read_name(dir)) != NULL) { gchar* srcChildPath = g_build_filename(srcPath, entry, NULL); gchar* dstChildPath = g_build_filename(dstPath, entry, NULL); isSuccess = utility_copyAll(srcChildPath, dstChildPath); g_free(srcChildPath); g_free(dstChildPath); if(!isSuccess) { break; } } g_dir_close(dir); if(!isSuccess) { return FALSE; } } } } else { gchar* srcContents = NULL; gsize srcLength = 0; GError* err = NULL; gboolean isSuccess = g_file_get_contents(srcPath, &srcContents, &srcLength, &err); if(isSuccess && !err) { isSuccess = g_file_set_contents(dstPath, srcContents, (gssize)srcLength, &err); if(isSuccess & !err) { info("copied path '%s' to '%s'", srcPath, dstPath); } } if(srcContents) { g_free(srcContents); } if(err) { warning("unable to read file '%s': error %i: %s", srcPath, err->code, err->message); g_error_free(err); return FALSE; } } if(g_chmod(dstPath, statbuf.st_mode) != 0) { warning("unable to chmod dst path '%s': error %i: %s", dstPath, errno, strerror(errno)); return FALSE; } return TRUE; }
/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) { Stat_t sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == BG_EOS) { /* End of pattern? */ *pathend = BG_EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != BG_SEP #ifdef DOSISH && pathend[-1] != BG_SEP2 #endif ) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { #ifdef MACOS_TRADITIONAL short err; err = glob_mark_Mac(pathbuf, pathend, pathend_last); if (err) return (err); #else if (pathend+1 > pathend_last) return (1); *pathend++ = BG_SEP; *pathend = BG_EOS; #endif } ++pglob->gl_matchc; #ifdef GLOB_DEBUG printf("calling globextend from glob2\n"); #endif /* GLOB_DEBUG */ return(globextend(pathbuf, pglob, limitp)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != BG_EOS && *p != BG_SEP #ifdef DOSISH && *p != BG_SEP2 #endif ) { if (ismeta(*p)) anymeta = 1; if (q+1 > pathend_last) return (1); *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (*pattern == BG_SEP #ifdef DOSISH || *pattern == BG_SEP2 #endif ) { if (pathend+1 > pathend_last) return (1); *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, p, pattern_last, pglob, limitp)); } /* NOTREACHED */ }
int main (int argc, char *argv[]) { MetaTree *tree; GError *error = NULL; GOptionContext *context; MetaLookupCache *lookup; struct stat statbuf; const char *path, *key; const char *metatreefile; char *tree_path; GVfsMetadata *proxy; g_type_init(); context = g_option_context_new ("<path> <key> <value> - set metadata"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("option parsing failed: %s\n", error->message); return 1; } if (argc < 2) { g_printerr ("no path specified\n"); return 1; } path = argv[1]; if (argc < 3) { g_printerr ("no key specified\n"); return 1; } key = argv[2]; if (!list && !unset && argc != 4) { g_print ("No value specified\n"); return 1; } if (treename) { tree = meta_tree_lookup_by_name (treename, TRUE); if (tree) tree_path = g_strdup (path); if (tree == NULL) { g_printerr ("can't open metadata tree %s\n", path); return 1; } } else { lookup = meta_lookup_cache_new (); if (g_lstat (path, &statbuf) != 0) { g_printerr ("can't find file %s\n", path); return 1; } tree = meta_lookup_cache_lookup_path (lookup, path, statbuf.st_dev, TRUE, &tree_path); meta_lookup_cache_free (lookup); if (tree == NULL) { g_printerr ("can't open metadata tree for file %s\n", path); return 1; } } proxy = NULL; if (use_dbus) { proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, G_VFS_DBUS_METADATA_NAME, G_VFS_DBUS_METADATA_PATH, NULL, &error); if (proxy == NULL) { g_printerr ("Unable to connect to dbus: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); return 1; } g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), 1000*30); } if (unset) { if (use_dbus) { metatreefile = meta_tree_get_filename (tree); if (! gvfs_metadata_call_unset_sync (proxy, metatreefile, tree_path, key, NULL, &error)) { g_printerr ("Unset error: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); return 1; } } else { if (!meta_tree_unset (tree, tree_path, key)) { g_printerr ("Unable to unset key\n"); return 1; } } } else if (list) { if (use_dbus) { char **strv; GVariantBuilder *builder; metatreefile = meta_tree_get_filename (tree); strv = &argv[3]; builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const *) strv, -1)); if (! gvfs_metadata_call_set_sync (proxy, metatreefile, tree_path, g_variant_builder_end (builder), NULL, &error)) { g_printerr ("SetStringv error: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); return 1; } g_variant_builder_unref (builder); } else { if (!meta_tree_set_stringv (tree, tree_path, key, &argv[3])) { g_printerr ("Unable to set key\n"); return 1; } } } else { if (use_dbus) { GVariantBuilder *builder; metatreefile = meta_tree_get_filename (tree); builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (argv[3])); if (! gvfs_metadata_call_set_sync (proxy, metatreefile, tree_path, g_variant_builder_end (builder), NULL, &error)) { g_printerr ("SetString error: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); return 1; } g_variant_builder_unref (builder); } else { if (!meta_tree_set_string (tree, tree_path, key, argv[3])) { g_printerr ("Unable to set key\n"); return 1; } } } if (proxy) g_object_unref (proxy); return 0; }
SeafileSession * seafile_session_new(const char *seafile_dir, CcnetClient *ccnet_session) { char *abs_seafile_dir; char *tmp_file_dir; char *config_file_path; struct stat st; GKeyFile *config; SeafileSession *session = NULL; if (!ccnet_session) return NULL; abs_seafile_dir = ccnet_expand_path (seafile_dir); tmp_file_dir = g_build_filename (abs_seafile_dir, "tmpfiles", NULL); config_file_path = g_build_filename (abs_seafile_dir, "seafile.conf", NULL); if (g_lstat(abs_seafile_dir, &st) < 0 || !S_ISDIR(st.st_mode)) { g_warning ("Seafile data dir %s does not exist\n", abs_seafile_dir); goto onerror; } if (g_lstat(tmp_file_dir, &st) < 0 || !S_ISDIR(st.st_mode)) { g_warning ("Seafile tmp dir %s does not exist\n", tmp_file_dir); goto onerror; } GError *error = NULL; config = g_key_file_new (); if (!g_key_file_load_from_file (config, config_file_path, G_KEY_FILE_NONE, &error)) { g_warning ("Failed to load config file.\n"); g_key_file_free (config); goto onerror; } session = g_new0(SeafileSession, 1); session->seaf_dir = abs_seafile_dir; session->tmp_file_dir = tmp_file_dir; session->session = ccnet_session; session->config = config; if (load_database_config (session) < 0) { g_warning ("Failed to load database config.\n"); goto onerror; } session->fs_mgr = seaf_fs_manager_new (session, abs_seafile_dir); if (!session->fs_mgr) goto onerror; session->block_mgr = seaf_block_manager_new (session, abs_seafile_dir); if (!session->block_mgr) goto onerror; session->commit_mgr = seaf_commit_manager_new (session); if (!session->commit_mgr) goto onerror; session->repo_mgr = seaf_repo_manager_new (session); if (!session->repo_mgr) goto onerror; session->branch_mgr = seaf_branch_manager_new (session); if (!session->branch_mgr) goto onerror; return session; onerror: free (abs_seafile_dir); g_free (tmp_file_dir); g_free (config_file_path); g_free (session); return NULL; }