00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <unistd.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024
00025 #include <qfile.h>
00026 #include <qtextstream.h>
00027 #include <qregexp.h>
00028
00029 #include <dcopclient.h>
00030
00031 #include <kcmdlineargs.h>
00032 #include <kapplication.h>
00033 #include <klocale.h>
00034 #include <kaboutdata.h>
00035 #include <kglobal.h>
00036 #include <kstandarddirs.h>
00037 #include <kprocess.h>
00038 #include <kde_file.h>
00039
00040 static KCmdLineOptions options[] = {
00041 { "+old", I18N_NOOP("Old hostname"), 0 },
00042 { "+new", I18N_NOOP("New hostname"), 0 },
00043 KCmdLineLastOption
00044 };
00045
00046 static const char appName[] = "kdontchangethehostname";
00047 static const char appVersion[] = "1.1";
00048
00049 class KHostName
00050 {
00051 public:
00052 KHostName();
00053
00054 void changeX();
00055 void changeDcop();
00056 void changeStdDirs(const QCString &type);
00057 void changeSessionManager();
00058
00059 protected:
00060 QCString oldName;
00061 QCString newName;
00062 QCString display;
00063 QCString home;
00064 };
00065
00066 KHostName::KHostName()
00067 {
00068 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00069 if (args->count() != 2)
00070 args->usage();
00071 oldName = args->arg(0);
00072 newName = args->arg(1);
00073 if (oldName == newName)
00074 exit(0);
00075
00076 home = ::getenv("HOME");
00077 if (home.isEmpty())
00078 {
00079 fprintf(stderr, "%s", i18n("Error: HOME environment variable not set.\n").local8Bit().data());
00080 exit(1);
00081 }
00082
00083 display = ::getenv("DISPLAY");
00084
00085 display.replace(QRegExp("\\.[0-9]+$"), "");
00086 if (display.isEmpty())
00087 {
00088 fprintf(stderr, "%s", i18n("Error: DISPLAY environment variable not set.\n").local8Bit().data());
00089 exit(1);
00090 }
00091 }
00092
00093 static QCStringList split(const QCString &str)
00094 {
00095 const char *s = str.data();
00096 QCStringList result;
00097 while (*s)
00098 {
00099 const char *i = strchr(s, ' ');
00100 if (!i)
00101 {
00102 result.append(QCString(s));
00103 return result;
00104 }
00105 result.append(QCString(s, i-s+1));
00106 s = i;
00107 while (*s == ' ') s++;
00108 }
00109 return result;
00110 }
00111
00112 void KHostName::changeX()
00113 {
00114 QString cmd = "xauth list";
00115 FILE *xFile = popen(QFile::encodeName(cmd), "r");
00116 if (!xFile)
00117 {
00118 fprintf(stderr, "Warning: Can't run xauth.\n");
00119 return;
00120 }
00121 QCStringList lines;
00122 {
00123 char buf[1024+1];
00124 while (!feof(xFile))
00125 {
00126 QCString line = fgets(buf, 1024, xFile);
00127 if (line.length())
00128 line.truncate(line.length()-1);
00129 if (!line.isEmpty())
00130 lines.append(line);
00131 }
00132 }
00133 pclose(xFile);
00134
00135 for(QCStringList::ConstIterator it = lines.begin();
00136 it != lines.end(); ++it)
00137 {
00138 QCStringList entries = split(*it);
00139 if (entries.count() != 3)
00140 continue;
00141
00142 QCString netId = entries[0];
00143 QCString authName = entries[1];
00144 QCString authKey = entries[2];
00145
00146 int i = netId.findRev(':');
00147 if (i == -1)
00148 continue;
00149 QCString netDisplay = netId.mid(i);
00150 if (netDisplay != display)
00151 continue;
00152
00153 i = netId.find('/');
00154 if (i == -1)
00155 continue;
00156
00157 QCString newNetId = newName+netId.mid(i);
00158
00159 cmd = "xauth remove "+KProcess::quote(netId);
00160 system(QFile::encodeName(cmd));
00161 cmd = "xauth add ";
00162 cmd += KProcess::quote(newNetId);
00163 cmd += " ";
00164 cmd += KProcess::quote(authName);
00165 cmd += " ";
00166 cmd += KProcess::quote(authKey);
00167 system(QFile::encodeName(cmd));
00168 }
00169 }
00170
00171 void KHostName::changeDcop()
00172 {
00173 QCString origFNameOld = DCOPClient::dcopServerFileOld(oldName);
00174 QCString fname = DCOPClient::dcopServerFile(oldName);
00175 QCString origFName = fname;
00176 FILE *dcopFile = fopen(fname.data(), "r");
00177 if (!dcopFile)
00178 {
00179 fprintf(stderr, "Warning: Can't open '%s' for reading.\n", fname.data());
00180 return;
00181 }
00182
00183 QCString line1, line2;
00184 {
00185 char buf[1024+1];
00186 line1 = fgets(buf, 1024, dcopFile);
00187 if (line1.length())
00188 line1.truncate(line1.length()-1);
00189
00190 line2 = fgets(buf, 1024, dcopFile);
00191 if (line2.length())
00192 line2.truncate(line2.length()-1);
00193 }
00194 fclose(dcopFile);
00195
00196 QCString oldNetId = line1;
00197
00198 if (!newName.isEmpty())
00199 {
00200 int i = line1.findRev(':');
00201 if (i == -1)
00202 {
00203 fprintf(stderr, "Warning: File '%s' has unexpected format.\n", fname.data());
00204 return;
00205 }
00206 line1 = "local/"+newName+line1.mid(i);
00207 QCString newNetId = line1;
00208 fname = DCOPClient::dcopServerFile(newName);
00209 unlink(fname.data());
00210 dcopFile = fopen(fname.data(), "w");
00211 if (!dcopFile)
00212 {
00213 fprintf(stderr, "Warning: Can't open '%s' for writing.\n", fname.data());
00214 return;
00215 }
00216
00217 fputs(line1.data(), dcopFile);
00218 fputc('\n', dcopFile);
00219 fputs(line2.data(), dcopFile);
00220 fputc('\n', dcopFile);
00221
00222 fclose(dcopFile);
00223
00224 QCString compatLink = DCOPClient::dcopServerFileOld(newName);
00225 ::symlink(fname.data(), compatLink.data());
00226
00227
00228 QString cmd = "iceauth list "+KProcess::quote("netid="+oldNetId);
00229 FILE *iceFile = popen(QFile::encodeName(cmd), "r");
00230 if (!iceFile)
00231 {
00232 fprintf(stderr, "Warning: Can't run iceauth.\n");
00233 return;
00234 }
00235 QCStringList lines;
00236 {
00237 char buf[1024+1];
00238 while (!feof(iceFile))
00239 {
00240 QCString line = fgets(buf, 1024, iceFile);
00241 if (line.length())
00242 line.truncate(line.length()-1);
00243 if (!line.isEmpty())
00244 lines.append(line);
00245 }
00246 }
00247 pclose(iceFile);
00248
00249 for(QCStringList::ConstIterator it = lines.begin();
00250 it != lines.end(); ++it)
00251 {
00252 QCStringList entries = split(*it);
00253 if (entries.count() != 5)
00254 continue;
00255
00256 QCString protName = entries[0];
00257 QCString netId = entries[2];
00258 QCString authName = entries[3];
00259 QCString authKey = entries[4];
00260 if (netId != oldNetId)
00261 continue;
00262
00263 cmd = "iceauth add ";
00264 cmd += KProcess::quote(protName);
00265 cmd += " '' ";
00266 cmd += KProcess::quote(newNetId);
00267 cmd += " ";
00268 cmd += KProcess::quote(authName);
00269 cmd += " ";
00270 cmd += KProcess::quote(authKey);
00271 system(QFile::encodeName(cmd));
00272 }
00273 }
00274
00275
00276 {
00277 QString cmd = "iceauth remove "+KProcess::quote("netid="+oldNetId);
00278 system(QFile::encodeName(cmd));
00279 unlink(origFName.data());
00280 origFName = DCOPClient::dcopServerFileOld(oldName);
00281 unlink(origFName.data());
00282 }
00283 }
00284
00285 void KHostName::changeStdDirs(const QCString &type)
00286 {
00287
00288 QCString oldDir = QFile::encodeName(QString("%1%2-%3").arg(KGlobal::dirs()->localkdedir()).arg(type).arg(oldName));
00289 QCString newDir = QFile::encodeName(QString("%1%2-%3").arg(KGlobal::dirs()->localkdedir()).arg(type).arg(newName));
00290
00291 KDE_struct_stat st_buf;
00292
00293 int result = KDE_lstat(oldDir.data(), &st_buf);
00294 if (result == 0)
00295 {
00296 if (S_ISLNK(st_buf.st_mode))
00297 {
00298 char buf[4096+1];
00299 result = readlink(oldDir.data(), buf, 4096);
00300 if (result >= 0)
00301 {
00302 buf[result] = 0;
00303 result = symlink(buf, newDir.data());
00304 }
00305 }
00306 else if (S_ISDIR(st_buf.st_mode))
00307 {
00308 result = symlink(oldDir.data(), newDir.data());
00309 }
00310 else
00311 {
00312 result = -1;
00313 }
00314 }
00315 if (result != 0)
00316 {
00317 system(("lnusertemp "+type).data());
00318 }
00319 }
00320
00321 void KHostName::changeSessionManager()
00322 {
00323 QCString sm = ::getenv("SESSION_MANAGER");
00324 if (sm.isEmpty())
00325 {
00326 fprintf(stderr, "Warning: No session management specified.\n");
00327 return;
00328 }
00329 int i = sm.findRev(':');
00330 if ((i == -1) || (sm.left(6) != "local/"))
00331 {
00332 fprintf(stderr, "Warning: Session Management socket '%s' has unexpected format.\n", sm.data());
00333 return;
00334 }
00335 sm = "local/"+newName+sm.mid(i);
00336 QCString name = "SESSION_MANAGER";
00337 QByteArray params;
00338 QDataStream stream(params, IO_WriteOnly);
00339 stream << name << sm;
00340 DCOPClient *client = new DCOPClient();
00341 if (!client->attach())
00342 {
00343 fprintf(stderr, "Warning: DCOP communication problem, can't fix Session Management.\n");
00344 delete client;
00345 return;
00346 }
00347 QCString launcher = KApplication::launcher();
00348 client->send(launcher, launcher, "setLaunchEnv(QCString,QCString)", params);
00349 delete client;
00350 }
00351
00352 int main(int argc, char **argv)
00353 {
00354 KLocale::setMainCatalogue("kdelibs");
00355 KAboutData d(appName, I18N_NOOP("KDontChangeTheHostName"), appVersion,
00356 I18N_NOOP("Informs KDE about a change in hostname"),
00357 KAboutData::License_GPL, "(c) 2001 Waldo Bastian");
00358 d.addAuthor("Waldo Bastian", I18N_NOOP("Author"), "bastian@kde.org");
00359
00360 KCmdLineArgs::init(argc, argv, &d);
00361 KCmdLineArgs::addCmdLineOptions(options);
00362
00363 KInstance k(&d);
00364
00365 KHostName hn;
00366
00367 hn.changeX();
00368 hn.changeDcop();
00369 hn.changeStdDirs("socket");
00370 hn.changeStdDirs("tmp");
00371 hn.changeSessionManager();
00372 }
00373