//TODO: JS_EXPORT_API JSObjectRef dentry_get_flags (Entry* e) { JSObjectRef json = json_array_create(); GFile* f; if (!G_IS_FILE(e)) { return json; } f = e; GFileInfo* info = g_file_query_info (f, "standard::*,access::*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); if (info != NULL) { gboolean is_read_only = FALSE; gboolean is_symlink = FALSE; gboolean is_unreadable = FALSE; is_unreadable = !g_file_info_get_attribute_boolean(info, "access::can-read"); is_read_only = !g_file_info_get_attribute_boolean(info, "access::can-write"); is_symlink = g_file_info_get_is_symlink(info); g_object_unref(info); json_append_number(json, "read_only", is_read_only); json_append_number(json, "symbolic_link", is_symlink); json_append_number(json, "unreadable", is_unreadable); } return json; }
gchar * get_file_type_description (const gchar * file, GFileInfo * file_info) { const char * content_type = NULL; gchar * desc; if (file != NULL) { content_type = g_file_info_get_content_type (file_info); } if (content_type == NULL || g_content_type_is_unknown (content_type) == TRUE) { return g_strdup (g_content_type_get_description ("application/octet-stream")); } desc = g_strdup (g_content_type_get_description (content_type)); if (g_file_info_get_is_symlink (file_info) == TRUE) { const gchar * symlink_target; gchar * absolute_symlink = NULL; gchar * str = NULL; symlink_target = g_file_info_get_symlink_target (file_info); if (g_path_is_absolute (symlink_target) != TRUE) { gchar *dirname; dirname = g_path_get_dirname (file); absolute_symlink = g_strconcat (dirname, G_DIR_SEPARATOR_S, symlink_target, NULL); g_free (dirname); } else { absolute_symlink = g_strdup (symlink_target); } if (g_file_test (absolute_symlink, G_FILE_TEST_EXISTS) != TRUE) { if ((g_ascii_strcasecmp (content_type, "x-special/socket") != 0) && (g_ascii_strcasecmp (content_type, "x-special/fifo") != 0)) { g_free (absolute_symlink); g_free (desc); return g_strdup (_("link (broken)")); } } str = g_strdup_printf (_("link to %s"), (desc != NULL) ? desc : content_type); g_free (absolute_symlink); g_free (desc); return str; } return desc; }
PRIVATE void _add_monitor_directory(GFile* f) { g_assert(_inotify_fd != -1); GFileInfo* info = g_file_query_info(f, "standard::type", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); if (info == NULL) return; //temp file may cause this like downloading file or compressing file GFileType type = g_file_info_get_attribute_uint32(info, G_FILE_ATTRIBUTE_STANDARD_TYPE); g_assert(info != NULL); if (g_file_info_get_is_symlink(info)) { GFile* maybe_real_target = g_file_new_for_uri(g_file_info_get_symlink_target(info)); _add_monitor_directory(maybe_real_target); g_object_unref(maybe_real_target); } else if (type == G_FILE_TYPE_DIRECTORY) { char* path = g_file_get_path(f); int watch = inotify_add_watch(_inotify_fd, path, IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO | IN_ATTRIB); g_free(path); g_hash_table_insert(_monitor_table, GINT_TO_POINTER(watch), g_object_ref(f)); } g_object_unref(info); }
static git_filemode_t file_info_to_filemode (GFileInfo *info) { git_filemode_t ret = 0; if (g_file_info_get_is_symlink (info)) { ret |= GIT_FILEMODE_LINK; } else if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { ret |= GIT_FILEMODE_TREE; } else if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE)) { ret |= GIT_FILEMODE_BLOB_EXECUTABLE; } else { ret |= GIT_FILEMODE_BLOB; } return ret; }
static gboolean run (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; const char *dirpath; OtTrivialHttpd appstruct = { 0, }; OtTrivialHttpd *app = &appstruct; glnx_unref_object SoupServer *server = NULL; g_autoptr(GFileMonitor) dirmon = NULL; context = g_option_context_new ("[DIR] - Simple webserver"); g_option_context_add_main_entries (context, options, NULL); app->root_dfd = -1; if (!g_option_context_parse (context, &argc, &argv, error)) goto out; if (argc > 1) dirpath = argv[1]; else dirpath = "."; if (!glnx_opendirat (AT_FDCWD, dirpath, TRUE, &app->root_dfd, error)) goto out; if (!(opt_random_500s_percentage >= 0 && opt_random_500s_percentage <= 99)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid --random-500s=%u", opt_random_500s_percentage); goto out; } if (opt_log) { GOutputStream *stream = NULL; if (g_strcmp0 (opt_log, "-") == 0) { if (opt_daemonize) { ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error); goto out; } stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE)); } else { g_autoptr(GFile) log_file = NULL; GFileOutputStream* log_stream; log_file = g_file_new_for_path (opt_log); log_stream = g_file_create (log_file, G_FILE_CREATE_PRIVATE, cancellable, error); if (!log_stream) goto out; stream = G_OUTPUT_STREAM (log_stream); } app->log = stream; } #if SOUP_CHECK_VERSION(2, 48, 0) server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); if (!soup_server_listen_all (server, opt_port, 0, error)) goto out; #else server = soup_server_new (SOUP_SERVER_PORT, opt_port, SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); #endif soup_server_add_handler (server, NULL, httpd_callback, app, NULL); if (opt_port_file) { g_autofree char *portstr = NULL; #if SOUP_CHECK_VERSION(2, 48, 0) GSList *listeners = soup_server_get_listeners (server); g_autoptr(GSocket) listener = NULL; g_autoptr(GSocketAddress) addr = NULL; g_assert (listeners); listener = g_object_ref (listeners->data); g_slist_free (listeners); listeners = NULL; addr = g_socket_get_local_address (listener, error); if (!addr) goto out; g_assert (G_IS_INET_SOCKET_ADDRESS (addr)); portstr = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress*)addr)); #else portstr = g_strdup_printf ("%u\n", soup_server_get_port (server)); #endif if (g_strcmp0 ("-", opt_port_file) == 0) { fputs (portstr, stdout); // not g_print - this must go to stdout, not a handler fflush (stdout); } else if (!g_file_set_contents (opt_port_file, portstr, strlen (portstr), error)) goto out; } #if !SOUP_CHECK_VERSION(2, 48, 0) soup_server_run_async (server); #endif if (opt_daemonize) { pid_t pid = fork(); if (pid == -1) { int errsv = errno; g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), g_strerror (errsv)); goto out; } else if (pid > 0) { ret = TRUE; goto out; } /* Child, continue */ if (setsid () < 0) err (1, "setsid"); /* Daemonising: close stdout/stderr so $() et al work on us */ if (freopen("/dev/null", "r", stdin) == NULL) err (1, "freopen"); if (freopen("/dev/null", "w", stdout) == NULL) err (1, "freopen"); if (freopen("/dev/null", "w", stderr) == NULL) err (1, "freopen"); } else { /* Since we're used for testing purposes, let's just do this by * default. This ensures we exit when our parent does. */ if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0) { if (errno != ENOSYS) { glnx_set_error_from_errno (error); goto out; } } } app->running = TRUE; if (opt_autoexit) { gboolean is_symlink = FALSE; g_autoptr(GFile) root = NULL; g_autoptr(GFileInfo) info = NULL; root = g_file_new_for_path (dirpath); info = g_file_query_info (root, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!info) goto out; is_symlink = g_file_info_get_is_symlink (info); if (is_symlink) dirmon = g_file_monitor_file (root, 0, cancellable, error); else dirmon = g_file_monitor_directory (root, 0, cancellable, error); if (!dirmon) goto out; g_signal_connect (dirmon, "changed", G_CALLBACK (on_dir_changed), app); } httpd_log (app, "serving at root %s\n", dirpath); while (app->running) g_main_context_iteration (NULL, TRUE); ret = TRUE; out: if (app->root_dfd != -1) (void) close (app->root_dfd); g_clear_object (&app->log); return ret; }
static void do_tree (GFile *f, int level, guint64 pattern) { GFileEnumerator *enumerator; GError *error = NULL; unsigned int n; GFileInfo *info; info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, 0, NULL, NULL); if (info != NULL) { if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) == G_FILE_TYPE_MOUNTABLE) { /* don't process mountables; we avoid these by getting the target_uri below */ g_object_unref (info); return; } g_object_unref (info); } enumerator = g_file_enumerate_children (f, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, 0, NULL, &error); if (enumerator != NULL) { GList *l; GList *info_list; info_list = NULL; while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { if (g_file_info_get_is_hidden (info) && !show_hidden) { g_object_unref (info); } else { info_list = g_list_prepend (info_list, info); } } g_file_enumerator_close (enumerator, NULL, NULL); info_list = g_list_sort (info_list, (GCompareFunc) sort_info_by_name); for (l = info_list; l != NULL; l = l->next) { const char *name; const char *target_uri; GFileType type; gboolean is_last_item; info = l->data; is_last_item = (l->next == NULL); name = g_file_info_get_name (info); type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); if (name != NULL) { for (n = 0; n < level; n++) { if (pattern & (1<<n)) { g_print ("| "); } else { g_print (" "); } } if (is_last_item) { g_print ("`-- %s", name); } else { g_print ("|-- %s", name); } target_uri = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); if (target_uri != NULL) { g_print (" -> %s", target_uri); } else { if (g_file_info_get_is_symlink (info)) { const char *target; target = g_file_info_get_symlink_target (info); g_print (" -> %s", target); } } g_print ("\n"); if ((type & G_FILE_TYPE_DIRECTORY) && (follow_symlinks || !g_file_info_get_is_symlink (info))) { guint64 new_pattern; GFile *child; if (is_last_item) new_pattern = pattern; else new_pattern = pattern | (1<<level); child = NULL; if (target_uri != NULL) { if (follow_symlinks) child = g_file_new_for_uri (target_uri); } else { child = g_file_get_child (f, name); } if (child != NULL) { do_tree (child, level + 1, new_pattern); g_object_unref (child); } } } g_object_unref (info); } g_list_free (info_list); } else { for (n = 0; n < level; n++) { if (pattern & (1<<n)) { g_print ("| "); } else { g_print (" "); } } g_print (" [%s]\n", error->message); g_error_free (error); } }
static GFileInfo * g_vfs_ftp_dir_cache_resolve_symlink (GVfsFtpDirCache * cache, GVfsFtpTask * task, const GVfsFtpFile *file, GFileInfo * original, guint stamp) { static const char *copy_attributes[] = { G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET }; GFileInfo *info, *result; GVfsFtpFile *tmp, *link; guint i, lookups = 0; const char *target; if (!g_file_info_get_is_symlink (original) || g_vfs_ftp_task_is_in_error (task)) return original; info = g_object_ref (original); link = g_vfs_ftp_file_copy (file); do { target = g_file_info_get_symlink_target (info); if (target == NULL) { /* This happens when bad servers don't report a symlink target. * We now want to figure out if this is a directory or regular file, * so we can at least report something useful. */ g_object_unref (info); info = cache->funcs->lookup_uncached (task, file); break; } tmp = link; link = cache->funcs->resolve_symlink (task, tmp, g_file_info_get_symlink_target (info)); g_vfs_ftp_file_free (tmp); g_object_unref (info); if (link == NULL) { g_vfs_ftp_task_clear_error (task); return original; } info = g_vfs_ftp_dir_cache_lookup_file_internal (cache, task, link, stamp); if (info == NULL) { g_vfs_ftp_file_free (link); g_vfs_ftp_task_clear_error (task); return original; } } while (g_file_info_get_is_symlink (info) && lookups++ < 8); g_vfs_ftp_file_free (link); if (g_file_info_get_is_symlink (info)) { /* too many recursions */ g_object_unref (info); return original; } result = g_file_info_dup (info); g_object_unref (info); for (i = 0; i < G_N_ELEMENTS (copy_attributes); i++) { GFileAttributeType type; gpointer value; if (!g_file_info_get_attribute_data (original, copy_attributes[i], &type, &value, NULL)) continue; g_file_info_set_attribute (result, copy_attributes[i], type, value); } g_object_unref (original); return result; }