mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
kdepasswd: format and indent
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
7207617d83
commit
de3036ebc0
8 changed files with 384 additions and 373 deletions
|
@ -50,28 +50,31 @@
|
||||||
* TODO: It would be nice if the widget were in a .ui
|
* TODO: It would be nice if the widget were in a .ui
|
||||||
*/
|
*/
|
||||||
ChFaceDlg::ChFaceDlg(const QString& picsdir, QWidget *parent)
|
ChFaceDlg::ChFaceDlg(const QString& picsdir, QWidget *parent)
|
||||||
: KDialog( parent )
|
: KDialog(parent)
|
||||||
{
|
{
|
||||||
setCaption( i18nc("@title:window", "Change your Face") );
|
setCaption(i18nc("@title:window", "Change your Face") );
|
||||||
setButtons( Ok|Cancel|User1|User2 );
|
setButtons(KDialog::Ok | KDialog::Cancel | KDialog::User1| KDialog::User2);
|
||||||
setDefaultButton( Ok );
|
setDefaultButton(KDialog::Ok);
|
||||||
|
|
||||||
setButtonText( User1, i18n("Custom Image...") );
|
setButtonText(KDialog::User1, i18n("Custom Image..."));
|
||||||
setButtonText( User2, i18n("Remove Image") );
|
setButtonText(KDialog::User2, i18n("Remove Image"));
|
||||||
|
|
||||||
QWidget *faceDlg = new QWidget;
|
QWidget *faceDlg = new QWidget;
|
||||||
ui.setupUi(faceDlg);
|
ui.setupUi(faceDlg);
|
||||||
|
|
||||||
setMainWidget(faceDlg);
|
setMainWidget(faceDlg);
|
||||||
|
|
||||||
connect( ui.m_FacesWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(slotFaceWidgetSelectionChanged(QListWidgetItem*)) );
|
connect(
|
||||||
|
ui.m_FacesWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
|
||||||
|
this, SLOT(slotFaceWidgetSelectionChanged(QListWidgetItem*))
|
||||||
|
);
|
||||||
|
|
||||||
connect( ui.m_FacesWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(accept()) );
|
connect(ui.m_FacesWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
|
||||||
connect( this, SIGNAL(okClicked()), this, SLOT(accept()));
|
connect(this, SIGNAL(okClicked()), this, SLOT(accept()));
|
||||||
|
|
||||||
connect( this, SIGNAL(user1Clicked()), this, SLOT(slotGetCustomImage()) );
|
connect(this, SIGNAL(user1Clicked()), this, SLOT(slotGetCustomImage()));
|
||||||
|
|
||||||
connect( this, SIGNAL(user2Clicked()), this, SLOT(slotRemoveImage()) );
|
connect(this, SIGNAL(user2Clicked()), this, SLOT(slotRemoveImage()));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
QPushButton *acquireBtn = new QPushButton( i18n("&Acquire Image..."), page );
|
QPushButton *acquireBtn = new QPushButton( i18n("&Acquire Image..."), page );
|
||||||
|
@ -80,80 +83,94 @@ ChFaceDlg::ChFaceDlg(const QString& picsdir, QWidget *parent)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Filling the icon view
|
// Filling the icon view
|
||||||
QDir facesDir( picsdir );
|
QDir facesDir(picsdir);
|
||||||
if ( facesDir.exists() )
|
if (facesDir.exists()) {
|
||||||
{
|
|
||||||
const QStringList picslist = facesDir.entryList( QDir::Files );
|
const QStringList picslist = facesDir.entryList( QDir::Files );
|
||||||
for ( QStringList::const_iterator it = picslist.constBegin(); it != picslist.constEnd(); ++it )
|
foreach (const QString &it, picslist) {
|
||||||
new QListWidgetItem( QIcon( picsdir + *it ), (*it).section('.',0,0), ui.m_FacesWidget );
|
new QListWidgetItem(QIcon(picsdir + it), it.section('.',0,0), ui.m_FacesWidget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
facesDir.setPath( KCFGUserAccount::userFaceDir() );
|
facesDir.setPath( KCFGUserAccount::userFaceDir() );
|
||||||
if ( facesDir.exists() )
|
if (facesDir.exists()) {
|
||||||
{
|
|
||||||
const QStringList picslist = facesDir.entryList( QDir::Files );
|
const QStringList picslist = facesDir.entryList( QDir::Files );
|
||||||
for ( QStringList::const_iterator it = picslist.constBegin(); it != picslist.constEnd(); ++it )
|
foreach (const QString &it, picslist) {
|
||||||
new QListWidgetItem( QIcon( KCFGUserAccount::userFaceDir() + *it ),
|
new QListWidgetItem(
|
||||||
QString('/'+(*it)) == KCFGUserAccount::customFaceFile() ?
|
QIcon(KCFGUserAccount::userFaceDir() + it),
|
||||||
i18n("(Custom)") : (*it).section('.',0,0),
|
QString('/'+ it) == KCFGUserAccount::customFaceFile() ?
|
||||||
ui.m_FacesWidget );
|
i18n("(Custom)") : it.section('.',0,0),
|
||||||
|
ui.m_FacesWidget
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableButtonOk(false); // since no item is pre-selected, we must only enable the Ok button once a selection is done!
|
||||||
enableButtonOk( false ); // since no item is pre-selected, we must only enable the Ok button once a selection is done!
|
// connect(this, SIGNAL(okClicked()), SLOT(slotSaveCustomImage()));
|
||||||
//connect( this, SIGNAL(okClicked()), SLOT(slotSaveCustomImage()) );
|
|
||||||
|
|
||||||
resize( 420, 400 );
|
resize( 420, 400 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChFaceDlg::addCustomPixmap( const QString &imPath, bool saveCopy )
|
void ChFaceDlg::addCustomPixmap(const QString &imPath, bool saveCopy)
|
||||||
{
|
{
|
||||||
QImage pix( imPath );
|
QImage pix(imPath);
|
||||||
// TODO: save pix to TMPDIR/userinfo-tmp,
|
// TODO: save pix to TMPDIR/userinfo-tmp,
|
||||||
// then scale and copy *that* to ~/.faces
|
// then scale and copy *that* to ~/.faces
|
||||||
|
|
||||||
if (pix.isNull())
|
if (pix.isNull()) {
|
||||||
{
|
|
||||||
KMessageBox::sorry( this, i18n("There was an error loading the image.") );
|
KMessageBox::sorry( this, i18n("There was an error loading the image.") );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( (pix.width() > KCFGUserAccount::faceSize())
|
if ((pix.width() > KCFGUserAccount::faceSize()) || (pix.height() > KCFGUserAccount::faceSize())) {
|
||||||
|| (pix.height() > KCFGUserAccount::faceSize()) )
|
// Should be no bigger than certain size.
|
||||||
pix = pix.scaled( KCFGUserAccount::faceSize(), KCFGUserAccount::faceSize(), Qt::KeepAspectRatio );// Should be no bigger than certain size.
|
pix = pix.scaled(KCFGUserAccount::faceSize(), KCFGUserAccount::faceSize(), Qt::KeepAspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
if ( saveCopy )
|
if (saveCopy) {
|
||||||
{
|
|
||||||
// If we should save a copy:
|
// If we should save a copy:
|
||||||
QDir userfaces( KCFGUserAccount::userFaceDir() );
|
QDir userfaces(KCFGUserAccount::userFaceDir());
|
||||||
if ( !userfaces.exists( ) )
|
if (!userfaces.exists()) {
|
||||||
userfaces.mkdir( userfaces.absolutePath() );
|
userfaces.mkdir( userfaces.absolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
pix.save( userfaces.absolutePath() + "/.userinfo-tmp" , "PNG" );
|
pix.save(userfaces.absolutePath() + "/.userinfo-tmp" , "PNG" );
|
||||||
KonqOperations::copy( this, KonqOperations::COPY, KUrl::List( KUrl( userfaces.absolutePath() + "/.userinfo-tmp" ) ), KUrl( userfaces.absolutePath() + '/' + QFileInfo(imPath).fileName().section('.',0,0) ) );
|
KonqOperations::copy(
|
||||||
|
this,
|
||||||
|
KonqOperations::COPY,
|
||||||
|
KUrl::List(
|
||||||
|
KUrl(userfaces.absolutePath() + "/.userinfo-tmp")),
|
||||||
|
KUrl(userfaces.absolutePath() + '/' + QFileInfo(imPath).fileName().section('.',0,0)
|
||||||
|
)
|
||||||
|
);
|
||||||
#if 0
|
#if 0
|
||||||
if ( !pix.save( userfaces.absolutePath() + '/' + imPath , "PNG" ) )
|
if (!pix.save(userfaces.absolutePath() + '/' + imPath , "PNG"))
|
||||||
KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1", userfaces.absolutePath() ) );
|
KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1", userfaces.absolutePath()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QListWidgetItem* newface = new QListWidgetItem( QIcon(QPixmap::fromImage(pix)), QFileInfo(imPath).fileName().section('.',0,0), ui.m_FacesWidget );
|
QListWidgetItem* newface = new QListWidgetItem(
|
||||||
ui.m_FacesWidget->scrollToItem( newface );
|
QIcon(QPixmap::fromImage(pix)),
|
||||||
ui.m_FacesWidget->setCurrentItem( newface );
|
QFileInfo(imPath).fileName().section('.',0,0), ui.m_FacesWidget
|
||||||
|
);
|
||||||
|
ui.m_FacesWidget->scrollToItem(newface);
|
||||||
|
ui.m_FacesWidget->setCurrentItem(newface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChFaceDlg::slotGetCustomImage( )
|
void ChFaceDlg::slotGetCustomImage()
|
||||||
{
|
{
|
||||||
QCheckBox* checkWidget = new QCheckBox( i18n("&Save copy in custom faces folder for future use"), 0 );
|
QCheckBox* checkWidget = new QCheckBox(i18n("&Save copy in custom faces folder for future use"), nullptr);
|
||||||
|
|
||||||
KFileDialog dlg( QDir::homePath(), KImageIO::pattern( KImageIO::Reading ),
|
KFileDialog dlg(
|
||||||
this, checkWidget);
|
QDir::homePath(), KImageIO::pattern(KImageIO::Reading),
|
||||||
|
this, checkWidget
|
||||||
|
);
|
||||||
|
|
||||||
dlg.setOperationMode( KFileDialog::Opening );
|
dlg.setOperationMode(KFileDialog::Opening);
|
||||||
dlg.setInlinePreviewShown( true );
|
dlg.setInlinePreviewShown(true);
|
||||||
dlg.setCaption( i18nc("@title:window", "Choose Image") );
|
dlg.setCaption( i18nc("@title:window", "Choose Image"));
|
||||||
dlg.setMode( KFile::File | KFile::LocalOnly );
|
dlg.setMode(KFile::File | KFile::LocalOnly);
|
||||||
|
|
||||||
if (dlg.exec() == QDialog::Accepted)
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
addCustomPixmap( dlg.selectedFile(), checkWidget->isChecked() );
|
addCustomPixmap(dlg.selectedFile(), checkWidget->isChecked());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChFaceDlg::slotRemoveImage()
|
void ChFaceDlg::slotRemoveImage()
|
||||||
|
@ -165,14 +182,15 @@ void ChFaceDlg::slotRemoveImage()
|
||||||
#if 0
|
#if 0
|
||||||
void ChFaceDlg::slotSaveCustomImage()
|
void ChFaceDlg::slotSaveCustomImage()
|
||||||
{
|
{
|
||||||
if ( m_FacesWidget->currentItem()->key() == USER_CUSTOM_KEY)
|
if (m_FacesWidget->currentItem()->key() == USER_CUSTOM_KEY) {
|
||||||
{
|
QDir userfaces(QDir::homePath() + USER_FACES_DIR);
|
||||||
QDir userfaces( QDir::homePath() + USER_FACES_DIR );
|
if (!userfaces.exists()) {
|
||||||
if ( !userfaces.exists( ) )
|
userfaces.mkdir(userfaces.absolutePath());
|
||||||
userfaces.mkdir( userfaces.absolutePath() );
|
}
|
||||||
|
|
||||||
if ( !m_FacesWidget->currentItem()->pixmap()->save( userfaces.absolutePath() + USER_CUSTOM_FILE , "PNG" ) )
|
if (!m_FacesWidget->currentItem()->pixmap()->save(userfaces.absolutePath() + USER_CUSTOM_FILE, "PNG")) {
|
||||||
KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1", userfaces.absolutePath() ) );
|
KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1", userfaces.absolutePath()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,30 +63,30 @@ int main(int argc, char **argv)
|
||||||
bool bRoot = ku.isSuperUser();
|
bool bRoot = ku.isSuperUser();
|
||||||
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
||||||
|
|
||||||
if (args->count())
|
if (args->count()) {
|
||||||
user = args->arg(0);
|
user = args->arg(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* You must be able to run "kdepasswd loginName" */
|
/* You must be able to run "kdepasswd loginName" */
|
||||||
if ( !user.isEmpty() && user!=KUser().loginName() && !bRoot)
|
if (!user.isEmpty() && user != KUser().loginName() && !bRoot) {
|
||||||
{
|
|
||||||
KMessageBox::sorry(0, i18n("You need to be root to change the password of other users."));
|
KMessageBox::sorry(0, i18n("You need to be root to change the password of other users."));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray oldpass;
|
QByteArray oldpass;
|
||||||
if (!bRoot)
|
if (!bRoot) {
|
||||||
{
|
|
||||||
int result = KDEpasswd1Dialog::getPassword(oldpass);
|
int result = KDEpasswd1Dialog::getPassword(oldpass);
|
||||||
if (result != KDEpasswd1Dialog::Accepted)
|
if (result != KDEpasswd1Dialog::Accepted) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KDEpasswd2Dialog *dlg = new KDEpasswd2Dialog(oldpass, user.toLocal8Bit());
|
KDEpasswd2Dialog *dlg = new KDEpasswd2Dialog(oldpass, user.toLocal8Bit());
|
||||||
|
|
||||||
|
|
||||||
dlg->exec();
|
dlg->exec();
|
||||||
if (dlg->result() == KDEpasswd2Dialog::Rejected)
|
if (dlg->result() == KDEpasswd2Dialog::Rejected) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,20 +46,16 @@ PasswdProcess::PasswdProcess(const QString &user)
|
||||||
{
|
{
|
||||||
uid_t userid = -1;
|
uid_t userid = -1;
|
||||||
|
|
||||||
if (user.isEmpty())
|
if (user.isEmpty()) {
|
||||||
{
|
|
||||||
const KUser kuser(::getuid());
|
const KUser kuser(::getuid());
|
||||||
if (!kuser.isValid())
|
if (!kuser.isValid()) {
|
||||||
{
|
|
||||||
kDebug(1512) << "You don't exist!\n";
|
kDebug(1512) << "You don't exist!\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_User = kuser.loginName();
|
m_User = kuser.loginName();
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
const KUser kuser(user);
|
const KUser kuser(user);
|
||||||
if (!kuser.isValid())
|
if (!kuser.isValid()) {
|
||||||
{
|
|
||||||
kDebug(1512) << "User " << user << "does not exist.\n";
|
kDebug(1512) << "User " << user << "does not exist.\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -73,18 +69,16 @@ PasswdProcess::~PasswdProcess()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PasswdProcess::checkCurrent(const char *oldpass)
|
int PasswdProcess::checkCurrent(const char *oldpass)
|
||||||
{
|
{
|
||||||
return exec(oldpass, 0L, 1);
|
return exec(oldpass, 0L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PasswdProcess::exec(const char *oldpass, const char *newpass, int check)
|
||||||
int PasswdProcess::exec(const char *oldpass, const char *newpass,
|
|
||||||
int check)
|
|
||||||
{
|
{
|
||||||
if (m_User.isEmpty())
|
if (m_User.isEmpty()) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
// if (check)
|
// if (check)
|
||||||
// setTerminal(true);
|
// setTerminal(true);
|
||||||
|
|
||||||
|
@ -93,21 +87,23 @@ int PasswdProcess::exec(const char *oldpass, const char *newpass,
|
||||||
::setenv("LANG","C", true /* override */);
|
::setenv("LANG","C", true /* override */);
|
||||||
|
|
||||||
QList<QByteArray> args;
|
QList<QByteArray> args;
|
||||||
if(bOtherUser)
|
if (bOtherUser) {
|
||||||
args += m_User.toLocal8Bit();
|
args += m_User.toLocal8Bit();
|
||||||
|
}
|
||||||
int ret = PtyProcess::exec("passwd", args);
|
int ret = PtyProcess::exec("passwd", args);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
{
|
|
||||||
kDebug(1512) << "Passwd not found!\n";
|
kDebug(1512) << "Passwd not found!\n";
|
||||||
return PasswdNotFound;
|
return PasswdNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ConversePasswd(oldpass, newpass, check);
|
ret = ConversePasswd(oldpass, newpass, check);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
kDebug(1512) << "Conversation with passwd failed. pid = " << pid();
|
kDebug(1512) << "Conversation with passwd failed. pid = " << pid();
|
||||||
|
}
|
||||||
|
|
||||||
if ((waitForChild() != 0) && !check)
|
if ((waitForChild() != 0) && !check) {
|
||||||
return PasswordNotGood;
|
return PasswordNotGood;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -119,57 +115,56 @@ int PasswdProcess::exec(const char *oldpass, const char *newpass,
|
||||||
* Return values: -1 = unknown error, 0 = ok, >0 = error code.
|
* Return values: -1 = unknown error, 0 = ok, >0 = error code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
|
int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass, int check)
|
||||||
int check)
|
|
||||||
{
|
{
|
||||||
QByteArray line, errline;
|
QByteArray line, errline;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
|
||||||
while (state != 7)
|
while (state != 7) {
|
||||||
{
|
|
||||||
line = readLine();
|
line = readLine();
|
||||||
if (line.isNull())
|
if (line.isNull()) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == 0 && isPrompt(line, "new"))
|
if (state == 0 && isPrompt(line, "new")) {
|
||||||
// If root is changing a user's password,
|
// If root is changing a user's password,
|
||||||
// passwd can't prompt for the original password.
|
// passwd can't prompt for the original password.
|
||||||
// Therefore, we have to start at state=2.
|
// Therefore, we have to start at state=2.
|
||||||
state=2;
|
state = 2;
|
||||||
|
}
|
||||||
|
|
||||||
switch (state)
|
switch (state) {
|
||||||
{
|
case 0: {
|
||||||
case 0:
|
|
||||||
// Eat garbage, wait for prompt
|
// Eat garbage, wait for prompt
|
||||||
m_Error += line+'\n';
|
m_Error += line+'\n';
|
||||||
if (isPrompt(line, "password"))
|
if (isPrompt(line, "password")) {
|
||||||
{
|
|
||||||
WaitSlave();
|
WaitSlave();
|
||||||
write(fd(), oldpass, strlen(oldpass));
|
write(fd(), oldpass, strlen(oldpass));
|
||||||
write(fd(), "\n", 1);
|
write(fd(), "\n", 1);
|
||||||
state++;
|
state++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (m_bTerminal)
|
if (m_bTerminal) {
|
||||||
fputs(line, stdout);
|
fputs(line, stdout);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 1: case 3: case 6:
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 6: {
|
||||||
// Wait for \n
|
// Wait for \n
|
||||||
if (line.isEmpty())
|
if (line.isEmpty()) {
|
||||||
{
|
|
||||||
state++;
|
state++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// error
|
// error
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
case 2:
|
case 2: {
|
||||||
m_Error = "";
|
m_Error = "";
|
||||||
if( line.contains("again"))
|
if( line.contains("again")) {
|
||||||
{
|
|
||||||
m_Error = line;
|
m_Error = line;
|
||||||
kill(m_Pid, SIGKILL);
|
kill(m_Pid, SIGKILL);
|
||||||
waitForChild();
|
waitForChild();
|
||||||
|
@ -177,22 +172,20 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
|
||||||
}
|
}
|
||||||
// Wait for second prompt.
|
// Wait for second prompt.
|
||||||
errline = line; // use first line for error message
|
errline = line; // use first line for error message
|
||||||
while (!isPrompt(line, "new"))
|
while (!isPrompt(line, "new")) {
|
||||||
{
|
|
||||||
line = readLine();
|
line = readLine();
|
||||||
if (line.isNull())
|
if (line.isNull()) {
|
||||||
{
|
|
||||||
// We didn't get the new prompt so assume incorrect password.
|
// We didn't get the new prompt so assume incorrect password.
|
||||||
if (m_bTerminal)
|
if (m_bTerminal) {
|
||||||
fputs(errline, stdout);
|
fputs(errline, stdout);
|
||||||
|
}
|
||||||
m_Error = errline;
|
m_Error = errline;
|
||||||
return PasswordIncorrect;
|
return PasswordIncorrect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have the new prompt
|
// we have the new prompt
|
||||||
if (check)
|
if (check) {
|
||||||
{
|
|
||||||
kill(m_Pid, SIGKILL);
|
kill(m_Pid, SIGKILL);
|
||||||
waitForChild();
|
waitForChild();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -202,11 +195,11 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
|
||||||
write(fd(), "\n", 1);
|
write(fd(), "\n", 1);
|
||||||
state++;
|
state++;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 4:
|
case 4: {
|
||||||
// Wait for third prompt
|
// Wait for third prompt
|
||||||
if (isPrompt(line, "re"))
|
if (isPrompt(line, "re")) {
|
||||||
{
|
|
||||||
WaitSlave();
|
WaitSlave();
|
||||||
write(fd(), newpass, strlen(newpass));
|
write(fd(), newpass, strlen(newpass));
|
||||||
write(fd(), "\n", 1);
|
write(fd(), "\n", 1);
|
||||||
|
@ -214,48 +207,46 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Warning or error about the new password
|
// Warning or error about the new password
|
||||||
if (m_bTerminal)
|
if (m_bTerminal) {
|
||||||
fputs(line, stdout);
|
fputs(line, stdout);
|
||||||
|
}
|
||||||
m_Error = line + '\n';
|
m_Error = line + '\n';
|
||||||
state++;
|
state++;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 5:
|
case 5: {
|
||||||
// Wait for either a "Reenter password" or a "Enter password" prompt
|
// Wait for either a "Reenter password" or a "Enter password" prompt
|
||||||
if (isPrompt(line, "re"))
|
if (isPrompt(line, "re")) {
|
||||||
{
|
|
||||||
WaitSlave();
|
WaitSlave();
|
||||||
write(fd(), newpass, strlen(newpass));
|
write(fd(), newpass, strlen(newpass));
|
||||||
write(fd(), "\n", 1);
|
write(fd(), "\n", 1);
|
||||||
state++;
|
state++;
|
||||||
break;
|
break;
|
||||||
}
|
} else if (isPrompt(line, "password")) {
|
||||||
else if (isPrompt(line, "password"))
|
|
||||||
{
|
|
||||||
kill(m_Pid, SIGKILL);
|
kill(m_Pid, SIGKILL);
|
||||||
waitForChild();
|
waitForChild();
|
||||||
return PasswordNotGood;
|
return PasswordNotGood;
|
||||||
}
|
}
|
||||||
if (m_bTerminal)
|
if (m_bTerminal) {
|
||||||
fputs(line, stdout);
|
fputs(line, stdout);
|
||||||
|
}
|
||||||
m_Error += line + '\n';
|
m_Error += line + '\n';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Are we ok or do we still get an error thrown at us?
|
// Are we ok or do we still get an error thrown at us?
|
||||||
m_Error = "";
|
m_Error = "";
|
||||||
state = 0;
|
state = 0;
|
||||||
while (state != 1)
|
while (state != 1) {
|
||||||
{
|
|
||||||
line = readLine();
|
line = readLine();
|
||||||
if (line.isNull())
|
if (line.isNull()) {
|
||||||
{
|
|
||||||
// No more input... OK
|
// No more input... OK
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (isPrompt(line, "password"))
|
if (isPrompt(line, "password")) {
|
||||||
{
|
|
||||||
// Uh oh, another prompt. Not good!
|
// Uh oh, another prompt. Not good!
|
||||||
kill(m_Pid, SIGKILL);
|
kill(m_Pid, SIGKILL);
|
||||||
waitForChild();
|
waitForChild();
|
||||||
|
@ -268,25 +259,25 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PasswdProcess::isPrompt(const QByteArray &line, const char *word)
|
bool PasswdProcess::isPrompt(const QByteArray &line, const char *word)
|
||||||
{
|
{
|
||||||
unsigned i, j, colon;
|
unsigned i, j, colon;
|
||||||
unsigned int lineLength(line.length());
|
unsigned int lineLength(line.length());
|
||||||
for (i=0,j=0,colon=0; i<lineLength; ++i)
|
for (i = 0,j = 0, colon = 0; i < lineLength; ++i) {
|
||||||
{
|
if (line[i] == ':') {
|
||||||
if (line[i] == ':')
|
|
||||||
{
|
|
||||||
j = i; ++colon;
|
j = i; ++colon;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!isspace(line[i]))
|
if (!isspace(line[i])) {
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((colon != 1) || (line[j] != ':'))
|
if ((colon != 1) || (line[j] != ':')) {
|
||||||
return false;
|
return false;
|
||||||
if (word == 0L)
|
}
|
||||||
|
if (word == 0L) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return line.toLower().contains(word);
|
return line.toLower().contains(word);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,29 +33,30 @@
|
||||||
* A C++ API to passwd.
|
* A C++ API to passwd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PasswdProcess
|
class PasswdProcess : public PtyProcess
|
||||||
: public PtyProcess
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PasswdProcess(const QString &user = QString());
|
PasswdProcess(const QString &user = QString());
|
||||||
~PasswdProcess();
|
~PasswdProcess();
|
||||||
|
|
||||||
enum Errors { PasswdNotFound=1, PasswordIncorrect, PasswordNotGood };
|
enum Errors {
|
||||||
|
PasswdNotFound = 1,
|
||||||
|
PasswordIncorrect,
|
||||||
|
PasswordNotGood
|
||||||
|
};
|
||||||
|
|
||||||
int checkCurrent(const char *oldpass);
|
int checkCurrent(const char *oldpass);
|
||||||
int exec(const char *oldpass, const char *newpass, int check=0);
|
int exec(const char *oldpass, const char *newpass, int check = 0);
|
||||||
|
|
||||||
QByteArray error() { return m_Error; }
|
QByteArray error() { return m_Error; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isPrompt(const QByteArray &line, const char *word=0L);
|
bool isPrompt(const QByteArray &line, const char *word = 0L);
|
||||||
int ConversePasswd(const char *oldpass, const char *newpass,
|
int ConversePasswd(const char *oldpass, const char *newpass, int check);
|
||||||
int check);
|
|
||||||
|
|
||||||
QString m_User;
|
QString m_User;
|
||||||
QByteArray m_Error;
|
QByteArray m_Error;
|
||||||
bool bOtherUser;
|
bool bOtherUser;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // PASSWD_H
|
#endif // PASSWD_H
|
||||||
|
|
|
@ -45,10 +45,8 @@ void KDEpasswd1Dialog::accept()
|
||||||
PasswdProcess proc;
|
PasswdProcess proc;
|
||||||
|
|
||||||
int ret = proc.checkCurrent(password().toLocal8Bit());
|
int ret = proc.checkCurrent(password().toLocal8Bit());
|
||||||
switch (ret)
|
switch (ret) {
|
||||||
{
|
case -1: {
|
||||||
case -1:
|
|
||||||
{
|
|
||||||
QString msg = QString::fromLocal8Bit(proc.error());
|
QString msg = QString::fromLocal8Bit(proc.error());
|
||||||
if (!msg.isEmpty())
|
if (!msg.isEmpty())
|
||||||
msg = "<p>\"<i>" + msg + "</i>\"";
|
msg = "<p>\"<i>" + msg + "</i>\"";
|
||||||
|
@ -58,34 +56,40 @@ void KDEpasswd1Dialog::accept()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0:
|
case 0: {
|
||||||
return KPasswordDialog::accept();
|
return KPasswordDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
case PasswdProcess::PasswdNotFound:
|
case PasswdProcess::PasswdNotFound: {
|
||||||
KMessageBox::error(this, i18n("Could not find the program 'passwd'."));
|
KMessageBox::error(this, i18n("Could not find the program 'passwd'."));
|
||||||
done(Rejected);
|
done(Rejected);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case PasswdProcess::PasswordIncorrect:
|
case PasswdProcess::PasswordIncorrect: {
|
||||||
KMessageBox::sorry(this, i18n("Incorrect password. Please try again."));
|
KMessageBox::sorry(this, i18n("Incorrect password. Please try again."));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
KMessageBox::error(this, i18n("Internal error: illegal return value "
|
KMessageBox::error(
|
||||||
"from PasswdProcess::checkCurrent."));
|
this, i18n("Internal error: illegal return value "
|
||||||
|
"from PasswdProcess::checkCurrent.")
|
||||||
|
);
|
||||||
done(Rejected);
|
done(Rejected);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int KDEpasswd1Dialog::getPassword(QByteArray &password)
|
int KDEpasswd1Dialog::getPassword(QByteArray &password)
|
||||||
{
|
{
|
||||||
KDEpasswd1Dialog *dlg = new KDEpasswd1Dialog();
|
KDEpasswd1Dialog *dlg = new KDEpasswd1Dialog();
|
||||||
int res = dlg->exec();
|
int res = dlg->exec();
|
||||||
if (res == Accepted)
|
if (res == Accepted) {
|
||||||
password = dlg->password().toLocal8Bit();
|
password = dlg->password().toLocal8Bit();
|
||||||
|
}
|
||||||
delete dlg;
|
delete dlg;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -99,10 +103,11 @@ KDEpasswd2Dialog::KDEpasswd2Dialog(const char *oldpass, const QString &user)
|
||||||
m_User = user;
|
m_User = user;
|
||||||
|
|
||||||
setCaption(i18nc("@title:window", "Change Password"));
|
setCaption(i18nc("@title:window", "Change Password"));
|
||||||
if (m_User.isEmpty())
|
if (m_User.isEmpty()) {
|
||||||
setPrompt(i18n("Please enter your new password:"));
|
setPrompt(i18n("Please enter your new password:"));
|
||||||
else
|
} else {
|
||||||
setPrompt(i18n("Please enter the new password for user <b>%1</b>:", m_User));
|
setPrompt(i18n("Please enter the new password for user <b>%1</b>:", m_User));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,19 +115,18 @@ KDEpasswd2Dialog::~KDEpasswd2Dialog()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void KDEpasswd2Dialog::accept()
|
void KDEpasswd2Dialog::accept()
|
||||||
{
|
{
|
||||||
PasswdProcess proc(m_User);
|
PasswdProcess proc(m_User);
|
||||||
|
|
||||||
QString p;
|
QString p;
|
||||||
if(!checkAndGetPassword(&p)){
|
if (!checkAndGetPassword(&p)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.length() > 8)
|
if (p.length() > 8) {
|
||||||
{
|
const int yesno = KMessageBox::warningYesNoCancel(
|
||||||
switch(KMessageBox::warningYesNoCancel(this,
|
this,
|
||||||
m_User.isEmpty() ?
|
m_User.isEmpty() ?
|
||||||
i18n("Your password is longer than 8 characters. On some "
|
i18n("Your password is longer than 8 characters. On some "
|
||||||
"systems, this can cause problems. You can truncate "
|
"systems, this can cause problems. You can truncate "
|
||||||
|
@ -135,36 +139,40 @@ void KDEpasswd2Dialog::accept()
|
||||||
KGuiItem(i18n("Truncate")),
|
KGuiItem(i18n("Truncate")),
|
||||||
KGuiItem(i18n("Use as Is")),
|
KGuiItem(i18n("Use as Is")),
|
||||||
KStandardGuiItem::cancel(),
|
KStandardGuiItem::cancel(),
|
||||||
"truncatePassword"))
|
"truncatePassword"
|
||||||
{
|
);
|
||||||
case KMessageBox::Yes :
|
switch(yesno) {
|
||||||
p=p.left(8);
|
case KMessageBox::Yes: {
|
||||||
|
p = p.left(8);
|
||||||
break;
|
break;
|
||||||
case KMessageBox::No :
|
}
|
||||||
|
case KMessageBox::No: {
|
||||||
break;
|
break;
|
||||||
default : return;
|
}
|
||||||
|
default: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = proc.exec(m_Pass, p.toLocal8Bit());
|
int ret = proc.exec(m_Pass, p.toLocal8Bit());
|
||||||
switch (ret)
|
switch (ret) {
|
||||||
{
|
case 0: {
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
hide();
|
hide();
|
||||||
QString msg = QString::fromLocal8Bit(proc.error());
|
QString msg = QString::fromLocal8Bit(proc.error());
|
||||||
if (!msg.isEmpty())
|
if (!msg.isEmpty()) {
|
||||||
msg = "<p>\"<i>" + msg + "</i>\"";
|
msg = "<p>\"<i>" + msg + "</i>\"";
|
||||||
|
}
|
||||||
msg = "<qt>" + i18n("Your password has been changed.") + msg;
|
msg = "<qt>" + i18n("Your password has been changed.") + msg;
|
||||||
KMessageBox::information(0L, msg);
|
KMessageBox::information(0L, msg);
|
||||||
return KNewPasswordDialog::accept();
|
return KNewPasswordDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
case PasswdProcess::PasswordNotGood:
|
case PasswdProcess::PasswordNotGood: {
|
||||||
{
|
|
||||||
QString msg = QString::fromLocal8Bit(proc.error());
|
QString msg = QString::fromLocal8Bit(proc.error());
|
||||||
if (!msg.isEmpty())
|
if (!msg.isEmpty()) {
|
||||||
msg = "<p>\"<i>" + msg + "</i>\"";
|
msg = "<p>\"<i>" + msg + "</i>\"";
|
||||||
|
}
|
||||||
msg = "<qt>" + i18n("Your password has not been changed.") + msg;
|
msg = "<qt>" + i18n("Your password has not been changed.") + msg;
|
||||||
|
|
||||||
// The pw change did not succeed. Print the error.
|
// The pw change did not succeed. Print the error.
|
||||||
|
@ -172,18 +180,19 @@ void KDEpasswd2Dialog::accept()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
QString msg = QString::fromLocal8Bit(proc.error());
|
QString msg = QString::fromLocal8Bit(proc.error());
|
||||||
if (!msg.isEmpty())
|
if (!msg.isEmpty()) {
|
||||||
msg = "<p>\"<i>" + msg + "</i>\"";
|
msg = "<p>\"<i>" + msg + "</i>\"";
|
||||||
|
}
|
||||||
msg = "<qt>" + i18n("Conversation with 'passwd' failed.") + msg;
|
msg = "<qt>" + i18n("Conversation with 'passwd' failed.") + msg;
|
||||||
KMessageBox::sorry(this, msg);
|
KMessageBox::sorry(this, msg);
|
||||||
done(Rejected);
|
done(Rejected);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return KNewPasswordDialog::accept();
|
return KNewPasswordDialog::accept();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@
|
||||||
#include <knewpassworddialog.h>
|
#include <knewpassworddialog.h>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class KDEpasswd1Dialog
|
class KDEpasswd1Dialog : public KPasswordDialog
|
||||||
: public KPasswordDialog
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,8 @@ bool PtyProcess::checkPid(pid_t pid)
|
||||||
//sudo does not accept signals from user so we except it
|
//sudo does not accept signals from user so we except it
|
||||||
if (superUserCommand == "sudo") {
|
if (superUserCommand == "sudo") {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return kill(pid, 0) == 0;
|
|
||||||
}
|
}
|
||||||
|
return kill(pid, 0) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -92,15 +91,14 @@ int PtyProcess::checkPidExited(pid_t pid)
|
||||||
int state, ret;
|
int state, ret;
|
||||||
ret = waitpid(pid, &state, WNOHANG);
|
ret = waitpid(pid, &state, WNOHANG);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
{
|
|
||||||
kError(1512) << "waitpid():" << ::strerror(errno);
|
kError(1512) << "waitpid():" << ::strerror(errno);
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
if (ret == pid)
|
if (ret == pid) {
|
||||||
{
|
if (WIFEXITED(state)) {
|
||||||
if (WIFEXITED(state))
|
|
||||||
return WEXITSTATUS(state);
|
return WEXITSTATUS(state);
|
||||||
|
}
|
||||||
return Killed;
|
return Killed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,11 +109,16 @@ int PtyProcess::checkPidExited(pid_t pid)
|
||||||
class PtyProcess::PtyProcessPrivate
|
class PtyProcess::PtyProcessPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PtyProcessPrivate() : m_pPTY(0L) {}
|
PtyProcessPrivate()
|
||||||
|
: m_pPTY(0L)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
~PtyProcessPrivate()
|
~PtyProcessPrivate()
|
||||||
{
|
{
|
||||||
delete m_pPTY;
|
delete m_pPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> env;
|
QList<QByteArray> env;
|
||||||
KPty *m_pPTY;
|
KPty *m_pPTY;
|
||||||
QByteArray m_Inbuf;
|
QByteArray m_Inbuf;
|
||||||
|
@ -123,7 +126,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
PtyProcess::PtyProcess()
|
PtyProcess::PtyProcess()
|
||||||
:d(new PtyProcessPrivate)
|
: d(new PtyProcessPrivate())
|
||||||
{
|
{
|
||||||
m_bTerminal = false;
|
m_bTerminal = false;
|
||||||
m_bErase = false;
|
m_bErase = false;
|
||||||
|
@ -134,8 +137,7 @@ int PtyProcess::init()
|
||||||
{
|
{
|
||||||
delete d->m_pPTY;
|
delete d->m_pPTY;
|
||||||
d->m_pPTY = new KPty();
|
d->m_pPTY = new KPty();
|
||||||
if (!d->m_pPTY->open())
|
if (!d->m_pPTY->open()) {
|
||||||
{
|
|
||||||
kError(1512) << "Failed to open PTY.";
|
kError(1512) << "Failed to open PTY.";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -150,14 +152,17 @@ PtyProcess::~PtyProcess()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set additional environment variables. */
|
/** Set additional environment variables. */
|
||||||
void PtyProcess::setEnvironment( const QList<QByteArray> &env )
|
void PtyProcess::setEnvironment(const QList<QByteArray> &env)
|
||||||
{
|
{
|
||||||
d->env = env;
|
d->env = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PtyProcess::fd() const
|
int PtyProcess::fd() const
|
||||||
{
|
{
|
||||||
return d->m_pPTY ? d->m_pPTY->masterFd() : -1;
|
if (d->m_pPTY) {
|
||||||
|
return d->m_pPTY->masterFd();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PtyProcess::pid() const
|
int PtyProcess::pid() const
|
||||||
|
@ -175,8 +180,7 @@ QList<QByteArray> PtyProcess::environment() const
|
||||||
QByteArray PtyProcess::readAll(bool block)
|
QByteArray PtyProcess::readAll(bool block)
|
||||||
{
|
{
|
||||||
QByteArray ret;
|
QByteArray ret;
|
||||||
if (!d->m_Inbuf.isEmpty())
|
if (!d->m_Inbuf.isEmpty()) {
|
||||||
{
|
|
||||||
// if there is still something in the buffer, we need not block.
|
// if there is still something in the buffer, we need not block.
|
||||||
// we should still try to read any further output, from the fd, though.
|
// we should still try to read any further output, from the fd, though.
|
||||||
block = false;
|
block = false;
|
||||||
|
@ -185,36 +189,37 @@ QByteArray PtyProcess::readAll(bool block)
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = fcntl(fd(), F_GETFL);
|
int flags = fcntl(fd(), F_GETFL);
|
||||||
if (flags < 0)
|
if (flags < 0) {
|
||||||
{
|
|
||||||
kError(1512) << "fcntl(F_GETFL):" << ::strerror(errno);
|
kError(1512) << "fcntl(F_GETFL):" << ::strerror(errno);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int oflags = flags;
|
int oflags = flags;
|
||||||
if (block)
|
if (block) {
|
||||||
flags &= ~O_NONBLOCK;
|
flags &= ~O_NONBLOCK;
|
||||||
else
|
} else {
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags != oflags) && (fcntl(fd(), F_SETFL, flags) < 0))
|
if ((flags != oflags) && (fcntl(fd(), F_SETFL, flags) < 0)) {
|
||||||
{
|
|
||||||
// We get an error here when the child process has closed
|
// We get an error here when the child process has closed
|
||||||
// the file descriptor already.
|
// the file descriptor already.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
ret.reserve(ret.size() + 0x8000);
|
ret.reserve(ret.size() + 0x8000);
|
||||||
int nbytes = read(fd(), ret.data() + ret.size(), 0x8000);
|
int nbytes = read(fd(), ret.data() + ret.size(), 0x8000);
|
||||||
if (nbytes == -1)
|
if (nbytes == -1) {
|
||||||
{
|
if (errno == EINTR) {
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
continue;
|
||||||
else break;
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nbytes == 0) {
|
||||||
|
// nothing available / eof
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (nbytes == 0)
|
|
||||||
break; // nothing available / eof
|
|
||||||
|
|
||||||
ret.resize(ret.size() + nbytes);
|
ret.resize(ret.size() + nbytes);
|
||||||
break;
|
break;
|
||||||
|
@ -229,16 +234,13 @@ QByteArray PtyProcess::readLine(bool block)
|
||||||
d->m_Inbuf = readAll(block);
|
d->m_Inbuf = readAll(block);
|
||||||
|
|
||||||
QByteArray ret;
|
QByteArray ret;
|
||||||
if (!d->m_Inbuf.isEmpty())
|
if (!d->m_Inbuf.isEmpty()) {
|
||||||
{
|
|
||||||
int pos = d->m_Inbuf.indexOf('\n');
|
int pos = d->m_Inbuf.indexOf('\n');
|
||||||
if (pos == -1)
|
if (pos == -1) {
|
||||||
{
|
|
||||||
// NOTE: this means we return something even if there in no full line!
|
// NOTE: this means we return something even if there in no full line!
|
||||||
ret = d->m_Inbuf;
|
ret = d->m_Inbuf;
|
||||||
d->m_Inbuf.resize(0);
|
d->m_Inbuf.resize(0);
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
ret = d->m_Inbuf.left(pos);
|
ret = d->m_Inbuf.left(pos);
|
||||||
d->m_Inbuf.remove(0, pos+1);
|
d->m_Inbuf.remove(0, pos+1);
|
||||||
}
|
}
|
||||||
|
@ -247,23 +249,26 @@ QByteArray PtyProcess::readLine(bool block)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PtyProcess::writeLine(const QByteArray &line, bool addnl)
|
void PtyProcess::writeLine(const QByteArray &line, bool addnl)
|
||||||
{
|
{
|
||||||
if (!line.isEmpty())
|
if (!line.isEmpty()) {
|
||||||
write(fd(), line, line.length());
|
write(fd(), line, line.length());
|
||||||
if (addnl)
|
}
|
||||||
|
if (addnl) {
|
||||||
write(fd(), "\n", 1);
|
write(fd(), "\n", 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PtyProcess::unreadLine(const QByteArray &line, bool addnl)
|
void PtyProcess::unreadLine(const QByteArray &line, bool addnl)
|
||||||
{
|
{
|
||||||
QByteArray tmp = line;
|
QByteArray tmp = line;
|
||||||
if (addnl)
|
if (addnl) {
|
||||||
tmp += '\n';
|
tmp += '\n';
|
||||||
if (!tmp.isEmpty())
|
}
|
||||||
|
if (!tmp.isEmpty()) {
|
||||||
d->m_Inbuf.prepend(tmp);
|
d->m_Inbuf.prepend(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PtyProcess::setExitString(const QByteArray &exit)
|
void PtyProcess::setExitString(const QByteArray &exit)
|
||||||
|
@ -282,25 +287,23 @@ int PtyProcess::exec(const QByteArray &command, const QList<QByteArray> &args)
|
||||||
if (init() < 0)
|
if (init() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((m_Pid = fork()) == -1)
|
if ((m_Pid = fork()) == -1) {
|
||||||
{
|
|
||||||
kError(1512) << "fork():" << ::strerror(errno);
|
kError(1512) << "fork():" << ::strerror(errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parent
|
// Parent
|
||||||
if (m_Pid)
|
if (m_Pid) {
|
||||||
{
|
|
||||||
d->m_pPTY->closeSlave();
|
d->m_pPTY->closeSlave();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child
|
// Child
|
||||||
if (setupTTY() < 0)
|
if (setupTTY() < 0) {
|
||||||
_exit(1);
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < d->env.count(); ++i)
|
for (int i = 0; i < d->env.count(); ++i) {
|
||||||
{
|
|
||||||
putenv(const_cast<char *>(d->env.at(i).constData()));
|
putenv(const_cast<char *>(d->env.at(i).constData()));
|
||||||
}
|
}
|
||||||
unsetenv("KDE_FULL_SESSION");
|
unsetenv("KDE_FULL_SESSION");
|
||||||
|
@ -311,11 +314,12 @@ int PtyProcess::exec(const QByteArray &command, const QList<QByteArray> &args)
|
||||||
unsetenv("DBUS_SESSION_BUS_ADDRESS");
|
unsetenv("DBUS_SESSION_BUS_ADDRESS");
|
||||||
|
|
||||||
// set temporarily LC_ALL to C, for su (to be able to parse "Password:")
|
// set temporarily LC_ALL to C, for su (to be able to parse "Password:")
|
||||||
const QByteArray old_lc_all = qgetenv( "LC_ALL" );
|
const QByteArray old_lc_all = qgetenv("LC_ALL");
|
||||||
if( !old_lc_all.isEmpty() )
|
if (!old_lc_all.isEmpty()) {
|
||||||
qputenv( "KDESU_LC_ALL", old_lc_all );
|
qputenv("KDESU_LC_ALL", old_lc_all);
|
||||||
else
|
} else {
|
||||||
unsetenv( "KDESU_LC_ALL" );
|
unsetenv("KDESU_LC_ALL");
|
||||||
|
}
|
||||||
qputenv("LC_ALL", "C");
|
qputenv("LC_ALL", "C");
|
||||||
|
|
||||||
// From now on, terminal output goes through the tty.
|
// From now on, terminal output goes through the tty.
|
||||||
|
@ -365,20 +369,16 @@ int PtyProcess::WaitSlave()
|
||||||
kDebug(1512) << "Child pid" << m_Pid;
|
kDebug(1512) << "Child pid" << m_Pid;
|
||||||
|
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
if (!checkPid(m_Pid)) {
|
||||||
if (!checkPid(m_Pid))
|
|
||||||
{
|
|
||||||
kError(1512) << "process has exited while waiting for password.";
|
kError(1512) << "process has exited while waiting for password.";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!d->m_pPTY->tcGetAttr(&tio))
|
if (!d->m_pPTY->tcGetAttr(&tio)) {
|
||||||
{
|
|
||||||
kError(1512) << "tcgetattr():" << ::strerror(errno);
|
kError(1512) << "tcgetattr():" << ::strerror(errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (tio.c_lflag & ECHO)
|
if (tio.c_lflag & ECHO) {
|
||||||
{
|
|
||||||
kDebug(1512) << "Echo mode still on.";
|
kDebug(1512) << "Echo mode still on.";
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
continue;
|
continue;
|
||||||
|
@ -419,8 +419,7 @@ int PtyProcess::waitForChild()
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
QByteArray remainder;
|
QByteArray remainder;
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
FD_SET(fd(), &fds);
|
FD_SET(fd(), &fds);
|
||||||
|
|
||||||
// specify timeout to make sure select() does not block, even if the
|
// specify timeout to make sure select() does not block, even if the
|
||||||
|
@ -431,29 +430,25 @@ int PtyProcess::waitForChild()
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = 100000;
|
timeout.tv_usec = 100000;
|
||||||
int ret = select(fd()+1, &fds, 0L, 0L, &timeout);
|
int ret = select(fd()+1, &fds, 0L, 0L, &timeout);
|
||||||
if (ret == -1)
|
if (ret == -1) {
|
||||||
{
|
if (errno != EINTR) {
|
||||||
if (errno != EINTR)
|
|
||||||
{
|
|
||||||
kError(1512) << "select():" << ::strerror(errno);
|
kError(1512) << "select():" << ::strerror(errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret) {
|
||||||
{
|
|
||||||
forever {
|
forever {
|
||||||
QByteArray output = readAll(false);
|
QByteArray output = readAll(false);
|
||||||
if (output.isEmpty())
|
if (output.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
if (m_bTerminal)
|
}
|
||||||
{
|
if (m_bTerminal) {
|
||||||
fwrite(output.constData(), output.size(), 1, stdout);
|
fwrite(output.constData(), output.size(), 1, stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
if (!m_Exit.isEmpty())
|
if (!m_Exit.isEmpty()) {
|
||||||
{
|
|
||||||
// match exit string only at line starts
|
// match exit string only at line starts
|
||||||
remainder += output;
|
remainder += output;
|
||||||
while (remainder.length() >= m_Exit.length()) {
|
while (remainder.length() >= m_Exit.length()) {
|
||||||
|
@ -462,8 +457,9 @@ int PtyProcess::waitForChild()
|
||||||
remainder.remove(0, m_Exit.length());
|
remainder.remove(0, m_Exit.length());
|
||||||
}
|
}
|
||||||
int off = remainder.indexOf('\n');
|
int off = remainder.indexOf('\n');
|
||||||
if (off < 0)
|
if (off < 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
remainder.remove(0, off + 1);
|
remainder.remove(0, off + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -471,21 +467,16 @@ int PtyProcess::waitForChild()
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = checkPidExited(m_Pid);
|
ret = checkPidExited(m_Pid);
|
||||||
if (ret == Error)
|
if (ret == Error) {
|
||||||
{
|
if (errno == ECHILD) {
|
||||||
if (errno == ECHILD) return 0;
|
|
||||||
else return 1;
|
|
||||||
}
|
|
||||||
else if (ret == Killed)
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (ret == NotExited)
|
return 1;
|
||||||
{
|
} else if (ret == Killed) {
|
||||||
|
return 0;
|
||||||
|
} else if (ret == NotExited) {
|
||||||
// keep checking
|
// keep checking
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,35 +492,37 @@ int PtyProcess::waitForChild()
|
||||||
int PtyProcess::setupTTY()
|
int PtyProcess::setupTTY()
|
||||||
{
|
{
|
||||||
// Reset signal handlers
|
// Reset signal handlers
|
||||||
for (int sig = 1; sig < NSIG; sig++)
|
for (int sig = 1; sig < NSIG; sig++) {
|
||||||
KDE_signal(sig, SIG_DFL);
|
KDE_signal(sig, SIG_DFL);
|
||||||
|
}
|
||||||
KDE_signal(SIGHUP, SIG_IGN);
|
KDE_signal(SIGHUP, SIG_IGN);
|
||||||
|
|
||||||
d->m_pPTY->setCTty();
|
d->m_pPTY->setCTty();
|
||||||
|
|
||||||
// Connect stdin, stdout and stderr
|
// Connect stdin, stdout and stderr
|
||||||
int slave = d->m_pPTY->slaveFd();
|
int slave = d->m_pPTY->slaveFd();
|
||||||
dup2(slave, 0); dup2(slave, 1); dup2(slave, 2);
|
dup2(slave, 0);
|
||||||
|
dup2(slave, 1);
|
||||||
|
dup2(slave, 2);
|
||||||
|
|
||||||
// Close all file handles
|
// Close all file handles
|
||||||
// XXX this caused problems in KProcess - not sure why anymore. -- ???
|
// XXX this caused problems in KProcess - not sure why anymore. -- ???
|
||||||
// Because it will close the start notification pipe. -- ossi
|
// Because it will close the start notification pipe. -- ossi
|
||||||
struct rlimit rlp;
|
struct rlimit rlp;
|
||||||
getrlimit(RLIMIT_NOFILE, &rlp);
|
getrlimit(RLIMIT_NOFILE, &rlp);
|
||||||
for (int i = 3; i < (int)rlp.rlim_cur; i++)
|
for (int i = 3; i < (int)rlp.rlim_cur; i++) {
|
||||||
close(i);
|
close(i);
|
||||||
|
}
|
||||||
|
|
||||||
// Disable OPOST processing. Otherwise, '\n' are (on Linux at least)
|
// Disable OPOST processing. Otherwise, '\n' are (on Linux at least)
|
||||||
// translated to '\r\n'.
|
// translated to '\r\n'.
|
||||||
struct ::termios tio;
|
struct ::termios tio;
|
||||||
if (tcgetattr(0, &tio) < 0)
|
if (tcgetattr(0, &tio) < 0) {
|
||||||
{
|
|
||||||
kError(1512) << "tcgetattr():" << ::strerror(errno);
|
kError(1512) << "tcgetattr():" << ::strerror(errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tio.c_oflag &= ~OPOST;
|
tio.c_oflag &= ~OPOST;
|
||||||
if (tcsetattr(0, TCSANOW, &tio) < 0)
|
if (tcsetattr(0, TCSANOW, &tio) < 0) {
|
||||||
{
|
|
||||||
kError(1512) << "tcsetattr():" << ::strerror(errno);
|
kError(1512) << "tcsetattr():" << ::strerror(errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
* @param block Block until a full line is read?
|
* @param block Block until a full line is read?
|
||||||
* @return The output string.
|
* @return The output string.
|
||||||
*/
|
*/
|
||||||
QByteArray readLine(bool block=true);
|
QByteArray readLine(bool block = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all available output from the program's standard out.
|
* Read all available output from the program's standard out.
|
||||||
|
@ -69,14 +69,14 @@ public:
|
||||||
* @param line The text to write.
|
* @param line The text to write.
|
||||||
* @param addNewline Adds a '\n' to the line.
|
* @param addNewline Adds a '\n' to the line.
|
||||||
*/
|
*/
|
||||||
void writeLine(const QByteArray &line, bool addNewline=true);
|
void writeLine(const QByteArray &line, bool addNewline = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts back a line of input.
|
* Puts back a line of input.
|
||||||
* @param line The line to put back.
|
* @param line The line to put back.
|
||||||
* @param addNewline Adds a '\n' to the line.
|
* @param addNewline Adds a '\n' to the line.
|
||||||
*/
|
*/
|
||||||
void unreadLine(const QByteArray &line, bool addNewline=true);
|
void unreadLine(const QByteArray &line, bool addNewline = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the exit string. If a line of program output matches this,
|
* Sets the exit string. If a line of program output matches this,
|
||||||
|
@ -99,7 +99,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Enables/disables local echo on the pseudo tty.
|
* Enables/disables local echo on the pseudo tty.
|
||||||
*/
|
*/
|
||||||
int enableLocalEcho(bool enable=true);
|
int enableLocalEcho(bool enable = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables/disables terminal output. Relevant only to some subclasses.
|
* Enables/disables terminal output. Relevant only to some subclasses.
|
||||||
|
@ -115,7 +115,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Set additinal environment variables.
|
* Set additinal environment variables.
|
||||||
*/
|
*/
|
||||||
void setEnvironment( const QList<QByteArray> &env );
|
void setEnvironment(const QList<QByteArray> &env);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the filedescriptor of the process.
|
* Returns the filedescriptor of the process.
|
||||||
|
@ -144,7 +144,7 @@ public /* static */:
|
||||||
** @p ms must be in the range 0..999 (i.e. the maximum wait
|
** @p ms must be in the range 0..999 (i.e. the maximum wait
|
||||||
** duration is 999ms, almost one second).
|
** duration is 999ms, almost one second).
|
||||||
*/
|
*/
|
||||||
static int waitMS(int fd,int ms);
|
static int waitMS(int fd, int ms);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,9 +156,10 @@ public /* static */:
|
||||||
|
|
||||||
|
|
||||||
/** Error return values for checkPidExited() */
|
/** Error return values for checkPidExited() */
|
||||||
enum checkPidStatus { Error=-1, /**< No child */
|
enum checkPidStatus {
|
||||||
NotExited=-2, /**< Child hasn't exited */
|
Error = -1, /**< No child */
|
||||||
Killed=-3 /**< Child terminated by signal */
|
NotExited = -2, /**< Child hasn't exited */
|
||||||
|
Killed = -3 /**< Child terminated by signal */
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,9 +180,8 @@ protected:
|
||||||
newlines to be printed after output. Set to @c false
|
newlines to be printed after output. Set to @c false
|
||||||
in constructor. @see setTerminal() */
|
in constructor. @see setTerminal() */
|
||||||
int m_Pid; /**< PID of child process */
|
int m_Pid; /**< PID of child process */
|
||||||
QByteArray m_Command, /**< Unused */
|
QByteArray m_Command; /**< Unused */
|
||||||
m_Exit; /**< String to scan for in output that indicates
|
QByteArray m_Exit; /**< String to scan for in output that indicates child has exited. */
|
||||||
child has exited. */
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int init();
|
int init();
|
||||||
|
|
Loading…
Add table
Reference in a new issue