void gnm_shutdown (void) { GSList *plugin_states; gnm_app_clipboard_clear (TRUE); plugin_states = go_plugins_shutdown (); if (NULL != plugin_states) { gnm_conf_set_plugins_file_states (plugin_states); g_slist_free_full (plugin_states, g_free); } stf_shutdown (); gnm_xml_sax_write_shutdown (); gnm_xml_sax_read_shutdown (); gnm_autofill_shutdown (); print_shutdown (); gnm_func_shutdown_ (); gnm_rendered_value_shutdown (); dependent_types_shutdown (); gui_clipboard_shutdown (); clipboard_shutdown (); gnm_sheet_cell_shutdown (); gnm_expr_deriv_shutdown_ (); gnm_expr_shutdown_ (); parse_util_shutdown (); value_shutdown (); // The style leak printer may access font/border/color info so // shut styles down first. gnm_style_shutdown (); gnm_font_shutdown (); gnm_border_shutdown (); gnm_color_shutdown (); gnm_conf_shutdown (); _gnm_unregister_resource (); libgoffice_shutdown (); go_plugin_services_shutdown (); g_object_unref (gnm_app_get_app ()); gutils_shutdown (); }
void signal_handler(int signum) { /* signal_handler * Signal handler for signals requiring shutdown - Hang-up, termination. */ switch (signum) { case SIGINT:raise_message(MESSAGE,"Interrupt (CTRL-C) (SIGHUP) "); break; case SIGHUP:raise_message(MESSAGE,"Hangup (SIGHUP) "); break; case SIGTERM:raise_message(MESSAGE,"Terminate (SIGTERM) "); break; default:raise_message(MESSAGE,"Signal (%d) ",signum); break; } raise_message(MESSAGE,"Signal handler - closing databases... ",signum); relations_dispose_all(current_db); LEAPAPI_db_destroy(¤t_db); relations_dispose_all(master_db); LEAPAPI_db_destroy(&master_db); relations_dispose_all(tempdb); LEAPAPI_db_destroy(&tempdb); /* Close the various files opened earlier */ util_close(); print_shutdown(); leap_fprintf(stdout,"\nLEAP terminated successfully following termination signal.\n"); exit(0); }
int main(int argc, char *argv[]) { /* main * The main LEAP program - This performs the display of the * title, and processes the command line. Clean termination * also should occur here. Everywhere else termination is * "unclean", and should return an error status. Define * error status' in the dtypes.h file */ #ifdef FULL_DEBUG /* Test vars */ char source[50],result[50],*sptr; #endif boolean tdebug=FALSE,ttiming=FALSE,ttimelog=FALSE,tlong=FALSE; boolean tquiet=FALSE,ttrace=FALSE,tpad=FALSE,tpjoin=FALSE; time_t tp; char *s; char *argptr; /******************************** * Startup - Firstly set up the * signal handlers ********************************/ /* Signal Interrupt from the keyboard - the daemon should handle it */ signal(SIGINT,&signal_handler); /* MSDOS/Windows does not know SIGQUIT/SIGHUP, whereas * these are important in Unix */ #ifndef __MSDOS__ /* Signal Quit from the keyboard - Ignore it */ signal(SIGQUIT,SIG_IGN); /* Signal Hang up - Handle it */ signal(SIGHUP,&signal_handler); #else #endif define_handle(&default_handler,&errorHandler); raise_message(EVENT, "%s","Event Handler initialised."); define_handle(&default_quiethandler,&messageHandler); raise_message(EVENT,"%s","Message Handler initialised."); /* Signal Terminate - Handle it */ signal(SIGTERM,&signal_handler); /* Perform some configuration... */ build_base_dir(LEAP_DEFAULT_DIR); /* Set the random seed to the time in secs since 01.01.1970 * should be random enough! */ srand(time(NULL)); s=getenv(LEAP_ENV_DIR); strcpy(dbtoopen,""); strcpy(activityfile,""); strcpy(tempdir,""); ACTIVITY_FILE=NULL; if (s!=NULL) { leap_fprintf(stdout,"Using environment variable %s for path (%s).\n",LEAP_ENV_DIR,s); build_base_dir(s); } /* Process the command line Stop if we run out of arguments or we get an argument without a dash */ /* NB. This is based on O'Reilly & Associates "Practical C Programming", by Steve Oualline, 2nd Ed. (pg 178) */ while ((argc > 1) && (argv[1][0] == '-')) { /* * argv[1][1] is the actual option character */ if ((argv[1][0]==ARGUMENT_PREFIX) && (argv[1][1]==ARGUMENT_PREFIX)) { argptr=&argv[1][2]; } else { argptr=&argv[1][1]; } switch (*argptr) { case 'a': case 'A': if ((strcmp(argptr,"activity-file")==0)||(strcmp(argptr,"activity")==0)||(strlen(argptr)==1)) { if (specify(activityfile,argv[2],FILE_PATH_SIZE)){ argv++; argc--; } else { leap_fprintf(stderr,"No file specified. Using %s\n",LEAP_ACTIVITY_FILE); strncpy(activityfile,LEAP_ACTIVITY_FILE,FILE_PATH_SIZE); } ACTIVITY_FILE=fopen(activityfile,"a"); if (ACTIVITY_FILE==NULL) { leap_fprintf(stderr,"Unable to open activity file for appending.\n"); } else { tp=time(NULL); fprintf(ACTIVITY_FILE,"###\n# Activity file STARTED at: %s###\n",ctime(&tp)); leap_printf("Activity file: %s\n",activityfile); } } break; case 'b': case 'B': if (specify(dbtoopen,argv[2],DATABASE_NAME_SIZE)){ argv++; argc--; } else { raise_message(MESSAGE,"No database specified on command line. %s will be used.",DEFAULT_DB); } break; case 'd': case 'D': if ((strcmp(argptr,"dir")==0)||(strcmp(argptr,"directory")==0)||(strlen(argptr)==1)) { if (argv[2]) { build_base_dir(argv[2]); /* Increment the counts... */ argv++; argc--; } else { leap_fprintf(stderr,"ERROR: No directory specified after directory flag.\n"); exit(1); } } else if (strcmp(argptr,"database")==0) { if (specify(dbtoopen,argv[2],DATABASE_NAME_SIZE)){ argv++; argc--; } } else if (strcmp(argptr,"debug")==0) { /* The user wants debug information */ leap_printf("Debug messages enabled\n"); tdebug=TRUE; } break; case 'e': case 'E': if (strlen(argptr)==1) { /* The user wants debug information */ leap_printf("Debug messages enabled\n"); tdebug=TRUE; } else if ((strcmp(argptr,"events")==0)||(strcmp(argptr,"event")==0)) { /* User wants event reports */ define_handle(&default_quiethandler,&eventHandler); raise_message(EVENT,"%s","Event Handler initialised."); } break; case 'h': case '?': case 'H': if ((strcmp(argptr,"help")==0)||(strlen(argptr)==1)) { /* The user wants some help... */ print_help(); /* Exit without an error */ exit(0); /* Lint-ified - The break is not reached */ /* break; */ } case 'i': case 'I': /* The user wants timing information */ leap_printf("Timing information enabled\n"); ttiming=TRUE; break; case 'l': case 'L': if ((strcmp(argptr,"time-logging")==0)||(strlen(argptr)==1)) { /* Do not fetch the system time in log file */ leap_printf("Time logging disabled\n"); ttimelog=FALSE; } else if ((strcmp(argptr,"long-commands")==0)||(strcmp(argptr,"long")==0)){ leap_printf("Long commands enabled\n"); tlong=TRUE; } break; case 'n': case 'N': /* Display warranty information */ do_warranty(); exit(0); /* Lint-ified - The break is not reached */ /* break; */ case 'o': case 'O': leap_printf("Long commands enabled\n"); tlong=TRUE; break; case 'p': case 'P': if ((strcmp(argptr,"padding")==0)||(strlen(argptr)==1)) { leap_printf("Relation Name Padding enabled\n"); tpad=TRUE; } else if ((strcmp(argptr,"product-join")==0)||(strcmp(argptr,"pjoin")==0)) { leap_printf("Product performed in no-condition join\n"); tpjoin=TRUE; } break; case 'q': case 'Q': if ((strcmp(argptr,"quiet")==0)||(strlen(argptr)==1)) { tquiet=TRUE; BEEP=' '; /* Shutdown the message handler */ define_handle(NULL,&messageHandler); } break; case 'r': case 'R': if ((strcmp(argptr,"regression")==0)||(strlen(argptr)==1)) { /* What!? This is to disable outputting * items that might cause regression tests * to fail for no good reason, ie. * temporary relation names which are random, * and will differ between runs. */ status_regression=TRUE; leap_printf("Regression test mode on\n"); } break; case 's': case 'S': if ((strcmp(argptr,"status")==0)||(strlen(argptr)==1)) { /* The user wants status messages to be displayed */ leap_printf("Status messages enabled\n"); status=TRUE; } break; case 't': case 'T': if ((strcmp(argptr,"time")==0)||(strcmp(argptr,"timing")==0)) { /* The user wants timing information */ leap_printf("Timing information enabled\n"); ttiming=TRUE; } else if ((strlen(argptr)==1)||(strcmp(argptr,"trace")==0)||(strcmp(argptr,"tracing")==0)) { /* The user wants tracing information */ leap_printf("Tracing information enabled\n"); ttrace=TRUE; } break; case 'v': case 'V': if ((strcmp(argptr,"version")==0)||(strlen(argptr)==1)) { /* Print BRIEF version information */ print_header(TRUE); exit(0); } break; case 'w': case 'W': if ((strcmp(argptr,"warranty")==0)||(strlen(argptr)==1)) { do_warranty(); exit(0); } break; case 'x': case 'X': if (argv[2]) { strncpy(tempdir,argv[2],FILE_PATH_SIZE); /* Increment the counts... */ argv++; argc--; } else { leap_fprintf(stderr,"ERROR: No directory specified after temporary directory flag.\n"); exit(1); } break; default: raise_error(ERROR_COMMAND_LINE,NONFATAL,argptr); } /* Move the argument list up one and the count down one */ argv++; argc--; } raise_message(EVENT,"%s","Command line processed."); /* First things first, report (verbosely) what we are. */ if ((status_regression!=TRUE) && (tquiet!=TRUE)) print_header(FALSE); if ( (status) && (tquiet!=TRUE) ) { sprintf(temp_80_chars,"LEAP Base directory set to: %s",LEAP_BASE_DIR); leap_printf(temp_80_chars); } /* Call any initialisation routines... */ util_init(); /* This has to be done after the path is read, so that * the variable config file is located. */ if (init_variables()!=RETURN_SUCCESS) { raise_message(MESSAGE,"Directory specified [%s] not valid. Trying [%s]",LEAP_BASE_DIR,LEAP_TRY_DIR); build_base_dir(LEAP_TRY_DIR); if (init_variables()!=RETURN_SUCCESS) { raise_message(MESSAGE,"[%s] is also not valid - Problems are likely",LEAP_TRY_DIR); } else { raise_message(MESSAGE,"Variables are now set."); } } if (tdebug==TRUE) set_variable(STATUS_DEBUG,STATUS_SETTING_ON); if (ttiming==TRUE) set_variable(STATUS_TIMING,STATUS_SETTING_ON); if (ttimelog==TRUE) set_variable(STATUS_TIMELOG,STATUS_SETTING_ON); if (tlong==FALSE) set_variable(STATUS_LONGLINE,STATUS_SETTING_OFF); if (tquiet==TRUE) set_variable(STATUS_QUIET,STATUS_SETTING_ON); if (ttrace==TRUE) set_variable(STATUS_TRACE,STATUS_SETTING_ON); if (tpad==TRUE) set_variable(STATUS_PADDING,STATUS_SETTING_ON); if (tpjoin==TRUE) set_variable(STATUS_PRODUCTJOIN,STATUS_SETTING_ON); /* Display some information */ if (status_quiet!=TRUE) { raise_message(MESSAGE,"LEAP is starting..."); } #ifdef DEBUG status_debug=TRUE; leap_fprintf(stderr,"DEBUG: LEAP debug mode forced on\n"); #endif /* Do the main leap operation */ (void) do_daemon(); print_shutdown(); /* Close the various files opened earlier */ util_close(); if (status_quiet!=TRUE) { /* Inform the user of a clean termination */ raise_message(MESSAGE,"LEAP Terminated successfully!"); } /* Return success. Elsewhere, non-zero should be returned */ return(0); }