static gint hashfs_fuse_open (const gchar *path, struct fuse_file_info *fi) { GList *entries, *item; gint rval = 0; const gchar *realpath; hashfs_db_entry_t *entry; printf("open: %s\n", path); entries = resolve_paths(path); if (!entries) return -ENOENT; if ((fi->flags & 3) != O_RDONLY) return -EACCES; item = g_list_last(entries); entry = item->data; if (hashfs_db_entry_lookup(entry, "path", &realpath)) { fi->fh = open(realpath, fi->flags); } free_entry_list(entries); return 0; }
static int process_file_entry(const char *base, const char *filename, const char *addr, const char *entry, int write_file) { int errors = 0; // base + '/' + filename + '\0' char *fn = malloc(strlen(base) + 1 + strlen(filename) + 1); strcpy(fn, base); strcat(fn, "/"); strcat(fn, filename); struct entry_list_t *entries; entries = read_entry_list(fn); if (set_entry_list(&entries, addr, entry)) { if (write_file) { errors += write_entry_list(fn, entries); } else { errors += 1; } } free_entry_list(entries); free(fn); return errors; }
/* free allocated memory */ static void free_test_array(test_array_t *pta) { int h; for (h = 0; h != MAX_HASH_VALUE; h++) { free_entry_list(pta->hash[h]); pta->hash[h] = NULL; } }
static gint hashfs_fuse_listattrs (const gchar *path, struct stat *stats) { GList *entries; gint rval; entries = resolve_paths(path); if (entries) { GList *item = g_list_last(entries); hashfs_db_entry_t *entry = item->data; const gchar *pkey; pkey = hashfs_db_entry_pkey(entry); if (g_strrstr(pkey, "set:")) { stats->st_mode = S_IFDIR | 0755; stats->st_nlink = 2; } else { struct stat realstats; const gchar *realpath; if (hashfs_db_entry_lookup(entry, "path", &realpath)) { stat(realpath, &realstats); stats->st_mode = S_IFREG | 0444; stats->st_nlink = 1; stats->st_size = realstats.st_size; } } rval = 0; free_entry_list(entries); } else { rval = -ENOENT; } return rval; }
static GList * resolve_paths (const gchar *path) { gchar **sschema, **spath; gchar *schema; GList *entries; spath = g_strsplit(path, "/", 0); schema = hashfs_mounts_get(spath[1]); sschema = g_strsplit(schema, "/", 0); entries = NULL; for (gint i = 2; i < g_strv_length(spath); i++) { GHashTable *hash = parse_schema(sschema[i]); gchar *q = g_hash_table_lookup(hash, "q"); gchar *d = g_hash_table_lookup(hash, "d"); gchar *g = g_hash_table_lookup(hash, "g"); gchar *query = prepare_query(q, entries); hashfs_db_entry_t *entry = resolve_path(query, g, d, spath[i]); if (entry) { entries = g_list_append(entries, entry); } else { if (entries) free_entry_list(entries); entries = NULL; } g_free(q); g_free(d); g_free(query); g_hash_table_unref(hash); } g_strfreev(sschema); g_strfreev(spath); return entries; }
static gint hashfs_fuse_readdir (const gchar *path, gpointer buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { printf("readdir: %s\n", path); filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); if (g_strcmp0(path, "/") == 0) { GList *keys, *item; keys = g_hash_table_get_keys(mounts); for (item = g_list_first(keys); item; item = g_list_next(item)) { gchar *key = item->data; filler(buf, key, NULL, 0); } g_list_free(keys); } else { gchar **sschema, **spath; gchar *schema; GList *entries; spath = g_strsplit(path, "/", 0); schema = hashfs_mounts_get(spath[1]); sschema = g_strsplit(schema, "/", 0); entries = NULL; for (gint i = 1; i < g_strv_length(spath); i++) { GHashTable *hash = parse_schema(sschema[i+1]); gchar *q = g_hash_table_lookup(hash, "q"); gchar *d = g_hash_table_lookup(hash, "d"); gchar *g = g_hash_table_lookup(hash, "g"); gchar *query = prepare_query(q, entries); if ((i + 1) == g_strv_length(spath)) { hashfs_fuse_listdir(query, g, d, buf, filler); break; } hashfs_db_entry_t *entry = resolve_path(query, g, d, spath[i+1]); if (entry) entries = g_list_append(entries, entry); g_free(q); g_free(d); g_free(query); g_hash_table_unref(hash); } g_strfreev(sschema); g_strfreev(spath); if (entries) free_entry_list(entries); } return 0; }
// Rebuild the internal module table. If an error occurs, old table remains // unchanged. static bool reload_table() { bool rc = false; trcVerbose("reload module table..."); entry_t* new_list = NULL; const struct ld_info* ldi = NULL; // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX. loadquery // requires a large enough buffer. uint8_t* buffer = NULL; size_t buflen = 1024; for (;;) { buffer = (uint8_t*) ::realloc(buffer, buflen); if (loadquery(L_GETINFO, buffer, buflen) == -1) { if (errno == ENOMEM) { buflen *= 2; } else { trcVerbose("loadquery failed (%d)", errno); goto cleanup; } } else { break; } } trcVerbose("loadquery buffer size is %llu.", buflen); // Iterate over the loadquery result. For details see sys/ldr.h on AIX. ldi = (struct ld_info*) buffer; for (;;) { entry_t* e = (entry_t*) ::malloc(sizeof(entry_t)); if (!e) { trcVerbose("OOM."); goto cleanup; } memset(e, 0, sizeof(entry_t)); e->info.text = ldi->ldinfo_textorg; e->info.text_len = ldi->ldinfo_textsize; e->info.data = ldi->ldinfo_dataorg; e->info.data_len = ldi->ldinfo_datasize; e->info.path = g_stringlist.add(ldi->ldinfo_filename); if (!e->info.path) { trcVerbose("OOM."); goto cleanup; } // Extract short name { const char* p = strrchr(e->info.path, '/'); if (p) { p ++; e->info.shortname = p; } else { e->info.shortname = e->info.path; } } // Do we have a member name as well (see ldr.h)? const char* p_mbr_name = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1; if (*p_mbr_name) { e->info.member = g_stringlist.add(p_mbr_name); if (!e->info.member) { trcVerbose("OOM."); goto cleanup; } } else { e->info.member = NULL; } if (strcmp(e->info.shortname, "libjvm.so") == 0) { // Note that this, theoretically, is fuzzy. We may accidentally contain // more than one libjvm.so. But that is improbable, so lets go with this // solution. e->info.is_in_vm = true; } trcVerbose("entry: %p %llu, %p %llu, %s %s %s, %d", e->info.text, e->info.text_len, e->info.data, e->info.data_len, e->info.path, e->info.shortname, (e->info.member ? e->info.member : "NULL"), e->info.is_in_vm ); // Add to list. add_entry_to_list(e, &new_list); // Next entry... if (ldi->ldinfo_next) { ldi = (struct ld_info*)(((char*)ldi) + ldi->ldinfo_next); } else { break; } } // We are done. All is well. Free old list and swap to new one. if (g_first) { free_entry_list(&g_first); } g_first = new_list; new_list = NULL; rc = true; cleanup: if (new_list) { free_entry_list(&new_list); } ::free(buffer); return rc; } // end LoadedLibraries::reload()