summaryrefslogtreecommitdiffstats
path: root/kded/khostname.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kded/khostname.cpp')
-rw-r--r--kded/khostname.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/kded/khostname.cpp b/kded/khostname.cpp
new file mode 100644
index 000000000..fe534119b
--- /dev/null
+++ b/kded/khostname.cpp
@@ -0,0 +1,379 @@
+/* This file is part of the KDE libraries
+ * Copyright (C) 2001 Waldo Bastian <bastian@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.
+ **/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#include <dcopclient.h>
+
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kaboutdata.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+#include <kde_file.h>
+
+static KCmdLineOptions options[] = {
+ { "+old", I18N_NOOP("Old hostname"), 0 },
+ { "+new", I18N_NOOP("New hostname"), 0 },
+ KCmdLineLastOption
+};
+
+static const char appName[] = "kdontchangethehostname";
+static const char appVersion[] = "1.1";
+
+class KHostName
+{
+public:
+ KHostName();
+
+ void changeX();
+ void changeDcop();
+ void changeStdDirs(const QCString &type);
+ void changeSessionManager();
+
+protected:
+ QCString oldName;
+ QCString newName;
+ QCString display;
+ QCString home;
+};
+
+KHostName::KHostName()
+{
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if (args->count() != 2)
+ args->usage();
+ oldName = args->arg(0);
+ newName = args->arg(1);
+ if (oldName == newName)
+ exit(0);
+
+ home = ::getenv("HOME");
+ if (home.isEmpty())
+ {
+ fprintf(stderr, "%s", i18n("Error: HOME environment variable not set.\n").local8Bit().data());
+ exit(1);
+ }
+
+ display = ::getenv("DISPLAY");
+ // strip the screen number from the display
+ display.replace(QRegExp("\\.[0-9]+$"), "");
+ if (display.isEmpty())
+ {
+ fprintf(stderr, "%s", i18n("Error: DISPLAY environment variable not set.\n").local8Bit().data());
+ exit(1);
+ }
+}
+
+static QCStringList split(const QCString &str)
+{
+ const char *s = str.data();
+ QCStringList result;
+ while (*s)
+ {
+ const char *i = strchr(s, ' ');
+ if (!i)
+ {
+ result.append(QCString(s));
+ return result;
+ }
+ result.append(QCString(s, i-s+1));
+ s = i;
+ while (*s == ' ') s++;
+ }
+ return result;
+}
+
+void KHostName::changeX()
+{
+ QString cmd = "xauth list";
+ FILE *xFile = popen(QFile::encodeName(cmd), "r");
+ if (!xFile)
+ {
+ fprintf(stderr, "Warning: Can't run xauth.\n");
+ return;
+ }
+ QCStringList lines;
+ {
+ char buf[1024+1];
+ while (!feof(xFile))
+ {
+ QCString line = fgets(buf, 1024, xFile);
+ if (line.length())
+ line.truncate(line.length()-1); // Strip LF.
+ if (!line.isEmpty())
+ lines.append(line);
+ }
+ }
+ pclose(xFile);
+
+ for(QCStringList::ConstIterator it = lines.begin();
+ it != lines.end(); ++it)
+ {
+ QCStringList entries = split(*it);
+ if (entries.count() != 3)
+ continue;
+
+ QCString netId = entries[0];
+ QCString authName = entries[1];
+ QCString authKey = entries[2];
+
+ int i = netId.findRev(':');
+ if (i == -1)
+ continue;
+ QCString netDisplay = netId.mid(i);
+ if (netDisplay != display)
+ continue;
+
+ i = netId.find('/');
+ if (i == -1)
+ continue;
+
+ QCString newNetId = newName+netId.mid(i);
+ QCString oldNetId = netId.left(i);
+
+ if(oldNetId != oldName)
+ continue;
+
+ cmd = "xauth remove "+KProcess::quote(netId);
+ system(QFile::encodeName(cmd));
+ cmd = "xauth add ";
+ cmd += KProcess::quote(newNetId);
+ cmd += " ";
+ cmd += KProcess::quote(authName);
+ cmd += " ";
+ cmd += KProcess::quote(authKey);
+ system(QFile::encodeName(cmd));
+ }
+}
+
+void KHostName::changeDcop()
+{
+ QCString origFNameOld = DCOPClient::dcopServerFileOld(oldName);
+ QCString fname = DCOPClient::dcopServerFile(oldName);
+ QCString origFName = fname;
+ FILE *dcopFile = fopen(fname.data(), "r");
+ if (!dcopFile)
+ {
+ fprintf(stderr, "Warning: Can't open '%s' for reading.\n", fname.data());
+ return;
+ }
+
+ QCString line1, line2;
+ {
+ char buf[1024+1];
+ line1 = fgets(buf, 1024, dcopFile);
+ if (line1.length())
+ line1.truncate(line1.length()-1); // Strip LF.
+
+ line2 = fgets(buf, 1024, dcopFile);
+ if (line2.length())
+ line2.truncate(line2.length()-1); // Strip LF.
+ }
+ fclose(dcopFile);
+
+ QCString oldNetId = line1;
+
+ if (!newName.isEmpty())
+ {
+ int i = line1.findRev(':');
+ if (i == -1)
+ {
+ fprintf(stderr, "Warning: File '%s' has unexpected format.\n", fname.data());
+ return;
+ }
+ line1 = "local/"+newName+line1.mid(i);
+ QCString newNetId = line1;
+ fname = DCOPClient::dcopServerFile(newName);
+ unlink(fname.data());
+ dcopFile = fopen(fname.data(), "w");
+ if (!dcopFile)
+ {
+ fprintf(stderr, "Warning: Can't open '%s' for writing.\n", fname.data());
+ return;
+ }
+
+ fputs(line1.data(), dcopFile);
+ fputc('\n', dcopFile);
+ fputs(line2.data(), dcopFile);
+ fputc('\n', dcopFile);
+
+ fclose(dcopFile);
+
+ QCString compatLink = DCOPClient::dcopServerFileOld(newName);
+ ::symlink(fname.data(), compatLink.data()); // Compatibility link
+
+ // Update .ICEauthority
+ QString cmd = "iceauth list "+KProcess::quote("netid="+oldNetId);
+ FILE *iceFile = popen(QFile::encodeName(cmd), "r");
+ if (!iceFile)
+ {
+ fprintf(stderr, "Warning: Can't run iceauth.\n");
+ return;
+ }
+ QCStringList lines;
+ {
+ char buf[1024+1];
+ while (!feof(iceFile))
+ {
+ QCString line = fgets(buf, 1024, iceFile);
+ if (line.length())
+ line.truncate(line.length()-1); // Strip LF.
+ if (!line.isEmpty())
+ lines.append(line);
+ }
+ }
+ pclose(iceFile);
+
+ for(QCStringList::ConstIterator it = lines.begin();
+ it != lines.end(); ++it)
+ {
+ QCStringList entries = split(*it);
+ if (entries.count() != 5)
+ continue;
+
+ QCString protName = entries[0];
+ QCString netId = entries[2];
+ QCString authName = entries[3];
+ QCString authKey = entries[4];
+ if (netId != oldNetId)
+ continue;
+
+ cmd = "iceauth add ";
+ cmd += KProcess::quote(protName);
+ cmd += " '' ";
+ cmd += KProcess::quote(newNetId);
+ cmd += " ";
+ cmd += KProcess::quote(authName);
+ cmd += " ";
+ cmd += KProcess::quote(authKey);
+ system(QFile::encodeName(cmd));
+ }
+ }
+
+ // Remove old entries
+ {
+ QString cmd = "iceauth remove "+KProcess::quote("netid="+oldNetId);
+ system(QFile::encodeName(cmd));
+ unlink(origFName.data());
+ origFName = DCOPClient::dcopServerFileOld(oldName); // Compatibility link
+ unlink(origFName.data());
+ }
+}
+
+void KHostName::changeStdDirs(const QCString &type)
+{
+ // We make links to the old dirs cause we can't delete the old dirs.
+ QCString oldDir = QFile::encodeName(QString("%1%2-%3").arg(KGlobal::dirs()->localkdedir()).arg(type).arg(oldName));
+ QCString newDir = QFile::encodeName(QString("%1%2-%3").arg(KGlobal::dirs()->localkdedir()).arg(type).arg(newName));
+
+ KDE_struct_stat st_buf;
+
+ int result = KDE_lstat(oldDir.data(), &st_buf);
+ if (result == 0)
+ {
+ if (S_ISLNK(st_buf.st_mode))
+ {
+ char buf[4096+1];
+ result = readlink(oldDir.data(), buf, 4096);
+ if (result >= 0)
+ {
+ buf[result] = 0;
+ result = symlink(buf, newDir.data());
+ }
+ }
+ else if (S_ISDIR(st_buf.st_mode))
+ {
+ result = symlink(oldDir.data(), newDir.data());
+ }
+ else
+ {
+ result = -1;
+ }
+ }
+ if (result != 0)
+ {
+ system(("lnusertemp "+type).data());
+ }
+}
+
+void KHostName::changeSessionManager()
+{
+ QCString sm = ::getenv("SESSION_MANAGER");
+ if (sm.isEmpty())
+ {
+ fprintf(stderr, "Warning: No session management specified.\n");
+ return;
+ }
+ int i = sm.findRev(':');
+ if ((i == -1) || (sm.left(6) != "local/"))
+ {
+ fprintf(stderr, "Warning: Session Management socket '%s' has unexpected format.\n", sm.data());
+ return;
+ }
+ sm = "local/"+newName+sm.mid(i);
+ QCString name = "SESSION_MANAGER";
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << name << sm;
+ DCOPClient *client = new DCOPClient();
+ if (!client->attach())
+ {
+ fprintf(stderr, "Warning: DCOP communication problem, can't fix Session Management.\n");
+ delete client;
+ return;
+ }
+ QCString launcher = KApplication::launcher();
+ client->send(launcher, launcher, "setLaunchEnv(QCString,QCString)", params);
+ delete client;
+}
+
+int main(int argc, char **argv)
+{
+ KLocale::setMainCatalogue("kdelibs");
+ KAboutData d(appName, I18N_NOOP("KDontChangeTheHostName"), appVersion,
+ I18N_NOOP("Informs KDE about a change in hostname"),
+ KAboutData::License_GPL, "(c) 2001 Waldo Bastian");
+ d.addAuthor("Waldo Bastian", I18N_NOOP("Author"), "bastian@kde.org");
+
+ KCmdLineArgs::init(argc, argv, &d);
+ KCmdLineArgs::addCmdLineOptions(options);
+
+ KInstance k(&d);
+
+ KHostName hn;
+
+ if(!getenv("XAUTHLOCALHOSTNAME"))
+ hn.changeX();
+
+ hn.changeDcop();
+ hn.changeStdDirs("socket");
+ hn.changeStdDirs("tmp");
+ hn.changeSessionManager();
+}
+