void chk_ecm_whitelist(char *value, ECM_WHITELIST *ecm_whitelist) { ecm_whitelist_clear(ecm_whitelist); char *ptr, *saveptr1 = NULL; for(ptr = strtok_r(value, ";", &saveptr1); ptr; ptr = strtok_r(NULL, ";", &saveptr1)) { ECM_WHITELIST_DATA d; memset(&d, 0, sizeof(d)); char *caid_end_ptr = strchr(ptr, ':'); // caid_end_ptr + 1 -> headers char *provid_ptr = strchr(ptr, '@'); // provid_ptr + 1 -> provid char *headers = ptr; if(caid_end_ptr) { caid_end_ptr[0] = '\0'; if (provid_ptr) { provid_ptr[0] = '\0'; provid_ptr++; d.ident = a2i(provid_ptr, 6); } d.caid = dyn_word_atob(ptr); headers = caid_end_ptr + 1; // -> headers } else if(provid_ptr) { provid_ptr[0] = '\0'; d.ident = a2i(provid_ptr, 6); } if (d.caid == 0xffff) d.caid = 0; if (d.ident == 0xffff) d.ident = 0; char *len_ptr, *savelen_ptr = NULL; for(len_ptr = strtok_r(headers, ",", &savelen_ptr); len_ptr; len_ptr = strtok_r(NULL, ",", &savelen_ptr)) { d.len = dyn_word_atob(len_ptr); if (d.len == 0xffff) continue; ecm_whitelist_add(ecm_whitelist, &d); } } }
void chk_ecm_hdr_whitelist(char *value, ECM_HDR_WHITELIST *ecm_hdr_whitelist) { ecm_hdr_whitelist_clear(ecm_hdr_whitelist); char *ptr, *saveptr = NULL; for(ptr = strtok_r(value, ";", &saveptr); ptr; ptr = strtok_r(NULL, ";", &saveptr)) { ECM_HDR_WHITELIST_DATA d; memset(&d, 0, sizeof(d)); char *caid_end_ptr = strchr(ptr, ':'); // caid_end_ptr + 1 -> headers char *provid_ptr = strchr(ptr, '@'); // provid_ptr + 1 -> provid char *headers = ptr; if(caid_end_ptr) { caid_end_ptr[0] = '\0'; if (provid_ptr) { provid_ptr[0] = '\0'; provid_ptr++; d.provid = a2i(provid_ptr, 6); } d.caid = dyn_word_atob(ptr); headers = caid_end_ptr + 1; // -> headers } else if(provid_ptr) { provid_ptr[0] = '\0'; d.provid = a2i(provid_ptr, 6); } if (d.caid == 0xffff) d.caid = 0; if (d.provid == 0xffff) d.provid = 0; char *hdr_ptr, *savehdr_ptr = NULL; for(hdr_ptr = strtok_r(headers, ",", &savehdr_ptr); hdr_ptr; hdr_ptr = strtok_r(NULL, ",", &savehdr_ptr)) { hdr_ptr = trim(hdr_ptr); d.len = strlen(hdr_ptr); if (d.len / 2 > sizeof(d.header)) d.len = sizeof(d.header) * 2; if (d.len > 1) { key_atob_l(hdr_ptr, d.header, d.len); ecm_hdr_whitelist_add(ecm_hdr_whitelist, &d); } } } }
int32_t init_srvid(void) { int8_t new_syntax = 1; FILE *fp = open_config_file("oscam.srvid2"); if(!fp) { fp = open_config_file(cs_srid); if(fp) { new_syntax = 0; } } if(!fp) { fp = create_config_file("oscam.srvid2"); if(fp) { flush_config_file(fp, "oscam.srvid2"); } return 0; } int32_t nr = 0, i, j; char *payload, *saveptr1 = NULL, *saveptr2 = NULL, *token; const char *tmp; if(!cs_malloc(&token, MAXLINESIZE)) { return 0; } struct s_srvid *srvid = NULL, *new_cfg_srvid[16], *last_srvid[16]; // A cache for strings within srvids. A checksum is calculated which is the start point in the array (some kind of primitive hash algo). // From this point, a sequential search is done. This greatly reduces the amount of string comparisons. const char **stringcache[1024]; int32_t allocated[1024] = { 0 }; int32_t used[1024] = { 0 }; struct timeb ts, te; cs_ftime(&ts); memset(last_srvid, 0, sizeof(last_srvid)); memset(new_cfg_srvid, 0, sizeof(new_cfg_srvid)); while(fgets(token, MAXLINESIZE, fp)) { int32_t l, len = 0, len2, srvidtmp; uint32_t k; uint32_t pos; char *srvidasc, *prov; tmp = trim(token); if(tmp[0] == '#') { continue; } if((l = strlen(tmp)) < 6) { continue; } if(!(srvidasc = strchr(token, ':'))) { continue; } if(!(payload = strchr(token, '|'))) { continue; } *payload++ = '\0'; if(!cs_malloc(&srvid, sizeof(struct s_srvid))) { NULLFREE(token); fclose(fp); return (1); } char tmptxt[128]; int32_t offset[4] = { -1, -1, -1, -1 }; char *ptr1 = NULL, *ptr2 = NULL; const char *searchptr[4] = { NULL, NULL, NULL, NULL }; const char **ptrs[4] = { &srvid->prov, &srvid->name, &srvid->type, &srvid->desc }; uint32_t max_payload_length = MAXLINESIZE - (payload - token); if(new_syntax) { ptrs[0] = &srvid->name; ptrs[1] = &srvid->type; ptrs[2] = &srvid->desc; ptrs[3] = &srvid->prov; } // allow empty strings as "||" if(payload[0] == '|' && (strlen(payload)+2 < max_payload_length)) { memmove(payload+1, payload, strlen(payload)+1); payload[0] = ' '; } for(k=1; ((k < max_payload_length) && (payload[k] != '\0')); k++) { if(payload[k-1] == '|' && payload[k] == '|') { if(strlen(payload+k)+2 < max_payload_length-k) { memmove(payload+k+1, payload+k, strlen(payload+k)+1); payload[k] = ' '; } else { break; } } } for(i = 0, ptr1 = strtok_r(payload, "|", &saveptr1); ptr1 && (i < 4) ; ptr1 = strtok_r(NULL, "|", &saveptr1), ++i) { // check if string is in cache len2 = strlen(ptr1); pos = 0; for(j = 0; j < len2; ++j) { pos += (uint8_t)ptr1[j]; } pos = pos % 1024; for(j = 0; j < used[pos]; ++j) { if(!strcmp(stringcache[pos][j], ptr1)) { searchptr[i] = stringcache[pos][j]; break; } } if(searchptr[i]) { continue; } offset[i] = len; cs_strncpy(tmptxt + len, trim(ptr1), sizeof(tmptxt) - len); len += strlen(ptr1) + 1; } char *tmpptr = NULL; if(len > 0 && !cs_malloc(&tmpptr, len)) { continue; } srvid->data = tmpptr; if(len > 0) { memcpy(tmpptr, tmptxt, len); } for(i = 0; i < 4; i++) { if(searchptr[i]) { *ptrs[i] = searchptr[i]; continue; } if(offset[i] > -1) { *ptrs[i] = tmpptr + offset[i]; // store string in stringcache tmp = *ptrs[i]; len2 = strlen(tmp); pos = 0; for(j = 0; j < len2; ++j) { pos += (uint8_t)tmp[j]; } pos = pos % 1024; if(used[pos] >= allocated[pos]) { if(allocated[pos] == 0) { if(!cs_malloc(&stringcache[pos], 16 * sizeof(char *))) { break; } } else { if(!cs_realloc(&stringcache[pos], (allocated[pos] + 16) * sizeof(char *))) { break; } } allocated[pos] += 16; } stringcache[pos][used[pos]] = tmp; used[pos] += 1; } } *srvidasc++ = '\0'; if(new_syntax) { srvidtmp = dyn_word_atob(token) & 0xFFFF; } else { srvidtmp = dyn_word_atob(srvidasc) & 0xFFFF; } if(srvidtmp < 0) { NULLFREE(tmpptr); NULLFREE(srvid); continue; } else { srvid->srvid = srvidtmp; } srvid->ncaid = 0; for(i = 0, ptr1 = strtok_r(new_syntax ? srvidasc : token, ",", &saveptr1); (ptr1); ptr1 = strtok_r(NULL, ",", &saveptr1), i++) { srvid->ncaid++; } if(!cs_malloc(&srvid->caid, sizeof(struct s_srvid_caid) * srvid->ncaid)) { NULLFREE(tmpptr); NULLFREE(srvid); return 0; } ptr1 = new_syntax ? srvidasc : token; for(i = 0; i < srvid->ncaid; i++) { prov = strchr(ptr1,'@'); srvid->caid[i].nprovid = 0; if(prov) { if(prov[1] != '\0') { for(j = 0, ptr2 = strtok_r(prov+1, "@", &saveptr2); (ptr2); ptr2 = strtok_r(NULL, "@", &saveptr2), j++) { srvid->caid[i].nprovid++; } if(!cs_malloc(&srvid->caid[i].provid, sizeof(uint32_t) * srvid->caid[i].nprovid)) { for(j = 0; j < i; j++) { NULLFREE(srvid->caid[j].provid); } NULLFREE(srvid->caid); NULLFREE(tmpptr); NULLFREE(srvid); return 0; } ptr2 = prov+1; for(j = 0; j < srvid->caid[i].nprovid; j++) { srvid->caid[i].provid[j] = dyn_word_atob(ptr2) & 0xFFFFFF; ptr2 = ptr2 + strlen(ptr2) + 1; } } else { ptr2 = prov+2; } prov[0] = '\0'; } srvid->caid[i].caid = dyn_word_atob(ptr1) & 0xFFFF; if(prov) { ptr1 = ptr2; } else { ptr1 = ptr1 + strlen(ptr1) + 1; } } nr++; if(new_cfg_srvid[srvid->srvid >> 12]) { last_srvid[srvid->srvid >> 12]->next = srvid; } else { new_cfg_srvid[srvid->srvid >> 12] = srvid; } last_srvid[srvid->srvid >> 12] = srvid; }
static void ecmwhitelist_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if (value) { char *ptr, *ptr2, *ptr3, *saveptr1 = NULL; struct s_ecmWhitelist *tmp, *last; struct s_ecmWhitelistIdent *tmpIdent, *lastIdent; struct s_ecmWhitelistLen *tmpLen, *lastLen; for(tmp = rdr->ecmWhitelist; tmp; tmp=tmp->next) { for(tmpIdent = tmp->idents; tmpIdent; tmpIdent=tmpIdent->next) { for(tmpLen = tmpIdent->lengths; tmpLen; tmpLen=tmpLen->next) { add_garbage(tmpLen); } add_garbage(tmpIdent); } add_garbage(tmp); } rdr->ecmWhitelist = NULL; if(strlen(value) > 0) { saveptr1 = NULL; char *saveptr2 = NULL; for (ptr = strtok_r(value, ";", &saveptr1); ptr; ptr = strtok_r(NULL, ";", &saveptr1)) { int16_t caid = 0, len; uint32_t ident = 0; ptr2=strchr(ptr,':'); if(ptr2 != NULL) { ptr2[0] = '\0'; ++ptr2; ptr3=strchr(ptr,'@'); if(ptr3 != NULL) { ptr3[0] = '\0'; ++ptr3; ident = (uint32_t)a2i(ptr3, 6); } caid = (int16_t)dyn_word_atob(ptr); } else ptr2 = ptr; for (ptr2 = strtok_r(ptr2, ",", &saveptr2); ptr2; ptr2 = strtok_r(NULL, ",", &saveptr2)) { len = (int16_t)dyn_word_atob(ptr2); last = NULL, tmpIdent = NULL, lastIdent = NULL, tmpLen = NULL, lastLen = NULL; for(tmp = rdr->ecmWhitelist; tmp; tmp=tmp->next) { last = tmp; if(tmp->caid == caid) { for(tmpIdent = tmp->idents; tmpIdent; tmpIdent=tmpIdent->next) { lastIdent = tmpIdent; if(tmpIdent->ident == ident) { for(tmpLen = tmpIdent->lengths; tmpLen; tmpLen=tmpLen->next) { lastLen = tmpLen; if(tmpLen->len == len) break; } break; } } } } if(tmp == NULL) { if (cs_malloc(&tmp, sizeof(struct s_ecmWhitelist))) { tmp->caid = caid; tmp->idents = NULL; tmp->next = NULL; if(last == NULL) { rdr->ecmWhitelist = tmp; } else { last->next = tmp; } } } if(tmp != NULL && tmpIdent == NULL) { if (cs_malloc(&tmpIdent, sizeof(struct s_ecmWhitelistIdent))) { tmpIdent->ident = ident; tmpIdent->lengths = NULL; tmpIdent->next = NULL; if(lastIdent == NULL) { tmp->idents = tmpIdent; } else { lastIdent->next = tmpIdent; } } } if(tmp != NULL && tmpIdent != NULL && tmpLen == NULL) { if (cs_malloc(&tmpLen, sizeof(struct s_ecmWhitelistLen))) { tmpLen->len = len; tmpLen->next = NULL; if(lastLen == NULL) { tmpIdent->lengths = tmpLen; } else { lastLen->next = tmpLen; } } } } } } return; } value = mk_t_ecmwhitelist(rdr->ecmWhitelist); if (strlen(value) > 0 || cfg.http_full_cfg) fprintf_conf(f, token, "%s\n", value); free_mk_t(value); }
static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if (value) { char *ptr, *ptr2, *ptr3; struct s_ecmHeaderwhitelist *tmp, *last = NULL; if (strlen(value) == 0) { for (tmp = rdr->ecmHeaderwhitelist; tmp; tmp=tmp->next) add_garbage(tmp); rdr->ecmHeaderwhitelist = NULL; } else { char *ptr4, *ptr5, *ptr6, *saveptr = NULL, *saveptr4 = NULL, *saveptr5 = NULL, *saveptr6 = NULL; uint16_t caid = 0; uint32_t provid = 0; int16_t len = 0; for (ptr = strtok_r(value, ";", &saveptr); ptr; ptr = strtok_r(NULL, ";", &saveptr)) { caid = 0; provid = 0; ptr2 = strchr(ptr, '@'); ptr3 = strchr(ptr, ':'); if (ptr2 == NULL && ptr3 == NULL) { //no Caid no Provid for (ptr4 = strtok_r(ptr, ",", &saveptr4); ptr4; ptr4 = strtok_r(NULL, ",", &saveptr4)) { if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) { ptr4 = trim(ptr4); len = strlen(ptr4); key_atob_l(ptr4, tmp->header, len); tmp->len = len; tmp->caid = 0; tmp->provid = 0; tmp->next = NULL; if (last == NULL) { rdr->ecmHeaderwhitelist = tmp; } else { last->next = tmp; } last = tmp; } } } if (ptr3 != NULL && ptr2 == NULL) { // only with Caid ptr3[0] = '\0'; ++ptr3; caid = (int16_t)dyn_word_atob(ptr); for (ptr5 = strtok_r(ptr3, ",", &saveptr5); ptr5; ptr5 = strtok_r(NULL, ",", &saveptr5)) { if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) { tmp->caid = caid; tmp->provid = 0; ptr5 = trim(ptr5); len = strlen(ptr5); key_atob_l(ptr5, tmp->header, len); tmp->len = len; tmp->next = NULL; if (last == NULL) { rdr->ecmHeaderwhitelist = tmp; } else { last->next = tmp; } last = tmp; } } } if (ptr3 != NULL && ptr2 != NULL) { // with Caid & Provid ptr2[0] = '\0'; ++ptr2; // -> provid ptr3[0] = '\0'; ++ptr3; // -> headers caid = (int16_t)dyn_word_atob(ptr); provid = (uint32_t)a2i(ptr2, 6); for (ptr6 = strtok_r(ptr3, ",", &saveptr6); ptr6; ptr6 = strtok_r(NULL, ",", &saveptr6)) { if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) { tmp->caid = caid; tmp->provid = provid; ptr6 = trim(ptr6); len = strlen(ptr6); key_atob_l(ptr6, tmp->header, len); tmp->len = len; tmp->next = NULL; if (last == NULL) { rdr->ecmHeaderwhitelist = tmp; } else { last->next = tmp; } last = tmp; } } } } } /* if (rdr->ecmHeaderwhitelist != NULL) { // debug cs_log("**********Begin ECM Header List for Reader: %s **************", rdr->label); struct s_ecmHeaderwhitelist *tmp; for(tmp = rdr->ecmHeaderwhitelist; tmp; tmp=tmp->next){ cs_log("Caid: %i Provid: %i Header: %02X Len: %i", tmp->caid, tmp->provid, tmp->header[0], tmp->len); } cs_log("***********End ECM Header List for Reader: %s ***************", rdr->label); } */ return; } value = mk_t_ecmheaderwhitelist(rdr->ecmHeaderwhitelist); if (strlen(value) > 0 || cfg.http_full_cfg) fprintf_conf(f, token, "%s\n", value); free_mk_t(value); }
int32_t init_srvid(void) { FILE *fp = open_config_file(cs_srid); if (!fp) return 0; int32_t nr = 0, i; char *payload, *tmp, *saveptr1 = NULL, *token; if (!cs_malloc(&token, MAXLINESIZE)) return 0; struct s_srvid *srvid=NULL, *new_cfg_srvid[16], *last_srvid[16]; // A cache for strings within srvids. A checksum is calculated which is the start point in the array (some kind of primitive hash algo). // From this point, a sequential search is done. This greatly reduces the amount of string comparisons. char **stringcache[1024]; int32_t allocated[1024] = { 0 }; int32_t used[1024] = { 0 }; struct timeb ts, te; cs_ftime(&ts); memset(last_srvid, 0, sizeof(last_srvid)); memset(new_cfg_srvid, 0, sizeof(new_cfg_srvid)); while (fgets(token, MAXLINESIZE, fp)) { int32_t l, j, len=0, len2, srvidtmp; uint32_t pos; char *srvidasc; tmp = trim(token); if (tmp[0] == '#') continue; if ((l=strlen(tmp)) < 6) continue; if (!(srvidasc = strchr(token, ':'))) continue; if (!(payload=strchr(token, '|'))) continue; *payload++ = '\0'; if (!cs_malloc(&srvid, sizeof(struct s_srvid))) { free(token); fclose(fp); return(1); } char tmptxt[128]; int32_t offset[4] = { -1, -1, -1, -1 }; char *ptr1, *searchptr[4] = { NULL, NULL, NULL, NULL }; char **ptrs[4] = { &srvid->prov, &srvid->name, &srvid->type, &srvid->desc }; for (i = 0, ptr1 = strtok_r(payload, "|", &saveptr1); ptr1 && (i < 4) ; ptr1 = strtok_r(NULL, "|", &saveptr1), ++i){ // check if string is in cache len2 = strlen(ptr1); pos = 0; for(j = 0; j < len2; ++j) pos += (uint8_t)ptr1[j]; pos = pos%1024; for(j = 0; j < used[pos]; ++j){ if (!strcmp(stringcache[pos][j], ptr1)){ searchptr[i]=stringcache[pos][j]; break; } } if (searchptr[i]) continue; offset[i]=len; cs_strncpy(tmptxt+len, trim(ptr1), sizeof(tmptxt)-len); len+=strlen(ptr1)+1; } char *tmpptr = NULL; if (len > 0 && !cs_malloc(&tmpptr, len)) continue; srvid->data=tmpptr; if(len > 0) memcpy(tmpptr, tmptxt, len); for (i=0;i<4;i++) { if (searchptr[i]) { *ptrs[i] = searchptr[i]; continue; } if (offset[i]>-1){ *ptrs[i] = tmpptr + offset[i]; // store string in stringcache tmp = *ptrs[i]; len2 = strlen(tmp); pos = 0; for(j = 0; j < len2; ++j) pos += (uint8_t)tmp[j]; pos = pos%1024; if(used[pos] >= allocated[pos]){ if (allocated[pos] == 0) { if (!cs_malloc(&stringcache[pos], 16 * sizeof(char *))) break; } else { if (!cs_realloc(&stringcache[pos], (allocated[pos] + 16) * sizeof(char *))) break; } allocated[pos] += 16; } stringcache[pos][used[pos]] = tmp; used[pos] += 1; } } *srvidasc++ = '\0'; srvidtmp = dyn_word_atob(srvidasc) & 0xFFFF; //printf("srvid %s - %d\n",srvidasc,srvid->srvid ); if (srvidtmp<0) { free(tmpptr); free(srvid); continue; } else srvid->srvid = srvidtmp; srvid->ncaid = 0; for (i = 0, ptr1 = strtok_r(token, ",", &saveptr1); (ptr1) && (i < 10) ; ptr1 = strtok_r(NULL, ",", &saveptr1), i++){ srvid->caid[i] = dyn_word_atob(ptr1); srvid->ncaid = i+1; //cs_debug_mask(D_CLIENT, "ld caid: %04X srvid: %04X Prov: %s Chan: %s",srvid->caid[i],srvid->srvid,srvid->prov,srvid->name); } nr++; if (new_cfg_srvid[srvid->srvid>>12]) last_srvid[srvid->srvid>>12]->next = srvid; else new_cfg_srvid[srvid->srvid>>12] = srvid; last_srvid[srvid->srvid>>12] = srvid; }