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,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

View file

@ -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;
} }

View file

@ -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);
} }

View file

@ -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

View file

@ -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();
} }

View file

@ -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

View file

@ -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;
} }

View file

@ -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();