You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/dcop/dcopserver_shutdown.c

205 lines
4.6 KiB

/*
This file is part of the KDE libraries
Copyright (c) 1999 Waldo Bastian <bastian@kde.org>
(c) 1999 Mario Weilguni <mweilguni@sime.com>
(c) 2001 Lubos Lunak <l.lunak@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <signal.h>
#define BUFFER_SIZE 4096
static char *getDisplay()
{
const char *display;
char *result;
char *screen;
char *colon;
/*
don't test for a value from tqglobal.h but instead distinguish
Qt/X11 from Qt/Embedded by the fact that Qt/E apps have -DQWS
on the commandline (which in tqglobal.h however triggers Q_WS_QWS,
but we don't want to include that here) (Simon)
#ifdef Q_WS_X11
*/
#if !defined(QWS)
display = getenv("DISPLAY");
#else
display = getenv("QWS_DISPLAY");
#endif
if (!display || !*display)
{
display = "NODISPLAY";
}
result = malloc(strlen(display)+1);
if (result == NULL)
return NULL;
strcpy(result, display);
screen = strrchr(result, '.');
colon = strrchr(result, ':');
if (screen && (screen > colon))
*screen = '\0';
return result;
}
static void getDCOPFile(char *dcop_file, char *dcop_file_old, int max_length)
{
const char *home_dir;
const char *dcop_authority;
char *display;
char *i;
int n;
n = max_length;
home_dir = getenv("HOME");
strncpy(dcop_file, home_dir, n);
dcop_file[ n - 1 ] = '\0';
n -= strlen(home_dir);
strncat(dcop_file, "/.DCOPserver_", n);
n -= strlen("/.DCOPserver_");
if (gethostname(dcop_file+strlen(dcop_file), n) != 0)
{
perror("Error. Could not determine hostname: ");
dcop_file[0] = '\0';
return;
}
dcop_file[max_length] = '\0';
n = max_length - strlen(dcop_file);
strncat(dcop_file, "_", n);
n -= strlen("_");
display = getDisplay();
if (display == NULL)
{
dcop_file[0] = '\0';
return; /* barf */
}
strcpy(dcop_file_old, dcop_file);
strncat(dcop_file_old,display, n);
while((i = strchr(display, ':')))
*i = '_';
strncat(dcop_file, display, n);
free(display);
dcop_authority = getenv("DCOPAUTHORITY");
if (dcop_authority && *dcop_authority)
{
strncpy(dcop_file, dcop_authority, max_length);
dcop_file[ max_length - 1 ] = '\0';
}
return;
}
static void cleanupDCOPsocket(char *buffer)
{
char cmd[BUFFER_SIZE];
const char *socket_file;
int l;
l = strlen(buffer);
if (!l)
return;
buffer[l-1] = '\0'; /* strip LF */
socket_file = strchr(buffer, ':');
if (socket_file)
socket_file++;
if (socket_file)
unlink(socket_file);
snprintf(cmd, BUFFER_SIZE, "iceauth remove netid='%s'", buffer);
system(cmd);
}
static void cleanupDCOP(int dont_kill_dcop, int wait_for_exit)
{
FILE *f;
char dcop_file[2048+1];
char dcop_file_old[2048+1];
char buffer[2048+1];
pid_t pid = 0;
getDCOPFile(dcop_file, dcop_file_old, 2048);
if (strlen(dcop_file) == 0)
return;
f = fopen(dcop_file, "r");
unlink(dcop_file); /* Clean up .DCOPserver file */
unlink(dcop_file_old);
if (!f)
return;
while (!feof(f))
{
if (!fgets(buffer, 2048, f))
break;
pid = strtol(buffer, NULL, 10);
if (pid)
break;
cleanupDCOPsocket(buffer);
}
fclose(f);
if (!dont_kill_dcop && pid)
kill(pid, SIGTERM);
while(wait_for_exit && (kill(pid, 0) == 0))
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
select(0,0,0,0,&tv);
}
}
int main(int argc, char **argv)
{
int dont_kill_dcop = (argc == 2) && (strcmp(argv[1], "--nokill") == 0);
int wait_for_exit = (argc == 2) && (strcmp(argv[1], "--wait") == 0);
cleanupDCOP(dont_kill_dcop, wait_for_exit);
return 0;
}