int32_t init_free_userdb(struct s_auth *ptr) { int32_t nro; for(nro = 0; ptr; nro++) { struct s_auth *ptr_next; ptr_next = ptr->next; ll_destroy(&ptr->aureader_list); ptr->next = NULL; config_list_gc_values(account_opts, ptr); ftab_clear(&ptr->ftab); ftab_clear(&ptr->fchid); tuntab_clear(&ptr->ttab); caidtab_clear(&ptr->ctab); NULLFREE(ptr->cltab.aclass); NULLFREE(ptr->cltab.bclass); #ifdef CS_CACHEEX cecspvaluetab_clear(&ptr->cacheex.filter_caidtab); #endif #ifdef WITH_LB caidvaluetab_clear(&ptr->lb_nbest_readers_tab); #endif add_garbage(ptr); ptr = ptr_next; } cs_log("userdb %d accounts freed", nro); return nro; }
void chk_ftab(char *value, FTAB *ftab) { ftab_clear(ftab); char *ptr1, *saveptr1 = NULL; errno = 0; for(ptr1 = strtok_r(value, ";", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ";", &saveptr1)) { FILTER d; memset(&d, 0, sizeof(d)); char *caid_end_ptr = strchr(ptr1, ':'); // caid_end_ptr + 1 -> headers if(!caid_end_ptr) continue; caid_end_ptr[0] = '\0'; d.caid = a2i(ptr1, 4); if (!d.caid || errno == EINVAL) { errno = 0; continue; } ptr1 = caid_end_ptr + 1; // -> headers char *ident_ptr, *saveident_ptr = NULL; for(ident_ptr = strtok_r(ptr1, ",", &saveident_ptr); ident_ptr && d.nprids < ARRAY_SIZE(d.prids); ident_ptr = strtok_r(NULL, ",", &saveident_ptr)) { uint32_t ident = a2i(ident_ptr, 4); if (errno == EINVAL) { errno = 0; continue; } d.prids[d.nprids++] = ident; } if (d.nprids) ftab_add(ftab, &d); } }
void ftab_fn(const char *token, char *value, void *setting, long ftab_type, FILE *f) { FTAB *ftab = setting; if(value) { if(strlen(value)) chk_ftab(value, ftab); else ftab_clear(ftab); return; } if(ftab_type & FTAB_READER) { struct s_reader *rdr = NULL; if(ftab_type & FTAB_PROVID) { rdr = container_of(setting, struct s_reader, ftab); } if(ftab_type & FTAB_CHID) { rdr = container_of(setting, struct s_reader, fchid); }
void chk_ftab_fn(const char *token, char *value, void *setting, FILE *f) { FTAB *ftab = setting; if(value) { if(strlen(value)) chk_ftab(value, ftab); else ftab_clear(ftab); return; } value = mk_t_ftab(ftab); if(strlen(value) > 0 || cfg.http_full_cfg) { fprintf_conf(f, token, "%s\n", value); } free_mk_t(value); }
void config_free(void) { config_sections_free(oscam_conf, &cfg); caidvaluetab_clear(&cfg.ftimeouttab); caidtab_clear(&cfg.double_check_caid); ftab_clear(&cfg.disablecrccws_only_for); #ifdef WITH_LB caidvaluetab_clear(&cfg.lb_retrylimittab); caidvaluetab_clear(&cfg.lb_nbest_readers_tab); caidtab_clear(&cfg.lb_noproviderforcaid); #endif #ifdef CS_CACHEEX caidvaluetab_clear(&cfg.cacheex_mode1_delay_tab); cecspvaluetab_clear(&cfg.cacheex_wait_timetab); #endif #ifdef CW_CYCLE_CHECK caidtab_clear(&cfg.cwcycle_check_caidtab); #endif }
void free_client(struct s_client *cl) { if(!cl) { return; } struct s_reader *rdr = cl->reader; // Remove client from client list. kill_thread also removes this client, so here just if client exits itself... struct s_client *prev, *cl2; cs_writelock(__func__, &clientlist_lock); if(!cl->kill_started) { cl->kill_started = 1; } else { cs_writeunlock(__func__, &clientlist_lock); cs_log("[free_client] ERROR: free already started!"); return; } cl->kill = 1; for(prev = first_client, cl2 = first_client->next; prev->next != NULL; prev = prev->next, cl2 = cl2->next) { if(cl == cl2) { break; } } if(cl == cl2) { prev->next = cl2->next; } // Remove client from list int32_t bucket = (uintptr_t)cl / 16 % CS_CLIENT_HASHBUCKETS; // Remove client from hashed list if(first_client_hashed[bucket] == cl) { first_client_hashed[bucket] = cl->nexthashed; } else { for(prev = first_client_hashed[bucket], cl2 = first_client_hashed[bucket]->nexthashed; prev->nexthashed != NULL; prev = prev->nexthashed, cl2 = cl2->nexthashed) { if(cl == cl2) { break; } } if(cl == cl2) { prev->nexthashed = cl2->nexthashed; } } cs_writeunlock(__func__, &clientlist_lock); cleanup_ecmtasks(cl); // Clean reader. The cleaned structures should be only used by the reader thread, so we should be save without waiting if(rdr) { ll_destroy_data(&rdr->emmstat); remove_reader_from_active(rdr); cs_sleepms(1000); //just wait a bit that really really nobody is accessing client data if(rdr->ph.cleanup) { rdr->ph.cleanup(cl); } if(cl->typ == 'r') { cardreader_close(rdr); } if(cl->typ == 'p') { network_tcp_connection_close(rdr, "cleanup"); } cl->reader = NULL; } // Clean client specific data if(cl->typ == 'c') { cs_statistics(cl); cl->last_caid = NO_CAID_VALUE; cl->last_provid = NO_PROVID_VALUE; cl->last_srvid = NO_SRVID_VALUE; cs_statistics(cl); cs_sleepms(1000); //just wait a bit that really really nobody is accessing client data } struct s_module *module = get_module(cl); if(module->cleanup) { module->cleanup(cl); } // Close network socket if not already cleaned by previous cleanup functions if(cl->pfd) { close(cl->pfd); } // Clean all remaining structures free_joblist(cl); NULLFREE(cl->work_mbuf); if(cl->ecmtask) { add_garbage(cl->ecmtask); cl->ecmtask = NULL; } ll_destroy_data(&cl->cascadeusers); ftab_clear(&cl->ftab); ftab_clear(&cl->fchid); tuntab_clear(&cl->ttab); caidtab_clear(&cl->ctab); NULLFREE(cl->cltab.aclass); NULLFREE(cl->cltab.bclass); NULLFREE(cl->cw_rass); ll_destroy_data(&cl->ra_buf); NULLFREE(cl->aes_keys); #ifdef MODULE_CCCAM add_garbage(cl->cc); #endif #ifdef MODULE_SERIAL add_garbage(cl->serialdata); #endif add_garbage(cl); }