/*------------------------------------------------------------------------- * Copyright (c) 1999-2003 Kenneth W. Sodemann (stuffle@mac.com) *------------------------------------------------------------------------- * prepsmain * * Synopsis: * Contains the main procedure, and the declaration of any * program global vars. * * $Id: prepsmain.c,v 1.38 2003/12/26 23:19:30 stuffle Exp $ * * 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 of the License, 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 * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * *------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "db_utils.h" #include "defs.h" #include "error_chks.h" #include "gtkutils.h" #include "login_dlg.h" #include "mainwin.h" #include "props.h" #include "unistd.h" #define STD_DISCLAIMER "\ \n%s version %s, Copyright (C) 2001 Kenneth W. Sodemann\n\n\ %s is free software; you can redistribute it and/or modify it\n\ under the terms of the GNU General Public License as published by the Free\n\ Software Foundation; either version 2 of the License, or (at your option)\n\ any later version.\n\n\ %s is distributed in the hope that it will be useful, but\n\ WITHOUT ANY WARRANTY; without even the implied warranty of\n\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ GNU General Public License for more details.\n\n" #define DEF_DB_NAME "myprs" static DbLoginData db_data; static PGconn *db_conn; GString *curr_db_name; static void session_die (GnomeClient *client, gpointer client_data) { gtk_main_quit (); } static int session_save (GnomeClient *client, int phase, GnomeSaveStyle save_style, int shutdown, GnomeInteractStyle interact_style, int fast, gpointer client_data) { char *prefix= (char *)gnome_client_get_config_prefix (client); char *argv[]= { "rm", "-r", NULL }; /* Save the state using gnome-config stuff. */ gnome_config_push_prefix (prefix); if (db_data.db_name != NULL) { gnome_config_set_string ("session/db_name", db_data.db_name->str); } gnome_config_pop_prefix (); gnome_config_sync(); /* Here is the real SM code. We set the argv to the parameters needed to restart/discard the session that we've just saved and call the gnome_session_set_*_command to tell the session manager it. */ argv[2]= gnome_config_get_real_path (prefix); gnome_client_set_discard_command (client, 3, argv); /* Set commands to clone and restart this application. Note that we use the same values for both -- the session management code will automatically add whatever magic option is required to set the session id on startup. The client_data was set to the command used to start this application when save_yourself handler was connected. */ argv[0]= (gchar*) client_data; gnome_client_set_clone_command (client, 1, argv); gnome_client_set_restart_command (client, 1, argv); return TRUE; } static gint get_schema_version (PGconn *conn) { gint ver = -1; PGresult *res = NULL; res = PQexec (conn, "SELECT MAX( schema_ver ) FROM version"); if (chk_sql_error (res, "Getting Schema Version")) { ver = atoi (PQgetvalue (res, 0, 0)); } PQclear (res); return ver; } int main (int argc, char *argv[]) { GConfClient *conf; GnomeClient *client; GtkWidget *Main; static gboolean show_login = FALSE; static gboolean show_copyright = FALSE; gchar *db_name = NULL; GString *msg; GString *tmp_str; GtkWidget *msg_dlg; gint schema; gboolean first_time = TRUE; /* The first failure to login will * only bring up the login dlg (no * error msg). The flag lets us know * if this is still the first attempt. */ struct poptOption options[] = { { "database", 'd', POPT_ARG_STRING, &db_name, 0, N_("Specify the name of the database to connect to."), N_("DATABASE") }, { "login", 'l', POPT_ARG_NONE, &show_login, 0, N_("Display the login dialog upon program startup."), NULL }, { "copyright", 'c', POPT_ARG_NONE, &show_copyright, 0, N_("Show the copyright information."), NULL }, { NULL, '\0', 0, NULL, 0, NULL, NULL } }; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); textdomain (GETTEXT_PACKAGE); #endif /* * Take care of the basic stuff right away. */ gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_POPT_TABLE, options, GNOME_PARAM_HUMAN_READABLE_NAME, _("Problem Reporting System"), GNOME_PARAM_APP_DATADIR, DATA_DIR, NULL); conf = gconf_client_get_default (); gconf_client_add_dir (conf, BASE_KEY, GCONF_CLIENT_PRELOAD_NONE, NULL); add_pixmap_directory (DATA_DIR); openlog (PACKAGE, LOG_ODELAY, LOG_USER); init_db_data (conf, &db_data); curr_db_name = g_string_new (""); /* * Do the session management junk. For now, the only thing I am * storing on a "save_yourself" is the current database. */ client = gnome_master_client(); g_signal_connect (client, "die", G_CALLBACK (session_die), NULL); g_signal_connect (client, "save_yourself", G_CALLBACK (session_save), argv[0]); if (GNOME_CLIENT_CONNECTED (client)) { gchar *tmp_str; gboolean is_def; /* * Set the db_name... */ gnome_config_push_prefix (gnome_client_get_config_prefix (client)); tmp_str = gnome_config_get_string_with_default ("session/db_name=bogus", &is_def); if (!is_def) { set_db_name (conf, &db_data, tmp_str, TRUE); } g_free (tmp_str); gnome_config_pop_prefix(); } if (show_copyright) { g_print (STD_DISCLAIMER, PACKAGE, VERSION, PACKAGE, PACKAGE); /* * If this was the only PRepS option used, then exit... */ if (!show_login && (db_name == NULL)) { exit (0); } } if (db_name) { set_db_name (conf, &db_data, db_name, TRUE); } if (show_login || show_login_dlg_on_startup (conf)) { /* * We are showing the login dlg, so we also would like * to see any error messages our input causes. IOW, * we do not want the normal "first_time" behaviour * of silently failing. */ first_time = FALSE; if (execute_login_dlg (NULL, &db_data, conf) == GTK_RESPONSE_CANCEL) { clear_db_data (&db_data); exit (0); } } /* * Attempt to connect once, if we fail perhaps we need more information * from the user. Put up the login dlg. If we fail from there on * in, annoy the user with message boxes. */ db_conn = db_login (&db_data); while (PQstatus (db_conn) == CONNECTION_BAD) { syslog (LOG_ERR, "Error logging on to database: %s", db_data.db_name->str); /* * We only want to give an error message if this is not the * first attempt at logging on. For the first attemp, fail * silently and bring up a login dialog box. */ if (!first_time) { msg_dlg = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, PQerrorMessage (db_conn)); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); } first_time = FALSE; /* * shutdown the last attempt now that we are done extracting * error messages from it. */ db_shutdown (db_conn); if (execute_login_dlg (NULL, &db_data, conf) == GTK_RESPONSE_CANCEL) { clear_db_data (&db_data); exit (0); } db_conn = db_login (&db_data); } schema = get_schema_version (db_conn); if (schema == TARGET_SCHEMA) { if (get_db_access_lvl (db_conn) == -1) { msg_dlg = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("You are setup as a PostgreSQL database user.\n" "However, you are not setup as a PRepS user for this database.\n" "Please see your PRepS database administrator.")); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); db_shutdown (db_conn); clear_db_data (&db_data); gtkutils_cleanup (); closelog(); exit (-1); } syslog (LOG_INFO, "Logged on to PRepS database: %s", db_data.db_name->str); commit_db_data (conf, &db_data); curr_db_name = g_string_assign (curr_db_name, db_data.db_name->str); Main = create_main_win (db_conn, conf); gtk_widget_show (Main); gtk_main (); } else { syslog (LOG_INFO, "Failed to log into PRepS database: %s, wrong schema version", db_data.db_name->str); msg = g_string_new (""); g_string_printf (msg, _("This version of PRepS works with database schema %d\n"), TARGET_SCHEMA); tmp_str = g_string_new (""); g_string_printf (tmp_str, _("The %s database is schema version %d\n"), db_data.db_name->str, schema); msg = g_string_append (msg, tmp_str->str); if (schema < TARGET_SCHEMA) { msg = g_string_append (msg, _("Ask your admin to use update_prepsdb to update your database.")); } else { msg = g_string_append (msg, _("Ask your admin to upgrade your version of PRepS.")); } msg_dlg = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg->str); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); g_string_free (msg, TRUE); g_string_free (tmp_str, TRUE); db_shutdown (db_conn); } g_object_unref (G_OBJECT (conf)); g_string_free (curr_db_name, TRUE); clear_db_data (&db_data); gtkutils_cleanup (); closelog(); return 0; }