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

qsodb.c

/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2006  Ladislav Vaiz <ok1zia@nagano.cz>

    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"

struct contest *ctest;
struct band *aband;

char *mode_msg[]={
    "unspecified",
    "SSB",
    "CW",
    "SSBs CWr",
    "CWs SSBr",
    "AM",
    "FM",
    "RTTY",
    "SSTV",
    "ATV"   /* 9 */
};


int init_ctest(){
    /*dbg("init_ctest\n");*/
    if (ctest) return 0;

    ctest = g_new0(struct contest, 1);
    ctest->bands = g_ptr_array_new();
    ctest->bystamp = g_hash_table_new(g_str_hash, g_str_equal);

/*    ctest->serial = 1;*/
      ctest->minute_timer_id=install_timer(60000, timer_minute_stats_all, CBA0);
    return 0;
}

int new_ctest(char *tdate){
    struct stat st;
    int counter;
    time_t now;
    struct tm tm;
    gchar *c;
    int ret;
    static char s[1024]; /* for msg_box */
    int nowdate_int, ctestdate_int;

    now = time(NULL);
    gmtime_r(&now, &tm);
    
    if (tdate){ 
        ctest->cdate = g_strdup(tdate);
        nowdate_int = (tm.tm_year+1900)*10000 + (tm.tm_mon+1)*100 + tm.tm_mday;
        ctestdate_int = atoi(ctest->cdate);
        if (/*nowdate_int >= ctestdate_int && */nowdate_int <= ctestdate_int + 2) 
            ctest->recording = 1;
        else
            ctest->recording = 0;
    }else{
        ctest->cdate = g_strdup_printf("%4d%02d%02d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday );
        ctest->recording = 1;
    }
    
    
    ctest->directory = g_strdup_printf("%s/tucnak/%s",
            getenv("HOME"), ctest->cdate);
    
    
    counter=0;
    while (stat(ctest->directory,&st)==0){
        counter++;
        g_free(ctest->directory);
        ctest->directory = g_strdup_printf("%s/tucnak/%s.%d",
                getenv("HOME"), ctest->cdate, counter);
    }
        
    if (mkdir_p(ctest->directory,0770)){

        g_snprintf(s,1000, VTEXT(T_CANT_CREATE_HOME_S),ctest->directory);
        errbox(s,errno);
        free_ctest();
        return -1;
    }

    
    c = g_strdup_printf("%s/desc",ctest->directory);
    ctest->descfile = fopen(c,"wt");
    if (!ctest->descfile){
        g_snprintf(s,1000, "%s %s", VTEXT(T_CANT_WRITE),c);
        errbox(s,errno);
        g_free(c);
        free_ctest();
        return -1;
    }
    g_free(c);
    setvbuf(ctest->descfile, NULL, _IONBF, 0);
    
    if (lockf(fileno(ctest->descfile), F_TLOCK, 0)){
        g_snprintf(s,1000, "%s %s", VTEXT(T_CANT_LOCK),c);
        errbox(s,errno);
        free_ctest();
        return -1;
    }
    
    ret=fprintf(ctest->descfile,"%s %s %s\n",
            ctest->cdate, uc(ctest->pcall), ctest->tname);    
    fsync(fileno(ctest->descfile));
    
    
    if (ctest->logfile) {
        fclose(ctest->logfile);
        ctest->logfile=NULL;
    }
    
    c=g_strdup_printf("%s/log", ctest->directory);
    ctest->logfile = fopen(c, "at");
    if (!ctest->logfile){
        g_snprintf(s,1000, VTEXT(T_CANT_OPEN_S),c);
        g_free(c);
        msg_box(NULL, VTEXT(T_ERROR), AL_CENTER, s, NULL, 1, VTEXT(T_OK), NULL, B_ENTER | B_ESC);
        g_free(c);
        free_ctest();
        return -1;
    }
    g_free(c);
    setvbuf(ctest->logfile, NULL, _IONBF, 0);

    
    set_ctest_title();
#ifdef HAVE_SDL
      maps_reload();
#endif      
    
    return 0; 
}

int load_ctest_from_mem(struct contest *ctest, gchar *datedir, GHashTable *hash){

    ctest->directory = g_strdup(datedir); 
    
    STORE_HASH_STR(ctest, tname);
    STORE_HASH_STR(ctest, tdate);
    STORE_HASH_STR(ctest, pcall);
    STORE_HASH_STR(ctest, pwwlo);
    STORE_HASH_STR(ctest, pexch);
    STORE_HASH_STR(ctest, padr1);
    STORE_HASH_STR(ctest, padr2);
    STORE_HASH_STR(ctest, pclub);
    STORE_HASH_STR(ctest, rname);
    STORE_HASH_STR(ctest, rcall);
    STORE_HASH_STR(ctest, radr1);
    STORE_HASH_STR(ctest, radr2);
    STORE_HASH_STR(ctest, rpoco);
    STORE_HASH_STR(ctest, rcity);
    STORE_HASH_STR(ctest, rcoun);
    STORE_HASH_STR(ctest, rphon);
    STORE_HASH_STR(ctest, rhbbs);

    STORE_HASH_STR(ctest, default_rs);
    STORE_HASH_STR(ctest, default_rst);
    STORE_HASH_INT(ctest, qsoused);
    STORE_HASH_INT(ctest, qsomult);
    STORE_HASH_INT(ctest, dxcbonu);
    STORE_HASH_INT(ctest, dxcmult);
    STORE_HASH_INT(ctest, excused);
    STORE_HASH_INT(ctest, excbonu);
    STORE_HASH_INT(ctest, excmult);
    STORE_HASH_INT(ctest, qsoused);
    STORE_HASH_INT(ctest, qsomult);
    STORE_HASH_INT(ctest, qsop_method);
    STORE_HASH_INT(ctest, rstused);
    STORE_HASH_INT(ctest, total_method);
    STORE_HASH_INT(ctest, wwltype);
    STORE_HASH_INT(ctest, wwlused);
    STORE_HASH_INT(ctest, wwlbonu);
    STORE_HASH_INT(ctest, wwlmult);
    
    set_ctest_title();
/*#ifdef HAVE_SDL
      maps_reload();
#endif      */
   
    return 0; 
}



struct band *init_band(struct config_band *confb, 
                       GHashTable *opt_band){
    struct band *b;
    gchar *c;
    static char s[1024]; /* for msg_box */

    if (init_ctest()) return NULL;
    
    if (confb){
        b=find_band_by_pband(confb->pband); /*FIXME confb*/
        if (b) return b;
    }

    b=g_new0(struct band,1);

    b->qsos = g_ptr_array_new();
    b->mode  = MOD_SSB_SSB;
    b->bandmulti = 1;
    b->spymode = SM_INPUTLINE;
    if (confb){   /* usally new contest */
        b->bandchar = confb->bandchar;
        b->pband = g_strdup(confb->pband);
        
        b->readonly = confb->readonly;

        b->psect = confb->psect; /* gint */
        if (cfg->operator && *cfg->operator){
            b->operator = fixsemi(g_strdup(cfg->operator));
        }else{
            b->operator = fixsemi(g_strdup(get_raw_call(s,ctest->pcall)));
        }
        b->stxeq = g_strdup(confb->stxeq);
        b->spowe = g_strdup(confb->spowe);
        b->srxeq = g_strdup(confb->srxeq);
        b->sante = g_strdup(confb->sante);
        b->santh = g_strdup(confb->santh);
        b->mope1 = g_strdup(confb->mope1);
        b->mope2 = g_strdup(confb->mope2);
        b->remarks = g_strdup(confb->remarks);
            b->skedqrg = g_strdup(confb->skedqrg);
    }
    
    if (opt_band){ /* usually loading contest */
        GHashTable *hash = opt_band;
        gchar *ccc;

        STORE_HASH_STR(b, pband);   
        STORE_HASH_CHR(b, bandchar);
            if (!b->bandchar){
                struct config_band *tmpconfb;
                tmpconfb=get_config_band_by_pband(b->pband);
                if (tmpconfb) b->bandchar=tmpconfb->bandchar;
            }
        STORE_HASH_INT(b, mode);   
        STORE_HASH_STR(b, operator);
            if (!b->operator){
                b->operator = fixsemi(g_strdup(get_raw_call(s,ctest->pcall)));
            }
        
        ccc = g_hash_table_lookup(hash, "psect"); 
        /*dbg("c=%s\n",ccc);*/
        if (isdigit(ccc[0]))
            b->psect=atoi(ccc);
        else
            b->psect=get_psect_int(ccc);
                
        STORE_HASH_INT(b, readonly);
        STORE_HASH_INT(b, saveid);
        b->saveid++;
        STORE_HASH_STR(b, stxeq);
        STORE_HASH_STR(b, spowe);
        STORE_HASH_STR(b, srxeq);
        STORE_HASH_STR(b, sante);
        STORE_HASH_STR(b, santh);
/*        STORE_HASH_INT(b, mode);*/
        STORE_HASH_STR(b, mope1);
        STORE_HASH_STR(b, mope2);
 /*        STORE_HASH_STR(b, remarks); NO */
            STORE_HASH_STR(b, skedqrg);
        if (!b->skedqrg) b->skedqrg=g_strdup("");
    }    

    b->spypeers=g_ptr_array_new();
    
    b->il = g_new0(struct inputln,1);
    b->il->term = term;
    b->il->enter = process_input;
    b->il->enterdata = (void *)b;
    b->il->upconvert = 1;
    b->il->readonly  = b->readonly;
    b->il->band = b;

    {
        struct event ev = {EV_INIT, 0,0,0};
        inputln_func(b->il,&ev);
    }

    b->stats = init_stats();
    b->tmpstats = init_stats();
    b->stats_mutex = g_mutex_new();
    
    c = g_strdup_printf("%s/%c.swp",ctest->directory,b->bandchar);
            
    clear_tmpqsos(b);
    
    if (!aband){
        aband=b;
        il_set_focus(aband->il);
    }
    
    b->swap = fopen(c,"at");
    if (!b->swap){
        log_addf(VTEXT(T_CANT_APPEND_S),c);
        g_free(c);
        free_band(b);
        return NULL;
    }
    g_free(c);
    fprintf(b->swap, "ST %d\n", b->saveid-1);

   
    b->swapfifo = init_fifo(500);
    b->qs = g_ptr_array_new();
    b->oqs = g_ptr_array_new();
    b->unfi = init_fifo(100);        
    b->statsfifo1 = init_fifo(1000);        
    
    g_ptr_array_add(ctest->bands, b);
    ctest->qrv|=1<<(upcase(b->bandchar)-'A');
    aband->tmplocqso.band=aband;
    
/*    init_spypeer(b->spypeers, "127.0.0.1:55555");
    init_spypeer(b->spypeers, "127.0.0.1:55556");*/
    
    return b;
}


struct band *find_band_by_pband(char *pband){
    int i;
    struct band *b;

    if (!ctest) return NULL;
    
    for (i=0;i<ctest->bands->len; i++){
        b = g_ptr_array_index(ctest->bands,i);
        if (!pband) continue;
        if (strcasecmp(pband, b->pband)==0){
            return b;
        }
    }
    return NULL;
}

struct band *find_band_by_bandchar(char bandchar){
    int i;
    struct band *b;

    for (i=0;i<ctest->bands->len; i++){
        b = g_ptr_array_index(ctest->bands,i);
        if (lowcase(bandchar)==lowcase(b->bandchar)){
            return b;
        }
    }
    return NULL;
}


struct band *init_qrv_bands(){
    int i;
    struct config_band *confb;

    /*dbg("init_qrv_bands\n");*/
    for (i=0;i<cfg->bands->len; i++){
        confb = g_ptr_array_index(cfg->bands,i);
        if (!confb) continue;
        if (confb->qrvnow){
            init_band(confb, NULL);
        }
    }
    return NULL;
}



void clear_tmpqsos(struct band *b){
    int i;
    char *c;

    if (!b) return;

    b->dupe_in_tmpqso = 0;
    b->last_item = LI_NONE;

    for(i=0;i<TMP_QSOS;i++){
        CLEAR_TMPQSO_STRING(b,date_str);
        CLEAR_TMPQSO_STRING(b,time_str);
        CLEAR_TMPQSO_STRING(b,callsign);
        CLEAR_TMPQSO_STRING(b,rsts);
        CLEAR_TMPQSO_STRING(b,rstr);
        CLEAR_TMPQSO_STRING(b,qsonrs);
        CLEAR_TMPQSO_STRING(b,qsonrr);
        CLEAR_TMPQSO_STRING(b,locator);
        CLEAR_TMPQSO_STRING(b,exc);
        CLEAR_TMPQSO_STRING(b,name);

        CLEAR_TMPQSO_GINT(b,qrb);/* qrb is double */
        CLEAR_TMPQSO_QTF(b);
        CLEAR_TMPQSO_GINT(b,ucallsign);
        CLEAR_TMPQSO_GINT(b,ulocator);
        CLEAR_TMPQSO_GINT(b,uexc);
        CLEAR_TMPQSO_GINT(b,uqrb);
        CLEAR_TMPQSO_GINT(b,uqtf);
        CLEAR_TMPQSO_GINT(b,suspcallsign);
        CLEAR_TMPQSO_GINT(b,susplocator);
        CLEAR_TMPQSO_GINT(b,suspexc);
        CLEAR_TMPQSO_GINT(b,qsl);
        CLEAR_TMPQSO_STRING(b,remark);
    } 
    CONDGFREE(b->unres);
    CONDGFREE(b->qrv_str);
    wkd_tmpqso(aband, WT_CLEAR, "");
    if (ctest->qsoused){
        c=g_strdup_printf("%03d",b->qsos->len+1);
        ADD_TMPQSO_STRING(b,qsonrs,c,1,udummy);
        wkd_tmpqso(b, WT_QSONRS, c);
        g_free(c);
    }

    default_rst_to_tmpqsos(b);
    ssbd_callsign(ssbd, "");

}

void default_rst_to_tmpqsos(struct band *b){
    gchar *c;
    int i;
    
      if (!ctest) return;
    for(i=0;i<TMP_QSOS;i++)  CLEAR_TMPQSO_STRING(b,rsts);

    /*if (!ctest->qsoused) return;*/
    
    if (b->mode == MOD_CW_CW)
        c=g_strdup(cfg->default_rst);
    else
        c=g_strdup(cfg->default_rs);
       
    ADD_TMPQSO_STRING(b,rsts,c,1,udummy);
    wkd_tmpqso(b, WT_RSTS, c);
    g_free(c);
}
       
#define APPEND_Q(item) \
    if (item) g_string_append(gs, item);
    
int write_qso_to_swap(struct band *b, struct qso *q){
    GString *gs;

    gs = g_string_new("Q ");
    
    add_qso_str1(gs, q, b);
    add_qso_str3(gs, q, b);
    
    /*fprintf(b->swap, "%s\n", gs->str);*/
    fprintf(b->swap, "%s  qrb=%4.1f\n", gs->str,q->qrb);
    fflush(b->swap);
    fifo_adds(b->swapfifo, gs->str);
    g_string_free(gs, TRUE);
    return 0;
}

/* after adding you must call g_index_array_qsort */
void add_qso(struct band *b, struct qso *q){
    q->band = b; /* don't dealloc! */
    /*q->serial = ctest->serial++;*/
    
    stats_thread_kill(b);
    g_ptr_array_add(b->qsos,q);
    add_qso_to_index(q, 0);
    dirty_band(b);
}

struct qso *get_qso(struct band *b, gint i){
    
    if (i<0 || i >=b->qsos->len) return NULL;
    return g_ptr_array_index(b->qsos, i);
}

struct qso *get_qso_by_callsign(struct band *b, gchar *callsign){
    struct qso *qso;
    int i;
    char raw[25], qraw[25];

    get_raw_call(raw, callsign);
    
              /* TODO callsigns in hash */
    for(i=0;i<b->qsos->len; i++){
        qso = g_ptr_array_index(b->qsos, i);

        if (qso->error) continue;
        
        get_raw_call(qraw, qso->callsign);
        if (strcasecmp(raw, qraw)==0) return qso;
    }
    return NULL;
}

struct qso *get_qso_by_id(struct band *b, gchar *source, gint ser_id){
    struct qso *qso;
    int i;
            
      /* TODO id's in hash */
      /*dbg("get_qso_by_id(src=%s, ser_id=%d) \n", source, ser_id);*/
    for(i=0;i<b->qsos->len; i++){
        qso = g_ptr_array_index(b->qsos, i);

            /*dbg("           %s %s %d ",qso->callsign, qso->source, qso->ser_id);*/
        if (ser_id != qso->ser_id) continue;
        if (strcasecmp(source, qso->source)!=0) continue;
            /*dbg("           OK\n");*/
        return qso;
    }
      /*dbg("           NULL\n");*/
    return NULL;
}

struct qso *get_qso_by_qsonr(struct band *b, gint qsonrs){
    struct qso *qso;
    int i;
              /* TODO id's in hash */
    for(i=0;i<b->qsos->len; i++){
        qso = g_ptr_array_index(b->qsos, i);

        if (qsonrs != atoi(qso->qsonrs)) continue;
        return qso;
    }
    return NULL;
}

void add_error(struct band *b, gchar *remark){
    struct qso *eq;
    time_t now;
    struct tm utc;

    if (!ctest && !b) return;
    if (b->readonly) return;

    log_addf("added ERROR for band %c, qsonr %d\n", b->bandchar, b->qsos->len+1);
    
    time(&now);
    gmtime_r(&now, &utc);
           
    eq = g_new0(struct qso, 1);
    eq->source   = g_strdup(net->myid);
    eq->operator = g_strdup(b->operator);
    if (b->tmpqsos[0].date_str){
        eq->date_str = g_strdup(b->tmpqsos[0].date_str);
        eq->time_str = g_strdup(b->tmpqsos[0].time_str);
    }else{
       eq->date_str = g_strdup_printf("%4d%02d%02d",1900+utc.tm_year, 1+utc.tm_mon, utc.tm_mday);
       eq->time_str = g_strdup_printf("%02d%02d",utc.tm_hour, utc.tm_min);    
    }
    eq->callsign = g_strdup(b->tmpqsos[0].callsign&&b->tmpqsos[0].ucallsign?b->tmpqsos[0].callsign:"ERROR");    
    eq->rsts     = g_strdup(b->tmpqsos[0].rsts?b->tmpqsos[0].rsts:"");        
    eq->rstr     = g_strdup(b->tmpqsos[0].rstr?b->tmpqsos[0].rstr:"");    
    eq->qsonrs   = g_strdup(b->tmpqsos[0].qsonrs?b->tmpqsos[0].qsonrs:"");    
    eq->qsonrr   = g_strdup(b->tmpqsos[0].qsonrr?b->tmpqsos[0].qsonrr:"");    
    eq->exc      = g_strdup(b->tmpqsos[0].exc?b->tmpqsos[0].exc:"");    
    eq->locator  = g_strdup(b->tmpqsos[0].locator&&b->tmpqsos[0].ulocator?b->tmpqsos[0].locator:"");    
    eq->error    = 1;
    eq->remark   = g_strdup(remark?remark:"");
    eq->ser_id   = -1;  /* computed by add_qso_to_index */
    
    add_qso(b, eq);
    stats_thread_join(b);
    update_stats(b, b->stats, eq);
      minute_stats(b);
    recalc_statsfifo(b);
    
    if (b->qsos->len+1 != atoi(b->tmpqsos[0].qsonrs)){
        g_free(b->tmpqsos[0].qsonrs);
        if (ctest->qsoused)
            b->tmpqsos[0].qsonrs = g_strdup_printf("%03d", b->qsos->len+1);
        else
            b->tmpqsos[0].qsonrs = g_strdup("");
    }
    wkd_tmpqso(aband, WT_QSONRS, TMPQ.qsonrs);

    replicate_qso(NULL, eq);
    redraw_later();
    check_autosave();

}

/* use update_stats() after this */
void qso_mark_as_error(struct band *b, gint i){
    struct qso *qso;
    
    qso = g_ptr_array_index(b->qsos, i);
    qso->error = 1;
    qso->qsop = 0;
    dirty_band(b);
    replicate_qso(NULL, qso);
}

int add_tmpxchg(struct band *band, gchar *xchg){
    if (band->ignoreswap) return -1;
    fprintf(band->swap, "# %s\n", xchg);
    fflush(band->swap);
    fifo_adds(band->swapfifo, xchg );
    return 0;
}

int add_swap(struct band *band, gchar *s){
    if (band->ignoreswap) return -1;
    fprintf(band->swap, "%s\n", s);
    fflush(band->swap);
    fifo_adds(band->swapfifo, s);
    return 0;
}



void activate_band(struct band *b){
    struct event ev={EV_RESIZE, 0, 0, 0};
    
    /*dbg("activate_band(ses=%p,b=%p) %c\n",ses,b);*/
    /* dbg("aband=%p\n",aband);*/
    if (!b) return;


    
    il_unset_focus(aband->il);
    aband=b;
    sw_all_func(&ev, 1);
/*    sw_default_func(gses->ontop, &ev, 1);*/
    gses->ontop->check_bounds(gses->ontop);
    sw_unset_focus();
    il_set_focus(aband->il);
    get_band_qs(aband, aband->il->cdata);
    get_oband_qs(aband, aband->il->cdata);
    get_cw_qs(aband->il->cdata);
    
    if (gses->ontop && gses->ontop->type == SWT_STAT)
        recalc_statsfifo(b);

    redraw_later();
      maps_reload();
}




struct config_band *get_config_band_by_bandchar(char bandchar){
    struct config_band *confb;
    int i;

    bandchar = upcase(bandchar);
    
    for (i=0;i<cfg->bands->len;i++){
        confb = g_ptr_array_index(cfg->bands, i);
        if (bandchar == upcase(confb->bandchar))
            return confb;
    }
    return NULL;
}

struct config_band *get_config_band_by_pband(char *pband){
    struct config_band *confb;
    int i;

    for (i=0;i<cfg->bands->len;i++){
        confb = g_ptr_array_index(cfg->bands, i);
        if (strcasecmp(pband, confb->pband)==0)
            return confb;
    }
    return NULL;
}

struct config_band *get_config_band_by_qrg(int qrg){ /* kHz */
    struct config_band *confb;
    int i;

    for (i=0;i<cfg->bands->len;i++){
        confb = g_ptr_array_index(cfg->bands, i);
        if (qrg>=confb->qrg_min && qrg<=confb->qrg_max)
            return confb;
    }
    return NULL;
}

#if 0

int add_qsos_from_swap(struct band *b, FILE *f){
    char s[1025];
    gchar **items;
    struct qso *q;
   
    clear_stats(b->stats);
    
    while ((fgets(s, 1024, f))!=NULL){
        if (s[0]=='#') continue;

        
        items = g_strsplit(s, ";", 0);
        q = g_new0(struct qso, 1);
        q->date_str = g_strdup(items[0]);
        q->time_str = g_strdup(items[1]);
        q->callsign = g_strdup(items[2]);
        q->mode     = atoi(items[3]);
        q->rsts     = g_strdup(items[4]);
        q->qsonrs   = g_strdup(items[5]);
        q->rstr     = g_strdup(items[6]);
        q->qsonrr   = g_strdup(items[7]);
        q->exc      = g_strdup(items[8]);
        q->locator  = g_strdup(items[9]);
    q->ser_id=-1; /* computed by add_qso_to_index */
        
        g_strfreev(items);
        compute_qrbqtf(q);
        
        add_qso(b, q);
        update_stats(b, q);
    }
    check_autosave();
    
}

#endif


void foreach_add_latests_str(gpointer key, gpointer value, gpointer data){
    GIndexArray *ia;
    GString *gs;
    struct qso *q;

    ia = (GIndexArray *)value;
    gs = (GString *)data;
    
    if (ia->len<=0) return;
    if (strcmp(key,"neterr")==0) return;
    q = (struct qso *) g_index_array_index(ia, ia->len - 1);
    if (q){
        g_string_sprintfa(gs, "%s;%d;", (char *)key, (int)q->stamp);
    }else{ /* not reached, NULL can be only in the middle of iarray */
        dbg("ERROR! q is NULL (foreach_add_latests_str)\n");
        g_string_sprintfa(gs, "%s;NULL;", (char *)key);
    }
}

gchar *get_latests_str(){
    GString *gs;
    gchar *c;

    gs = g_string_new("LA ");
    
    g_hash_table_foreach(ctest->bystamp, foreach_add_latests_str, gs);
    /*dbg("get_latests_str='%s'\n", gs->str);*/
    g_string_append(gs, "\n");
    c = g_strdup(gs->str);
    g_string_free(gs, 1);
    return c;
}

int compare_stamp(const void *a, const void *b){
    struct qso **qa, **qb;

    qa = (struct qso **)a;
    qb = (struct qso **)b;
    
    if (!*qa && !*qb) return 0;
    if (!*qa) return -1;
    if (!*qb) return +1;
    return (*qa)->stamp - (*qb)->stamp;
}

/* only for backward compatibility with version without ser_id in edi file */
void foreach_source_recalc_ser_id(gpointer key, gpointer value, gpointer data){
      int i;
      struct qso *q;
    GIndexArray *ia;

    ia = (GIndexArray *)value;

      for (i=0; i<ia->len; i++){
            q=(struct qso *)g_index_array_index(ia, i);
            q->ser_id=i;
      }
} 

void foreach_source_qsort_by_stamp(gpointer key, gpointer value, gpointer data){
    GIndexArray *ia;

    ia = (GIndexArray *)value;
    g_index_array_qsort(ia, compare_stamp);
}

void foreach_source_print(gpointer key, gpointer value, gpointer data){
    GIndexArray *ia;
    struct qso *q;
    int i;

    ia = (GIndexArray *)value;
    dbg_qsos("source: %s", key);

    for (i=0; i<ia->len; i++){
        q = (struct qso *) g_index_array_index(ia, i);   
        dump_qso(q, "foreach_source_print");
    }
}

void dump_all_sources(struct contest *ctest){
    if (!ctest){
        dbg_qsos("dump_all_sources(NULL)\n");
        return;
    }
    g_hash_table_foreach(ctest->bystamp, foreach_source_print, NULL);
    dbg_qsos("---end---");
}

void add_qso_to_index(struct qso *q, int qsort_if_needed){
    GIndexArray *ia;
    struct qso *ql;
    
    if (q && q->source && strcmp(q->source,"neterr")==0) return;
    
    ia = (GIndexArray *) g_hash_table_lookup(ctest->bystamp, q->source);
    if (!ia) {
        ia = g_index_array_new();
        g_hash_table_insert(ctest->bystamp, g_strdup(q->source), ia);
    }
        
      if (q->ser_id==-1) q->ser_id=ia->len; /* ia is NOT sorted by ser_id! */
    g_index_array_add(ia, q);

    if (qsort_if_needed && ia->len >= 2){
        ql = (struct qso *) g_index_array_index(ia, ia->len-2);
        if (ql->stamp > q->stamp){ /* q is not latest */
            g_index_array_qsort(ia, compare_stamp);
            }
    }
}

void remove_qso_from_index(struct qso *q){
    GIndexArray *ia;
    int ret;
    
    ia = (GIndexArray *) g_hash_table_lookup(ctest->bystamp, q->source);
    ret=g_index_array_remove(ia, q);
    dbg("remove: ret=%d\n", ret);
}

void compute_qrbqtf(struct qso *q){
    double qtf, qtfrad;
    
    if (!q) return;
    /* CHANGE look at add_tmpqso_locator */    
    qrbqtf(ctest->pwwlo, q->locator, &q->qrb, &qtf, NULL, 2);
    q->qtf = (int) (qtf+0.5);
    if (q->qrb < 0.1) {
        q->qrb = 0;
        q->qtf = 0;
    }
    qtfrad=qtf*MY_PI/180.0;
    q->kx =   q->qrb*sin(qtfrad);
    q->ky = - q->qrb*cos(qtfrad);
    /*dbg("compute_qrbqtf(%s) %s->%s qrb=%f qtf=%d kx=%d ky=%d\n", 
            q->callsign, ctest->pwwlo, q->locator, q->qrb, q->qtf, q->kx, q->ky); */
}



int check_autosave(void){
    time_t now;

    now = time(NULL);
    
/*    if (cfg->as_disk_aq){
        if (!ctest->as_disk_qsonr){*/
            save_all_bands_txt(1);
/*            ctest->as_disk_qsonr = cfg->as_disk_aq;
        }
        ctest->as_disk_qsonr--;
    }*/

    if (cfg->as_floppy_aq){
        if (!ctest->as_floppy_qsonr){
            save_all_bands_txt(2);
            ctest->as_floppy_qsonr = cfg->as_floppy_aq;
        }
        ctest->as_floppy_qsonr--;
    }
    return 0;
}

typedef unsigned chartype;

char *my_strstr(const char *phaystack, const char *pneedle){
    register const unsigned char *haystack, *needle;
    register chartype b, c;

    haystack = (const unsigned char *) phaystack;
    needle = (const unsigned char *) pneedle;

    b = *needle;
    if (b != '\0'){
        if (b != '.' && b != '?'){
            haystack--;             /* possible ANSI violation */
            do{
                c = *++haystack;
                if (c == '\0') goto ret0;
            }while (c != b);
        }
        c = *++needle;
        if (c == '\0') goto foundneedle;
        ++needle;
        goto jin;

        for (;;){
            register chartype a;
            register const unsigned char *rhaystack, *rneedle;

            do{
                a = *++haystack;
                if (a == '\0') goto ret0;
                if (a == b) break;
                a = *++haystack;
                if (a == '\0') goto ret0;
shloop:;
            }while (a != b && b != '.' && b != '?');

jin:;     
            a = *++haystack;
            if (a == '\0') goto ret0;
            if (c!='.' && c!='?' && a != c)    goto shloop;

            rhaystack = haystack-- + 1;
            rneedle = needle;
            a = *rneedle;

            if (*rhaystack == a || a=='.' || a=='?')
                do{
                    if (a == '\0') goto foundneedle;
                    ++rhaystack;
                    a = *++needle;
                    if (a!='.' && a!='?'){
                        if (*rhaystack != a) break;
                    }
                    if (a == '\0') goto foundneedle;
                        
                    ++rhaystack;
                    a = *++needle;
                }while (*rhaystack == a || a == '.' || a=='?');

            needle = rneedle;       /* took the register-poor approach */

            if (a == '\0') break;
        }
    }
foundneedle:;
    return (char*) haystack;
ret0:;
    return 0;
}


char *my_strcasestr(const char *phaystack, const char *pneedle){
    register const unsigned char *haystack, *needle;
    register chartype b, c;

    haystack = (const unsigned char *) phaystack;
    needle = (const unsigned char *) pneedle;

    b = tolower(*needle);
    if (b != '\0'){
            haystack--;             /* possible ANSI violation */
            do{
                c = tolower(*++haystack);
                if (c == '\0') goto ret0;
            }while (c != b);
        c = tolower(*++needle);
        if (c == '\0') goto foundneedle;
        ++needle;
        goto jin;

        for (;;){
            register chartype a;
            register const unsigned char *rhaystack, *rneedle;

            do{
                a = tolower(*++haystack);
                if (a == '\0') goto ret0;
                if (a == b) break;
                a = tolower(*++haystack);
                if (a == '\0') goto ret0;
shloop:;
            }while (a != b);

jin:;     
            a = tolower(*++haystack);
            if (a == '\0') goto ret0;
            if (a != c)    goto shloop;

            rhaystack = haystack-- + 1;
            rneedle = needle;
            a = tolower(*rneedle);

            if (tolower(*rhaystack) == a)
                do{
                    if (a == '\0') goto foundneedle;
                    ++rhaystack;
                    a = tolower(*++needle);
                        if (tolower(*rhaystack) != a) break;
                    if (a == '\0') goto foundneedle;
                        
                    ++rhaystack;
                    a = tolower(*++needle);
                }while (tolower(*rhaystack) == a);

            needle = rneedle;       /* took the register-poor approach */

            if (a == '\0') break;
        }
    }
foundneedle:;
    return (char*) haystack;
ret0:;
    return 0;
}


GPtrArray *get_band_qs(struct band *band, gchar *str){
    int i, len;
    gchar *c;
    struct qs *qs;
    struct qso *qso;

    /*ST_START;*/
    g_ptr_array_free_items(band->qs);

    len = strlen(str);
    if (len<2) return NULL;
    
    qs = g_new0(struct qs, 1);
    qs->result1 = band->qs;
    qs->str = str;


    for (i=0;i<band->qsos->len;i++){
        qso = (struct qso *)g_ptr_array_index(band->qsos, i);
        if (qso->error || qso->dupe) continue;
        if (qs->result1->len == term->y - QSONR_HEIGHT - 4 - cfg->loglines - band->spypeers->len - 1) break;
        
        if (qso->callsign && my_strstr(qso->callsign, qs->str)){
            if (qso->locator)
                c=g_strdup_printf("%-10s %-6s%5d/%3d", qso->callsign, qso->locator, (int)qso->qrb, qso->qtf);
            else
                c=g_strdup(qso->callsign);
/*            dbg(",%s", c);*/
            g_ptr_array_add(qs->result1, c);
            continue;
        }
        
        if (qso->locator && my_strstr(qso->locator, qs->str)){
            if (qso->callsign) 
                c=g_strdup_printf("%-10s %-6s%5d/%3d", qso->callsign, qso->locator, (int)qso->qrb, qso->qtf);
            else
                c=g_strdup_printf("%-10s %-6s%5d/%3d", "", qso->locator, (int)qso->qrb, qso->qtf);
/*            dbg(",%s", c);*/
            g_ptr_array_add(qs->result1, c);
            continue;                 
        }
        
    }
/*    dbg("<\n");*/
    
    g_free(qs);
    g_index_array_qsort((GIndexArray *)band->qs, compare_gstring);
    /*ST_STOP;*/
    return band->qs;
}

GPtrArray *get_oband_qs(struct band *oband, gchar *str){
    int i, len, j;
    gchar *c;
    struct qs *qs;
    struct qso *qso;

    /*ST_START;*/
    if (ctest->bands->len<2) return oband->oqs;
    
    g_ptr_array_free_items(oband->oqs);

    len = strlen(str);
    if (len<2) return NULL;
    
    qs = g_new0(struct qs, 1);
    qs->result1 = oband->oqs;
    qs->str = str;

    for (j=0;j<ctest->bands->len;j++){
        struct band *band;
        
        band = (struct band *)g_ptr_array_index(ctest->bands, j);
        if (band==oband) continue;
        
        for (i=0;i<band->qsos->len;i++){
            qso = (struct qso *)g_ptr_array_index(band->qsos, i);
            if (qso->error || qso->dupe) continue;
            if (qs->result1->len == term->y - QSONR_HEIGHT - 4 - cfg->loglines - oband->spypeers->len - 1) break;
            /* FIXME contest without locator */
            if ((qso->callsign && my_strstr(qso->callsign, qs->str))||
                (qso->locator  && my_strstr(qso->locator, qs->str))){    
                
                int j;

                for (j=0;j<qs->result1->len; j++){
                    char d[20], *pd, *line;
                    
                    safe_strncpy(d, line=g_ptr_array_index(qs->result1,j), 10);
                    pd = index(d, ' ');
                    if (pd) *pd='\0';
                    
                    if (strcmp(d, qso->callsign)==0){ 
/*                        dbg("add %s %c\n", line, band->bandchar);*/
                        c = g_strdup_printf("%s%c", line, upcase(band->bandchar));
                        g_ptr_array_index(qs->result1, j) = c;
                        g_free(line);
                        goto cont;
                    }
                }
/*                dbg("ins %s %s %c\n", qso->callsign, qso->locator, band->bandchar);*/
                c=g_strdup_printf("%-10s %-6s %c", qso->callsign, qso->locator, upcase(band->bandchar));
                set_mem_comment(c, c, strlen(c));
                g_ptr_array_add(qs->result1, c);
                goto cont;
            }
cont:;                
        }
    }
/*    dbg("<\n");*/
    
    g_free(qs);
    g_index_array_qsort((GIndexArray *)oband->oqs, compare_gstring);
    /*ST_STOP;*/
    return oband->oqs;
}


gchar *find_wwl_by_oband(struct band *oband, gchar *call){
    int i, j;
    struct qso *qso;
    static char raw[256];

    if (ctest->bands->len<2) return NULL;
    if (!ctest->wwlused) return NULL;
    
    ST_START;
    for (j=0;j<ctest->bands->len;j++){
        struct band *band;
        
        band = (struct band *)g_ptr_array_index(ctest->bands, j);
        if (band==oband) continue;
        
        for (i=0;i<band->qsos->len;i++){
            qso = (struct qso *)g_ptr_array_index(band->qsos, i);
            if (qso->error || qso->dupe) continue;
            get_raw_call(raw, qso->callsign);
            if (strcasecmp(raw,call)) continue;
            return qso->locator; /* can be NULL */
        }
    }
    ST_STOP;
    return NULL;
}


char *get_raw_call(char *buf, char *call){
    char s[20], *c;
    char *token_ptr;

    safe_strncpy0(s,call,20);
   
    for (c=strtok_r(s, "/", &token_ptr); c!=NULL; c=strtok_r(NULL, "/", &token_ptr)){ 
        if (strlen(c)<3) continue;
        if (strlen(c)==3 && c[2]>='0' && c[2]<='9') continue;
          /*  3rd char cannot be number , OK1 vs G8M */
        safe_strncpy0(buf, c, 20);  
        return buf;
    }
    safe_strncpy0(buf, call, 20);  
    return buf;
}


int get_psect_int(char *psect){
    if (strcasecmp(psect, "single")==0) return 1;
    else if (strcasecmp(psect, "check")==0) return 2;
    else return 0;
}

void dump_qso(struct qso *q, char *desc){
    if (!q){
        dbg_qsos("  NULL");
        return;
    }
   /* dbg_qsos("  %8s %c%03d %s:%d.%05d  %s", q->callsign, upcase(q->band->bandchar), atoi(q->qsonrs), q->source, q->ser_id, q->stamp%100000, desc);*/
    dbg_qsos("  %8s %c%03d %s:%d.%05d  (qsop=%d error=%d dupe=%d) %s", q->callsign, upcase(q->band->bandchar), atoi(q->qsonrs), q->source, q->ser_id, q->stamp%100000, q->qsop, q->error, q->dupe,  desc);
}

void invalidate_tmpqso(struct band *b, struct qso *q){
    char raw[20];
    char s[20];
    int i;

    get_raw_call(raw, q->callsign);
    for (i=0;i<TMP_QSOS;i++){
        get_raw_call(s, b->tmpqsos[i].callsign);
        if (strcasecmp(s, raw)==0){
            b->tmpqsos[i].ucallsign=0;   
            redraw_later();
        }
    }
}

void foreach_free_bystamp(gpointer key, gpointer value, gpointer data){
    GIndexArray *ia;

    ia = (GIndexArray *)value;
    g_index_array_free(ia, TRUE);
    g_free(key);

}
    
void free_ctest(){
    int i;

    if (!ctest) return;


      kill_timer(ctest->minute_timer_id);
      
    dump_all_sources(ctest);
    
    if (gses->last_cq_timer_id) {
        kill_timer(gses->last_cq_timer_id);
        gses->last_cq_timer_id = 0;
    }
    

    for (i=0;i<ctest->bands->len; i++){
        free_band(g_ptr_array_index(ctest->bands,i));
    }

    if (ctest->descfile)  fclose(ctest->descfile);
    if (ctest->logfile)   fclose(ctest->logfile);
    CONDGFREE(ctest->directory);
    CONDGFREE(ctest->cdate);
    CONDGFREE(ctest->tname);
    CONDGFREE(ctest->tdate);
    CONDGFREE(ctest->pcall);
    CONDGFREE(ctest->padr1);
    CONDGFREE(ctest->padr2);
    CONDGFREE(ctest->pclub);
    CONDGFREE(ctest->pwwlo);
    CONDGFREE(ctest->pexch);
    CONDGFREE(ctest->default_rs);
    CONDGFREE(ctest->default_rst);
    
    CONDGFREE(ctest->rname);
    CONDGFREE(ctest->rcall);
    CONDGFREE(ctest->radr1);
    CONDGFREE(ctest->radr2);
    CONDGFREE(ctest->rpoco);
    CONDGFREE(ctest->rcity);
    CONDGFREE(ctest->rcoun);
    CONDGFREE(ctest->rphon);
    CONDGFREE(ctest->rhbbs);
    
    CONDGFREE(ctest->directory);
/*    CONDGFREE(ctest->pband);
    CONDGFREE(ctest->);
    CONDGFREE(ctest->);
    CONDGFREE(ctest->);
  */

    g_hash_table_foreach(ctest->bystamp, foreach_free_bystamp, NULL); 
    g_ptr_array_free(ctest->bands, TRUE);
    if (ctest->redraw_timer_id) kill_timer(ctest->redraw_timer_id);
    g_free(ctest);
    ctest=NULL;
    aband=NULL;
    
    set_ctest_title();
    cq_abort(0);
    if (!terminate) maps_reload();
}



/* called ONLY when ctest is freeed. bands remain in memory */
void free_band(struct band *b){
    int i;
    struct event ev = {EV_ABORT, 0,0,0};

    stats_thread_kill(b);
    clear_tmpqsos(b);
    if (b->tmpqsos[0].qsonrs) g_free(b->tmpqsos[0].qsonrs);
    if (b->tmpqsos[0].rsts)   g_free(b->tmpqsos[0].rsts);

    for (i=0;i<b->qsos->len;i++){
        struct qso *qso;
        qso=g_ptr_array_index(b->qsos, i);
        free_qso(qso);
    }
    
    CONDGFREE(b->pband);
    CONDGFREE(b->operator);
    CONDGFREE(b->stxeq);
    CONDGFREE(b->spowe);
    CONDGFREE(b->srxeq);
    CONDGFREE(b->sante);
    CONDGFREE(b->santh);
    CONDGFREE(b->mope1);
    CONDGFREE(b->mope2);
    CONDGFREE(b->remarks);
      CONDGFREE(b->skedqrg);
    /*CONDGFREE(b->);
    CONDGFREE(b->);
    CONDGFREE(b->);
    CONDGFREE(b->);*/
    
    
    
    inputln_func(b->il,&ev);
    g_free(b->il);
    if (b->unres) g_free(b->unres);
    if (b->stats) free_stats(b->stats);
    if (b->tmpstats) free_stats(b->tmpstats);
    g_mutex_free(b->stats_mutex);
    if (b->swap) fclose(b->swap);
    if (b->qs)  g_ptr_array_free_all(b->qs);
    if (b->oqs) g_ptr_array_free_all(b->oqs);
    if (b->swapfifo)  free_fifo(b->swapfifo);
    if (b->unfi)      free_fifo(b->unfi);
    if (b->statsfifo1) free_fifo(b->statsfifo1);
    if (b->ctrlsp)    g_free(b->ctrlsp);
    free_spypeers(b->spypeers);
    CONDGFREE(b->tmplocqso.locator);
    g_free(b);
}


void free_qso(struct qso *qso){
    CONDGFREE(qso->source);
    CONDGFREE(qso->operator);
    CONDGFREE(qso->date_str);
    CONDGFREE(qso->time_str);
    CONDGFREE(qso->callsign);
    CONDGFREE(qso->rsts);
    CONDGFREE(qso->rstr);
    CONDGFREE(qso->qsonrs);
    CONDGFREE(qso->qsonrr);
    CONDGFREE(qso->exc);
    CONDGFREE(qso->locator);
    CONDGFREE(qso->remark);

    g_free(qso);
}


void dirty_band(struct band *band) {
    dbg_qsos("DIRTY_BAND %c",band->bandchar);
    band->dirty_save = 1;
    band->dirty_stats = 1;
    band->dirty_statsf = 1;
};

enum modes get_mode(void){
      if (aband) return aband->mode;
      else return gses->mode;
}

void set_mode(enum modes mode){
      if (aband) aband->mode=mode;
      else gses->mode=mode;
}

Generated by  Doxygen 1.6.0   Back to index