📄 user_share.c
字号:
{ sw_result result; result = sw_discovery_publish (howl_session, 0, get_share_name (), "_webdav._tcp", NULL, NULL, port, /* TODO: should be u=guest */ /* text */ (unsigned char *) "", 0, publish_reply, NULL, &published_id); if (result != SW_OKAY) { return FALSE; } return TRUE;}static voidstop_publishing (void){ if (published_id != 0) sw_discovery_cancel (howl_session, published_id); published_id = 0;}#endif /* HAVE_HOWL */static voidensure_public_dir (char *dirname){ if (!g_file_test (dirname, G_FILE_TEST_IS_DIR)) { mkdir (dirname, 0755); }}static voidensure_conf_dir (void){ char *dirname; dirname = g_build_filename (g_get_home_dir (), ".gnome2", NULL); if (!g_file_test (dirname, G_FILE_TEST_IS_DIR)) { mkdir (dirname, 0755); } g_free (dirname); dirname = g_build_filename (g_get_home_dir (), ".gnome2", "user-share", NULL); if (!g_file_test (dirname, G_FILE_TEST_IS_DIR)) { mkdir (dirname, 0755); } g_free (dirname);}static voidhttpd_child_setup (gpointer user_data){#ifdef HAVE_SELINUX char *mycon; /* If selinux is enabled, avoid transitioning to the httpd_t context, as this normally means you can't read the users homedir. */ if (is_selinux_enabled()) { if (getcon (&mycon) < 0) { abort (); } if (setexeccon (mycon) < 0) abort (); freecon (mycon); }#endif}static gbooleanspawn_httpd (int port, pid_t *pid_out){ char *free1, *free2, *free3; gboolean res; char *argv[10]; char *env[10]; int i; gint status; char *pid_filename; char *pidfile; GError *error; gboolean got_pidfile; GConfClient *client; char *str; char *public_dir; public_dir = lookup_public_dir (); ensure_public_dir (public_dir); ensure_conf_dir (); i = 0; argv[i++] = HTTPD_PROGRAM; argv[i++] = "-f"; argv[i++] = HTTPD_CONFIG; argv[i++] = "-C"; free1 = argv[i++] = g_strdup_printf ("Listen %d", port); client = gconf_client_get_default (); str = gconf_client_get_string (client, FILE_SHARING_REQUIRE_PASSWORD, NULL); if (str && strcmp (str, "never") == 0) { /* Do nothing */ } else if (str && strcmp (str, "on_write") == 0){ argv[i++] = "-D"; argv[i++] = "RequirePasswordOnWrite"; } else { /* always, or safe fallback */ argv[i++] = "-D"; argv[i++] = "RequirePasswordAlways"; } g_object_unref (client); argv[i] = NULL; i = 0; free2 = env[i++] = g_strdup_printf("HOME=%s", g_get_home_dir()); free3 = env[i++] = g_strdup_printf("XDG_PUBLICSHARE_DIR=%s", public_dir); env[i++] = "LANG=C"; env[i] = NULL; pid_filename = g_build_filename (g_get_home_dir (), ".gnome2/user-share/pid", NULL); /* Remove pid file before spawning to avoid races with child and old pidfile */ unlink (pid_filename); error = NULL; res = g_spawn_sync (g_get_home_dir(), argv, env, 0, httpd_child_setup, NULL, NULL, NULL, &status, &error); g_free (free1); g_free (free2); g_free (free3); g_free (public_dir); if (!res) { fprintf (stderr, "error spawning httpd: %s\n", error->message); g_error_free (error); return FALSE; } if (status != 0) { g_free (pid_filename); return FALSE; } got_pidfile = FALSE; error = NULL; for (i = 0; i < 5; i++) { if (error != NULL) g_error_free (error); error = NULL; if (g_file_get_contents (pid_filename, &pidfile, NULL, &error)) { got_pidfile = TRUE; *pid_out = atoi (pidfile); g_free (pidfile); break; } sleep (1); } g_free (pid_filename); if (!got_pidfile) { fprintf (stderr, "error opening httpd pidfile: %s\n", error->message); g_error_free (error); return FALSE; } return TRUE;}static voidkill_httpd (void){ if (httpd_pid != 0) { kill (httpd_pid, SIGTERM); /* Allow child time to die, we can't waitpid, because its not a direct child */ sleep (1); } httpd_pid = 0;}static RETSIGTYPEcleanup_handler (int sig){ kill_httpd (); _exit (2);}/* File sharing was disabled for some time, exit now *//* If we re-enable it in the ui, this will be restarted anyway */static gbooleandisabled_timeout_callback (void){ kill_httpd (); exit (0); return FALSE;}static voidup (void){ guint port; port = get_port (); if (!spawn_httpd (port, &httpd_pid)) { fprintf (stderr, "spawning httpd failed\n"); } else { if (!publish_service (port)) { fprintf (stderr, "publishing failed\n"); } }}static voiddown (void){ kill_httpd (); stop_publishing ();}static voidrequire_password_changed (GConfClient* client, guint cnxn_id, GConfEntry *entry, gpointer data){ /* Need to restart to get new password setting */ if (httpd_pid != 0) { down (); up (); }}static voidfile_sharing_enabled_changed (GConfClient* client, guint cnxn_id, GConfEntry *entry, gpointer data){ gboolean enabled; if (disabled_timeout_tag != 0) { g_source_remove (disabled_timeout_tag); disabled_timeout_tag = 0; } enabled = gconf_client_get_bool (client, FILE_SHARING_ENABLED, NULL); if (enabled) { if (httpd_pid == 0) { up (); } } else { down (); disabled_timeout_tag = g_timeout_add (3*1000, (GSourceFunc)disabled_timeout_callback, NULL); }}static intx_io_error_handler (Display *xdisplay){ kill_httpd (); _exit (2);}static gbooleanx_input (GIOChannel *io_channel, GIOCondition cond, gpointer callback_data){ Display *xdisplay; XEvent ignored; xdisplay = callback_data; while (XPending (xdisplay)) { XNextEvent (xdisplay, &ignored); } return TRUE;}intmain (int argc, char **argv){ GConfClient *client; Display *xdisplay; int x_fd; GIOChannel *channel; Window selection_owner; Atom xatom; g_type_init (); loop = g_main_loop_new (NULL, FALSE); signal (SIGPIPE, SIG_IGN); signal (SIGINT, cleanup_handler); signal (SIGHUP, cleanup_handler); signal (SIGTERM, cleanup_handler); xdisplay = XOpenDisplay (NULL); if (xdisplay == NULL) { fprintf (stderr, "Can't open display\n"); return 1; } xatom = XInternAtom (xdisplay, "_GNOME_USER_SHARE", FALSE); selection_owner = XGetSelectionOwner (xdisplay, xatom); if (selection_owner != None) { /* There is an owner already, quit */ return 1; } selection_owner = XCreateSimpleWindow (xdisplay, RootWindow (xdisplay, 0), 0, 0, 1, 1, 0, 0, 0); XSetSelectionOwner (xdisplay, xatom, selection_owner, CurrentTime); if (XGetSelectionOwner (xdisplay, xatom) != selection_owner) { /* Didn't get the selection */ return 1; } x_fd = ConnectionNumber (xdisplay); XSetIOErrorHandler (x_io_error_handler); channel = g_io_channel_unix_new (x_fd); g_io_add_watch (channel, G_IO_IN, x_input, xdisplay); g_io_channel_unref (channel); #ifdef HAVE_AVAHI if (!init_avahi ()) { /* Print out the error string */ fprintf (stderr, "avahi init failed\n"); return 1; }#endif#ifdef HAVE_HOWL if (sw_discovery_init (&howl_session) != SW_OKAY) { fprintf (stderr, "howl init failed\n"); return 1; } set_up_howl_session (howl_session);#endif client = gconf_client_get_default (); gconf_client_add_dir (client, FILE_SHARING_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); gconf_client_notify_add (client, FILE_SHARING_ENABLED, file_sharing_enabled_changed, NULL, NULL, NULL); gconf_client_notify_add (client, FILE_SHARING_REQUIRE_PASSWORD, require_password_changed, NULL, NULL, NULL); g_object_unref (client); /* Initial setting */ file_sharing_enabled_changed (client, 0, NULL, NULL); g_main_loop_run (loop); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -