⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user_share.c

📁 本书是学习GTK+少有的书籍
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- *//* *  Copyright (C) 2004 Red Hat, Inc. * *  Nautilus is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License as *  published by the Free Software Foundation; either version 2 of the *  License, or (at your option) any later version. * *  Nautilus is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *  Authors: Alexander Larsson <alexl@redhat.com> * */#include "config.h"#include <glib.h>#include <glib/gi18n.h>#include <X11/Xlib.h>#ifdef HAVE_AVAHI#include <avahi-client/client.h>#include <avahi-client/publish.h>#include <avahi-common/alternative.h>#include <avahi-common/error.h>#include <avahi-glib/glib-watch.h>#include <avahi-glib/glib-malloc.h>#endif /* HAVE_AVAHI */#ifdef HAVE_HOWL/* Workaround broken howl installing config.h */#undef PACKAGE#undef VERSION#include <howl.h>#endif /* HAVE_HOWL */#include <gconf/gconf-client.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/stat.h>#ifdef HAVE_SELINUX#include <selinux/selinux.h>#endif#define FILE_SHARING_DIR "/desktop/gnome/file_sharing"#define FILE_SHARING_ENABLED "/desktop/gnome/file_sharing/enabled"#define FILE_SHARING_REQUIRE_PASSWORD "/desktop/gnome/file_sharing/require_password"static GMainLoop *loop = NULL;static pid_t httpd_pid = 0;static guint disabled_timeout_tag = 0;static char *lookup_public_dir (void){  FILE *file;  char *config_file;  char buffer[512];  char *user_dir;  char *p, *d;  int len;  int relative;    config_file = g_build_filename (g_get_user_config_dir (), "user-dirs.dirs", NULL);  file = fopen (config_file, "r");  free (config_file);  if (file == NULL)	  goto error;    user_dir = NULL;  while (fgets (buffer, sizeof (buffer), file)) {	  /* Remove newline at end */	  len = strlen (buffer);      if (len > 0 && buffer[len-1] == '\n')		  buffer[len-1] = 0;            p = buffer;      while (*p == ' ' || *p == '\t')		  p++;            if (!g_str_has_prefix (p, "XDG_PUBLICSHARE_DIR"))		  continue;      p += strlen ("XDG_PUBLICSHARE_DIR");	        while (*p == ' ' || *p == '\t')		  p++;	        if (*p != '=')		  continue;      p++;            while (*p == ' ' || *p == '\t')		  p++;	        if (*p != '"')		  continue;      p++;            relative = 0;      if (strncmp (p, "$HOME/", 6) == 0) {		  p += 6;		  relative = 1;	  }      else if (*p != '/')		  continue;            if (relative)	{		  user_dir = g_malloc (strlen (g_get_home_dir()) + 1 + strlen (p) + 1);		  strcpy (user_dir, g_get_home_dir ());		  strcat (user_dir, "/");	  } else {		  user_dir = g_malloc (strlen (p) + 1);		  *user_dir = 0;	  }            d = user_dir + strlen (user_dir);      while (*p && *p != '"') {		  if ((*p == '\\') && (*(p+1) != 0))			  p++;		  *d++ = *p++;	  }      *d = 0;  }    fclose (file);    if (user_dir)	  return user_dir;   error:  return g_build_filename (g_get_home_dir (), "Public", NULL);}static intget_port (void){    int sock;    struct sockaddr_in addr;    int reuse;    socklen_t len;        sock = socket (PF_INET, SOCK_STREAM, 0);    if (sock < 0) {		return -1;    }        memset (&addr, 0, sizeof (addr));    addr.sin_port = 0;    addr.sin_addr.s_addr = INADDR_ANY;        reuse = 1;    setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse));    if (bind (sock, (struct sockaddr *)&addr, sizeof (addr)) == -1) {		close (sock);		return -1;    }        len = sizeof (addr);    if (getsockname (sock, (struct sockaddr *)&addr, &len) == -1) {		close (sock);		return -1;    }    #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)    /* XXX This exposes a potential race condition, but without this,     * httpd will not start on the above listed platforms due to the fact     * that SO_REUSEADDR is also needed when Apache binds to the listening     * socket.  At this time, Apache does not support that socket option.     */    close (sock);#endif    return ntohs (addr.sin_port);}static char *get_share_name (void){	static char *name = NULL;	const char *host_name;		if (name == NULL) {		host_name = g_get_host_name ();		if (strcmp (host_name, "localhost") == 0) {			/* Translators: The %s will get filled in with the user name			   of the user, to form a genitive. If this is difficult to			   translate correctly so that it will work correctly in your			   language, you may use something equivalent to			   "Public files of %s", or leave out the %s altogether.			   In the latter case, please put "%.0s" somewhere in the string,			   which will match the user name string passed by the C code,			   but not put the user name in the final string. This is to			   avoid the warning that msgfmt might otherwise generate. */			name = g_strdup_printf (_("%s's public files"), g_get_user_name ());		} else {			/* Translators: This is similar to the string before, only it			   has the hostname in it too. */			name = g_strdup_printf (_("%s's public files on %s"),									g_get_user_name (),									host_name);		}				}	return name;}#ifdef HAVE_AVAHIstatic AvahiClient *avahi_client = NULL;static gboolean avahi_should_publish = FALSE;static gboolean avahi_running = FALSE;static int avahi_port = 0;static AvahiEntryGroup *entry_group = NULL;static char *avahi_name = NULL;static gbooleancreate_service (void) {    int ret;	if (avahi_name == NULL) {		avahi_name = g_strdup (get_share_name ());	}	ret = avahi_entry_group_add_service (entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 										 AVAHI_PUBLISH_USE_MULTICAST,										 avahi_name, "_webdav._tcp", NULL, NULL, 										 avahi_port, "u=guest", NULL);	if (ret < 0) {		return FALSE;	}	ret = avahi_entry_group_commit (entry_group);    if (ret < 0) {        return FALSE;    }    return TRUE;}static void entry_group_callback (AvahiEntryGroup *g, 					  AvahiEntryGroupState state, 					  void *userdata) {    if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {    } else if (state == AVAHI_ENTRY_GROUP_COLLISION) {        char *n;        /* A service name collision happened. Let's pick a new name */        n = avahi_alternative_service_name (avahi_name);        g_free (avahi_name);        avahi_name = n;        fprintf (stderr, "Service name collision, renaming service to '%s'\n", avahi_name);        /* And recreate the services */        create_service();    }}static voidavahi_client_callback (AvahiClient *client, AvahiClientState state, void *userdata){    if (state == AVAHI_CLIENT_S_RUNNING) {		avahi_running = TRUE;		if (avahi_should_publish) {			create_service ();		}	} else if (state == AVAHI_CLIENT_S_COLLISION) {		avahi_entry_group_reset (entry_group);    } else if (state == AVAHI_CLIENT_FAILURE) {		avahi_running = FALSE;    }}static gbooleaninit_avahi (void){	AvahiGLibPoll *poll;	int error;    avahi_set_allocator (avahi_glib_allocator ());	poll = avahi_glib_poll_new (NULL, G_PRIORITY_DEFAULT);	/* Create a new AvahiClient instance */	avahi_client = avahi_client_new (avahi_glib_poll_get (poll),									 AVAHI_CLIENT_NO_FAIL,									 avahi_client_callback,									 NULL,									 &error);	if (avahi_client == NULL) {		return FALSE;	}	entry_group = avahi_entry_group_new (avahi_client, entry_group_callback, NULL);	if (entry_group == NULL) {		return FALSE;	}		return TRUE;}static gbooleanpublish_service (int port){	avahi_should_publish = TRUE;	avahi_port = port;	if (avahi_running) {		create_service ();	}	return TRUE;}static voidstop_publishing (void){	avahi_should_publish = FALSE;	avahi_entry_group_reset (entry_group);}#endif#ifdef HAVE_HOWLstatic sw_discovery_publish_id published_id = 0;static sw_discovery howl_session;static gbooleanhowl_input (GIOChannel  *io_channel,			GIOCondition cond,			gpointer     callback_data){	sw_discovery session;	session = callback_data;	sw_salt salt;	if (sw_discovery_salt (session, &salt) == SW_OKAY) {		sw_salt_lock (salt);		sw_discovery_read_socket (session);		sw_salt_unlock (salt);	}	return TRUE;}static voidset_up_howl_session (sw_discovery session){	int fd;	GIOChannel *channel;	fd = sw_discovery_socket (session);	channel = g_io_channel_unix_new (fd);	g_io_add_watch (channel,					G_IO_IN,					howl_input, session);	g_io_channel_unref (channel);}static sw_resultpublish_reply (sw_discovery			discovery,			   sw_discovery_publish_status	status,			   sw_discovery_oid			id,			   sw_opaque			extra){	return SW_OKAY;}static gbooleanpublish_service (int port)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -