1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 20e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington/* dbus-cleanup-sockets.c dbus-cleanup-sockets utility 30e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * 40e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * Copyright (C) 2003 Red Hat, Inc. 50e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * Copyright (C) 2002 Michael Meeks 60e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * 70e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * Note that this file is NOT licensed under the Academic Free License, 80e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * as it is based on linc-cleanup-sockets which is LGPL. 90e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * 100e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * This program is free software; you can redistribute it and/or modify 110e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * it under the terms of the GNU General Public License as published by 120e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * the Free Software Foundation; either version 2 of the License, or 130e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * (at your option) any later version. 140e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * 150e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * This program is distributed in the hope that it will be useful, 160e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of 170e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 180e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * GNU General Public License for more details. 190e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * 200e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * You should have received a copy of the GNU General Public License 210e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * along with this program; if not, write to the Free Software 225baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 230e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * 240e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington */ 250e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <config.h> 260e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <sys/types.h> 270e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <sys/stat.h> 280e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <stdio.h> 290e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <fcntl.h> 300e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <unistd.h> 310e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <dirent.h> 320e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <sys/socket.h> 330e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <sys/un.h> 340e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <errno.h> 350e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <stdlib.h> 360e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#include <string.h> 370e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 380e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#ifndef TRUE 390e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#define TRUE (1) 400e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#endif 410e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 420e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#ifndef FALSE 430e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#define FALSE (0) 440e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#endif 450e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 460e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#ifndef NULL 470e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#define NULL ((void*) 0) 480e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#endif 490e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 500e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void* 510e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonxmalloc (size_t bytes) 520e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 530e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington void *mem; 540e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 550e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (bytes == 0) 560e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return NULL; 570e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 580e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington mem = malloc (bytes); 590e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 600e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (mem == NULL) 610e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 620e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Allocation of %d bytes failed\n", 630e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington (int) bytes); 640e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (1); 650e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 660e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 670e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return mem; 680e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 690e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 700e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void* 710e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonxrealloc (void *old, size_t bytes) 720e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 730e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington void *mem; 740e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 750e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (bytes == 0) 760e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 770e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington free (old); 780e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return NULL; 790e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 800e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 810e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington mem = realloc (old, bytes); 820e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 830e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (mem == NULL) 840e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 850e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Reallocation of %d bytes failed\n", 860e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington (int) bytes); 870e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (1); 880e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 890e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 900e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return mem; 910e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 920e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 930e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#ifdef AF_UNIX 940e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 950e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtontypedef enum 960e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 970e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SOCKET_UNKNOWN, 980e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SOCKET_FAILED_TO_HANDLE, 990e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SOCKET_DEAD, 1000e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SOCKET_ALIVE, 1010e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SOCKET_UNLINKED 1020e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } SocketStatus; 1030e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1040e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic int alive_count = 0; 1050e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic int cleaned_count = 0; 1060e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic int unhandled_count = 0; 1070e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1080e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtontypedef struct 1090e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 1100e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington char *name; 1110e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int fd; 1120e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketStatus status; 1130e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int n_retries; 1140e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} SocketEntry; 1150e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1160e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic SocketEntry* 1170e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonsocket_entry_new (const char *dir, 1180e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington const char *fname) 1190e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 1200e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketEntry *se; 1210e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int len; 1220e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1230e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se = xmalloc (sizeof (SocketEntry)); 1240e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1250e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington len = strlen (dir) + strlen (fname) + 2; /* 2 = nul and '/' */ 1260e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->name = xmalloc (len); 1270e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1280e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strcpy (se->name, dir); 1290e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strcat (se->name, "/"); 1300e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strcat (se->name, fname); 1310e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1320e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->fd = -1; 1330e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1340e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->status = SOCKET_UNKNOWN; 1350e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1360e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->n_retries = 0; 1370e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1380e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return se; 1390e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 1400e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1410e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#if 0 1420e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void 1430e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonfree_socket_entry (SocketEntry *se) 1440e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 1450e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington free (se->name); 1460e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->fd >= 0) 1470e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington close (se->fd); 1480e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington free (se); 1490e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 1500e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#endif 1510e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1520e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void 1530e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonread_sockets (const char *dir, 1540e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketEntry ***entries_p, 1550e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int *n_entries_p) 1560e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 1570e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington DIR *dirh; 1580e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington struct dirent *dent; 1590e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketEntry **entries; 1600e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int n_entries; 1610e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int allocated; 1620e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1630e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington n_entries = 0; 1640e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington allocated = 2; 1650e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington entries = xmalloc (sizeof (SocketEntry*) * allocated); 1660e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1670e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington dirh = opendir (dir); 1680e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (dirh == NULL) 1690e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 1700e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Failed to open directory %s: %s\n", 1710e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington dir, strerror (errno)); 1720e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (1); 1730e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 1740e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1750e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington while ((dent = readdir (dirh))) 1760e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 1770e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketEntry *se; 1780e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1790e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (strncmp (dent->d_name, "dbus-", 5) != 0) 1800e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington continue; 1810e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1820e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se = socket_entry_new (dir, dent->d_name); 1830e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1840e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (n_entries == allocated) 1850e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 1860e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington allocated *= 2; 1870e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington entries = xrealloc (entries, sizeof (SocketEntry*) * allocated); 1880e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 1890e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1900e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington entries[n_entries] = se; 1910e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington n_entries += 1; 1920e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 1930e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1940e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington closedir (dirh); 1950e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 1960e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington *entries_p = entries; 1970e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington *n_entries_p = n_entries; 1980e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 1990e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2000e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic SocketStatus 2010e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonopen_socket (SocketEntry *se) 2020e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 2030e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int ret; 2040e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington struct sockaddr_un saddr; 2050e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2060e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->n_retries > 5) 2070e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2080e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Warning: giving up on socket %s after several retries; unable to determine socket's status\n", 2090e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->name); 2100e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_FAILED_TO_HANDLE; 2110e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2120e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2130e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->n_retries += 1; 2140e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2150e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->fd = socket (AF_UNIX, SOCK_STREAM, 0); 2160e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->fd < 0) 2170e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2180e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Warning: failed to open a socket to use for connecting: %s\n", 2190e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strerror (errno)); 2200e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_UNKNOWN; 2210e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2220e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2230e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (fcntl (se->fd, F_SETFL, O_NONBLOCK) < 0) 2240e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2250e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Warning: failed set socket %s nonblocking: %s\n", 2260e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->name, strerror (errno)); 2270e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_UNKNOWN; 2280e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2290e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2300e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2310e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington memset (&saddr, '\0', sizeof (saddr)); /* nul-terminates the sun_path */ 2320e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2330e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington saddr.sun_family = AF_UNIX; 2340e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strncpy (saddr.sun_path, se->name, sizeof (saddr.sun_path) - 1); 2350e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2360e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington do 2370e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2380e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington ret = connect (se->fd, (struct sockaddr*) &saddr, sizeof (saddr)); 2390e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2400e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington while (ret < 0 && errno == EINTR); 2410e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2420e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (ret >= 0) 2430e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_ALIVE; 2440e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington else 2450e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2460e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington switch (errno) 2470e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2480e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case EINPROGRESS: 2490e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case EAGAIN: 2500e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_UNKNOWN; 2510e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case ECONNREFUSED: 2520e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_DEAD; 2530e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington default: 2540e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Warning: unexpected error connecting to socket %s: %s\n", 2550e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->name, strerror (errno)); 2560e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return SOCKET_FAILED_TO_HANDLE; 2570e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2580e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2590e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 2600e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2610e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic int 2620e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonhandle_sockets (SocketEntry **entries, 2630e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int n_entries) 2640e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 2650e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int i; 2660e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int n_unknown; 2670e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2680e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington n_unknown = 0; 2690e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2700e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington i = 0; 2710e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington while (i < n_entries) 2720e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2730e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketEntry *se; 2740e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketStatus status; 2750e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2760e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se = entries[i]; 2770e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington ++i; 2780e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2790e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->fd >= 0) 2800e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2810e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Internal error, socket has fd kept open while status = %d\n", 2820e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->status); 2830e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (1); 2840e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 2850e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2860e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->status != SOCKET_UNKNOWN) 2870e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington continue; 2880e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2890e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington status = open_socket (se); 2900e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 2910e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington switch (status) 2920e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2930e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case SOCKET_DEAD: 2940e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington cleaned_count += 1; 2950e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (unlink (se->name) < 0) 2960e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 2970e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Warning: Failed to delete %s: %s\n", 2980e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->name, strerror (errno)); 2990e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3000e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->status = SOCKET_FAILED_TO_HANDLE; 3010e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 3020e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington else 3030e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->status = SOCKET_UNLINKED; 3040e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington break; 3050e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3060e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case SOCKET_ALIVE: 3070e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington alive_count += 1; 3080e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington /* FALL THRU */ 3090e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3100e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case SOCKET_FAILED_TO_HANDLE: 3110e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case SOCKET_UNKNOWN: 3120e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->status = status; 3130e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington break; 3140e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3150e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington case SOCKET_UNLINKED: 3160e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Bad status from open_socket(), should not happen\n"); 3170e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (1); 3180e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington break; 3190e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 3200e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3210e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->fd >= 0) 3220e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 3230e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington close (se->fd); 3240e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington se->fd = -1; 3250e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 3260e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3270e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (se->status == SOCKET_UNKNOWN) 3280e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington n_unknown += 1; 3290e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 3300e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3310e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return n_unknown == 0; 3320e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 3330e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3340e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void 3350e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonclean_dir (const char *dir) 3360e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 3370e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington SocketEntry **entries; 3380e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int n_entries; 3390e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3400e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington read_sockets (dir, &entries, &n_entries); 3410e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3420e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington /* open_socket() will fail conclusively after 3430e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * several retries, so this loop is guaranteed 3440e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington * to terminate eventually 3450e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington */ 3460e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington while (!handle_sockets (entries, n_entries)) 3470e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 3480e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "Unable to determine state of some sockets, retrying in 2 seconds\n"); 3490e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington sleep (2); 3500e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 3510e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3520e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington unhandled_count += (n_entries - alive_count - cleaned_count); 3530e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 3540e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3550e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#endif /* AF_UNIX */ 3560e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3570e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void 3580e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonusage (int ecode) 3590e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 3600e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "dbus-cleanup-sockets [--version] [--help] <socketdir>\n"); 3610e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (ecode); 3620e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 3630e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3640e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonstatic void 3650e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonversion (void) 3660e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 3677652304bff969afb3969603149bb385efe861fe8John (J printf ("D-Bus Socket Cleanup Utility %s\n" 3680e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington "Copyright (C) 2003 Red Hat, Inc.\n" 3690e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington "Copyright (C) 2002 Michael Meeks\n" 3700e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington "This is free software; see the source for copying conditions.\n" 3710e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", 3720e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington VERSION); 3730e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (0); 3740e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 3750e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3760e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonint 3770e024fc53a5effadedd56427ffe261c417e45222Havoc Penningtonmain (int argc, char **argv) 3780e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington{ 3790e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int i; 3800e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington int saw_doubledash; 3810e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington const char *dirname; 3820e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3830e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington saw_doubledash = FALSE; 3840e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington dirname = NULL; 3850e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington i = 1; 3860e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington while (i < argc) 3870e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 3880e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington const char *arg = argv[i]; 3890e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 3900e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (strcmp (arg, "--help") == 0 || 3910e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strcmp (arg, "-h") == 0 || 3920e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington strcmp (arg, "-?") == 0) 3930e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington usage (0); 3940e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington else if (strcmp (arg, "--version") == 0) 3950e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington version (); 3960e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington else if (!saw_doubledash) 3970e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 3980e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (strcmp (arg, "--") == 0) 3990e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington saw_doubledash = TRUE; 4000e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington else if (*arg == '-') 4010e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington usage (1); 4020e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 4030e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington else 4040e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 4050e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (dirname != NULL) 4060e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington { 4070e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington fprintf (stderr, "dbus-cleanup-sockets only supports a single directory name\n"); 4080e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington exit (1); 4090e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 4100e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 4110e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington dirname = arg; 4120e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 4130e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 4140e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington ++i; 4150e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington } 4160e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 4170e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington /* Default to session socket dir, usually /tmp */ 4180e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington if (dirname == NULL) 4190e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington dirname = DBUS_SESSION_SOCKET_DIR; 4200e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 4210e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#ifdef AF_UNIX 4220e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington clean_dir (dirname); 4230e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 4240e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington printf ("Cleaned up %d sockets in %s; %d sockets are still in use; %d in unknown state\n", 4250e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington cleaned_count, dirname, alive_count, unhandled_count); 4260e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#else 4270e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington printf ("This system does not support UNIX domain sockets, so dbus-cleanup-sockets does nothing\n"); 4280e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington#endif 4290e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington 4300e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington return 0; 4310e024fc53a5effadedd56427ffe261c417e45222Havoc Pennington} 432