summaryrefslogtreecommitdiff
path: root/src/3rd_party/dbus-1.7.8/tools/dbus-cleanup-sockets.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rd_party/dbus-1.7.8/tools/dbus-cleanup-sockets.c')
-rw-r--r--src/3rd_party/dbus-1.7.8/tools/dbus-cleanup-sockets.c448
1 files changed, 0 insertions, 448 deletions
diff --git a/src/3rd_party/dbus-1.7.8/tools/dbus-cleanup-sockets.c b/src/3rd_party/dbus-1.7.8/tools/dbus-cleanup-sockets.c
deleted file mode 100644
index 1b6709af54..0000000000
--- a/src/3rd_party/dbus-1.7.8/tools/dbus-cleanup-sockets.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* dbus-cleanup-sockets.c dbus-cleanup-sockets utility
- *
- * Copyright (C) 2003 Red Hat, Inc.
- * Copyright (C) 2002 Michael Meeks
- *
- * Note that this file is NOT licensed under the Academic Free License,
- * as it is based on linc-cleanup-sockets which is LGPL.
- *
- * This program 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.
- *
- * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef TRUE
-#define TRUE (1)
-#endif
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#ifndef NULL
-#define NULL ((void*) 0)
-#endif
-
-static void*
-xmalloc (size_t bytes)
-{
- void *mem;
-
- if (bytes == 0)
- return NULL;
-
- mem = malloc (bytes);
-
- if (mem == NULL)
- {
- fprintf (stderr, "Allocation of %d bytes failed\n",
- (int) bytes);
- exit (1);
- }
-
- return mem;
-}
-
-static void*
-xrealloc (void *old, size_t bytes)
-{
- void *mem;
-
- if (bytes == 0)
- {
- free (old);
- return NULL;
- }
-
- mem = realloc (old, bytes);
-
- if (mem == NULL)
- {
- fprintf (stderr, "Reallocation of %d bytes failed\n",
- (int) bytes);
- exit (1);
- }
-
- return mem;
-}
-
-#ifdef AF_UNIX
-
-typedef enum
- {
- SOCKET_UNKNOWN,
- SOCKET_FAILED_TO_HANDLE,
- SOCKET_DEAD,
- SOCKET_ALIVE,
- SOCKET_UNLINKED
- } SocketStatus;
-
-static int alive_count = 0;
-static int cleaned_count = 0;
-static int unhandled_count = 0;
-
-typedef struct
-{
- char *name;
- int fd;
- SocketStatus status;
- int n_retries;
-} SocketEntry;
-
-static SocketEntry*
-socket_entry_new (const char *dir,
- const char *fname)
-{
- SocketEntry *se;
- int len;
-
- se = xmalloc (sizeof (SocketEntry));
-
- len = strlen (dir) + strlen (fname) + 2; /* 2 = nul and '/' */
- se->name = xmalloc (len);
-
- strcpy (se->name, dir);
- strcat (se->name, "/");
- strcat (se->name, fname);
-
- se->fd = -1;
-
- se->status = SOCKET_UNKNOWN;
-
- se->n_retries = 0;
-
- return se;
-}
-
-static void
-free_socket_entry (SocketEntry *se)
-{
- if (se)
- {
- free (se->name);
- if (se->fd >= 0)
- close (se->fd);
- free (se);
- }
-}
-
-static void
-free_socket_entries (SocketEntry** entries,
- int n_entries)
-{
- int i;
-
- if (entries)
- {
- for (i = 0; i < n_entries; ++i)
- free_socket_entry (entries[i]);
- free (entries);
- }
-}
-
-static void
-read_sockets (const char *dir,
- SocketEntry ***entries_p,
- int *n_entries_p)
-{
- DIR *dirh;
- struct dirent *dent;
- SocketEntry **entries;
- int n_entries;
- int allocated;
-
- n_entries = 0;
- allocated = 2;
- entries = xmalloc (sizeof (SocketEntry*) * allocated);
-
- dirh = opendir (dir);
- if (dirh == NULL)
- {
- fprintf (stderr, "Failed to open directory %s: %s\n",
- dir, strerror (errno));
- exit (1);
- }
-
- while ((dent = readdir (dirh)))
- {
- SocketEntry *se;
-
- if (strncmp (dent->d_name, "dbus-", 5) != 0)
- continue;
-
- se = socket_entry_new (dir, dent->d_name);
-
- if (n_entries == allocated)
- {
- allocated *= 2;
- entries = xrealloc (entries, sizeof (SocketEntry*) * allocated);
- }
-
- entries[n_entries] = se;
- n_entries += 1;
- }
-
- closedir (dirh);
-
- *entries_p = entries;
- *n_entries_p = n_entries;
-}
-
-static SocketStatus
-open_socket (SocketEntry *se)
-{
- int ret;
- struct sockaddr_un saddr;
-
- if (se->n_retries > 5)
- {
- fprintf (stderr, "Warning: giving up on socket %s after several retries; unable to determine socket's status\n",
- se->name);
- return SOCKET_FAILED_TO_HANDLE;
- }
-
- se->n_retries += 1;
-
- se->fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (se->fd < 0)
- {
- fprintf (stderr, "Warning: failed to open a socket to use for connecting: %s\n",
- strerror (errno));
- return SOCKET_UNKNOWN;
- }
-
- if (fcntl (se->fd, F_SETFL, O_NONBLOCK) < 0)
- {
- fprintf (stderr, "Warning: failed set socket %s nonblocking: %s\n",
- se->name, strerror (errno));
- return SOCKET_UNKNOWN;
- }
-
-
- memset (&saddr, '\0', sizeof (saddr)); /* nul-terminates the sun_path */
-
- saddr.sun_family = AF_UNIX;
- strncpy (saddr.sun_path, se->name, sizeof (saddr.sun_path) - 1);
-
- do
- {
- ret = connect (se->fd, (struct sockaddr*) &saddr, sizeof (saddr));
- }
- while (ret < 0 && errno == EINTR);
-
- if (ret >= 0)
- return SOCKET_ALIVE;
- else
- {
- switch (errno)
- {
- case EINPROGRESS:
- case EAGAIN:
- return SOCKET_UNKNOWN;
- case ECONNREFUSED:
- return SOCKET_DEAD;
- default:
- fprintf (stderr, "Warning: unexpected error connecting to socket %s: %s\n",
- se->name, strerror (errno));
- return SOCKET_FAILED_TO_HANDLE;
- }
- }
-}
-
-static int
-handle_sockets (SocketEntry **entries,
- int n_entries)
-{
- int i;
- int n_unknown;
-
- n_unknown = 0;
-
- i = 0;
- while (i < n_entries)
- {
- SocketEntry *se;
- SocketStatus status;
-
- se = entries[i];
- ++i;
-
- if (se->fd >= 0)
- {
- fprintf (stderr, "Internal error, socket has fd kept open while status = %d\n",
- se->status);
- exit (1);
- }
-
- if (se->status != SOCKET_UNKNOWN)
- continue;
-
- status = open_socket (se);
-
- switch (status)
- {
- case SOCKET_DEAD:
- cleaned_count += 1;
- if (unlink (se->name) < 0)
- {
- fprintf (stderr, "Warning: Failed to delete %s: %s\n",
- se->name, strerror (errno));
-
- se->status = SOCKET_FAILED_TO_HANDLE;
- }
- else
- se->status = SOCKET_UNLINKED;
- break;
-
- case SOCKET_ALIVE:
- alive_count += 1;
- /* FALL THRU */
-
- case SOCKET_FAILED_TO_HANDLE:
- case SOCKET_UNKNOWN:
- se->status = status;
- break;
-
- case SOCKET_UNLINKED:
- fprintf (stderr, "Bad status from open_socket(), should not happen\n");
- exit (1);
- break;
- }
-
- if (se->fd >= 0)
- {
- close (se->fd);
- se->fd = -1;
- }
-
- if (se->status == SOCKET_UNKNOWN)
- n_unknown += 1;
- }
-
- return n_unknown == 0;
-}
-
-static void
-clean_dir (const char *dir)
-{
- SocketEntry **entries;
- int n_entries;
-
- read_sockets (dir, &entries, &n_entries);
-
- /* open_socket() will fail conclusively after
- * several retries, so this loop is guaranteed
- * to terminate eventually
- */
- while (!handle_sockets (entries, n_entries))
- {
- fprintf (stderr, "Unable to determine state of some sockets, retrying in 2 seconds\n");
- sleep (2);
- }
-
- unhandled_count += (n_entries - alive_count - cleaned_count);
-
- free_socket_entries (entries, n_entries);
-}
-
-#endif /* AF_UNIX */
-
-static void
-usage (int ecode)
-{
- fprintf (stderr, "dbus-cleanup-sockets [--version] [--help] <socketdir>\n");
- exit (ecode);
-}
-
-static void
-version (void)
-{
- printf ("D-Bus Socket Cleanup Utility %s\n"
- "Copyright (C) 2003 Red Hat, Inc.\n"
- "Copyright (C) 2002 Michael Meeks\n"
- "This is free software; see the source for copying conditions.\n"
- "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
- VERSION);
- exit (0);
-}
-
-int
-main (int argc, char **argv)
-{
- int i;
- int saw_doubledash;
- const char *dirname;
-
- saw_doubledash = FALSE;
- dirname = NULL;
- i = 1;
- while (i < argc)
- {
- const char *arg = argv[i];
-
- if (strcmp (arg, "--help") == 0 ||
- strcmp (arg, "-h") == 0 ||
- strcmp (arg, "-?") == 0)
- usage (0);
- else if (strcmp (arg, "--version") == 0)
- version ();
- else if (!saw_doubledash)
- {
- if (strcmp (arg, "--") == 0)
- saw_doubledash = TRUE;
- else if (*arg == '-')
- usage (1);
- }
- else
- {
- if (dirname != NULL)
- {
- fprintf (stderr, "dbus-cleanup-sockets only supports a single directory name\n");
- exit (1);
- }
-
- dirname = arg;
- }
-
- ++i;
- }
-
- /* Default to session socket dir, usually /tmp */
- if (dirname == NULL)
- dirname = DBUS_SESSION_SOCKET_DIR;
-
-#ifdef AF_UNIX
- clean_dir (dirname);
-
- printf ("Cleaned up %d sockets in %s; %d sockets are still in use; %d in unknown state\n",
- cleaned_count, dirname, alive_count, unhandled_count);
-#else
- printf ("This system does not support UNIX domain sockets, so dbus-cleanup-sockets does nothing\n");
-#endif
-
- return 0;
-}