kdepasswd: format and indent

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-07-29 11:05:35 +03:00
parent 7207617d83
commit de3036ebc0
8 changed files with 384 additions and 373 deletions

View file

@ -50,130 +50,148 @@
* TODO: It would be nice if the widget were in a .ui
*/
ChFaceDlg::ChFaceDlg(const QString& picsdir, QWidget *parent)
: KDialog( parent )
: KDialog(parent)
{
setCaption( i18nc("@title:window", "Change your Face") );
setButtons( Ok|Cancel|User1|User2 );
setDefaultButton( Ok );
setCaption(i18nc("@title:window", "Change your Face") );
setButtons(KDialog::Ok | KDialog::Cancel | KDialog::User1| KDialog::User2);
setDefaultButton(KDialog::Ok);
setButtonText( User1, i18n("Custom Image...") );
setButtonText( User2, i18n("Remove Image") );
setButtonText(KDialog::User1, i18n("Custom Image..."));
setButtonText(KDialog::User2, i18n("Remove Image"));
QWidget *faceDlg = new QWidget;
ui.setupUi(faceDlg);
QWidget *faceDlg = new QWidget;
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( this, SIGNAL(okClicked()), this, SLOT(accept()));
connect(ui.m_FacesWidget, SIGNAL(doubleClicked(QModelIndex)), 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
QPushButton *acquireBtn = new QPushButton( i18n("&Acquire Image..."), page );
acquireBtn->setEnabled( false );
morePics->addWidget( acquireBtn );
QPushButton *acquireBtn = new QPushButton( i18n("&Acquire Image..."), page );
acquireBtn->setEnabled( false );
morePics->addWidget( acquireBtn );
#endif
// Filling the icon view
QDir facesDir( picsdir );
if ( facesDir.exists() )
{
const QStringList picslist = facesDir.entryList( QDir::Files );
for ( QStringList::const_iterator it = picslist.constBegin(); it != picslist.constEnd(); ++it )
new QListWidgetItem( QIcon( picsdir + *it ), (*it).section('.',0,0), ui.m_FacesWidget );
}
facesDir.setPath( KCFGUserAccount::userFaceDir() );
if ( facesDir.exists() )
{
const QStringList picslist = facesDir.entryList( QDir::Files );
for ( QStringList::const_iterator it = picslist.constBegin(); it != picslist.constEnd(); ++it )
new QListWidgetItem( QIcon( KCFGUserAccount::userFaceDir() + *it ),
QString('/'+(*it)) == KCFGUserAccount::customFaceFile() ?
i18n("(Custom)") : (*it).section('.',0,0),
ui.m_FacesWidget );
}
// Filling the icon view
QDir facesDir(picsdir);
if (facesDir.exists()) {
const QStringList picslist = facesDir.entryList( QDir::Files );
foreach (const QString &it, picslist) {
new QListWidgetItem(QIcon(picsdir + it), it.section('.',0,0), ui.m_FacesWidget);
}
}
facesDir.setPath( KCFGUserAccount::userFaceDir() );
if (facesDir.exists()) {
const QStringList picslist = facesDir.entryList( QDir::Files );
foreach (const QString &it, picslist) {
new QListWidgetItem(
QIcon(KCFGUserAccount::userFaceDir() + it),
QString('/'+ it) == KCFGUserAccount::customFaceFile() ?
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!
// connect(this, SIGNAL(okClicked()), SLOT(slotSaveCustomImage()));
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()) );
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 );
// TODO: save pix to TMPDIR/userinfo-tmp,
// then scale and copy *that* to ~/.faces
QImage pix(imPath);
// TODO: save pix to TMPDIR/userinfo-tmp,
// then scale and copy *that* to ~/.faces
if (pix.isNull())
{
KMessageBox::sorry( this, i18n("There was an error loading the image.") );
return;
}
if ( (pix.width() > KCFGUserAccount::faceSize())
|| (pix.height() > KCFGUserAccount::faceSize()) )
pix = pix.scaled( KCFGUserAccount::faceSize(), KCFGUserAccount::faceSize(), Qt::KeepAspectRatio );// Should be no bigger than certain size.
if (pix.isNull()) {
KMessageBox::sorry( this, i18n("There was an error loading the image.") );
return;
}
if ((pix.width() > KCFGUserAccount::faceSize()) || (pix.height() > KCFGUserAccount::faceSize())) {
// Should be no bigger than certain size.
pix = pix.scaled(KCFGUserAccount::faceSize(), KCFGUserAccount::faceSize(), Qt::KeepAspectRatio);
}
if ( saveCopy )
{
// If we should save a copy:
QDir userfaces( KCFGUserAccount::userFaceDir() );
if ( !userfaces.exists( ) )
userfaces.mkdir( userfaces.absolutePath() );
if (saveCopy) {
// If we should save a copy:
QDir userfaces(KCFGUserAccount::userFaceDir());
if (!userfaces.exists()) {
userfaces.mkdir( userfaces.absolutePath());
}
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) ) );
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)
)
);
#if 0
if ( !pix.save( userfaces.absolutePath() + '/' + imPath , "PNG" ) )
KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1", userfaces.absolutePath() ) );
if (!pix.save(userfaces.absolutePath() + '/' + imPath , "PNG"))
KMessageBox::sorry(this, i18n("There was an error saving the image:\n%1", userfaces.absolutePath()));
#endif
}
QListWidgetItem* newface = new QListWidgetItem( QIcon(QPixmap::fromImage(pix)), QFileInfo(imPath).fileName().section('.',0,0), ui.m_FacesWidget );
ui.m_FacesWidget->scrollToItem( newface );
ui.m_FacesWidget->setCurrentItem( newface );
QListWidgetItem* newface = new QListWidgetItem(
QIcon(QPixmap::fromImage(pix)),
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 ),
this, checkWidget);
KFileDialog dlg(
QDir::homePath(), KImageIO::pattern(KImageIO::Reading),
this, checkWidget
);
dlg.setOperationMode( KFileDialog::Opening );
dlg.setInlinePreviewShown( true );
dlg.setCaption( i18nc("@title:window", "Choose Image") );
dlg.setMode( KFile::File | KFile::LocalOnly );
dlg.setOperationMode(KFileDialog::Opening);
dlg.setInlinePreviewShown(true);
dlg.setCaption( i18nc("@title:window", "Choose Image"));
dlg.setMode(KFile::File | KFile::LocalOnly);
if (dlg.exec() == QDialog::Accepted)
addCustomPixmap( dlg.selectedFile(), checkWidget->isChecked() );
if (dlg.exec() == QDialog::Accepted) {
addCustomPixmap(dlg.selectedFile(), checkWidget->isChecked());
}
}
void ChFaceDlg::slotRemoveImage()
{
ui.m_FacesWidget->clearSelection();
accept();
ui.m_FacesWidget->clearSelection();
accept();
}
#if 0
void ChFaceDlg::slotSaveCustomImage()
{
if ( m_FacesWidget->currentItem()->key() == USER_CUSTOM_KEY)
{
QDir userfaces( QDir::homePath() + USER_FACES_DIR );
if ( !userfaces.exists( ) )
userfaces.mkdir( userfaces.absolutePath() );
if (m_FacesWidget->currentItem()->key() == USER_CUSTOM_KEY) {
QDir userfaces(QDir::homePath() + USER_FACES_DIR);
if (!userfaces.exists()) {
userfaces.mkdir(userfaces.absolutePath());
}
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() ) );
}
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()));
}
}
}
#endif

View file

@ -63,30 +63,30 @@ int main(int argc, char **argv)
bool bRoot = ku.isSuperUser();
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
if (args->count())
if (args->count()) {
user = args->arg(0);
}
/* 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."));
return 1;
}
QByteArray oldpass;
if (!bRoot)
{
if (!bRoot) {
int result = KDEpasswd1Dialog::getPassword(oldpass);
if (result != KDEpasswd1Dialog::Accepted)
if (result != KDEpasswd1Dialog::Accepted) {
return 1;
}
}
KDEpasswd2Dialog *dlg = new KDEpasswd2Dialog(oldpass, user.toLocal8Bit());
dlg->exec();
if (dlg->result() == KDEpasswd2Dialog::Rejected)
if (dlg->result() == KDEpasswd2Dialog::Rejected) {
return 1;
}
return 0;
}

View file

@ -46,20 +46,16 @@ PasswdProcess::PasswdProcess(const QString &user)
{
uid_t userid = -1;
if (user.isEmpty())
{
if (user.isEmpty()) {
const KUser kuser(::getuid());
if (!kuser.isValid())
{
if (!kuser.isValid()) {
kDebug(1512) << "You don't exist!\n";
return;
}
m_User = kuser.loginName();
} else
{
} else {
const KUser kuser(user);
if (!kuser.isValid())
{
if (!kuser.isValid()) {
kDebug(1512) << "User " << user << "does not exist.\n";
return;
}
@ -73,18 +69,16 @@ PasswdProcess::~PasswdProcess()
{
}
int PasswdProcess::checkCurrent(const char *oldpass)
{
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;
}
// if (check)
// setTerminal(true);
@ -93,21 +87,23 @@ int PasswdProcess::exec(const char *oldpass, const char *newpass,
::setenv("LANG","C", true /* override */);
QList<QByteArray> args;
if(bOtherUser)
if (bOtherUser) {
args += m_User.toLocal8Bit();
}
int ret = PtyProcess::exec("passwd", args);
if (ret < 0)
{
if (ret < 0) {
kDebug(1512) << "Passwd not found!\n";
return PasswdNotFound;
}
ret = ConversePasswd(oldpass, newpass, check);
if (ret < 0)
if (ret < 0) {
kDebug(1512) << "Conversation with passwd failed. pid = " << pid();
}
if ((waitForChild() != 0) && !check)
if ((waitForChild() != 0) && !check) {
return PasswordNotGood;
}
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.
*/
int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
int check)
int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass, int check)
{
QByteArray line, errline;
int state = 0;
while (state != 7)
{
while (state != 7) {
line = readLine();
if (line.isNull())
{
if (line.isNull()) {
return -1;
}
if (state == 0 && isPrompt(line, "new"))
if (state == 0 && isPrompt(line, "new")) {
// If root is changing a user's password,
// passwd can't prompt for the original password.
// Therefore, we have to start at state=2.
state=2;
state = 2;
}
switch (state)
{
case 0:
switch (state) {
case 0: {
// Eat garbage, wait for prompt
m_Error += line+'\n';
if (isPrompt(line, "password"))
{
if (isPrompt(line, "password")) {
WaitSlave();
write(fd(), oldpass, strlen(oldpass));
write(fd(), "\n", 1);
state++;
break;
}
if (m_bTerminal)
if (m_bTerminal) {
fputs(line, stdout);
}
break;
}
case 1: case 3: case 6:
case 1:
case 3:
case 6: {
// Wait for \n
if (line.isEmpty())
{
if (line.isEmpty()) {
state++;
break;
}
// error
return -1;
}
case 2:
case 2: {
m_Error = "";
if( line.contains("again"))
{
if( line.contains("again")) {
m_Error = line;
kill(m_Pid, SIGKILL);
waitForChild();
@ -177,22 +172,20 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
}
// Wait for second prompt.
errline = line; // use first line for error message
while (!isPrompt(line, "new"))
{
while (!isPrompt(line, "new")) {
line = readLine();
if (line.isNull())
{
if (line.isNull()) {
// We didn't get the new prompt so assume incorrect password.
if (m_bTerminal)
if (m_bTerminal) {
fputs(errline, stdout);
}
m_Error = errline;
return PasswordIncorrect;
}
}
// we have the new prompt
if (check)
{
if (check) {
kill(m_Pid, SIGKILL);
waitForChild();
return 0;
@ -202,11 +195,11 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
write(fd(), "\n", 1);
state++;
break;
}
case 4:
case 4: {
// Wait for third prompt
if (isPrompt(line, "re"))
{
if (isPrompt(line, "re")) {
WaitSlave();
write(fd(), newpass, strlen(newpass));
write(fd(), "\n", 1);
@ -214,48 +207,46 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
break;
}
// Warning or error about the new password
if (m_bTerminal)
if (m_bTerminal) {
fputs(line, stdout);
}
m_Error = line + '\n';
state++;
break;
}
case 5:
case 5: {
// Wait for either a "Reenter password" or a "Enter password" prompt
if (isPrompt(line, "re"))
{
if (isPrompt(line, "re")) {
WaitSlave();
write(fd(), newpass, strlen(newpass));
write(fd(), "\n", 1);
state++;
break;
}
else if (isPrompt(line, "password"))
{
} else if (isPrompt(line, "password")) {
kill(m_Pid, SIGKILL);
waitForChild();
return PasswordNotGood;
}
if (m_bTerminal)
if (m_bTerminal) {
fputs(line, stdout);
}
m_Error += line + '\n';
break;
}
}
}
// Are we ok or do we still get an error thrown at us?
m_Error = "";
state = 0;
while (state != 1)
{
while (state != 1) {
line = readLine();
if (line.isNull())
{
if (line.isNull()) {
// No more input... OK
return 0;
}
if (isPrompt(line, "password"))
{
if (isPrompt(line, "password")) {
// Uh oh, another prompt. Not good!
kill(m_Pid, SIGKILL);
waitForChild();
@ -268,25 +259,25 @@ int PasswdProcess::ConversePasswd(const char *oldpass, const char *newpass,
return 0;
}
bool PasswdProcess::isPrompt(const QByteArray &line, const char *word)
{
unsigned i, j, colon;
unsigned int lineLength(line.length());
for (i=0,j=0,colon=0; i<lineLength; ++i)
{
if (line[i] == ':')
{
for (i = 0,j = 0, colon = 0; i < lineLength; ++i) {
if (line[i] == ':') {
j = i; ++colon;
continue;
}
if (!isspace(line[i]))
if (!isspace(line[i])) {
++j;
}
}
if ((colon != 1) || (line[j] != ':'))
if ((colon != 1) || (line[j] != ':')) {
return false;
if (word == 0L)
}
if (word == 0L) {
return true;
}
return line.toLower().contains(word);
}

View file

@ -33,29 +33,30 @@
* A C++ API to passwd.
*/
class PasswdProcess
: public PtyProcess
class PasswdProcess : public PtyProcess
{
public:
PasswdProcess(const QString &user = QString());
~PasswdProcess();
enum Errors { PasswdNotFound=1, PasswordIncorrect, PasswordNotGood };
enum Errors {
PasswdNotFound = 1,
PasswordIncorrect,
PasswordNotGood
};
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; }
private:
bool isPrompt(const QByteArray &line, const char *word=0L);
int ConversePasswd(const char *oldpass, const char *newpass,
int check);
bool isPrompt(const QByteArray &line, const char *word = 0L);
int ConversePasswd(const char *oldpass, const char *newpass, int check);
QString m_User;
QByteArray m_Error;
bool bOtherUser;
};
#endif // PASSWD_H

View file

@ -45,47 +45,51 @@ void KDEpasswd1Dialog::accept()
PasswdProcess proc;
int ret = proc.checkCurrent(password().toLocal8Bit());
switch (ret)
{
case -1:
{
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty())
msg = "<p>\"<i>" + msg + "</i>\"";
msg = "<qt>" + i18n("Conversation with 'passwd' failed.") + msg;
KMessageBox::error(this, msg);
done(Rejected);
return;
}
switch (ret) {
case -1: {
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty())
msg = "<p>\"<i>" + msg + "</i>\"";
msg = "<qt>" + i18n("Conversation with 'passwd' failed.") + msg;
KMessageBox::error(this, msg);
done(Rejected);
return;
}
case 0:
case 0: {
return KPasswordDialog::accept();
}
case PasswdProcess::PasswdNotFound:
case PasswdProcess::PasswdNotFound: {
KMessageBox::error(this, i18n("Could not find the program 'passwd'."));
done(Rejected);
return;
}
case PasswdProcess::PasswordIncorrect:
case PasswdProcess::PasswordIncorrect: {
KMessageBox::sorry(this, i18n("Incorrect password. Please try again."));
return;
}
default:
KMessageBox::error(this, i18n("Internal error: illegal return value "
"from PasswdProcess::checkCurrent."));
default: {
KMessageBox::error(
this, i18n("Internal error: illegal return value "
"from PasswdProcess::checkCurrent.")
);
done(Rejected);
return;
}
}
}
// static
int KDEpasswd1Dialog::getPassword(QByteArray &password)
{
KDEpasswd1Dialog *dlg = new KDEpasswd1Dialog();
int res = dlg->exec();
if (res == Accepted)
if (res == Accepted) {
password = dlg->password().toLocal8Bit();
}
delete dlg;
return res;
}
@ -99,10 +103,11 @@ KDEpasswd2Dialog::KDEpasswd2Dialog(const char *oldpass, const QString &user)
m_User = user;
setCaption(i18nc("@title:window", "Change Password"));
if (m_User.isEmpty())
if (m_User.isEmpty()) {
setPrompt(i18n("Please enter your new password:"));
else
} else {
setPrompt(i18n("Please enter the new password for user <b>%1</b>:", m_User));
}
}
@ -110,80 +115,84 @@ KDEpasswd2Dialog::~KDEpasswd2Dialog()
{
}
void KDEpasswd2Dialog::accept()
void KDEpasswd2Dialog::accept()
{
PasswdProcess proc(m_User);
QString p;
if(!checkAndGetPassword(&p)){
if (!checkAndGetPassword(&p)){
return;
}
if (p.length() > 8)
{
switch(KMessageBox::warningYesNoCancel(this,
m_User.isEmpty() ?
i18n("Your password is longer than 8 characters. On some "
"systems, this can cause problems. You can truncate "
"the password to 8 characters, or leave it as it is.") :
i18n("The password is longer than 8 characters. On some "
"systems, this can cause problems. You can truncate "
"the password to 8 characters, or leave it as it is.")
,
i18n("Password Too Long"),
KGuiItem(i18n("Truncate")),
KGuiItem(i18n("Use as Is")),
KStandardGuiItem::cancel(),
"truncatePassword"))
{
case KMessageBox::Yes :
p=p.left(8);
if (p.length() > 8) {
const int yesno = KMessageBox::warningYesNoCancel(
this,
m_User.isEmpty() ?
i18n("Your password is longer than 8 characters. On some "
"systems, this can cause problems. You can truncate "
"the password to 8 characters, or leave it as it is.") :
i18n("The password is longer than 8 characters. On some "
"systems, this can cause problems. You can truncate "
"the password to 8 characters, or leave it as it is.")
,
i18n("Password Too Long"),
KGuiItem(i18n("Truncate")),
KGuiItem(i18n("Use as Is")),
KStandardGuiItem::cancel(),
"truncatePassword"
);
switch(yesno) {
case KMessageBox::Yes: {
p = p.left(8);
break;
case KMessageBox::No :
}
case KMessageBox::No: {
break;
default : return;
}
default: {
return;
}
}
}
int ret = proc.exec(m_Pass, p.toLocal8Bit());
switch (ret)
{
case 0:
{
hide();
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty())
msg = "<p>\"<i>" + msg + "</i>\"";
msg = "<qt>" + i18n("Your password has been changed.") + msg;
KMessageBox::information(0L, msg);
return KNewPasswordDialog::accept();
}
case PasswdProcess::PasswordNotGood:
{
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty())
msg = "<p>\"<i>" + msg + "</i>\"";
msg = "<qt>" + i18n("Your password has not been changed.") + msg;
// The pw change did not succeed. Print the error.
KMessageBox::sorry(this, msg);
return;
}
default:
switch (ret) {
case 0: {
hide();
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty())
if (!msg.isEmpty()) {
msg = "<p>\"<i>" + msg + "</i>\"";
}
msg = "<qt>" + i18n("Your password has been changed.") + msg;
KMessageBox::information(0L, msg);
return KNewPasswordDialog::accept();
}
case PasswdProcess::PasswordNotGood: {
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty()) {
msg = "<p>\"<i>" + msg + "</i>\"";
}
msg = "<qt>" + i18n("Your password has not been changed.") + msg;
// The pw change did not succeed. Print the error.
KMessageBox::sorry(this, msg);
return;
}
default: {
QString msg = QString::fromLocal8Bit(proc.error());
if (!msg.isEmpty()) {
msg = "<p>\"<i>" + msg + "</i>\"";
}
msg = "<qt>" + i18n("Conversation with 'passwd' failed.") + msg;
KMessageBox::sorry(this, msg);
done(Rejected);
return;
}
}
return KNewPasswordDialog::accept();
}

View file

@ -29,8 +29,7 @@
#include <knewpassworddialog.h>
#include <QString>
class KDEpasswd1Dialog
: public KPasswordDialog
class KDEpasswd1Dialog : public KPasswordDialog
{
Q_OBJECT

View file

@ -49,14 +49,14 @@
*/
int PtyProcess::waitMS(int fd,int ms)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000*ms;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000*ms;
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd,&fds);
return select(fd+1, &fds, 0L, 0L, &tv);
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd,&fds);
return select(fd+1, &fds, 0L, 0L, &tv);
}
// XXX this function is nonsense:
@ -74,9 +74,8 @@ bool PtyProcess::checkPid(pid_t pid)
//sudo does not accept signals from user so we except it
if (superUserCommand == "sudo") {
return true;
} else {
return kill(pid, 0) == 0;
}
return kill(pid, 0) == 0;
}
/*
@ -89,33 +88,37 @@ bool PtyProcess::checkPid(pid_t pid)
int PtyProcess::checkPidExited(pid_t pid)
{
int state, ret;
ret = waitpid(pid, &state, WNOHANG);
int state, ret;
ret = waitpid(pid, &state, WNOHANG);
if (ret < 0)
{
kError(1512) << "waitpid():" << ::strerror(errno);
return Error;
}
if (ret == pid)
{
if (WIFEXITED(state))
return WEXITSTATUS(state);
return Killed;
}
if (ret < 0) {
kError(1512) << "waitpid():" << ::strerror(errno);
return Error;
}
if (ret == pid) {
if (WIFEXITED(state)) {
return WEXITSTATUS(state);
}
return Killed;
}
return NotExited;
return NotExited;
}
class PtyProcess::PtyProcessPrivate
{
public:
PtyProcessPrivate() : m_pPTY(0L) {}
PtyProcessPrivate()
: m_pPTY(0L)
{
}
~PtyProcessPrivate()
{
delete m_pPTY;
}
QList<QByteArray> env;
KPty *m_pPTY;
QByteArray m_Inbuf;
@ -123,7 +126,7 @@ public:
PtyProcess::PtyProcess()
:d(new PtyProcessPrivate)
: d(new PtyProcessPrivate())
{
m_bTerminal = false;
m_bErase = false;
@ -134,8 +137,7 @@ int PtyProcess::init()
{
delete d->m_pPTY;
d->m_pPTY = new KPty();
if (!d->m_pPTY->open())
{
if (!d->m_pPTY->open()) {
kError(1512) << "Failed to open PTY.";
return -1;
}
@ -150,14 +152,17 @@ PtyProcess::~PtyProcess()
}
/** Set additional environment variables. */
void PtyProcess::setEnvironment( const QList<QByteArray> &env )
void PtyProcess::setEnvironment(const QList<QByteArray> &env)
{
d->env = env;
}
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
@ -175,8 +180,7 @@ QList<QByteArray> PtyProcess::environment() const
QByteArray PtyProcess::readAll(bool block)
{
QByteArray ret;
if (!d->m_Inbuf.isEmpty())
{
if (!d->m_Inbuf.isEmpty()) {
// 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.
block = false;
@ -185,36 +189,37 @@ QByteArray PtyProcess::readAll(bool block)
}
int flags = fcntl(fd(), F_GETFL);
if (flags < 0)
{
if (flags < 0) {
kError(1512) << "fcntl(F_GETFL):" << ::strerror(errno);
return ret;
}
int oflags = flags;
if (block)
if (block) {
flags &= ~O_NONBLOCK;
else
} else {
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
// the file descriptor already.
return ret;
}
while (1)
{
while (1) {
ret.reserve(ret.size() + 0x8000);
int nbytes = read(fd(), ret.data() + ret.size(), 0x8000);
if (nbytes == -1)
{
if (errno == EINTR)
if (nbytes == -1) {
if (errno == EINTR) {
continue;
else break;
} else {
break;
}
}
if (nbytes == 0) {
// nothing available / eof
break;
}
if (nbytes == 0)
break; // nothing available / eof
ret.resize(ret.size() + nbytes);
break;
@ -229,16 +234,13 @@ QByteArray PtyProcess::readLine(bool block)
d->m_Inbuf = readAll(block);
QByteArray ret;
if (!d->m_Inbuf.isEmpty())
{
if (!d->m_Inbuf.isEmpty()) {
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!
ret = d->m_Inbuf;
d->m_Inbuf.resize(0);
} else
{
} else {
ret = d->m_Inbuf.left(pos);
d->m_Inbuf.remove(0, pos+1);
}
@ -247,23 +249,26 @@ QByteArray PtyProcess::readLine(bool block)
return ret;
}
void PtyProcess::writeLine(const QByteArray &line, bool addnl)
{
if (!line.isEmpty())
if (!line.isEmpty()) {
write(fd(), line, line.length());
if (addnl)
}
if (addnl) {
write(fd(), "\n", 1);
}
}
void PtyProcess::unreadLine(const QByteArray &line, bool addnl)
{
QByteArray tmp = line;
if (addnl)
if (addnl) {
tmp += '\n';
if (!tmp.isEmpty())
}
if (!tmp.isEmpty()) {
d->m_Inbuf.prepend(tmp);
}
}
void PtyProcess::setExitString(const QByteArray &exit)
@ -282,25 +287,23 @@ int PtyProcess::exec(const QByteArray &command, const QList<QByteArray> &args)
if (init() < 0)
return -1;
if ((m_Pid = fork()) == -1)
{
if ((m_Pid = fork()) == -1) {
kError(1512) << "fork():" << ::strerror(errno);
return -1;
}
// Parent
if (m_Pid)
{
if (m_Pid) {
d->m_pPTY->closeSlave();
return 0;
}
// Child
if (setupTTY() < 0)
if (setupTTY() < 0) {
_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()));
}
unsetenv("KDE_FULL_SESSION");
@ -311,11 +314,12 @@ int PtyProcess::exec(const QByteArray &command, const QList<QByteArray> &args)
unsetenv("DBUS_SESSION_BUS_ADDRESS");
// set temporarily LC_ALL to C, for su (to be able to parse "Password:")
const QByteArray old_lc_all = qgetenv( "LC_ALL" );
if( !old_lc_all.isEmpty() )
qputenv( "KDESU_LC_ALL", old_lc_all );
else
unsetenv( "KDESU_LC_ALL" );
const QByteArray old_lc_all = qgetenv("LC_ALL");
if (!old_lc_all.isEmpty()) {
qputenv("KDESU_LC_ALL", old_lc_all);
} else {
unsetenv("KDESU_LC_ALL");
}
qputenv("LC_ALL", "C");
// From now on, terminal output goes through the tty.
@ -365,20 +369,16 @@ int PtyProcess::WaitSlave()
kDebug(1512) << "Child pid" << m_Pid;
struct termios tio;
while (1)
{
if (!checkPid(m_Pid))
{
while (1) {
if (!checkPid(m_Pid)) {
kError(1512) << "process has exited while waiting for password.";
return -1;
}
if (!d->m_pPTY->tcGetAttr(&tio))
{
if (!d->m_pPTY->tcGetAttr(&tio)) {
kError(1512) << "tcgetattr():" << ::strerror(errno);
return -1;
}
if (tio.c_lflag & ECHO)
{
if (tio.c_lflag & ECHO) {
kDebug(1512) << "Echo mode still on.";
usleep(10000);
continue;
@ -419,8 +419,7 @@ int PtyProcess::waitForChild()
FD_ZERO(&fds);
QByteArray remainder;
while (1)
{
while (1) {
FD_SET(fd(), &fds);
// 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_usec = 100000;
int ret = select(fd()+1, &fds, 0L, 0L, &timeout);
if (ret == -1)
{
if (errno != EINTR)
{
if (ret == -1) {
if (errno != EINTR) {
kError(1512) << "select():" << ::strerror(errno);
return -1;
}
ret = 0;
}
if (ret)
{
if (ret) {
forever {
QByteArray output = readAll(false);
if (output.isEmpty())
if (output.isEmpty()) {
break;
if (m_bTerminal)
{
}
if (m_bTerminal) {
fwrite(output.constData(), output.size(), 1, stdout);
fflush(stdout);
}
if (!m_Exit.isEmpty())
{
if (!m_Exit.isEmpty()) {
// match exit string only at line starts
remainder += output;
while (remainder.length() >= m_Exit.length()) {
@ -462,8 +457,9 @@ int PtyProcess::waitForChild()
remainder.remove(0, m_Exit.length());
}
int off = remainder.indexOf('\n');
if (off < 0)
if (off < 0) {
break;
}
remainder.remove(0, off + 1);
}
}
@ -471,21 +467,16 @@ int PtyProcess::waitForChild()
}
ret = checkPidExited(m_Pid);
if (ret == Error)
{
if (errno == ECHILD) return 0;
else return 1;
}
else if (ret == Killed)
{
if (ret == Error) {
if (errno == ECHILD) {
return 0;
}
return 1;
} else if (ret == Killed) {
return 0;
}
else if (ret == NotExited)
{
} else if (ret == NotExited) {
// keep checking
}
else
{
} else {
return ret;
}
}
@ -501,35 +492,37 @@ int PtyProcess::waitForChild()
int PtyProcess::setupTTY()
{
// Reset signal handlers
for (int sig = 1; sig < NSIG; sig++)
for (int sig = 1; sig < NSIG; sig++) {
KDE_signal(sig, SIG_DFL);
}
KDE_signal(SIGHUP, SIG_IGN);
d->m_pPTY->setCTty();
// Connect stdin, stdout and stderr
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
// XXX this caused problems in KProcess - not sure why anymore. -- ???
// Because it will close the start notification pipe. -- ossi
struct rlimit 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);
}
// Disable OPOST processing. Otherwise, '\n' are (on Linux at least)
// translated to '\r\n'.
struct ::termios tio;
if (tcgetattr(0, &tio) < 0)
{
if (tcgetattr(0, &tio) < 0) {
kError(1512) << "tcgetattr():" << ::strerror(errno);
return -1;
}
tio.c_oflag &= ~OPOST;
if (tcsetattr(0, TCSANOW, &tio) < 0)
{
if (tcsetattr(0, TCSANOW, &tio) < 0) {
kError(1512) << "tcsetattr():" << ::strerror(errno);
return -1;
}

View file

@ -54,7 +54,7 @@ public:
* @param block Block until a full line is read?
* @return The output string.
*/
QByteArray readLine(bool block=true);
QByteArray readLine(bool block = true);
/**
* Read all available output from the program's standard out.
@ -69,14 +69,14 @@ public:
* @param line The text to write.
* @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.
* @param line The line to put back.
* @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,
@ -99,7 +99,7 @@ public:
/**
* 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.
@ -115,7 +115,7 @@ public:
/**
* Set additinal environment variables.
*/
void setEnvironment( const QList<QByteArray> &env );
void setEnvironment(const QList<QByteArray> &env);
/**
* 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
** 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() */
enum checkPidStatus { Error=-1, /**< No child */
NotExited=-2, /**< Child hasn't exited */
Killed=-3 /**< Child terminated by signal */
enum checkPidStatus {
Error = -1, /**< No child */
NotExited = -2, /**< Child hasn't exited */
Killed = -3 /**< Child terminated by signal */
} ;
/**
@ -174,14 +175,13 @@ public /* static */:
protected:
QList<QByteArray> environment() const;
bool m_bErase, /**< @see setErase() */
m_bTerminal; /**< Indicates running in a terminal, causes additional
newlines to be printed after output. Set to @c false
in constructor. @see setTerminal() */
int m_Pid; /**< PID of child process */
QByteArray m_Command, /**< Unused */
m_Exit; /**< String to scan for in output that indicates
child has exited. */
bool m_bErase, /**< @see setErase() */
m_bTerminal; /**< Indicates running in a terminal, causes additional
newlines to be printed after output. Set to @c false
in constructor. @see setTerminal() */
int m_Pid; /**< PID of child process */
QByteArray m_Command; /**< Unused */
QByteArray m_Exit; /**< String to scan for in output that indicates child has exited. */
private:
int init();