Beispiel #1
0
//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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #6
0
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);
    }
}
Beispiel #7
0
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;
}