kalarm/lib
shellprocess.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include <stdlib.h>
00026 #include <sys/stat.h>
00027 #include <kapplication.h>
00028 #include <klocale.h>
00029 #include <kdebug.h>
00030
00031 #include "shellprocess.moc"
00032
00033
00034 QCString ShellProcess::mShellName;
00035 QCString ShellProcess::mShellPath;
00036 bool ShellProcess::mInitialised = false;
00037 bool ShellProcess::mAuthorised = false;
00038
00039
00040 ShellProcess::ShellProcess(const QString& command)
00041 : KShellProcess(shellName()),
00042 mCommand(command),
00043 mStatus(INACTIVE),
00044 mStdinExit(false)
00045 {
00046 }
00047
00048
00049
00050
00051 bool ShellProcess::start(Communication comm)
00052 {
00053 if (!authorised())
00054 {
00055 mStatus = UNAUTHORISED;
00056 return false;
00057 }
00058 KShellProcess::operator<<(mCommand);
00059 connect(this, SIGNAL(wroteStdin(KProcess*)), SLOT(writtenStdin(KProcess*)));
00060 connect(this, SIGNAL(processExited(KProcess*)), SLOT(slotExited(KProcess*)));
00061 if (!KShellProcess::start(KProcess::NotifyOnExit, comm))
00062 {
00063 mStatus = START_FAIL;
00064 return false;
00065 }
00066 mStatus = RUNNING;
00067 return true;
00068 }
00069
00070
00071
00072
00073
00074
00075 void ShellProcess::slotExited(KProcess* proc)
00076 {
00077 kdDebug(5950) << "ShellProcess::slotExited()\n";
00078 mStdinQueue.clear();
00079 mStatus = SUCCESS;
00080 if (!proc->normalExit())
00081 {
00082 kdWarning(5950) << "ShellProcess::slotExited(" << mCommand << ") " << mShellName << ": died/killed\n";
00083 mStatus = DIED;
00084 }
00085 else
00086 {
00087
00088 int status = proc->exitStatus();
00089 if (mShellName == "bash" && (status == 126 || status == 127)
00090 || mShellName == "ksh" && status == 127)
00091 {
00092 kdWarning(5950) << "ShellProcess::slotExited(" << mCommand << ") " << mShellName << ": not found or not executable\n";
00093 mStatus = NOT_FOUND;
00094 }
00095 }
00096 emit shellExited(this);
00097 }
00098
00099
00100
00101
00102 void ShellProcess::writeStdin(const char* buffer, int bufflen)
00103 {
00104 QCString scopy(buffer, bufflen+1);
00105 bool write = !mStdinQueue.count();
00106 mStdinQueue.append(scopy);
00107 if (write)
00108 KProcess::writeStdin(mStdinQueue.first(), mStdinQueue.first().length());
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 void ShellProcess::writtenStdin(KProcess* proc)
00118 {
00119 mStdinQueue.pop_front();
00120 if (mStdinQueue.count())
00121 proc->writeStdin(mStdinQueue.first(), mStdinQueue.first().length());
00122 else if (mStdinExit)
00123 kill();
00124 }
00125
00126
00127
00128
00129 void ShellProcess::stdinExit()
00130 {
00131 if (mStdinQueue.isEmpty())
00132 kill();
00133 else
00134 mStdinExit = true;
00135 }
00136
00137
00138
00139
00140
00141 QString ShellProcess::errorMessage() const
00142 {
00143 switch (mStatus)
00144 {
00145 case UNAUTHORISED:
00146 return i18n("Failed to execute command (shell access not authorized):");
00147 case START_FAIL:
00148 case NOT_FOUND:
00149 return i18n("Failed to execute command:");
00150 case DIED:
00151 return i18n("Command execution error:");
00152 case INACTIVE:
00153 case RUNNING:
00154 case SUCCESS:
00155 default:
00156 return QString::null;
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165 const QCString& ShellProcess::shellPath()
00166 {
00167 if (mShellPath.isEmpty())
00168 {
00169
00170 mShellPath = "/bin/sh";
00171 QCString envshell = QCString(getenv("SHELL")).stripWhiteSpace();
00172 if (!envshell.isEmpty())
00173 {
00174 struct stat fileinfo;
00175 if (stat(envshell.data(), &fileinfo) != -1
00176 && !S_ISDIR(fileinfo.st_mode)
00177 && !S_ISCHR(fileinfo.st_mode)
00178 && !S_ISBLK(fileinfo.st_mode)
00179 #ifdef S_ISSOCK
00180 && !S_ISSOCK(fileinfo.st_mode)
00181 #endif
00182 && !S_ISFIFO(fileinfo.st_mode)
00183 && !access(envshell.data(), X_OK))
00184 mShellPath = envshell;
00185 }
00186
00187
00188 int i = mShellPath.findRev('/');
00189 if (i >= 0)
00190 mShellName = mShellPath.mid(i + 1);
00191 else
00192 mShellName = mShellPath;
00193 }
00194 return mShellPath;
00195 }
00196
00197
00198
00199
00200 bool ShellProcess::authorised()
00201 {
00202 if (!mInitialised)
00203 {
00204 mAuthorised = kapp->authorize("shell_access");
00205 mInitialised = true;
00206 }
00207 return mAuthorised;
00208 }
|