KDEsu
stub.cpp
Go to the documentation of this file.
00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * This file is part of the KDE project, module kdesu. 00004 * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> 00005 * 00006 * This is free software; you can use this library under the GNU Library 00007 * General Public License, version 2. See the file "COPYING.LIB" for the 00008 * exact licensing terms. 00009 * 00010 * stub.cpp: Conversation with kdesu_stub. 00011 */ 00012 00013 #include "stub.h" 00014 #include "kcookie.h" 00015 00016 #include <config.h> 00017 #include <stdlib.h> 00018 #include <unistd.h> 00019 00020 #include <QtCore/QBool> 00021 00022 #include <kdebug.h> 00023 00024 extern int kdesuDebugArea(); 00025 00026 namespace KDESu { 00027 00028 using namespace KDESuPrivate; 00029 00030 StubProcess::StubProcess() 00031 : d(0) 00032 { 00033 m_User = "root"; 00034 m_Scheduler = SchedNormal; 00035 m_Priority = 50; 00036 m_pCookie = new KCookie; 00037 m_bXOnly = true; 00038 } 00039 00040 00041 StubProcess::~StubProcess() 00042 { 00043 delete m_pCookie; 00044 } 00045 00046 00047 void StubProcess::setCommand(const QByteArray &command) 00048 { 00049 m_Command = command; 00050 } 00051 00052 00053 void StubProcess::setUser(const QByteArray &user) 00054 { 00055 m_User = user; 00056 } 00057 00058 00059 void StubProcess::setXOnly(bool xonly) 00060 { 00061 m_bXOnly = xonly; 00062 } 00063 00064 00065 void StubProcess::setPriority(int prio) 00066 { 00067 if (prio > 100) 00068 m_Priority = 100; 00069 else if (prio < 0) 00070 m_Priority = 0; 00071 else 00072 m_Priority = prio; 00073 } 00074 00075 00076 void StubProcess::setScheduler(int sched) 00077 { 00078 m_Scheduler = sched; 00079 } 00080 00081 00082 QByteArray StubProcess::commaSeparatedList(const QList<QByteArray> &lst) 00083 { 00084 QByteArray str; 00085 for (int i = 0; i < lst.count(); ++i) { 00086 str += ','; 00087 str += lst.at(i); 00088 } 00089 return str; 00090 } 00091 00092 void StubProcess::writeString(const QByteArray &str) 00093 { 00094 QByteArray out; 00095 out.reserve(str.size() + 8); 00096 for (int i = 0; i < str.size(); i++) { 00097 uchar c = str.at(i); 00098 if (c < 32) { 00099 out.append('\\'); 00100 out.append(c + '@'); 00101 } else if (c == '\\') { 00102 out.append('\\'); 00103 out.append('/'); 00104 } else { 00105 out.append(c); 00106 } 00107 } 00108 writeLine(out); 00109 } 00110 00111 /* 00112 * Map pid_t to a signed integer type that makes sense for QByteArray; 00113 * only the most common sizes 16 bit and 32 bit are special-cased. 00114 */ 00115 template<int T> struct PIDType { typedef pid_t PID_t; } ; 00116 template<> struct PIDType<2> { typedef qint16 PID_t; } ; 00117 template<> struct PIDType<4> { typedef qint32 PID_t; } ; 00118 00119 /* 00120 * Conversation with kdesu_stub. This is how we pass the authentication 00121 * tokens (X11) and other stuff to kdesu_stub. 00122 * return values: -1 = error, 0 = ok, 1 = kill me 00123 */ 00124 00125 int StubProcess::ConverseStub(int check) 00126 { 00127 QByteArray line, tmp; 00128 00129 while (1) 00130 { 00131 line = readLine(); 00132 if (line.isNull()) 00133 return -1; 00134 00135 if (line == "kdesu_stub") 00136 { 00137 // This makes parsing a lot easier. 00138 enableLocalEcho(false); 00139 if (check) writeLine("stop"); 00140 else writeLine("ok"); 00141 break; 00142 } 00143 } 00144 00145 while (1) 00146 { 00147 line = readLine(); 00148 if (line.isNull()) 00149 return -1; 00150 00151 if (line == "display") { 00152 writeLine(display()); 00153 } else if (line == "display_auth") { 00154 #ifdef Q_WS_X11 00155 writeLine(displayAuth()); 00156 #else 00157 writeLine(""); 00158 #endif 00159 } else if (line == "command") { 00160 writeString(m_Command); 00161 } else if (line == "path") { 00162 QByteArray path = qgetenv("PATH"); 00163 if (!path.isEmpty() && path[0] == ':') 00164 path = path.mid(1); 00165 if (m_User == "root") { 00166 if (!path.isEmpty()) 00167 path = "/sbin:/bin:/usr/sbin:/usr/bin:" + path; 00168 else 00169 path = "/sbin:/bin:/usr/sbin:/usr/bin"; 00170 } 00171 writeLine(path); 00172 } else if (line == "user") { 00173 writeLine(m_User); 00174 } else if (line == "priority") { 00175 tmp.setNum(m_Priority); 00176 writeLine(tmp); 00177 } else if (line == "scheduler") { 00178 if (m_Scheduler == SchedRealtime) writeLine("realtime"); 00179 else writeLine("normal"); 00180 } else if (line == "xwindows_only") { 00181 if (m_bXOnly) writeLine("no"); 00182 else writeLine("yes"); 00183 } else if (line == "app_startup_id") { 00184 QList<QByteArray> env = environment(); 00185 QByteArray tmp; 00186 for(int i = 0; i < env.count(); ++i) 00187 { 00188 const char startup_env[] = "DESKTOP_STARTUP_ID="; 00189 if (env.at(i).startsWith(startup_env)) 00190 tmp = env.at(i).mid(sizeof(startup_env) - 1); 00191 } 00192 if( tmp.isEmpty()) 00193 tmp = "0"; // krazy:exclude=doublequote_chars 00194 writeLine(tmp); 00195 } else if (line == "app_start_pid") { // obsolete 00196 // Force the pid_t returned from getpid() into 00197 // something QByteArray understands; avoids ambiguity 00198 // between short and unsigned short in particular. 00199 tmp.setNum((PIDType<sizeof(pid_t)>::PID_t)(getpid())); 00200 writeLine(tmp); 00201 } else if (line == "environment") { // additional env vars 00202 QList<QByteArray> env = environment(); 00203 for (int i = 0; i < env.count(); ++i) 00204 writeString(env.at(i)); 00205 writeLine( "" ); 00206 } else if (line == "end") { 00207 return 0; 00208 } else 00209 { 00210 kWarning(kdesuDebugArea()) << k_lineinfo << "Unknown request:" << line; 00211 return 1; 00212 } 00213 } 00214 00215 return 0; 00216 } 00217 00218 00219 QByteArray StubProcess::display() 00220 { 00221 return m_pCookie->display(); 00222 } 00223 00224 00225 #ifdef Q_WS_X11 00226 QByteArray StubProcess::displayAuth() 00227 { 00228 return m_pCookie->displayAuth(); 00229 } 00230 #endif 00231 00232 00233 void StubProcess::virtual_hook( int id, void* data ) 00234 { PtyProcess::virtual_hook( id, data ); } 00235 00236 }
KDE 4.6 API Reference