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 <tqfile.h>
00026 #include <tqtextstream.h>
00027 #include <tqregexp.h>
00028
00029 #include <dcopclient.h>
00030
00031 #include <tdecmdlineargs.h>
00032 #include <tdeapplication.h>
00033 #include <tdelocale.h>
00034 #include <tdeaboutdata.h>
00035 #include <tdeglobal.h>
00036 #include <kstandarddirs.h>
00037 #include <kprocess.h>
00038 #include <kde_file.h>
00039
00040 static TDECmdLineOptions options[] = {
00041 { "+old", I18N_NOOP("Old hostname"), 0 },
00042 { "+new", I18N_NOOP("New hostname"), 0 },
00043 TDECmdLineLastOption
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 TQCString &type);
00057 void changeSessionManager();
00058
00059 protected:
00060 TQCString oldName;
00061 TQCString newName;
00062 TQCString display;
00063 TQCString home;
00064 };
00065
00066 KHostName::KHostName()
00067 {
00068 TDECmdLineArgs *args = TDECmdLineArgs::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(TQRegExp("\\.[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 TQCString &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(TQCString(s));
00103 return result;
00104 }
00105 result.append(TQCString(s, i-s+1));
00106 s = i;
00107 while (*s == ' ') s++;
00108 }
00109 return result;
00110 }
00111
00112 void KHostName::changeX()
00113 {
00114 const char* xauthlocalhostname = getenv("XAUTHLOCALHOSTNAME");
00115 TQString cmd = "xauth -n list";
00116 FILE *xFile = popen(TQFile::encodeName(cmd), "r");
00117 if (!xFile)
00118 {
00119 fprintf(stderr, "Warning: Can't run xauth.\n");
00120 return;
00121 }
00122 QCStringList lines;
00123 {
00124 char buf[1024+1];
00125 while (!feof(xFile))
00126 {
00127 buf[1024]='\0';
00128 TQCString line = fgets(buf, 1024, xFile);
00129 if (line.length())
00130 line.truncate(line.length()-1);
00131 if (!line.isEmpty())
00132 lines.append(line);
00133 }
00134 }
00135 pclose(xFile);
00136
00137 for(QCStringList::ConstIterator it = lines.begin();
00138 it != lines.end(); ++it)
00139 {
00140 QCStringList entries = split(*it);
00141 if (entries.count() != 3)
00142 continue;
00143
00144 TQCString netId = entries[0];
00145 TQCString authName = entries[1];
00146 TQCString authKey = entries[2];
00147
00148 int i = netId.findRev(':');
00149 if (i == -1)
00150 continue;
00151 TQCString netDisplay = netId.mid(i);
00152 if (netDisplay != display)
00153 continue;
00154
00155 i = netId.find('/');
00156 if (i == -1)
00157 continue;
00158
00159 TQCString newNetId = newName+netId.mid(i);
00160 TQCString oldNetId = netId.left(i);
00161
00162 if(oldNetId != oldName
00163 && (!xauthlocalhostname || strcmp(xauthlocalhostname, oldNetId.data()) != 0))
00164 continue;
00165
00166
00167 if (!xauthlocalhostname || oldNetId != xauthlocalhostname)
00168 {
00169 cmd = "xauth -n remove "+TDEProcess::quote(netId);
00170 system(TQFile::encodeName(cmd));
00171 }
00172 cmd = "xauth -n add ";
00173 cmd += TDEProcess::quote(newNetId);
00174 cmd += " ";
00175 cmd += TDEProcess::quote(authName);
00176 cmd += " ";
00177 cmd += TDEProcess::quote(authKey);
00178 system(TQFile::encodeName(cmd));
00179 }
00180 }
00181
00182 void KHostName::changeDcop()
00183 {
00184 TQCString origFNameOld = DCOPClient::dcopServerFileOld(oldName);
00185 TQCString fname = DCOPClient::dcopServerFile(oldName);
00186 TQCString origFName = fname;
00187 FILE *dcopFile = fopen(fname.data(), "r");
00188 if (!dcopFile)
00189 {
00190 fprintf(stderr, "Warning: Can't open '%s' for reading.\n", fname.data());
00191 return;
00192 }
00193
00194 TQCString line1, line2;
00195 {
00196 char buf[1024+1];
00197 line1 = fgets(buf, 1024, dcopFile);
00198 if (line1.length())
00199 line1.truncate(line1.length()-1);
00200
00201 line2 = fgets(buf, 1024, dcopFile);
00202 if (line2.length())
00203 line2.truncate(line2.length()-1);
00204 }
00205 fclose(dcopFile);
00206
00207 TQCString oldNetId = line1;
00208
00209 if (!newName.isEmpty())
00210 {
00211 int i = line1.findRev(':');
00212 if (i == -1)
00213 {
00214 fprintf(stderr, "Warning: File '%s' has unexpected format.\n", fname.data());
00215 return;
00216 }
00217 line1 = "local/"+newName+line1.mid(i);
00218 TQCString newNetId = line1;
00219 fname = DCOPClient::dcopServerFile(newName);
00220 unlink(fname.data());
00221 dcopFile = fopen(fname.data(), "w");
00222 if (!dcopFile)
00223 {
00224 fprintf(stderr, "Warning: Can't open '%s' for writing.\n", fname.data());
00225 return;
00226 }
00227
00228 fputs(line1.data(), dcopFile);
00229 fputc('\n', dcopFile);
00230 fputs(line2.data(), dcopFile);
00231 fputc('\n', dcopFile);
00232
00233 fclose(dcopFile);
00234
00235 TQCString compatLink = DCOPClient::dcopServerFileOld(newName);
00236 ::symlink(fname.data(), compatLink.data());
00237
00238
00239 TQString cmd = "iceauth list "+TDEProcess::quote("netid="+oldNetId);
00240 FILE *iceFile = popen(TQFile::encodeName(cmd), "r");
00241 if (!iceFile)
00242 {
00243 fprintf(stderr, "Warning: Can't run iceauth.\n");
00244 return;
00245 }
00246 QCStringList lines;
00247 {
00248 char buf[1024+1];
00249 while (!feof(iceFile))
00250 {
00251 TQCString line = fgets(buf, 1024, iceFile);
00252 if (line.length())
00253 line.truncate(line.length()-1);
00254 if (!line.isEmpty())
00255 lines.append(line);
00256 }
00257 }
00258 pclose(iceFile);
00259
00260 for(QCStringList::ConstIterator it = lines.begin();
00261 it != lines.end(); ++it)
00262 {
00263 QCStringList entries = split(*it);
00264 if (entries.count() != 5)
00265 continue;
00266
00267 TQCString protName = entries[0];
00268 TQCString netId = entries[2];
00269 TQCString authName = entries[3];
00270 TQCString authKey = entries[4];
00271 if (netId != oldNetId)
00272 continue;
00273
00274 cmd = "iceauth add ";
00275 cmd += TDEProcess::quote(protName);
00276 cmd += " '' ";
00277 cmd += TDEProcess::quote(newNetId);
00278 cmd += " ";
00279 cmd += TDEProcess::quote(authName);
00280 cmd += " ";
00281 cmd += TDEProcess::quote(authKey);
00282 system(TQFile::encodeName(cmd));
00283 }
00284 }
00285
00286
00287
00288 char* xauthlocalhostname = getenv("XAUTHLOCALHOSTNAME");
00289 if (!xauthlocalhostname || !oldNetId.contains(xauthlocalhostname))
00290 {
00291 TQString cmd = "iceauth remove "+TDEProcess::quote("netid="+oldNetId);
00292 system(TQFile::encodeName(cmd));
00293 unlink(origFName.data());
00294 origFName = DCOPClient::dcopServerFileOld(oldName);
00295 unlink(origFName.data());
00296 }
00297 }
00298
00299 void KHostName::changeStdDirs(const TQCString &type)
00300 {
00301
00302 TQCString oldDir = TQFile::encodeName(TQString("%1%2-%3").arg(TDEGlobal::dirs()->localtdedir()).arg(type.data()).arg(oldName.data()));
00303 TQCString newDir = TQFile::encodeName(TQString("%1%2-%3").arg(TDEGlobal::dirs()->localtdedir()).arg(type.data()).arg(newName.data()));
00304
00305 KDE_struct_stat st_buf;
00306
00307 int result = KDE_lstat(oldDir.data(), &st_buf);
00308 if (result == 0)
00309 {
00310 if (S_ISLNK(st_buf.st_mode))
00311 {
00312 char buf[4096+1];
00313 result = readlink(oldDir.data(), buf, 4096);
00314 if (result >= 0)
00315 {
00316 buf[result] = 0;
00317 result = symlink(buf, newDir.data());
00318 }
00319 }
00320 else if (S_ISDIR(st_buf.st_mode))
00321 {
00322 result = symlink(oldDir.data(), newDir.data());
00323 }
00324 else
00325 {
00326 result = -1;
00327 }
00328 }
00329 if (result != 0)
00330 {
00331 system(("lnusertemp "+type).data());
00332 }
00333 }
00334
00335 void KHostName::changeSessionManager()
00336 {
00337 TQCString sm = ::getenv("SESSION_MANAGER");
00338 if (sm.isEmpty())
00339 {
00340 fprintf(stderr, "Warning: No session management specified.\n");
00341 return;
00342 }
00343 int i = sm.findRev(':');
00344 if ((i == -1) || (sm.left(6) != "local/"))
00345 {
00346 fprintf(stderr, "Warning: Session Management socket '%s' has unexpected format.\n", sm.data());
00347 return;
00348 }
00349 sm = "local/"+newName+sm.mid(i);
00350 TQCString name = "SESSION_MANAGER";
00351 TQByteArray params;
00352 TQDataStream stream(params, IO_WriteOnly);
00353 stream << name << sm;
00354 DCOPClient *client = new DCOPClient();
00355 if (!client->attach())
00356 {
00357 fprintf(stderr, "Warning: DCOP communication problem, can't fix Session Management.\n");
00358 delete client;
00359 return;
00360 }
00361 TQCString launcher = TDEApplication::launcher();
00362 client->send(launcher, launcher, "setLaunchEnv(TQCString,TQCString)", params);
00363 delete client;
00364 }
00365
00366 int main(int argc, char **argv)
00367 {
00368 TDELocale::setMainCatalogue("tdelibs");
00369 TDEAboutData d(appName, I18N_NOOP("KDontChangeTheHostName"), appVersion,
00370 I18N_NOOP("Informs TDE about a change in hostname"),
00371 TDEAboutData::License_GPL, "(c) 2001 Waldo Bastian");
00372 d.addAuthor("Waldo Bastian", I18N_NOOP("Author"), "bastian@kde.org");
00373
00374 TDECmdLineArgs::init(argc, argv, &d);
00375 TDECmdLineArgs::addCmdLineOptions(options);
00376
00377 TDEInstance k(&d);
00378
00379 KHostName hn;
00380
00381 hn.changeX();
00382 hn.changeDcop();
00383 hn.changeStdDirs("socket");
00384 hn.changeStdDirs("tmp");
00385 hn.changeSessionManager();
00386 }
00387