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 QCString oldNetId = netId.left(i);
00159
00160 if(oldNetId != oldName)
00161 continue;
00162
00163 cmd = "xauth remove "+KProcess::quote(netId);
00164 system(QFile::encodeName(cmd));
00165 cmd = "xauth add ";
00166 cmd += KProcess::quote(newNetId);
00167 cmd += " ";
00168 cmd += KProcess::quote(authName);
00169 cmd += " ";
00170 cmd += KProcess::quote(authKey);
00171 system(QFile::encodeName(cmd));
00172 }
00173 }
00174
00175 void KHostName::changeDcop()
00176 {
00177 QCString origFNameOld = DCOPClient::dcopServerFileOld(oldName);
00178 QCString fname = DCOPClient::dcopServerFile(oldName);
00179 QCString origFName = fname;
00180 FILE *dcopFile = fopen(fname.data(), "r");
00181 if (!dcopFile)
00182 {
00183 fprintf(stderr, "Warning: Can't open '%s' for reading.\n", fname.data());
00184 return;
00185 }
00186
00187 QCString line1, line2;
00188 {
00189 char buf[1024+1];
00190 line1 = fgets(buf, 1024, dcopFile);
00191 if (line1.length())
00192 line1.truncate(line1.length()-1);
00193
00194 line2 = fgets(buf, 1024, dcopFile);
00195 if (line2.length())
00196 line2.truncate(line2.length()-1);
00197 }
00198 fclose(dcopFile);
00199
00200 QCString oldNetId = line1;
00201
00202 if (!newName.isEmpty())
00203 {
00204 int i = line1.findRev(':');
00205 if (i == -1)
00206 {
00207 fprintf(stderr, "Warning: File '%s' has unexpected format.\n", fname.data());
00208 return;
00209 }
00210 line1 = "local/"+newName+line1.mid(i);
00211 QCString newNetId = line1;
00212 fname = DCOPClient::dcopServerFile(newName);
00213 unlink(fname.data());
00214 dcopFile = fopen(fname.data(), "w");
00215 if (!dcopFile)
00216 {
00217 fprintf(stderr, "Warning: Can't open '%s' for writing.\n", fname.data());
00218 return;
00219 }
00220
00221 fputs(line1.data(), dcopFile);
00222 fputc('\n', dcopFile);
00223 fputs(line2.data(), dcopFile);
00224 fputc('\n', dcopFile);
00225
00226 fclose(dcopFile);
00227
00228 QCString compatLink = DCOPClient::dcopServerFileOld(newName);
00229 ::symlink(fname.data(), compatLink.data());
00230
00231
00232 QString cmd = "iceauth list "+KProcess::quote("netid="+oldNetId);
00233 FILE *iceFile = popen(QFile::encodeName(cmd), "r");
00234 if (!iceFile)
00235 {
00236 fprintf(stderr, "Warning: Can't run iceauth.\n");
00237 return;
00238 }
00239 QCStringList lines;
00240 {
00241 char buf[1024+1];
00242 while (!feof(iceFile))
00243 {
00244 QCString line = fgets(buf, 1024, iceFile);
00245 if (line.length())
00246 line.truncate(line.length()-1);
00247 if (!line.isEmpty())
00248 lines.append(line);
00249 }
00250 }
00251 pclose(iceFile);
00252
00253 for(QCStringList::ConstIterator it = lines.begin();
00254 it != lines.end(); ++it)
00255 {
00256 QCStringList entries = split(*it);
00257 if (entries.count() != 5)
00258 continue;
00259
00260 QCString protName = entries[0];
00261 QCString netId = entries[2];
00262 QCString authName = entries[3];
00263 QCString authKey = entries[4];
00264 if (netId != oldNetId)
00265 continue;
00266
00267 cmd = "iceauth add ";
00268 cmd += KProcess::quote(protName);
00269 cmd += " '' ";
00270 cmd += KProcess::quote(newNetId);
00271 cmd += " ";
00272 cmd += KProcess::quote(authName);
00273 cmd += " ";
00274 cmd += KProcess::quote(authKey);
00275 system(QFile::encodeName(cmd));
00276 }
00277 }
00278
00279
00280 {
00281 QString cmd = "iceauth remove "+KProcess::quote("netid="+oldNetId);
00282 system(QFile::encodeName(cmd));
00283 unlink(origFName.data());
00284 origFName = DCOPClient::dcopServerFileOld(oldName);
00285 unlink(origFName.data());
00286 }
00287 }
00288
00289 void KHostName::changeStdDirs(const QCString &type)
00290 {
00291
00292 QCString oldDir = QFile::encodeName(QString("%1%2-%3").arg(KGlobal::dirs()->localkdedir()).arg(type).arg(oldName));
00293 QCString newDir = QFile::encodeName(QString("%1%2-%3").arg(KGlobal::dirs()->localkdedir()).arg(type).arg(newName));
00294
00295 KDE_struct_stat st_buf;
00296
00297 int result = KDE_lstat(oldDir.data(), &st_buf);
00298 if (result == 0)
00299 {
00300 if (S_ISLNK(st_buf.st_mode))
00301 {
00302 char buf[4096+1];
00303 result = readlink(oldDir.data(), buf, 4096);
00304 if (result >= 0)
00305 {
00306 buf[result] = 0;
00307 result = symlink(buf, newDir.data());
00308 }
00309 }
00310 else if (S_ISDIR(st_buf.st_mode))
00311 {
00312 result = symlink(oldDir.data(), newDir.data());
00313 }
00314 else
00315 {
00316 result = -1;
00317 }
00318 }
00319 if (result != 0)
00320 {
00321 system(("lnusertemp "+type).data());
00322 }
00323 }
00324
00325 void KHostName::changeSessionManager()
00326 {
00327 QCString sm = ::getenv("SESSION_MANAGER");
00328 if (sm.isEmpty())
00329 {
00330 fprintf(stderr, "Warning: No session management specified.\n");
00331 return;
00332 }
00333 int i = sm.findRev(':');
00334 if ((i == -1) || (sm.left(6) != "local/"))
00335 {
00336 fprintf(stderr, "Warning: Session Management socket '%s' has unexpected format.\n", sm.data());
00337 return;
00338 }
00339 sm = "local/"+newName+sm.mid(i);
00340 QCString name = "SESSION_MANAGER";
00341 QByteArray params;
00342 QDataStream stream(params, IO_WriteOnly);
00343 stream << name << sm;
00344 DCOPClient *client = new DCOPClient();
00345 if (!client->attach())
00346 {
00347 fprintf(stderr, "Warning: DCOP communication problem, can't fix Session Management.\n");
00348 delete client;
00349 return;
00350 }
00351 QCString launcher = KApplication::launcher();
00352 client->send(launcher, launcher, "setLaunchEnv(QCString,QCString)", params);
00353 delete client;
00354 }
00355
00356 int main(int argc, char **argv)
00357 {
00358 KLocale::setMainCatalogue("kdelibs");
00359 KAboutData d(appName, I18N_NOOP("KDontChangeTheHostName"), appVersion,
00360 I18N_NOOP("Informs KDE about a change in hostname"),
00361 KAboutData::License_GPL, "(c) 2001 Waldo Bastian");
00362 d.addAuthor("Waldo Bastian", I18N_NOOP("Author"), "bastian@kde.org");
00363
00364 KCmdLineArgs::init(argc, argv, &d);
00365 KCmdLineArgs::addCmdLineOptions(options);
00366
00367 KInstance k(&d);
00368
00369 KHostName hn;
00370
00371 if(!getenv("XAUTHLOCALHOSTNAME"))
00372 hn.changeX();
00373
00374 hn.changeDcop();
00375 hn.changeStdDirs("socket");
00376 hn.changeStdDirs("tmp");
00377 hn.changeSessionManager();
00378 }
00379