Logo Search packages:      
Sourcecode: tucnak2 version File versions  Download package

main.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>
    and authors of web browser Links 0.96

    This program is free software; you can redistribute it and/or                                                        
    modify it under the terms of the GNU General Public License                                                          
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"

#include <sched.h>



int retval = RET_OK;
long int starting_sbrk;


    
void sig_terminate(union cba_t cba)
{
    unhandle_basic_signals();
    terminate = 1;
    retval = RET_SIGNAL;
}

void sig_intr(union cba_t cba)
{              
    if (!term) {
        unhandle_basic_signals();
        terminate = 1;
    } else {
        unhandle_basic_signals();
        exit_prog(CBA0);
    }
}

void sig_ctrl_c(union cba_t cba)
{
    dbg("sig_ctrl_c\n");
    if (!is_blocked()) kbd_ctrl_c();
}

void sig_ign(union cba_t cba)
{
}

void sig_tstp(union cba_t cba)
{              
#ifdef SIGSTOP
    int pid = getpid();
    block_itrm(0);
#if defined (SIGCONT) && defined(SIGTTOU)
    if (!fork()) {
        sleep(1);
        kill(pid, SIGCONT);
        exit(0);
    }
#endif
    raise(SIGSTOP);
#endif
}

void sig_cont(union cba_t cba)
{
    if (!unblock_itrm(0)) resize_terminal(CBA0);
}

void sig_segv(union cba_t cba){
    signal(SIGSEGV, SIG_DFL);
/*    printf("\n\n\n  sig_segv() sdl=%p \n\n\n",sdl);*/
/*  install_signal_handler(SIGSEGV, NULL, CBA0, 0);*/
    cwdaemon_safe_abort(cwda);
#ifdef HAVE_SDL    
    if (sdl) {
        SDL_Quit();
    }
    else
#endif    
    {
        itrm_safe_abort();
    }
    raise(SIGSEGV);
}   

void sig_pipe(int a){
    dbg("sig_pipe(%d)\n", a);
}
    
void handle_basic_signals(struct terminal *term)
{
#ifndef HAVE_SDL    
#define sdl 0
#endif
    install_signal_handler(SIGHUP, sig_intr, CBA0, 0);
    if (!sdl) install_signal_handler(SIGINT, sig_ctrl_c, CBA0, 0);
    install_signal_handler(SIGTERM, sig_terminate, CBA0, 0);
    if (!sdl){
#ifdef SIGTSTP
        install_signal_handler(SIGTSTP, sig_tstp, CBA0, 0);
#endif
#ifdef SIGTTIN
        install_signal_handler(SIGTTIN, sig_tstp, CBA0, 0);
#endif
#ifdef SIGCONT
        install_signal_handler(SIGCONT, sig_cont, CBA0, 0);
#endif
    }
#ifdef SIGTTOU
    install_signal_handler(SIGTTOU, sig_ign, CBA0, 0);
#endif
    install_signal_handler(SIGSEGV, sig_segv, CBA0, 1);
      signal(SIGPIPE, sig_pipe);
}

void handle_sdl_signals(void){
    install_signal_handler(SIGSEGV, sig_segv, CBA0, 1);
}


void unhandle_terminal_signals()
{
    install_signal_handler(SIGHUP, NULL, CBA0, 0);
    if (!sdl) install_signal_handler(SIGINT, NULL, CBA0, 0);
#ifdef SIGTSTP
    install_signal_handler(SIGTSTP, NULL, CBA0, 0);
#endif
#ifdef SIGTTIN
    install_signal_handler(SIGTTIN, NULL, CBA0, 0);
#endif
#ifdef SIGCONT
    install_signal_handler(SIGCONT, NULL, CBA0, 0);
#endif
#ifdef SIGTTOU
    install_signal_handler(SIGTTOU, NULL, CBA0, 0);
#endif
    install_signal_handler(SIGSEGV, NULL, CBA0, 0);
      signal(SIGPIPE, SIG_IGN);
}

void unhandle_basic_signals()
{
    install_signal_handler(SIGHUP, NULL, CBA0, 0);
    if (!sdl) install_signal_handler(SIGINT, NULL, CBA0, 0);
    install_signal_handler(SIGTERM, NULL, CBA0, 0);
#ifdef SIGTSTP
    install_signal_handler(SIGTSTP, NULL, CBA0, 0);
#endif
#ifdef SIGTTIN
    install_signal_handler(SIGTTIN, NULL, CBA0, 0);
#endif
#ifdef SIGCONT
    install_signal_handler(SIGCONT, NULL, CBA0, 0);
#endif
#ifdef SIGTTOU
    install_signal_handler(SIGTTOU, NULL, CBA0, 0);
#endif
    install_signal_handler(SIGSEGV, NULL, CBA0, 0);
      signal(SIGPIPE, SIG_IGN);
}

#ifndef HAVE_SDL
#undef sdl
#endif

int term_attach_terminal(int in, int out, int ctl)
{
    /*struct terminal *term;*/
    dbg("attach_terminal\n");
    int fd[2];
    if (c_pipe(fd)) {
        error("ERROR: can't create pipe for internal communication");
        return -1;
    }
    fcntl(fd[0], F_SETFL, O_NONBLOCK);
    fcntl(fd[1], F_SETFL, O_NONBLOCK);
    handle_trm(in, out, out, fd[1], ctl);
    if ((term = init_term(fd[0], out, win_func))) {
        handle_basic_signals(term); /* OK, this is race condition, but it must be so; GPM installs it's own buggy TSTP handler */
        return fd[1];
    }

    close(fd[0]);
    close(fd[1]);
    return -1;
}

/*struct status dump_stat;*/
int dump_pos;

int ac;
char **av;

char *path_to_exe;

/*int init_b = 0;*/

char *tucnak_home = NULL;
int first_use = 0;
int first_contest_def = 0;

/*void get_system_name(void)
{
    FILE *f;
    char *p;
    memset(system_name, 0, MAX_STR_LEN);
    if (!(f = popen("uname -srm", "r"))) goto fail;
    if (fread(system_name, 1, MAX_STR_LEN - 1, f) <= 0) {
        pclose(f);
        goto fail;
    }
    pclose(f);
    for (p = system_name; *p; p++) if (*p < ' ') {
        *p = 0;
        break;
    }
    if (system_name[0]) return;
    fail:
    strcpy(system_name, SYSTEM_NAME);
} */

char *get_home(int *n)
{
    struct stat st;
    char *home = stracpy(getenv("HOME"));
    char *home_tucnak;
    char *config_dir = stracpy(getenv("CONFIG_DIR"));

    if (n) *n = 1;
    if (!home) {
        int i;
        home = stracpy(path_to_exe);
        if (!home) {
            if (config_dir) mem_free(config_dir);
            return NULL;
        }
        for (i = strlen(home) - 1; i >= 0; i--) if (dir_sep(home[i])) {
            home[i + 1] = 0;
            goto br;
        }
        home[0] = 0;
        br:;
    }
    while (home[0] && dir_sep(home[strlen(home) - 1])) home[strlen(home) - 1] = 0;
    if (home[0]) add_to_strn(&home, "/");
    home_tucnak = stracpy(home);
    if (config_dir)     
    {
        add_to_strn(&home_tucnak, config_dir);
        while (home_tucnak[0] && dir_sep(home_tucnak[strlen(home_tucnak) - 1])) home_tucnak[strlen(home_tucnak) - 1] = 0;
        if (stat(home_tucnak, &st) != -1 && S_ISDIR(st.st_mode)) {
            add_to_strn(&home_tucnak, "/tucnak");
            } else {
            fprintf(stderr, "CONFIG_DIR set to %s. But directory %s doesn't exist.\n\007", config_dir, home_tucnak);
            sleep(3);
            mem_free(home_tucnak);
            home_tucnak = stracpy(home);
            add_to_strn(&home_tucnak, "tucnak");        
        }
        mem_free(config_dir);
    } else add_to_strn(&home_tucnak, "tucnak");
    if (stat(home_tucnak, &st)) {
        if (!mkdir(home_tucnak, 0777)) goto home_creat;
        if (config_dir) goto failed;
        goto first_failed;
    }
    if (S_ISDIR(st.st_mode)) goto home_ok;
    first_failed:
    mem_free(home_tucnak);
    home_tucnak = stracpy(home);
    add_to_strn(&home_tucnak, "tucnak");
    if (stat(home_tucnak, &st)) {
        if (!mkdir(home_tucnak, 0777)) goto home_creat;
        goto failed;
    }
    if (S_ISDIR(st.st_mode)) goto home_ok;
    failed:
    mem_free(home_tucnak);
    mem_free(home);
    return NULL;

    home_ok:
    if (n) *n = 0;
    home_creat:
#ifdef HAVE_CHMOD
    chmod(home_tucnak, 0700);
#endif
    add_to_strn(&home_tucnak, "/");
    mem_free(home);
    return home_tucnak;
}

void init_home(void)
{
    tucnak_home = get_home(&first_use);
    if (!tucnak_home) {
        fprintf(stderr, "Unable to find or create tucnak config directory. Please check, that you have $HOME variable set correctly and that you have write permission to your home directory.\n\007");
        sleep(3);
        return;
    }
}

void init(void)
{
    parse_options(ac, av);
    if (opt_i){
#ifdef HAVE_SDL        
        sdl_info();
#endif
#ifdef HAVE_LINUX_PPDEV_H        
        parport_info();
#endif        
#ifdef HAVE_ALSA        
        alsa_info();
#endif        
#ifdef HAVE_LIBFTDI
        usb_info();
#endif
        exit(0);
    }
        
    g_thread_init(NULL);
    init_debug();

    init_trans();
    init_rc();
    term_spec_init();
      
    set_sigcld();
    init_home();
    init_keymaps();
    tpipe=init_threadpipe();
      
      read_rc_files();
      
#ifdef HAVE_SDL    
    sdl=init_sdl();
    if (sdl) handle_sdl_signals(); 

    if (sdl){
        if (!sdl_attach_terminal(get_input_handle(), get_output_handle(), get_ctl_handle())==-1){
            retval = RET_FATAL;
            terminate = 1;
        }
    }
    else
#endif
    {
        if (!term_attach_terminal(get_input_handle(), get_output_handle(), get_ctl_handle())==-1){
            retval = RET_FATAL;
            terminate = 1;
        }
    }
    if (!term) raise(SIGSEGV);
        
    
      glog = init_fifo(1000);        
    gtalk = init_fifo(1000);        
    gsked = init_fifo(1000);        

    

    
    cw = init_cw();
    dw = init_dw();
    wizz = init_wizz();
      namedb = init_namedb();
    sdevlist = init_sdevlist();
    init_rotars();
#ifdef HAVE_SDL    
    cor = init_cor();
#endif

    disable_screensaver();
    
    read_cw_files(cw);
    read_dw_files(dw);
    read_wizz_files(wizz);
      read_namedb_files(namedb);
      /*read_ebw_files(cw,namedb);*/
#ifdef HAVE_SDL    
    read_cor_files();
#endif
    
    init_sound();
    net = init_net();
    cwda = init_cwdaemon();
    dsp = init_dsp();
    ssbd = init_ssbd();

    spotdb = init_spotdb();
    
    
}

void terminate_all_subsystems(void)
{
#ifdef HAVE_SDL
    /*free_gfx();*/
#endif
    dbg("terminate_all_subsystems\n");
    check_bottom_halves();
    check_bottom_halves();
      check_bottom_halves();


#ifdef HAVE_SDL    
    sdl_stop_event_thread();
    free_cor(cor);
#endif
    free_dw(dw);
    free_cw(cw);
    free_wizz(wizz);
      free_namedb(namedb);
    free_rotars();
      free_sdevlist(sdevlist);
    free_spotdb(spotdb);
    free_net(net);
    free_cwdaemon(cwda);
    free_ssbd(ssbd);
    free_dsp(dsp);
    free_sound();
      free_threadpipe(tpipe);
    
    free_fifo(glog);
    free_fifo(gtalk);
    free_fifo(gsked);
      

    free_namelist();
    free_all_itrms();
    shrink_memory(1);

    free_history_lists();
    free_term_specs();
    free_keymaps();
    free_conv_table();
    check_bottom_halves();
    check_bottom_halves();
    destroy_terminal(CBA0);
#ifdef HAVE_SDL    
    free_sdl();
#endif

    if (tucnak_home) mem_free(tucnak_home);

    shutdown_trans();
    terminate_osdep();
    free_rc();
    check_memory_leaks();
    free_debug();
}

#if 0
gpointer func(gpointer data){
   raise(SIGSEGV); 
}
#endif

int main(int argc, char *argv[])
{
#if 0
    g_thread_init(NULL);
    debug_type=2;
    init_debug();
    ST_START;
    similar_calls("OK2M", "OK1ZIA",0,1);
    similar_calls("OK2M", "OK1KRQ",0,1);

    similar_calls("OK2M", "OK2",0,1);
    similar_calls("OK2M", "OKM",0,1);
    similar_calls("OK2M", "O2M",0,1);
    similar_calls("OK2M", "K2M",0,1);
    
    similar_calls("OK2M", "OK2X",0,1);
    similar_calls("OK2M", "OKXM",0,1);
    similar_calls("OK2M", "OX2M",0,1);
    similar_calls("OK2M", "XK2M",0,1);
    
    similar_calls("OK2M", "OK2MX",0,1);
    similar_calls("OK2M", "OK2XM",0,1);
    similar_calls("OK2M", "OKX2M",0,1);
    similar_calls("OK2M", "OXK2M",0,1);
    similar_calls("OK2M", "XOK2M",0,1);
    
    similar_calls("OK2M", "DK2M",0,1);
    similar_calls("OK2M", "DK3M",0,1);
    similar_calls("OK2M", "DK3O",0,1);
    similar_calls("OK2M", "DL2M",0,1);
    similar_calls("OK2M", "DL3M",0,1);
    similar_calls("OK2M", "DL3O",0,1);
    
    similar_calls("OK1KRQ", "OK1ZIA",0,1);

    similar_calls("OK1KRQ", "OK1KRQ",0,1);
    similar_calls("OK1KRQ", "OK1KR",0,1);
    similar_calls("OK1KRQ", "OK1KQ",0,1);
    similar_calls("OK1KRQ", "OK1RQ",0,1);
    similar_calls("OK1KRQ", "OKKRQ",0,1);
    similar_calls("OK1KRQ", "K1KRQ",0,1);
    
    similar_calls("OK1KRQ", "OK1KQR",0,1);
    similar_calls("OK1KRQ", "OK1RKQ",0,1);
    similar_calls("OK1KRQ", "OKK1RQ",0,1);
    similar_calls("OK1KRQ", "O1KKRQ",0,1);
    similar_calls("OK1KRQ", "KO1KRQ",0,1);

    similar_calls("OK1KRQ", "OK1KRX",0,1);
    similar_calls("OK1KRQ", "OK1KXQ",0,1);
    similar_calls("OK1KRQ", "OK1XRQ",0,1);
    similar_calls("OK1KRQ", "OKXKRQ",0,1);
    similar_calls("OK1KRQ", "OX1KRQ",0,1);
    similar_calls("OK1KRQ", "XK1KRQ",0,1);
    similar_calls("OK1KRQ", "OK1Q",0,1);
    ST_STOP;
    return;
#endif    
#if 0    
    GThread *thr;
    GError *gerr;
    gpointer ex;

    g_thread_init(NULL);
    thr=g_thread_create(func, NULL, 1,&gerr); 
    ex=g_thread_join(thr);
    printf("thread exited %p\n", ex);
    return(0);
#endif
    
#if 0    
    {
        void *p;
        init_debug();
        p=mem_alloc(10);
        p=mem_realloc(p, 20);
        mem_free(p);
                
        free_debug();
        check_memory_leaks();
        exit(0);
    }
#endif    
    
#if 0
    char *s;
    g_thread_init(NULL);
    init_debug();

    s=g_strdup("");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup(".");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("/");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("./");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("/.");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a./");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a/./");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("./b");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a./b");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a//b");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a/../b");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("../b/c");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a/..");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    s=g_strdup("a/../");
    printf("'%s'  ", s);
    s=optimize_path(s);
    printf(" '%s'\n", s);
    g_free(s);
    
    exit(1);
#endif    

    path_to_exe = argv[0];
    ac = argc;
    av = (char **)argv;

    starting_sbrk = (long int)sbrk;
/*    dbg("\n\n");*/
    select_loop(init);
    terminate_all_subsystems();

    
    return retval;
}


void shrink_memory(int u)
{
/*  shrink_dns_cache(u);
    shrink_format_cache(u);
    garbage_collection(u);
    delete_unused_format_cache_entries();*/
}

Generated by  Doxygen 1.6.0   Back to index