From 8771d103b742783a4e6d2794165efc956dd5ea15 Mon Sep 17 00:00:00 2001 From: Jaromil Date: Wed, 27 Apr 2011 23:19:06 +0200 Subject: [PATCH] Added slam command exposed as command the implementation by Anathema: kills all processes using the tomb (denying it to be closed) and umounts tomb (the commandline script) is not supposed to be interactive we leave interactivity to be implemented by wrappers as tomb-open so it should stop to ask the used if to slam, rather than offer it as a command. now also tomb-status has the menu option to slam. --- doc/tomb.1 | 16 ++++++++++---- src/tomb | 17 ++++++++------- src/tomb-status.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/doc/tomb.1 b/doc/tomb.1 index 9455fbf..255ed35 100644 --- a/doc/tomb.1 +++ b/doc/tomb.1 @@ -51,10 +51,18 @@ mounted in a directory named after the filename and inside /media. .B .IP "close" Closes a currently open tomb. When \fIan argument\fR is specified, it -should point to the tomb mount on /dev/mapper; if not specified and -only one tomb is open then it will be closed; if multiple tombs are -open, the command will list them on the terminal. The special -\fIargument\fR 'all' will close all currently open tombs. +should be the name of a mounted tomb; if not specified and only one +tomb is open then it will be closed; if multiple tombs are open, the +command will list them on the terminal. The special +\fIargument\fR 'all' will close all currently open tombs. This command +fails if the tomb is in use by running processes, the command +\fIslam\fR can be used to force close. + +.B +.IP "slam" +Closes a tomb like the command \fIclose\fR does, but in case it is in +use looks for all the processes accessing its files and violently +kills them using \-9. .B .IP "bury" diff --git a/src/tomb b/src/tomb index f21e206..9dc053e 100755 --- a/src/tomb +++ b/src/tomb @@ -210,7 +210,8 @@ Commands: create create a new tomb FILE and its keys open open an existing tomb FILE on PLACE - close closes the tomb open on PLACE + close close the open tomb called FILE (or all) + slam close tomb FILE and kill all pids using it bury hide a tomb key FILE inside a jpeg PLACE exhume extract a tomb key FILE from a jpeg PLACE @@ -707,16 +708,15 @@ umount_tomb() { umount ${tombmount} 2> /dev/null if ! [ $? = 0 ]; then error "Tomb is busy, cannot umount!" - notice "Do you want to force umount? y/N: " - read ans - if [ "$ans" = "S" -o "$ans" = "s" -o "$ans" = "y" -o "$ans" = "Y" ]; then + if [ $SLAM ]; then + notice "Slamming tomb killing all processes using it" pidk=`lsof -t "$tombmount"` for p in "$pidk"; do - pname=`pidof $p` - func "killing PID $p of $pname..." - kill -9 $p + pname=`pidof $p` + func "killing PID $p of $pname..." + kill -9 $p done - umount "${tombmount}" + umount "${tombmount}" else error "Cannot umount $tombname on $tombmount" return 1 @@ -877,6 +877,7 @@ main () { umount) check_priv ; umount_tomb ${CMD2} ;; unmount) check_priv ; umount_tomb ${CMD2} ;; close) check_priv ; umount_tomb ${CMD2} ;; + slam) chack_priv ; SLAM=1; umount_tomb ${CMD2} ;; bury) if [ "$STEGHIDE" = 0 ]; then error "steghide not installed. Cannot bury your key" return 1 diff --git a/src/tomb-status.c b/src/tomb-status.c index 399442d..cdfac90 100644 --- a/src/tomb-status.c +++ b/src/tomb-status.c @@ -49,13 +49,15 @@ char mountpoint[256]; gboolean left_click(GtkWidget *w, GdkEvent *e); gboolean cb_view(GtkWidget *w, GdkEvent *e); gboolean cb_close(GtkWidget *w, GdkEvent *e); +gboolean cb_slam(GtkWidget *w, GdkEvent *e); gboolean right_click(GtkWidget *w, GdkEvent *e); gboolean cb_about(GtkWidget *w, GdkEvent *e); int main(int argc, char **argv) { - GtkWidget *item_close, *item_view, *item_about; + GtkWidget *item_close, *item_slam; + GtkWidget *item_view, *item_about; gint menu_x, menu_y; gboolean push_in = TRUE; @@ -104,6 +106,11 @@ int main(int argc, char **argv) { gtk_menu_attach(menu_left, item_close, 0, 1, 1, 2); g_signal_connect_swapped(item_close, "activate", G_CALLBACK(cb_close), NULL); gtk_widget_show(item_close); + // slam + item_slam = gtk_menu_item_new_with_label("Slam"); + gtk_menu_attach(menu_left, item_slam, 0, 1, 2, 3); + g_signal_connect_swapped(item_slam, "activate", G_CALLBACK(cb_slam), NULL); + gtk_widget_show(item_slam); // connect it g_signal_connect_swapped(status_tomb, "activate", G_CALLBACK(left_click), menu_left); @@ -196,7 +203,6 @@ gboolean cb_close(GtkWidget *w, GdkEvent *e) { fprintf(stderr,"pipe creation error: %s\n", strerror(errno)); return FALSE; } - cpid = fork(); if (cpid == -1) { @@ -228,6 +234,49 @@ gboolean cb_close(GtkWidget *w, GdkEvent *e) { return TRUE; } + +gboolean cb_slam(GtkWidget *w, GdkEvent *e) { + int pipefd[2]; + pid_t cpid; + char buf; + int c, res; + char map[256]; + + if (pipe(pipefd) <0) { + fprintf(stderr,"pipe creation error: %s\n", strerror(errno)); + return FALSE; + } + + cpid = fork(); + if (cpid == -1) { + fprintf(stderr,"fork error: %s\n", strerror(errno)); + return FALSE; + } + if (cpid == 0) { // Child + close(pipefd[1]); // close unused write end + for(c=0; read(pipefd[0], &buf, 1) > 0; c++) + map[c] = buf; + close(pipefd[0]); + map[c] = 0; + execlp("tomb", "tomb", "slam", map, (char*)NULL); + _exit(1); + } + close(pipefd[0]); // close unused read end + write(pipefd[1], mapper, strlen(mapper)); + close(pipefd[1]); // reader will see EOF + + waitpid(cpid, &res, 0); + if(res==0) { + gtk_main_quit(); + notify_uninit(); + exit(0); + } + /* tomb-notify "Tomb '$tombname' is too busy." \ + "Close all applications and file managers, then try again." + */ + return TRUE; +} + // callbacks right click gboolean right_click(GtkWidget *w, GdkEvent *e) { gtk_menu_popup(menu_right, NULL, NULL,