STATIC_FUNC void check_for_changed_sms(void *unused) { uint16_t found_sms = 0; uint16_t matching_sms = 0; struct opt_type *opt = get_option( 0, 0, ARG_SMS ); struct opt_parent *p = NULL; struct json_sms * sms = NULL; struct avl_node *an = NULL; char name[MAX_JSON_SMS_NAME_LEN]; char data[MAX_JSON_SMS_DATA_LEN + 1]; dbgf_all(DBGT_INFO, "checking..."); if (extensions_fd == -1) { task_remove(check_for_changed_sms, NULL); task_register(SMS_POLLING_INTERVAL, check_for_changed_sms, NULL, 300000); } while ((sms = avl_iterate_item(&json_sms_tree, &an))) { sms->stale = 1; } while ((p = list_iterate(&opt->d.parents_instance_list, p))) { int len = 0; memset(name, 0, sizeof (name)); strcpy(name, p->val); int fd = -1; char path_name[MAX_PATH_SIZE + 20] = ""; sprintf(path_name, "%s/%s", smsTx_dir, p->val); if ((fd = open(path_name, O_RDONLY, 0)) < 0) { dbgf_all(DBGT_INFO, "could not open %s - %s", path_name, strerror(errno)); continue; } else if ((len = read(fd, data, sizeof (data))) < 0 || len > MAX_JSON_SMS_DATA_LEN) { dbgf_sys(DBGT_ERR, "sms=%s data_len>=%d MUST BE <=%d bytes! errno: %s", path_name, len, MAX_JSON_SMS_DATA_LEN, strerror(errno)); close(fd); continue; } else if ((sms = avl_find_item(&json_sms_tree, name)) && sms->text_len == len && !memcmp(sms->text, data, len)) { matching_sms++; sms->stale = 0; close(fd); } else { if (sms) { avl_remove(&json_sms_tree, sms->name, -300378); debugFree(sms, -300369); } sms = debugMalloc(sizeof (struct json_sms) +len, -300370); memset(sms, 0, sizeof (struct json_sms) +len); strcpy(sms->name, name); sms->text_len = len; sms->stale = 0; memcpy(sms->text, data, len); avl_insert(&json_sms_tree, sms, -300371); close(fd); dbgf_track(DBGT_INFO, "new sms=%s size=%d! updating description..-", path_name, sms->text_len); } found_sms++; } if (found_sms != matching_sms || found_sms != json_sms_tree.items) { dbgf_all(DBGT_INFO, "sms found=%d matching=%d items=%d", found_sms, matching_sms, json_sms_tree.items); memset(name, 0, sizeof (name)); while ((sms = avl_next_item(&json_sms_tree, name))) { memcpy(name, sms->name, sizeof (sms->name)); if (sms->stale) { dbgf_track(DBGT_INFO, "removed sms=%s/%s size=%d! updating description...", smsTx_dir, sms->name, sms->text_len); avl_remove(&json_sms_tree, sms->name, -300373); debugFree(sms, -300374); } } my_description_changed = YES; } }
/* iterate though the hash. first element is selected with iter_in NULL. * use the returned iterator to access the elements until hash_it_t returns * NULL. */ struct hash_it_t *hash_iterate(struct hashtable_t *hash, struct hash_it_t *iter_in) { struct hash_it_t *iter; if (!iter_in) { iter = debugMalloc(sizeof(struct hash_it_t), 301); iter->index = -1; iter->bucket = NULL; iter->prev_bucket = NULL; } else { iter = iter_in; } /* sanity checks first (if our bucket got deleted in the last * iteration): */ if (iter->bucket) { if (iter->first_bucket) { /* we're on the first element and it got removed after * the last iteration. */ if ((*iter->first_bucket) != iter->bucket) { /* there are still other elements in the list */ if (*iter->first_bucket) { iter->prev_bucket = NULL; iter->bucket = (*iter->first_bucket); iter->first_bucket = &hash->table[iter->index]; return iter; } iter->bucket = NULL; } } else if (iter->prev_bucket) { /* we're not on the first element, and the bucket got * removed after the last iteration. The last bucket's * next pointer is not pointing to our actual bucket * anymore. Select the next. */ if (iter->prev_bucket->next != iter->bucket) iter->bucket = iter->prev_bucket; } } /* now as we are sane, select the next one if there is some */ if (iter->bucket) { if (iter->bucket->next) { iter->prev_bucket = iter->bucket; iter->bucket = iter->bucket->next; iter->first_bucket = NULL; return iter; } } /* if not returned yet, we've reached the last one on the index and * have to search forward */ iter->index++; /* go through the entries of the hash table */ while (iter->index < hash->size) { if (!hash->table[iter->index]) { iter->index++; continue; } iter->prev_bucket = NULL; iter->bucket = hash->table[iter->index]; iter->first_bucket = &hash->table[iter->index]; return iter; /* if this table entry is not null, return it */ } /* nothing to iterate over anymore */ hash_iterate_free(iter); return NULL; }
static void avl_test() { struct avl_node *an = NULL; AVL_TREE(t, sizeof (int)); int i; struct p { int i; int v; }; struct p * p; for (i = 0; i <= 19; i++) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 0; avl_insert(&t, p); } for (i = 19; i >= 10; i--) { p = avl_remove(&t, &i); printf(" removed %d/%d\n", p->i, p->v ); debugFree( p, 1999 ); } for (i = 9; i >= 0; i--) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 1; avl_insert(&t, p); } for (i = 5; i <= 15; i++) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 2; avl_insert(&t, p); } for (i = 3; i <= 9; i++) { p = debugMalloc(sizeof ( struct p), 999); p->i = 2; p->v = i; avl_insert(&t, p); } printf("\navl_iterate():\n"); i=0; an = NULL; while( (an = avl_iterate( &t, an ) ) ) { p = ((struct p*)(an->key)); if ( i > p->i) printf("\nERROR %d > %d \n", i, p->i); i = p->i; printf( "%3d/%1d ", p->i, p->v ); } printf("\n"); #ifdef AVL_DEBUG printf("avl_debug():\n"); avl_debug( &t ); #endif for (i = 9; i >= 3; i--) { int v = 2; if ((p = avl_remove(&t, &v)) ) { printf(" removed %d/%d\n", p->i, p->v); debugFree(p, 1999); } } for (i = 9; i >= 0; i--) { if ( (p = avl_remove(&t, &i) ) ) { printf(" removed %d/%d\n", p->i, p->v); debugFree(p, 1999); } } for (i = 0; i <= 19; i++) { if ((p = avl_remove(&t, &i))) { printf(" removed %d/%d\n", p->i, p->v); debugFree(p, 1999); } else { printf(" failed rm %d\n", i); } } /* for (i = 20; i >= 0; i--) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 5; avl_insert(&t, p); } */ i = 0; printf("\n"); printf("\navl_next():\n"); int32_t j = 0; while( (an = avl_next( &t, &j )) ) { p = ((struct p*)(an->key)); j = p->i; if ( i > p->i) printf("\nERROR %d > %d \n", i, p->i); i = p->i; printf( "N%4d/%1d ", p->i, p->v ); if ( i%10 == 0 ) printf("\n"); } printf("\navl_iterate():\n"); i=0; while( (an = avl_iterate( &t, an ) ) ) { p = ((struct p*)(an->key)); if ( i > p->i) printf("\nERROR %d > %d \n", i, p->i); i = p->i; printf( "%3d/%1d ", p->i, p->v ); } printf("\n"); #ifdef AVL_DEBUG printf("avl_debug():\n"); avl_debug( &t ); #endif while( t.root ) { p = (struct p*)t.root->key; p = avl_remove( &t, p ); printf(" removed %d/%d\n", p->i, p->v ); debugFree( p, 1999 ); } printf("\n"); cleanup_all(CLEANUP_SUCCESS); }