Advertisement
Mark2020H

GTK GUI written in C for SSH and Apache Server control

Dec 8th, 2024 (edited)
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.79 KB | Source Code | 0 0
  1. // Part one of a simple GUI mechanism  to control your SSH and Apache web servers
  2. // MD Harrington  London Bexleyheath  Kent DA6 8NP UK
  3. // Links to to this plus Makfile  you can find on  git hub at this address https://github.com/markh2024/GTKServerControl
  4. // More at https://www.facebook.com/mark.harrington.14289/
  5.  
  6. // Part two   contains the glade file  for this application link is @ https://pastebin.com/Tn3jmiqH
  7.  
  8. // Part three contains the Makefile https://pastebin.com/F5n5b353
  9.  
  10.  
  11. #include <gtk/gtk.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <unistd.h>
  15. #include <stdio.h>
  16. #include <glib.h>
  17.  
  18. // Define a structure to hold the widget references
  19. typedef struct {
  20.     GtkWidget *window;  // the main window
  21.     GtkButton *btnstartssh;  // buttons that will call functions
  22.     GtkButton *btnstopssh;
  23.     GtkButton *btnstatussh;
  24.     GtkButton *btnstartapach;
  25.     GtkButton *btnstopapach;
  26.     GtkButton *btnstatusapache;
  27.    
  28.     GtkTextView *txtview1; // Add GtkTextView for output
  29. } AppWidgets;
  30.  
  31. static char *sudo_password = NULL;
  32.  
  33.  
  34. void prompt_password(GtkWindow *parent_window) {
  35.     GtkWidget *dialog, *content_area, *entry;
  36.     GtkDialogFlags flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
  37.     gint response;
  38.  
  39.     // Create a new dialog
  40.     dialog = gtk_dialog_new_with_buttons("Enter Password",
  41.                                          parent_window,
  42.                                          flags,
  43.                                          "_OK",
  44.                                          GTK_RESPONSE_OK,
  45.                                          "_Cancel",
  46.                                          GTK_RESPONSE_CANCEL,
  47.                                          NULL);
  48.  
  49.     // Set the dialog's default width
  50.     gtk_window_set_default_size(GTK_WINDOW(dialog), 250, -1); // 400px wide, height is automatic (-1)
  51.  
  52.     // Get the content area and create the entry
  53.     content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
  54.     entry = gtk_entry_new();
  55.     gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); // Hide password input
  56.     gtk_entry_set_placeholder_text(GTK_ENTRY(entry), "Enter your sudo password");
  57.  
  58.     // Add the entry to the dialog
  59.     gtk_container_add(GTK_CONTAINER(content_area), entry);
  60.  
  61.     // Show all widgets in the dialog
  62.     gtk_widget_show_all(dialog);
  63.  
  64.     // Run the dialog and capture the response
  65.     response = gtk_dialog_run(GTK_DIALOG(dialog));
  66.     if (response == GTK_RESPONSE_OK) {
  67.         const char *password = gtk_entry_get_text(GTK_ENTRY(entry));
  68.         if (password && strlen(password) > 0) {
  69.             sudo_password = g_strdup(password); // Duplicate password to store it
  70.         } else {
  71.             fprintf(stderr, "Password cannot be empty. Exiting.\n");
  72.             gtk_widget_destroy(dialog);
  73.             exit(EXIT_FAILURE);
  74.         }
  75.     } else {
  76.         fprintf(stderr, "Password input canceled. Exiting.\n");
  77.         gtk_widget_destroy(dialog);
  78.         exit(EXIT_FAILURE);
  79.     }
  80.  
  81.     // Destroy the dialog after use
  82.     gtk_widget_destroy(dialog);
  83. }
  84.  
  85.  
  86.  
  87. // Function to execute a command using sudo with the password provided
  88. gboolean execute_command(const char *command, GtkTextView *text_view) {
  89.     char full_command[512];
  90.     FILE *pipe;
  91.  
  92.     snprintf(full_command, sizeof(full_command), "echo '%s' | sudo -S %s 2>&1", sudo_password, command);
  93.  
  94.     pipe = popen(full_command, "r");
  95.     if (!pipe) {
  96.         perror("popen");
  97.         return FALSE;
  98.     }
  99.  
  100.     // Get the GtkTextBuffer associated with the GtkTextView
  101.     GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
  102.     gtk_text_buffer_set_text(buffer, "", -1); // Clear any existing text
  103.  
  104.     char buffer_line[256];
  105.     while (fgets(buffer_line, sizeof(buffer_line), pipe)) {
  106.         // Append each line to the GtkTextView
  107.         GtkTextIter end;
  108.         gtk_text_buffer_get_end_iter(buffer, &end);
  109.         gtk_text_buffer_insert(buffer, &end, buffer_line, -1);
  110.     }
  111.  
  112.     int ret_code = pclose(pipe);
  113.     if (WEXITSTATUS(ret_code) != 0) {
  114.         GtkTextIter end;
  115.         gtk_text_buffer_get_end_iter(buffer, &end);
  116.         gtk_text_buffer_insert(buffer, &end, "\nCommand failed.\n", -1);
  117.         return FALSE;
  118.     }
  119.  
  120.     GtkTextIter end;
  121.     gtk_text_buffer_get_end_iter(buffer, &end);
  122.     gtk_text_buffer_insert(buffer, &end, "\nCommand executed successfully.\n", -1);
  123.  
  124.     return TRUE;
  125. }
  126.  
  127.  
  128. // Signal handlers for the buttons
  129. void on_btnstartssh_clicked(GtkButton *button, gpointer user_data) {
  130.     AppWidgets *widgets = (AppWidgets *)user_data; // Cast user_data to AppWidgets
  131.    
  132.     execute_command("systemctl start ssh", widgets->txtview1);
  133. }
  134.  
  135. void on_btnstopssh_clicked(GtkButton *button, gpointer user_data) {
  136.     AppWidgets *widgets = (AppWidgets *)user_data;
  137.    
  138.     execute_command("systemctl stop ssh", widgets->txtview1);
  139. }
  140.  
  141. void on_btnstatussh_clicked(GtkButton *button, gpointer user_data) {
  142.     AppWidgets *widgets = (AppWidgets *)user_data;
  143.    
  144.     execute_command("systemctl status ssh", widgets->txtview1);
  145. }
  146.  
  147. void on_btnstartapach_clicked(GtkButton *button, gpointer user_data) {
  148.     AppWidgets *widgets = (AppWidgets *)user_data;
  149.  
  150.     execute_command("systemctl start apache2", widgets->txtview1);
  151. }
  152.  
  153. void on_btnstopapach_clicked(GtkButton *button, gpointer user_data) {
  154.     AppWidgets *widgets = (AppWidgets *)user_data;
  155.    
  156.     execute_command("systemctl stop apache2", widgets->txtview1);
  157. }
  158.  
  159. void on_btnstatusapache_clicked(GtkButton *button, gpointer user_data) {
  160.     AppWidgets *widgets = (AppWidgets *)user_data;
  161.    
  162.     execute_command("systemctl status apache2", widgets->txtview1);
  163. }
  164.  
  165.  
  166. int main(int argc, char *argv[]) {
  167.     gtk_init(&argc, &argv);
  168.  
  169.     // Load the Glade file and set up the UI
  170.     GtkBuilder *builder = gtk_builder_new_from_file("servernewgui.glade");
  171.  
  172.     // Create an AppWidgets structure and populate it
  173.     AppWidgets widgets;
  174.    
  175.    
  176.     // get the window we are working with
  177.     widgets.window = GTK_WIDGET(gtk_builder_get_object(builder, "mainwindow"));
  178.    
  179.     // Prompt for the password using a dialog
  180.     prompt_password(GTK_WINDOW(widgets.window));
  181.      
  182.     // get the textView
  183.     widgets.txtview1 = GTK_TEXT_VIEW(gtk_builder_get_object(builder, "txtview1"));
  184.    
  185.     // set the style  for the textiew widget
  186.    
  187.     GtkCssProvider *cssProviderLog = gtk_css_provider_new();
  188.     GtkStyleContext *context;
  189.  
  190.     // Set the CSS for the textview
  191.     gtk_css_provider_load_from_data(cssProviderLog,
  192.                                     "textview {"
  193.                                     "font-family: serif;"
  194.                                     "font-size: 12px;"                                    
  195.                                     "color: green;"
  196.                                     "}", -1, NULL);
  197.  
  198.     // Add the CSS provider to the context of the GtkTextView
  199.     context = gtk_widget_get_style_context(GTK_WIDGET(widgets.txtview1));
  200.     gtk_style_context_add_provider(context,
  201.                                    GTK_STYLE_PROVIDER(cssProviderLog),
  202.                                    GTK_STYLE_PROVIDER_PRIORITY_USER);
  203.  
  204.     // Unreference the CSS provider to avoid memory leaks
  205.     g_object_unref(cssProviderLog);
  206.  
  207.  
  208.    // assign  buttons
  209.    
  210.     widgets.btnstartssh = GTK_BUTTON(gtk_builder_get_object(builder, "btnstartssh"));
  211.     widgets.btnstopssh = GTK_BUTTON(gtk_builder_get_object(builder, "btnstopssh"));
  212.     widgets.btnstatussh = GTK_BUTTON(gtk_builder_get_object(builder, "btnstatussh"));
  213.     widgets.btnstartapach = GTK_BUTTON(gtk_builder_get_object(builder, "btnstartapach"));
  214.     widgets.btnstopapach = GTK_BUTTON(gtk_builder_get_object(builder, "btnstopapach"));
  215.     widgets.btnstatusapache = GTK_BUTTON(gtk_builder_get_object(builder, "btnstatusapache"));
  216.  
  217.        
  218.     // buttons  signals  ssh
  219.     g_signal_connect(widgets.btnstartssh, "clicked", G_CALLBACK(on_btnstartssh_clicked), &widgets);
  220.     g_signal_connect(widgets.btnstopssh, "clicked", G_CALLBACK(on_btnstopssh_clicked), &widgets);
  221.     g_signal_connect(widgets.btnstatussh, "clicked", G_CALLBACK(on_btnstatussh_clicked), &widgets);
  222.  
  223.  
  224.    // buttons  signals apache2
  225.     g_signal_connect(widgets.btnstartapach, "clicked", G_CALLBACK(on_btnstartapach_clicked), &widgets);
  226.     g_signal_connect(widgets.btnstopapach, "clicked", G_CALLBACK(on_btnstopapach_clicked), &widgets);
  227.     g_signal_connect(widgets.btnstatusapache, "clicked", G_CALLBACK(on_btnstatusapache_clicked), &widgets);
  228.  
  229.     // window close  signal
  230.    
  231.     // Connect the "destroy" signal to quit the application
  232.     g_signal_connect(widgets.window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  233.  
  234.  
  235.     g_object_unref(builder);
  236.  
  237.     // Show the window and start the GTK main loop
  238.     gtk_widget_show(widgets.window);
  239.     gtk_main();
  240.  
  241.     // Clean up the password from memory
  242.     g_free(sudo_password);
  243.  
  244.     return 0;
  245.    
  246. }
  247.  
  248.  
  249.    
  250.  
  251.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement