2004-11-03 20:29:08 +00:00
/* gnome-about-me.c
* Copyright ( C ) 2002 Diego Gonzalez
*
* Written by : Diego Gonzalez < diego @ pemas . net >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA
* 02111 - 1307 , USA .
*
* Parts of this code come from Gnome - System - Tools .
*/
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
2005-11-25 20:18:23 +00:00
# include <stropts.h>
2004-11-03 20:29:08 +00:00
# include <gnome.h>
# include <pwd.h>
2005-06-15 00:25:55 +00:00
# include <stdlib.h>
2004-11-03 20:29:08 +00:00
# include <glade/glade.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/wait.h>
2005-06-15 00:25:55 +00:00
# include <sys/poll.h>
2004-11-03 20:29:08 +00:00
# include <termios.h>
2005-11-25 20:18:23 +00:00
# if HAVE_PTY_H
2004-11-03 20:29:08 +00:00
# include <pty.h>
2005-11-25 20:18:23 +00:00
# endif
# if HAVE_STROPTS_H
# include <stropts.h>
# endif
# if __sun
# include <sys/types.h>
# include <signal.h>
# endif
2004-11-03 20:29:08 +00:00
# include "capplet-util.h"
2005-06-15 00:25:55 +00:00
# include "eel-alert-dialog.h"
2004-11-03 20:29:08 +00:00
2005-11-25 20:18:23 +00:00
# ifndef HAVE_FORKPTY
pid_t forkpty ( int * , char * , struct termios * , struct winsize * ) ;
# endif
2004-11-03 20:29:08 +00:00
typedef struct {
2005-06-15 00:25:55 +00:00
GladeXML * xml ;
2004-11-03 20:29:08 +00:00
GtkWidget * old_password ;
GtkWidget * new_password ;
GtkWidget * retyped_password ;
2005-06-15 00:25:55 +00:00
guint timeout_id ;
guint check_password_timeout_id ;
gboolean good_password ;
2004-11-03 20:29:08 +00:00
/* Communication with the passwd program */
int backend_pid ;
2005-06-15 00:25:55 +00:00
int write_fd ;
int read_fd ;
FILE * write_stream ;
FILE * read_stream ;
2004-11-03 20:29:08 +00:00
} PasswordDialog ;
enum
{
RESPONSE_APPLY = 1 ,
RESPONSE_CLOSE
} ;
static void passdlg_set_busy ( PasswordDialog * dlg , gboolean busy ) ;
# define REDRAW_NCHARS 1
static gboolean
wait_child ( PasswordDialog * pdialog )
{
gint status , pid ;
2005-06-15 00:25:55 +00:00
gchar * msg , * details , * title ;
GladeXML * dialog ;
GtkWidget * wmessage , * wbulb ;
GtkWidget * wedialog ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
dialog = pdialog - > xml ;
wmessage = WID ( " message " ) ;
wbulb = WID ( " bulb " ) ;
2004-11-03 20:29:08 +00:00
pid = waitpid ( pdialog - > backend_pid , & status , WNOHANG ) ;
2005-06-15 00:25:55 +00:00
passdlg_set_busy ( pdialog , FALSE ) ;
2004-11-03 20:29:08 +00:00
if ( pid > 0 ) {
if ( WIFEXITED ( status ) & & ( WEXITSTATUS ( status ) = = 0 ) ) {
2005-08-06 15:49:13 +00:00
/* I need to quit here */
2004-11-03 20:29:08 +00:00
return FALSE ;
} else if ( ( WIFEXITED ( status ) ) & & ( WEXITSTATUS ( status ) ) & & ( WEXITSTATUS ( status ) < 255 ) ) {
2005-07-12 18:06:41 +00:00
msg = g_strdup_printf ( " <b>%s</b> " , _ ( " Old password is incorrect, please retype it " ) ) ;
2005-06-15 00:25:55 +00:00
gtk_label_set_markup ( GTK_LABEL ( wmessage ) , msg ) ;
g_free ( msg ) ;
gtk_image_set_from_file ( GTK_IMAGE ( wbulb ) ,
GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-off.png " ) ;
return FALSE ;
2004-11-03 20:29:08 +00:00
} else if ( ( WIFEXITED ( status ) ) & & ( WEXITSTATUS ( status ) ) & & ( WEXITSTATUS ( status ) = = 255 ) ) {
2005-07-12 18:06:41 +00:00
msg = g_strdup ( _ ( " System error has occurred " ) ) ;
2005-06-15 00:25:55 +00:00
details = g_strdup ( _ ( " Could not run /usr/bin/passwd " ) ) ;
title = g_strdup ( _ ( " Unable to launch backend " ) ) ;
2004-11-03 20:29:08 +00:00
} else {
2005-07-07 21:24:03 +00:00
msg = g_strdup ( _ ( " Unexpected error has occurred " ) ) ;
title = g_strdup ( _ ( " Unexpected error has occurred " ) ) ;
2005-06-15 00:25:55 +00:00
details = NULL ;
2004-11-03 20:29:08 +00:00
}
2005-06-15 00:25:55 +00:00
wedialog = eel_alert_dialog_new ( NULL , 0 , GTK_MESSAGE_ERROR , GTK_BUTTONS_OK ,
msg , NULL , title ) ;
if ( details ! = NULL )
eel_alert_dialog_set_details_label ( EEL_ALERT_DIALOG ( wedialog ) , details ) ;
g_signal_connect ( G_OBJECT ( wedialog ) , " response " ,
2004-11-03 20:29:08 +00:00
G_CALLBACK ( gtk_widget_destroy ) , NULL ) ;
2005-06-15 00:25:55 +00:00
gtk_window_set_resizable ( GTK_WINDOW ( wedialog ) , FALSE ) ;
gtk_widget_show ( wedialog ) ;
g_free ( msg ) ;
g_free ( title ) ;
g_free ( details ) ;
2004-11-03 20:29:08 +00:00
return FALSE ;
}
return TRUE ;
}
static gboolean
is_string_complete ( gchar * str , GSList * list )
{
GSList * elem ;
if ( strlen ( str ) = = 0 )
return FALSE ;
for ( elem = list ; elem ; elem = g_slist_next ( elem ) )
2005-06-15 00:25:55 +00:00
if ( g_strrstr ( str , elem - > data ) ! = NULL ) {
2004-11-03 20:29:08 +00:00
return TRUE ;
2005-06-15 00:25:55 +00:00
}
2004-11-03 20:29:08 +00:00
return FALSE ;
}
2005-06-15 00:25:55 +00:00
static gchar *
read_everything ( PasswordDialog * pdialog , gchar * needle , va_list ap )
2004-11-03 20:29:08 +00:00
{
2005-06-15 00:25:55 +00:00
GString * str = g_string_new ( " " ) ;
GSList * list = NULL ;
2005-08-15 18:09:33 +00:00
gchar * arg , * ptr ;
int c ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
list = g_slist_prepend ( list , needle ) ;
2004-11-03 20:29:08 +00:00
while ( ( arg = va_arg ( ap , char * ) ) ! = NULL )
list = g_slist_prepend ( list , arg ) ;
2005-06-15 00:25:55 +00:00
2004-11-03 20:29:08 +00:00
va_end ( ap ) ;
2005-06-15 00:25:55 +00:00
2004-11-03 20:29:08 +00:00
while ( ! is_string_complete ( str - > str , list ) ) {
2005-06-15 00:25:55 +00:00
c = fgetc ( pdialog - > read_stream ) ;
if ( c ! = EOF )
2004-11-03 20:29:08 +00:00
g_string_append_c ( str , c ) ;
}
2005-06-15 00:25:55 +00:00
ptr = str - > str ;
g_string_free ( str , FALSE ) ;
2004-11-03 20:29:08 +00:00
return ptr ;
}
2005-06-15 00:25:55 +00:00
static void
poll_backend ( PasswordDialog * pdialog )
{
struct pollfd fd ;
fd . fd = pdialog - > read_fd ;
fd . events = POLLIN | | POLLPRI ;
while ( poll ( & fd , 1 , 100 ) < = 0 ) {
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
}
}
static char *
read_from_backend_va ( PasswordDialog * pdialog , gchar * needle , va_list ap )
{
poll_backend ( pdialog ) ;
return read_everything ( pdialog , needle , ap ) ;
}
2004-11-03 20:29:08 +00:00
static gchar *
read_from_backend ( PasswordDialog * pdialog , gchar * needle , . . . )
{
va_list ap ;
va_start ( ap , needle ) ;
return read_from_backend_va ( pdialog , needle , ap ) ;
}
static void
write_to_backend ( PasswordDialog * pdialog , char * str )
{
gint nread = 0 ;
int ret ;
do {
2005-06-15 00:25:55 +00:00
ret = fputc ( str [ nread ] , pdialog - > write_stream ) ;
usleep ( 1000 ) ;
2004-11-03 20:29:08 +00:00
if ( ret ! = EOF )
nread + + ;
/* ugly hack for redrawing UI */
if ( nread % REDRAW_NCHARS = = 0 )
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
} while ( nread < strlen ( str ) ) ;
2005-06-15 00:25:55 +00:00
while ( fflush ( pdialog - > write_stream ) ! = 0 ) ;
2004-11-03 20:29:08 +00:00
}
static void
passdlg_set_busy ( PasswordDialog * pdialog , gboolean busy )
{
2005-06-15 00:25:55 +00:00
GladeXML * dialog ;
GtkWidget * toplevel ;
2004-11-03 20:29:08 +00:00
GdkCursor * cursor = NULL ;
GdkDisplay * display ;
2005-06-15 00:25:55 +00:00
dialog = pdialog - > xml ;
toplevel = WID ( " change-password " ) ;
display = gtk_widget_get_display ( toplevel ) ;
2004-11-03 20:29:08 +00:00
if ( busy )
cursor = gdk_cursor_new_for_display ( display , GDK_WATCH ) ;
2005-06-15 00:25:55 +00:00
gdk_window_set_cursor ( toplevel - > window , cursor ) ;
2004-11-03 20:29:08 +00:00
gdk_display_flush ( display ) ;
if ( busy )
gdk_cursor_unref ( cursor ) ;
}
2005-06-15 00:25:55 +00:00
static gint
2005-08-06 16:29:26 +00:00
update_password ( PasswordDialog * pdialog , gchar * * msg )
2004-11-03 20:29:08 +00:00
{
2005-06-15 00:25:55 +00:00
GtkWidget * wopasswd , * wnpasswd , * wrnpasswd ;
2004-11-03 20:29:08 +00:00
char * new_password ;
char * retyped_password ;
char * old_password ;
gchar * s ;
2005-06-15 00:25:55 +00:00
GladeXML * dialog ;
2005-08-06 16:29:26 +00:00
gint retcode ;
2005-06-15 00:25:55 +00:00
dialog = pdialog - > xml ;
wopasswd = WID ( " old-password " ) ;
wnpasswd = WID ( " new-password " ) ;
wrnpasswd = WID ( " retyped-password " ) ;
2005-08-06 16:29:26 +00:00
retcode = 0 ;
2005-06-15 00:25:55 +00:00
/* */
old_password = g_strdup_printf ( " %s \n " , gtk_entry_get_text ( GTK_ENTRY ( wopasswd ) ) ) ;
new_password = g_strdup_printf ( " %s \n " , gtk_entry_get_text ( GTK_ENTRY ( wnpasswd ) ) ) ;
retyped_password = g_strdup_printf ( " %s \n " , gtk_entry_get_text ( GTK_ENTRY ( wrnpasswd ) ) ) ;
/* Set the busy cursor as this can be a long process */
passdlg_set_busy ( pdialog , TRUE ) ;
s = read_from_backend ( pdialog , " assword: " , NULL ) ;
g_free ( s ) ;
write_to_backend ( pdialog , old_password ) ;
/* New password */
2005-11-25 20:18:23 +00:00
s = read_from_backend ( pdialog , " assword: " , " failure " , " wrong " , NULL ) ;
if ( g_strrstr ( s , " failure " ) ! = NULL | |
g_strrstr ( s , " wrong " ) ! = NULL ) {
2005-06-15 00:25:55 +00:00
g_free ( s ) ;
return - 1 ;
}
g_free ( s ) ;
write_to_backend ( pdialog , new_password ) ;
/* Retype password */
s = read_from_backend ( pdialog , " assword: " , NULL ) ;
g_free ( s ) ;
write_to_backend ( pdialog , retyped_password ) ;
2005-11-25 20:18:23 +00:00
s = read_from_backend ( pdialog , " successfully " , " short " , " panlindrome " , " simple " , " similar " , " wrapped " , " recovered " , " unchanged " , " match " , " 1 numeric or special " , NULL ) ;
2005-06-15 00:25:55 +00:00
if ( g_strrstr ( s , " recovered " ) ! = NULL ) {
2005-08-06 16:29:26 +00:00
retcode = - 2 ;
} else if ( g_strrstr ( s , " short " ) ! = NULL ) {
* msg = g_strdup ( _ ( " Password is too short " ) ) ;
retcode = - 3 ;
} else if ( g_strrstr ( s , " panlindrome " ) ! = NULL ) {
* msg = g_strdup ( _ ( " Password is too simple " ) ) ;
retcode = - 3 ;
} else if ( g_strrstr ( s , " simple " ) ! = NULL ) {
2005-08-14 21:13:54 +00:00
* msg = g_strdup ( _ ( " Password is too simple " ) ) ;
2005-08-06 16:29:26 +00:00
retcode = - 3 ;
2005-08-15 18:09:33 +00:00
} else if ( ( g_strrstr ( s , " similar " ) ! = NULL ) | | ( g_strrstr ( s , " wrapped " ) ! = NULL ) ) {
2005-08-06 16:29:26 +00:00
* msg = g_strdup ( _ ( " Old and new passwords are too similar " ) ) ;
retcode = - 3 ;
2005-11-25 20:18:23 +00:00
} else if ( g_strrstr ( s , " 1 numeric or special " ) ! = NULL ) {
* msg = g_strdup ( _ ( " Must contain numeric or special character(s) " ) ) ;
retcode = - 3 ;
} else if ( ( g_strrstr ( s , " unchanged " ) ! = NULL ) | |
( g_strrstr ( s , " match " ) ! = NULL ) ) {
2005-08-08 01:28:40 +00:00
kill ( pdialog - > backend_pid , SIGKILL ) ;
* msg = g_strdup ( _ ( " Old and new password are the same " ) ) ;
retcode = - 3 ;
2005-11-25 20:18:23 +00:00
}
2005-06-15 00:25:55 +00:00
2005-08-06 16:29:26 +00:00
g_free ( s ) ;
return retcode ;
2005-06-15 00:25:55 +00:00
}
2005-11-25 20:18:23 +00:00
# ifndef HAVE_FORKPTY
/*
// Emulation of the BSD function forkpty.
// Copied from rootsh (http://sourceforge.net/projects/rootsh) also
// under GPL license. Slightly modified to not copy terminal modes
// or window size from the parent to the child if NULL is passed in
// for termp or winp. The logic still sets the termp or winp values
// if passed in. When launching from the gnome-panel, there are no
// such values for the parent and attempting to copy them was causing
// a lengthy delay.
*/
# ifndef MASTERPTYDEV
# error you need to specify a master pty device
# endif
pid_t forkpty ( int * amaster , char * name , struct termios * termp , struct winsize * winp ) {
/*
// amaster A pointer to the master pty's file descriptor which
// will be set here.
//
// name If name is NULL, the name of the slave pty will be
// returned in name.
//
// termp If termp is not NULL, the terminal parameters
// of the slave will be set to the values in termp.
//
// winsize If winp is not NULL, the window size of the slave
// will be set to the values in winp.
//
// pid The process id of the forked child process.
//
// master The file descriptor of the master pty.
//
// slave The file descriptor of the slave pty.
//
// slavename The file name of the slave pty.
//
*/
pid_t pid ;
int master , slave ;
char * slavename ;
/*
// Get a master pseudo-tty.
*/
if ( ( master = open ( MASTERPTYDEV , O_RDWR ) ) < 0 ) {
perror ( MASTERPTYDEV ) ;
return ( - 1 ) ;
}
/*
// Set the permissions on the slave pty.
*/
if ( grantpt ( master ) < 0 ) {
perror ( " grantpt " ) ;
close ( master ) ;
return ( - 1 ) ;
}
/*
// Unlock the slave pty.
*/
if ( unlockpt ( master ) < 0 ) {
perror ( " unlockpt " ) ;
close ( master ) ;
return ( - 1 ) ;
}
/*
// Start a child process.
*/
if ( ( pid = fork ( ) ) < 0 ) {
perror ( " fork in forkpty " ) ;
close ( master ) ;
return ( - 1 ) ;
}
/*
// The child process will open the slave, which will become
// its controlling terminal.
*/
if ( pid = = 0 ) {
/*
// Get rid of our current controlling terminal.
*/
setsid ( ) ;
/*
// Get the name of the slave pseudo tty.
*/
if ( ( slavename = ptsname ( master ) ) = = NULL ) {
perror ( " ptsname " ) ;
close ( master ) ;
return ( - 1 ) ;
}
/*
// Open the slave pseudo tty.
*/
if ( ( slave = open ( slavename , O_RDWR ) ) < 0 ) {
perror ( slavename ) ;
close ( master ) ;
return ( - 1 ) ;
}
# ifndef AIX_COMPAT
/*
// Push the pseudo-terminal emulation module.
*/
if ( ioctl ( slave , I_PUSH , " ptem " ) < 0 ) {
perror ( " ioctl: ptem " ) ;
close ( master ) ;
close ( slave ) ;
return ( - 1 ) ;
}
/*
// Push the terminal line discipline module.
*/
if ( ioctl ( slave , I_PUSH , " ldterm " ) < 0 ) {
perror ( " ioctl: ldterm " ) ;
close ( master ) ;
close ( slave ) ;
return ( - 1 ) ;
}
# ifdef HAVE_TTCOMPAT
/*
// Push the compatibility for older ioctl calls module (solaris).
*/
if ( ioctl ( slave , I_PUSH , " ttcompat " ) < 0 ) {
perror ( " ioctl: ttcompat " ) ;
close ( master ) ;
close ( slave ) ;
return ( - 1 ) ;
}
# endif
# endif
/*
// Copy the caller's terminal modes to the slave pty.
*/
if ( termp ! = NULL ) {
if ( tcsetattr ( slave , TCSANOW , termp ) < 0 ) {
perror ( " tcsetattr: slave pty " ) ;
close ( master ) ;
close ( slave ) ;
return ( - 1 ) ;
}
}
/*
// Set the slave pty window size to the caller's size.
*/
if ( winp ! = NULL ) {
if ( ioctl ( slave , TIOCSWINSZ , winp ) < 0 ) {
perror ( " ioctl: slave winsz " ) ;
close ( master ) ;
close ( slave ) ;
return ( - 1 ) ;
}
}
/*
// Close the master pty.
// No need for this in the slave process.
*/
close ( master ) ;
/*
// Set the slave to be our standard input, output and error output.
// Then get rid of the original file descriptor.
*/
dup2 ( slave , 0 ) ;
dup2 ( slave , 1 ) ;
dup2 ( slave , 2 ) ;
close ( slave ) ;
/*
// If the caller wants it, give him back the slave pty's name.
*/
if ( name ! = NULL )
strcpy ( name , slavename ) ;
return ( 0 ) ;
} else {
/*
// Return the slave pty device name if caller wishes so.
*/
if ( name ! = NULL ) {
if ( ( slavename = ptsname ( master ) ) = = NULL ) {
perror ( " ptsname " ) ;
close ( master ) ;
return ( - 1 ) ;
}
strcpy ( name , slavename ) ;
}
/*
// Return the file descriptor for communicating with the process
// to the caller.
*/
* amaster = master ;
return ( pid ) ;
}
}
# endif
2005-08-06 15:49:13 +00:00
static gint
2005-06-15 00:25:55 +00:00
spawn_passwd ( PasswordDialog * pdialog )
{
char * args [ 2 ] ;
int p [ 2 ] ;
/* Prepare the execution environment of passwd */
args [ 0 ] = " /usr/bin/passwd " ;
args [ 1 ] = NULL ;
pipe ( p ) ;
pdialog - > backend_pid = forkpty ( & pdialog - > write_fd , NULL , NULL , NULL ) ;
if ( pdialog - > backend_pid < 0 ) {
g_warning ( " could not fork to backend " ) ;
2005-08-06 15:49:13 +00:00
return - 1 ;
2005-06-15 00:25:55 +00:00
} else if ( pdialog - > backend_pid = = 0 ) {
dup2 ( p [ 1 ] , 1 ) ;
dup2 ( p [ 1 ] , 2 ) ;
close ( p [ 0 ] ) ;
unsetenv ( " LC_ALL " ) ;
unsetenv ( " LC_MESSAGES " ) ;
unsetenv ( " LANG " ) ;
unsetenv ( " LANGUAGE " ) ;
execv ( args [ 0 ] , args ) ;
exit ( 255 ) ;
} else {
close ( p [ 1 ] ) ;
pdialog - > read_fd = p [ 0 ] ;
pdialog - > timeout_id = g_timeout_add ( 4000 , ( GSourceFunc ) wait_child , pdialog ) ;
pdialog - > read_stream = fdopen ( pdialog - > read_fd , " r " ) ; ;
pdialog - > write_stream = fdopen ( pdialog - > write_fd , " w " ) ;
setvbuf ( pdialog - > read_stream , NULL , _IONBF , 0 ) ;
fcntl ( pdialog - > read_fd , F_SETFL , 0 ) ;
}
2005-08-06 15:49:13 +00:00
return 1 ;
2005-06-15 00:25:55 +00:00
}
2005-08-06 15:49:13 +00:00
2005-06-15 00:25:55 +00:00
static gboolean
passdlg_check_password_timeout_cb ( PasswordDialog * pdialog )
{
const gchar * password ;
const gchar * retyped_password ;
2005-08-06 16:29:26 +00:00
char * msg ;
2005-06-15 00:25:55 +00:00
gboolean good_password ;
GtkWidget * wbulb , * wok , * wmessage ;
GtkWidget * wnpassword , * wrnpassword ;
GladeXML * dialog ;
dialog = pdialog - > xml ;
wnpassword = WID ( " new-password " ) ;
wrnpassword = WID ( " retyped-password " ) ;
wmessage = WID ( " message " ) ;
wbulb = WID ( " bulb " ) ;
wok = WID ( " ok " ) ;
password = gtk_entry_get_text ( GTK_ENTRY ( wnpassword ) ) ;
retyped_password = gtk_entry_get_text ( GTK_ENTRY ( wrnpassword ) ) ;
if ( strlen ( password ) = = 0 | | strlen ( retyped_password ) = = 0 ) {
gtk_image_set_from_file ( GTK_IMAGE ( wbulb ) ,
GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-off.png " ) ;
2005-07-16 21:37:15 +00:00
msg = g_strconcat ( " <b> " , _ ( " Please type the passwords. " ) , " </b> " , NULL ) ;
gtk_label_set_markup ( GTK_LABEL ( wmessage ) , msg ) ;
g_free ( msg ) ;
2005-06-15 00:25:55 +00:00
return FALSE ;
}
if ( strcmp ( password , retyped_password ) ! = 0 ) {
2005-07-16 21:37:15 +00:00
msg = g_strconcat ( " <b> " , _ ( " Please type the password again, it is wrong. " ) , " </b> " , NULL ) ;
2005-06-15 00:25:55 +00:00
good_password = FALSE ;
} else {
2005-08-06 17:32:04 +00:00
msg = g_strconcat ( " <b> " , _ ( " Click on Change Password to change the password. " ) , " </b> " , NULL ) ;
2005-06-23 11:27:21 +00:00
good_password = TRUE ;
2005-06-15 00:25:55 +00:00
}
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
if ( good_password & & pdialog - > good_password = = FALSE ) {
gtk_image_set_from_file ( GTK_IMAGE ( wbulb ) ,
GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-on.png " ) ;
gtk_widget_set_sensitive ( wok , TRUE ) ;
} else if ( good_password = = FALSE & & pdialog - > good_password = = TRUE ) {
gtk_image_set_from_file ( GTK_IMAGE ( wbulb ) ,
GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-off.png " ) ;
gtk_widget_set_sensitive ( wok , FALSE ) ;
}
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
pdialog - > good_password = good_password ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
gtk_label_set_markup ( GTK_LABEL ( wmessage ) , msg ) ;
g_free ( msg ) ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
return FALSE ;
}
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
static void
passdlg_check_password ( GtkEntry * entry , PasswordDialog * pdialog )
{
if ( pdialog - > check_password_timeout_id ) {
g_source_remove ( pdialog - > check_password_timeout_id ) ;
2004-11-03 20:29:08 +00:00
}
2005-06-15 00:25:55 +00:00
pdialog - > check_password_timeout_id =
2005-08-15 18:09:33 +00:00
g_timeout_add ( 500 , ( GSourceFunc ) passdlg_check_password_timeout_cb , pdialog ) ;
2005-06-15 00:25:55 +00:00
2004-11-03 20:29:08 +00:00
}
2005-08-06 15:49:13 +00:00
static gint
passdlg_process_response ( PasswordDialog * pdialog , gint response_id )
{
GladeXML * dialog ;
GtkWidget * wmessage , * wbulb ;
2005-08-06 16:29:26 +00:00
gchar * msg , * msgerr ;
2005-08-06 15:49:13 +00:00
gint ret ;
dialog = pdialog - > xml ;
wmessage = WID ( " message " ) ;
wbulb = WID ( " bulb " ) ;
2005-08-06 16:29:26 +00:00
msgerr = NULL ;
2005-08-06 15:49:13 +00:00
if ( response_id = = GTK_RESPONSE_OK ) {
ret = spawn_passwd ( pdialog ) ;
if ( ret < 0 )
return 1 ;
2005-08-06 16:29:26 +00:00
ret = update_password ( pdialog , & msgerr ) ;
2005-08-06 15:49:13 +00:00
passdlg_set_busy ( pdialog , FALSE ) ;
/* No longer need the wait_child fallback, remove the timeout */
g_source_remove ( pdialog - > timeout_id ) ;
if ( ret = = - 1 ) {
msg = g_strdup_printf ( " <b>%s</b> " , _ ( " Old password is incorrect, please retype it " ) ) ;
gtk_label_set_markup ( GTK_LABEL ( wmessage ) , msg ) ;
g_free ( msg ) ;
gtk_image_set_from_file ( GTK_IMAGE ( wbulb ) ,
GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-off.png " ) ;
2005-08-06 16:29:26 +00:00
return - 1 ;
} else if ( ret = = - 3 ) {
msg = g_strdup_printf ( " <b>%s</b> " , msgerr ) ;
gtk_label_set_markup ( GTK_LABEL ( wmessage ) , msg ) ;
g_free ( msg ) ;
gtk_image_set_from_file ( GTK_IMAGE ( wbulb ) ,
GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-off.png " ) ;
g_free ( msgerr ) ;
2005-08-06 15:49:13 +00:00
return - 1 ;
}
/* This is the standard way of returning from the dialog with passwd
* If we return this way we can safely kill passwd as it has completed
* its task . In case of problems we still have the wait_child fallback
*/
fclose ( pdialog - > write_stream ) ;
fclose ( pdialog - > read_stream ) ;
close ( pdialog - > read_fd ) ;
close ( pdialog - > write_fd ) ;
kill ( pdialog - > backend_pid , 9 ) ;
if ( ret = = 0 )
return 1 ;
} else {
return 1 ;
}
}
2004-11-03 20:29:08 +00:00
void
2005-06-15 00:25:55 +00:00
gnome_about_me_password ( GtkWindow * parent )
2004-11-03 20:29:08 +00:00
{
PasswordDialog * pdialog ;
2005-06-15 00:25:55 +00:00
GtkWidget * wpassdlg ;
2004-11-03 20:29:08 +00:00
GladeXML * dialog ;
2005-08-06 15:49:13 +00:00
gint result ;
2004-11-03 20:29:08 +00:00
pdialog = g_new0 ( PasswordDialog , 1 ) ;
dialog = glade_xml_new ( GNOMECC_DATA_DIR " /interfaces/gnome-about-me.glade " , " change-password " , NULL ) ;
2005-06-15 00:25:55 +00:00
pdialog - > xml = dialog ;
wpassdlg = WID ( " change-password " ) ;
2005-07-16 21:37:15 +00:00
capplet_set_icon ( wpassdlg , " user-info " ) ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
pdialog - > good_password = FALSE ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
g_signal_connect ( G_OBJECT ( WID ( " new-password " ) ) , " changed " ,
G_CALLBACK ( passdlg_check_password ) , pdialog ) ;
g_signal_connect ( G_OBJECT ( WID ( " retyped-password " ) ) , " changed " ,
G_CALLBACK ( passdlg_check_password ) , pdialog ) ;
gtk_image_set_from_file ( GTK_IMAGE ( WID ( " bulb " ) ) , GNOMECC_DATA_DIR " /pixmaps/gnome-about-me-bulb-off.png " ) ;
gtk_widget_set_sensitive ( WID ( " ok " ) , FALSE ) ;
gtk_window_set_resizable ( GTK_WINDOW ( wpassdlg ) , FALSE ) ;
gtk_window_set_transient_for ( GTK_WINDOW ( wpassdlg ) , GTK_WINDOW ( parent ) ) ;
gtk_widget_show_all ( wpassdlg ) ;
2005-08-06 15:49:13 +00:00
2005-08-15 18:09:33 +00:00
do {
result = gtk_dialog_run ( GTK_DIALOG ( wpassdlg ) ) ;
result = passdlg_process_response ( pdialog , result ) ;
} while ( result < = 0 ) ;
2004-11-03 20:29:08 +00:00
2005-06-15 00:25:55 +00:00
gtk_widget_destroy ( wpassdlg ) ;
2004-11-03 20:29:08 +00:00
g_free ( pdialog ) ;
}