tomb

the crypto undertaker
git clone git://parazyd.org/tomb.git
Log | Files | Refs | README | LICENSE

tomb-gtk-tray.c (10764B)


      1 /*  Tomb - encrypted storage undertaker
      2  *  
      3  *  (c) Copyright 2007-2011 Denis Roio <jaromil@dyne.org>
      4  *
      5  * This source code is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Public License as published 
      7  * by the Free Software Foundation; either version 3 of the License,
      8  * or (at your option) any later version.
      9  *
     10  * This source code is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     13  * Please refer to the GNU Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Public License along with
     16  * this source code; if not, write to:
     17  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  */
     19 
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include <unistd.h>
     23 #include <string.h>
     24 #include <errno.h>
     25 #include <libgen.h>
     26 
     27 #include <sys/types.h>
     28 #include <sys/wait.h>
     29 
     30 #include <gtk/gtk.h>
     31 #include <libnotify/notify.h>
     32 
     33 /* The Tomb icon is an artwork by Jordi aka MonMort
     34    a nomadic graffiti artist from Barcelona */
     35 #include <monmort.xpm>
     36 
     37 GdkPixbuf *pb_monmort;
     38 GtkStatusIcon *status_tomb;
     39 GtkMenu *menu_left, *menu_right;
     40 
     41 NotifyNotification *notice;
     42 GError *error;
     43 
     44 char mapper[256];
     45 char filename[256];
     46 char mountpoint[256];
     47 
     48 // forward declaration of callbacks
     49 gboolean left_click(GtkWidget *w, GdkEvent *e);
     50 gboolean cb_view(GtkWidget *w, GdkEvent *e);
     51 gboolean cb_close(GtkWidget *w, GdkEvent *e);
     52 gboolean cb_slam(GtkWidget *w, GdkEvent *e);
     53 
     54 gboolean right_click(GtkWidget *w, GdkEvent *e);
     55 gboolean cb_about(GtkWidget *w, GdkEvent *e);
     56 
     57 
     58 int main(int argc, char **argv) {
     59   GtkWidget *item_close, *item_slam;
     60   GtkWidget *item_view, *item_about;
     61   gint menu_x, menu_y;
     62   gboolean push_in = TRUE;
     63 
     64   char tomb_file[512];
     65   char tooltip[256];
     66 
     67 //  gtk_set_locale();
     68   gtk_init(&argc, &argv);
     69 
     70   // get the information from commandline
     71   if(argc<2) {
     72     fprintf(stderr, "error: need at least one argument, the name of an open tomb.\n");
     73     exit(1);
     74   } else {
     75     // TODO: check if mapper really exists
     76     snprintf(mapper,255, "%s", argv[1]);
     77   }
     78 
     79   snprintf(filename,255, "%s", argv[1]);
     80   snprintf(mountpoint,255, "/media/%s.tomb", argv[1]);
     81 
     82   // libnotify
     83   notify_init("Tomb");
     84 
     85   // set and show the status icon
     86   pb_monmort = gdk_pixbuf_new_from_xpm_data(monmort);
     87   status_tomb = gtk_status_icon_new_from_pixbuf(pb_monmort);
     88   //  gtk_status_icon_set_name(status_tomb, "tomb");
     89   gtk_status_icon_set_title(status_tomb, "Tomb");
     90 
     91   snprintf(tooltip,255,"%s",filename);
     92   gtk_status_icon_set_tooltip_text (status_tomb, tooltip);
     93 
     94   // LEFT click menu
     95   menu_left = (GtkMenu*) gtk_menu_new();
     96   // view
     97   item_view = gtk_menu_item_new_with_label("Explore");
     98   gtk_menu_attach(menu_left, item_view, 0, 1, 0, 1);
     99   g_signal_connect_swapped(item_view, "activate", G_CALLBACK(cb_view), NULL);
    100   gtk_widget_show(item_view);
    101   // close
    102   item_close = gtk_menu_item_new_with_label("Close");
    103   gtk_menu_attach(menu_left, item_close, 0, 1, 1, 2);
    104   g_signal_connect_swapped(item_close, "activate", G_CALLBACK(cb_close), NULL);
    105   gtk_widget_show(item_close);
    106   // slam
    107   item_slam = gtk_menu_item_new_with_label("Slam");
    108   gtk_menu_attach(menu_left, item_slam, 0, 1, 2, 3);
    109   g_signal_connect_swapped(item_slam, "activate", G_CALLBACK(cb_slam), NULL);
    110   gtk_widget_show(item_slam);
    111 
    112   // connect it
    113   g_signal_connect_swapped(status_tomb, "activate", G_CALLBACK(left_click), menu_left);
    114 
    115 
    116   // RIGHT click menu
    117   menu_right = (GtkMenu*) gtk_menu_new();
    118   // about
    119   item_about = gtk_menu_item_new_with_label("About");
    120   gtk_menu_attach(menu_right, item_about, 0, 1, 0, 1);
    121   g_signal_connect_swapped(item_about, "activate", G_CALLBACK(cb_about), NULL);
    122   g_signal_connect_swapped(item_about, "popup-menu", G_CALLBACK(cb_about), NULL);
    123   gtk_widget_show(item_about);
    124   // connect it
    125   g_signal_connect_swapped(status_tomb, "popup-menu", G_CALLBACK(right_click), menu_right);
    126 
    127   // status icon
    128 #if (HAVE_NOTIFY_NOTIFICATION_NEW_WITH_STATUS_ICON)
    129   notice = notify_notification_new_with_status_icon
    130     ("Tomb encrypted undertaker",
    131      "We started digging out bones",
    132      NULL, status_tomb);
    133 #else
    134   notice = notify_notification_new
    135     ("Tomb encrypted undertaker",
    136      "We started digging out bones",
    137      NULL);
    138 #endif
    139   notify_notification_set_icon_from_pixbuf(notice, pb_monmort);
    140 
    141   notify_notification_show(notice, &error);
    142 
    143   gtk_main();
    144   
    145   notify_uninit();
    146 
    147   exit(0);
    148   
    149 }
    150 
    151 // callbacks left click
    152 gboolean left_click(GtkWidget *w, GdkEvent *e) {
    153   gtk_menu_popup(menu_left, NULL, NULL,
    154 		 gtk_status_icon_position_menu, status_tomb,
    155 		 1, gtk_get_current_event_time());
    156   return TRUE;
    157 } 
    158 gboolean cb_view(GtkWidget *w, GdkEvent *e) { 
    159   int pipefd[2];
    160   pid_t cpid;
    161   char buf;
    162   int c, res;
    163   char map[256];
    164 
    165   if (pipe(pipefd) <0) {
    166     fprintf(stderr,"pipe creation error: %s\n", strerror(errno));
    167     return FALSE;
    168   }
    169 
    170   cpid = fork();
    171   if (cpid == -1) {
    172     fprintf(stderr,"fork error: %s\n", strerror(errno));
    173     return FALSE;
    174   }
    175   if (cpid == 0) {    // Child
    176     close(pipefd[1]); // close unused write end
    177     for(c=0; read(pipefd[0], &buf, 1) > 0; c++)
    178       map[c] = buf;
    179     close(pipefd[0]);
    180     map[c] = 0;
    181     execlp("xdg-open", "xdg-open", map, (char*)NULL);
    182     _exit(1);
    183   }
    184   close(pipefd[0]); // close unused read end
    185   write(pipefd[1], mountpoint, strlen(mountpoint));
    186   close(pipefd[1]); // reader will see EOF
    187 
    188   return TRUE;
    189 }
    190 
    191 
    192 gboolean cb_close(GtkWidget *w, GdkEvent *e) { 
    193   int pipefd[2];
    194   pid_t cpid;
    195   char buf;
    196   int c, res;
    197   char map[256];
    198 
    199   if (pipe(pipefd) <0) {
    200     fprintf(stderr,"pipe creation error: %s\n", strerror(errno));
    201     return FALSE;
    202   }
    203 
    204   cpid = fork();
    205   if (cpid == -1) {
    206     fprintf(stderr,"fork error: %s\n", strerror(errno));
    207     return FALSE;
    208   }
    209   if (cpid == 0) {    // Child
    210     close(pipefd[1]); // close unused write end
    211     for(c=0; read(pipefd[0], &buf, 1) > 0; c++)
    212       map[c] = buf;
    213     close(pipefd[0]);
    214     map[c] = 0;
    215     execlp("tomb", "tomb", "close", map, (char*)NULL);
    216     _exit(1);
    217   }
    218   close(pipefd[0]); // close unused read end
    219   write(pipefd[1], mapper, strlen(mapper));
    220   close(pipefd[1]); // reader will see EOF
    221 
    222   waitpid(cpid, &res, 0);
    223   if(res==0) {
    224     gtk_main_quit();
    225     notify_uninit();
    226     exit(0);
    227   }
    228   /*  tomb-notify "Tomb '$tombname' is too busy."		\
    229       "Close all applications and file managers, then try again."
    230   */
    231   return TRUE;
    232 }
    233 
    234 
    235 gboolean cb_slam(GtkWidget *w, GdkEvent *e) {
    236   int pipefd[2];
    237   pid_t cpid;
    238   char buf;
    239   int c, res;
    240   char map[256];
    241 
    242   if (pipe(pipefd) <0) {
    243     fprintf(stderr,"pipe creation error: %s\n", strerror(errno));
    244     return FALSE;
    245   }
    246 
    247   cpid = fork();
    248   if (cpid == -1) {
    249     fprintf(stderr,"fork error: %s\n", strerror(errno));
    250     return FALSE;
    251   }
    252   if (cpid == 0) {    // Child
    253     close(pipefd[1]); // close unused write end
    254     for(c=0; read(pipefd[0], &buf, 1) > 0; c++)
    255       map[c] = buf;
    256     close(pipefd[0]);
    257     map[c] = 0;
    258     execlp("tomb", "tomb", "slam", map, (char*)NULL);
    259     _exit(1);
    260   }
    261   close(pipefd[0]); // close unused read end
    262   write(pipefd[1], mapper, strlen(mapper));
    263   close(pipefd[1]); // reader will see EOF
    264 
    265   waitpid(cpid, &res, 0);
    266   if(res==0) {
    267     gtk_main_quit();
    268     notify_uninit();
    269     exit(0);
    270   }
    271   /*  tomb-notify "Tomb '$tombname' is too busy."		\
    272       "Close all applications and file managers, then try again."
    273   */
    274   return TRUE;
    275 }
    276 
    277 // callbacks right click
    278 gboolean right_click(GtkWidget *w, GdkEvent *e) {
    279   gtk_menu_popup(menu_right, NULL, NULL,
    280 		 gtk_status_icon_position_menu, status_tomb,
    281 		 1, gtk_get_current_event_time());
    282   return TRUE;
    283 } 
    284 gboolean cb_about(GtkWidget *w, GdkEvent *e) {
    285   const gchar *authors[] = {"Jaromil - http://jaromil.dyne.org",
    286 			    "Code reviews and contributions by:",
    287 			    "Dreamer, Hellekin O. Wolf, Shining, Mancausoft,",
    288 			    "Anathema, Boyska and Nignux", NULL};
    289   const gchar *artists[] = {"Món Mort - http://monmort.blogspot.com",
    290 			    "Asbesto Molesto - http://freaknet.org/asbesto",
    291 			    NULL};
    292   GtkWidget *dialog = gtk_about_dialog_new();
    293 //  gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "Tomb GTK Tray");
    294   gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "1.4"); 
    295   gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), 
    296 				 "(C)2007-2013 Jaromil @ Dyne.org Foundation");
    297   gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(dialog), artists);
    298   gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog), authors);
    299 
    300   gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), 
    301 				"The Crypto Undertaker\n"
    302 "\n"
    303 "This program helps people keeping their bones together by taking care of their private data inside encrypted storage filesystems that are easy to access and transport.\n"
    304 "\n"
    305 "The level of security provided by this program is fairly strong: it uses  AES/SHA256 (cbc-essiv) to access the encrypted volumes in realtime so that all what is physically stored on your disc is only in an encrypted form.\n"
    306 "Tomb also encourages users to separate keys from data, for instance storing them on USB.\n"
    307 "\n"
    308 );
    309   gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://tomb.dyne.org");
    310   gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pb_monmort);
    311   gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog), "monmort");
    312   // this below is active since gtk 3.0 so too early for it now
    313   //  gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(dialog), GtkLicense.GTK_LICENSE_GPL_3_0);
    314   gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(dialog),
    315 "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 3 of the License, or (at your option) any later version.\n"
    316 "\n"
    317 "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.\n"
    318 "\n"
    319 "You should have received a copy of the GNU General Public License along with this program.\n"
    320 "If not, see <http://www.gnu.org/licenses>\n"
    321 "\n"
    322 " The latest Tomb sourcecode is published on <http://tomb.dyne.org>\n");
    323   gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(dialog), TRUE);
    324   gtk_dialog_run(GTK_DIALOG (dialog));
    325   gtk_widget_destroy(dialog);
    326   return TRUE;
    327 }
    328   
    329 
    330   // GtkWidget *dialog = 
    331   //   gtk_message_dialog_new (NULL,
    332   // 			    GTK_DIALOG_DESTROY_WITH_PARENT,
    333   // 			    GTK_MESSAGE_INFO,
    334   // 			    GTK_BUTTONS_CLOSE,
    335   // 			    "Tomb '%s' open on '%s'\n"
    336   // 			    "device mapper: %s", filename, mountpoint, mapper);
    337   // gtk_dialog_run (GTK_DIALOG (dialog));
    338   // gtk_widget_destroy (dialog);