/* Search. */ void * dwarf_tfind(const void *key, void *const*headppin, int (*compar)(const void *, const void *)) { struct ts_entry *head = (struct ts_entry *)*headppin; struct ts_entry **proot = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; if(!headppin) { return NULL; } head = (struct ts_entry *)*headppin; if(!head) { return NULL; } proot = &head->rlink; root = *proot; if(!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; }
/* * Extract the PFS id from path. */ static int scanpfsid(struct hammer_ioc_pseudofs_rw *pfs, const char *path) { char *linkpath; char buf[64]; uintmax_t dummy_tid; struct stat st; if (stat(path, &st)) { /* possibly slave PFS */ } else if (S_ISDIR(st.st_mode)) { /* possibly master or slave PFS */ } else { return(-1); /* neither */ } linkpath = getlink(path); if (linkpath) { /* * Read the symlink assuming it's a link to PFS. */ bzero(buf, sizeof(buf)); if (readlink(linkpath, buf, sizeof(buf) - 1) < 0) { free(linkpath); return(-1); } free(linkpath); path = buf; } /* * The symlink created by pfs-master|slave is just a symlink. * One could happen to remove a symlink and relink PFS as * # ln -s ./@@-1:00001 ./link * which results PFS having something extra before @@. * One could also directly use the PFS and results the same. * Get rid of it before we extract the PFS id. */ if (strchr(path, '/')) { path = basename(path); /* strips trailing / first if any */ if (path == NULL) err(1, "basename"); } /* * Test and extract the PFS id from the link. * "@@%jx:%d" covers both "@@-1:%05d" format for master PFS * and "@@0x%016jx:%05d" format for slave PFS. */ if (sscanf(path, "@@%jx:%d", &dummy_tid, &pfs->pfs_id) == 2) { assert(pfs->pfs_id > 0); return(0); } return(-1); }
/* * make a new chain: extract a link from the free-list pointed to by * "chainbase", link it to itself, add appropriate entries. * Newchain1 will handle single scalar and pointer entries so long * as the C compiler has pointers and integers the same length (this * is a language requirement). */ static WlzLLink *newchain1(WlzLLink *chainbase, unsigned long entry) { WlzLLink *newlink; newlink = getlink(chainbase); newlink->l_link = newlink; newlink->l_u.line = entry; return(newlink); }
int eraselink (char* str, char* str2) { LINK* clon; LINK* aux; if (getlink(str,str2)==NULL) { return(0); } if (linkdir==NULL) { return(0); } if((linkdir->p2next)==NULL) { if(((strcmp(linkdir->origen,str)!=0)|| (strcmp(linkdir->destino, str2)!=0))) { } else { free(linkdir); linkdir=NULL; --linknumb; } return(1); } if(!((strcmp(linkdir->origen,str)!=0)|| (strcmp(linkdir->destino, str2)!=0))) { aux=linkdir->p2next; free(linkdir); linkdir = aux; --linknumb; return(1); } for(clon=linkdir;((strcmp(clon->p2next->origen,str)!=0)|| (strcmp(clon->p2next->destino, str2)!=0));clon=clon->p2next) { if(clon->p2next==NULL) { return(1); } } aux=clon->p2next->p2next; free(clon->p2next); clon->p2next = aux; --linknumb; return(1); }
/* Newchain2 is for intervals */ static WlzLLink *newchain2(WlzLLink *chainbase, int entry1, int entry2) { WlzLLink *newlink; newlink = getlink(chainbase); newlink->l_link = newlink; newlink->l_u.intv.ileft = entry1; newlink->l_u.intv.iright = entry2; return(newlink); }
void printit() { p_link l; char pbuf[PATHSIZE]; /* print home */ if (Cflag) printf("%ld\t", (long) getnode(Home)->n_cost); printf("%s\t%%s\n", getnode(Home)->n_name); strcpy(pbuf, "%s"); for (l = getnode(Home)->n_link; l; l = getlink(l)->l_next) { if (getlink(l)->l_flag & LTREE) { getlink(l)->l_flag &= ~LTREE; Ancestor = l; preorder(l, pbuf); strcpy(pbuf, "%s"); } } fflush(stdout); fflush(stderr); }
/* privates */ static link *Lcache; #endif /*TMPFILES*/ static unsigned int Memwaste; #ifndef TMPFILES p_link newlink() { register link *rval; if (Lcache) { rval = Lcache; Lcache = Lcache->l_next; strclear((char *) rval, sizeof(link)); } else if ((rval = (link * ) calloc(1, sizeof(link))) == 0) nomem(); return rval; } #else /*TMPFILES*/ p_link newlink() { p_link l_seq; /* * We find the end of the file, use it to get the sequence number of * the link (which we use instead of an offset, since the offset would * have to be long and the sequence number can be short), and * finally zero out the appropriate spot in the link temporary file. * We then fill in and return the sequence number. */ l_seq = lseek(fdlink, (off_t) 0, L_XTND) / sizeof(link); if (write(fdlink, (char *) &nulllink, sizeof(link)) < 0) { perror("newlink"); exit(1); } getlink(l_seq)->l_seq = l_seq; return l_seq; }
/* Search without insert. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = 0; struct ts_entry *p = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } p = head->rlink; while(p) { int kc = compar(key,p->keyptr); if(!kc) { return (void *)(&(p->keyptr)); } p = getlink(p,kc); } return NULL; }
//LuminesRobot::LuminesRobot(){} //LuminesRobot::~LuminesRobot(){} void LuminesRobot::thinkNextBlockI( Sets &baseSet, ::std::vector< int > &tops, ::std::vector< Sets > &sets, int level, btype *map, int width, int height, const BlockSet coming[3]) { int i, r, t; int top1, top2, score; BlockSet bs; top2 = tops[0]; for (i=0; i < width-1; i++) { top1 = tops[i]; top2 = tops[i+1]; tops[i] = max(0, top1 - 2); tops[i+1] = max(0, top2 - 2); for (r = 0; r < 4; r++) { score = 0; bs = s_rotmap[coming[level]][r]; // rotate by y times if (top1>=0) { score += getlink(map, width, height, i, top1, s_posbt[bs][2]); t = i+top1*width; assert(t >=0 && t < width*height); map[t] = s_posbt[bs][2]; if (top1>0) { score += getlink(map, width, height, i, top1-1, s_posbt[bs][0]); t = i+(top1-1)*width; assert(t >=0 && t < width*height); map[t] = s_posbt[bs][0]; } } if (top2>=0) { score += getlink(map, width, height, i+1, top2, s_posbt[bs][3]); t = i+1+top2*width; assert(t >=0 && t < width*height); map[t] = s_posbt[bs][3]; if (top2>0) { score += getlink(map, width, height, i+1, top2-1, s_posbt[bs][1]); t = i+1+(top2-1)*width; assert(t >=0 && t < width*height); map[t] = s_posbt[bs][1]; } } if (level < MAX_LEVEL - 1) { thinkNextBlockI( Sets(baseSet, i, r, score, max(0, min(top1,top2)-1)), tops, sets, level+1, map, width, height, coming); } else { sets.push_back( Sets(baseSet, i, r, score, max(0, min(top1,top2)-1)) ); } if (top1>=0) { map[i+top1*width] = BT_NONE; if (top1>0) map[i+(top1-1)*width] = BT_NONE; } if (top2>=0) { map[i+1+top2*width] = BT_NONE; if (top2>0) map[i+1+(top2-1)*width] = BT_NONE; } } tops[i] = top1; tops[i+1] = top2; } }
int getlist(const char *filename) { CURL *curl; FILE *listfile; struct failures failed[1000]; char line[1000]; char *url; int ret; int i = 0; int fail = 0; if(strcmp(filename, "usestdin") == 0) { listfile = stdin; } else { listfile = fopen(filename, "r"); } if(listfile == NULL) { perror("failed to open links list"); return -1; } curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); while(fgets(line, 1000, listfile) != NULL) { for(i = 0;line[i] != '\0';i++) { if((line[i] == '\r') || (line[i] == '\n')) line[i] = '\0'; } if(strlen(line) < 8) continue; if((line[0] == ' ') || (line[0] == '\t')) continue; url = line; i = 0; ret = getlink(url, curl, i); if(ret == -1) { for(i++;i<NTRYMAX+1;i++) { sleep(1); fprintf(stderr, "[Try %d]\n", (i+1)); ret = getlink(url, curl, i); if(ret == 0) { break; } if((ret == -1) && (i == NTRYMAX)) { failed[fail].link = strdup(line); fail++; } } } curl_easy_reset(curl); } curl_easy_cleanup(curl); curl_global_cleanup(); fclose(listfile); unlink(filename); if(fail != 0) { listfile = fopen(filename, "w"); for(i=0;i<fail;i++) { if(i == 0) fprintf(stderr, "\n\n***FAILED DOWNLOADS:\n\n"); fprintf(stderr, " => %s\n", failed[i].link); fprintf(listfile, "%s\n", failed[i].link); free(failed[i].link); } fclose(listfile); return -1; } return 0; }
void * dwarf_tdelete(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry *phead = 0; struct ts_entry **rootp = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int parentcomparv = 0; int done = 0; if (!headin) { return NULL; } phead = (struct ts_entry *)*headin; if (!phead) { return NULL; } rootp = &phead->rlink; root = phead->rlink; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { break; } parentp = p; parentcomparv = kc; p = getlink(p,kc); } if(!p) { return NULL; } { /* In Knuth Algorithm D, the parenthetical comment "(For example, if Q===RLINK(P) for some P we would set RLINK(P)<- LLINK(T).)" informs us that Q is assumed to be a conceptual name for some RLINK or LLINK, not a C local variable. In the rest of this algorithm variables can be ordinary C pointers, but not true for Q. Hence in the following we use *q to set Q. */ struct ts_entry **q = 0; struct ts_entry *t = 0; struct ts_entry *r = 0; struct ts_entry *s = 0; int emptied_a_leaf = 0; /* Either we found root (to remove) or we have a parentp and the parent mismatched the key so parentcomparv is != 0 */ if (p == root) { q = rootp; } else if (parentcomparv < 0) { q = &parentp->llink; } else /* (parentcomparv > 0) */ { q = &parentp->rlink; } /* D1. Here *q is what Knuth calls q. */ t = *q; r = t->rlink; if (!r) { *q = t->llink; done = 1; } else { /* D2. */ if (!r->llink) { r->llink = t->llink; *q = r; done = 1; } } while (!done) { /* D3. */ s = r->llink; if(s->llink) { r = s; continue; } s->llink = t->llink; r->llink = s->rlink; s->rlink = t->rlink; *q = s; done = 1; } /* Step D4. */ if(!t->llink && !t->rlink) { emptied_a_leaf = 1; } free(t); if(emptied_a_leaf) { if (p == root) { /* The tree is completely empty now. Free the special head node. Notify the caller. */ free(phead); *headin = 0; return NULL; } } if(!parentp) { /* The item we found was at top of tree, found == root. We have a new root node. We return it, there is no parent. Other than one might say, the fake parent phead (with only rlink, but that has no key so we ignore). */ return (void *)(&(root->keyptr)); } return (void *)(&(parentp->keyptr)); } return NULL; }
/* transform the graph to a shortest-path tree by marking tree edges */ void mapit() { register p_node n; register p_link l; p_link lparent; static int firsttime = 0; vprintf(stderr, "*** mapping\n"); Tflag = Tflag && Vflag; /* tracing here only if verbose */ /* re-use the hash table space for the heap */ Heap = (p_link *) Table; Hashpart = pack(0L, Tabsize - 1); /* expunge penalties from -a option and make circular copy lists */ resetnodes(); if (firsttime++) { if (Linkout && *Linkout) /* dump cheapest links */ showlinks(); if (Graphout && *Graphout) /* dump the edge list */ dumpgraph(); } /* insert Home to get things started */ l = newlink(); /* link to get things started */ getlink(l)->l_to = Home; (void) dehash(Home); insert(l); /* main mapping loop */ remap: Heaphighwater = Nheap; while ((lparent = min_node()) != 0) { chkheap(1); getlink(lparent)->l_flag |= LTREE; n = getlink(lparent)->l_to; if (Tflag && maptrace(n, n)) fprintf(stderr, "%s -> %s mapped\n", getnode(getnode(n)->n_parent)->n_name, getnode(n)->n_name); if (getnode(n)->n_flag & MAPPED) die("mapped node in heap"); getnode(n)->n_flag |= MAPPED; /* add children to heap */ heapchildren(n); } vprintf(stderr, "heap high water mark was %ld\n", Heaphighwater); /* sanity check on implementation */ if (Nheap != 0) die("null entry in heap"); if (Hashpart < Tabsize) { /* * add back links from unreachable hosts to * reachable neighbors, then remap. * * asymptotically, this is quadratic; in * practice, this is done once or twice. */ backlinks(); if (Nheap) goto remap; } if (Hashpart < Tabsize) { fputs("You can't get there from here:\n", stderr); for ( ; Hashpart < Tabsize; Hashpart++) { fprintf(stderr, "\t%s", getnode(Table[Hashpart])->n_name); if (getnode(Table[Hashpart])->n_flag & ISPRIVATE) fputs(" (private)", stderr); putc('\n', stderr); } } }
void * dwarf_tdelete(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry *phead = 0; struct ts_entry **rootp = 0; struct ts_entry *root = 0; struct ts_entry * p= 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int parentcomparv = 0; int done = 0; /* We don't really care much if multiple tree tables use this simultaneously. This left/right is a practical thing not supported by known theory, according to Knuth. We start with eppingerleftr=1 because that happens to show a different tree than standard knuth in one of our standard tsearch regression test sequences. */ static unsigned eppingerleft = 1; if (!headin) { return NULL; } phead = (struct ts_entry *)*headin; if (!phead) { return NULL; } rootp = &phead->rlink; root = phead->rlink; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { break; } parentp = p; parentcomparv = kc; p = getlink(p,kc); } if(!p) { return NULL; } { struct ts_entry **q = 0; struct ts_entry *t = 0; struct ts_entry *s = 0; int emptied_a_leaf = 0; /* Either we found root (to remove) or we have a parentp and the parent mismatched the key so parentcomparv is != 0 */ if (p == root) { q = rootp; } else if (parentcomparv < 0) { q = &parentp->llink; } else /* (parentcomparv > 0) */ { q = &parentp->rlink; } /* D1. *q is what Knuth calls q. */ t = *q; if(!eppingerleft) { struct ts_entry *r = 0; eppingerleft = 1; r = t->rlink; if (!r) { *q = t->llink; done = 1; } else { /* D2. */ if (!r->llink) { r->llink = t->llink; *q = r; done = 1; } } while (!done) { /* D3. */ s = r->llink; if(s->llink) { r = s; continue; } s->llink = t->llink; r->llink = s->rlink; s->rlink = t->rlink; *q = s; done = 1; } } else { struct ts_entry *l = 0; eppingerleft = 0; l = t->llink; if (!l) { *q = t->rlink; done = 1; } else { /* D2. */ if (!l->rlink) { l->rlink = t->rlink; *q = l; done = 1; } } while (!done) { /* D3. */ s = l->rlink; if(s->rlink) { l = s; continue; } s->rlink = t->rlink; l->rlink = s->llink; s->llink = t->llink; *q = s; done = 1; } } /* Step D4. */ if(!t->llink && !t->rlink) { emptied_a_leaf = 1; } free(t); if(emptied_a_leaf) { if (p == root) { /* The tree is completely empty now. Free the special head node. Notify the caller. */ free(phead); *headin = 0; return NULL; } } if(!parentp) { /* The item we found was at top of tree, found == root. We have a new root node. We return it, there is no parent. */ return (void *)(&(root->keyptr)); } return (void *)(&(parentp->keyptr)); } return NULL; }
//Download file index goc va loop, get link de down het nhung file con lai bool main_download(char *path) { //Get host, page char *host, *page, *filename; char *query; char *buffer; host = get_host(path); page = get_page(path, host); filename = get_filename(path); printf("File name got: %s\n",filename); //Tao folder va luu file vao folder char *folder_name = NULL; if(filename[strlen(filename) - 1] == '/') { char *tmp = strdup(filename); tmp[strlen(tmp) - 1] = '\0'; folder_name = (char*)malloc(strlen(tmp) + 4); //+4 for "./" voi '\0' va '/'; strcpy(folder_name,"./"); strcat(folder_name,tmp); strcat(folder_name,"/"); printf("Folder name: %s\n",folder_name); if (stat(folder_name, &st) == -1) { if(!mkdir(folder_name, 0777)) printf("Made dir!\n"); else { printf("Cannot create new directory! :(\n"); printf("Plz try again :(\n"); exit(EXIT_FAILURE); } } free(tmp); } //---------Het phan code tao folder--------- //DOWNLOAD file index goc!!! //Hoac download 1 file char *main_file = download_file(path, folder_name, 1); //Kiem tra coi file nay la file gi? //Neu la file binh thuong: .mp3, .doc thi ngung lai, ko down nua bool file = true; //Mac dinh la down file, true la down 1 file thoi!! if(filename[strlen(filename)-1] == '/') { printf("Download them cac file tu link trong file index goc.\n"); file = false; } //Neu la down 1 trang web thi moi vo vong lap nay if (file == false) { printf("Download mot folder!\n"); //Get link and download file con! FILE *fp = fopen(main_file,"r"); if(fp == NULL) { printf("Error: Cannot open main file!!\n"); return false; } printf("Doc file index goc thanh cong\n"); char *short_link; while( !feof(fp)) { //printf("Ok 2\n"); if( (short_link = getlink(fp)) == NULL ) { printf("Ok 2.5\n"); break; } //printf("Ok 3\n"); //short_link = getlink(fp); //printf("Short link: %s\n",short_link); //Download file con! char *full_link = (char*)malloc(strlen(host) + strlen(page) + strlen(short_link) + 1); strcpy(full_link,host); strcat(full_link,page); strcat(full_link,short_link); //printf("Full link: %s\n",full_link); if(full_link!=NULL) download_file(full_link, folder_name, 2); else printf("Link Error!\n"); //printf("Ok\n"); free(short_link); free(full_link); }; fclose(fp); printf("Folder is downloaded!\n"); } else { printf("File is downloaded!\n"); } printf("\nDownload Completed!^^\n"); //Giai phong bo nho free(main_file); free(host); free(page); free(filename); free(folder_name); return true; }
void Store( pwr_tBoolean *firstTime, pwr_tUInt32 *nrOfEvents, pwr_tUInt32 *nrOfKeys ) { char msg[80]; pwr_tInt32 ret = 0; DBT key; sKey skey; /*flush the cache to the DB-file*/ dataBaseP->sync(dataBaseP, 0); /*check if it's time to clean the DB*/ if( *firstTime || ((*nrOfEvents + nrOfInsertsSinceLastTime) > lHelCB.MaxCardinality ) ) { *firstTime = FALSE; if(nrOfInsertsSinceLastTime > 0) { nrOfInsertsSinceLastTime--; *nrOfEvents = *nrOfEvents + 1; } if( *nrOfKeys <= 0) { ret = GetOldestEvents(nrOfEvents, nrOfKeys); nrOfInsertsSinceLastTime = 0; switch(ret) { case RT_ELOG_UNKNOWN_ERROR: errh_Error("RT_ELOG_UNKNOWN_ERROR"); break; case RT_ELOG_OK: break; case RT_ELOG_DB_EMPTY: break; default: errh_Error("Undefined return: %d", ret); break; } } else { lanklank = firstlink(listhead); skey = getlink(lanklank); memset(&key, 0, sizeof(key)); key.data = &skey; key.size = sizeof(sKey); if( (ret = dataBaseP->del(dataBaseP, NULL, &key, 0)) != 0 ) { sprintf(msg, "Error deleting Record in HistDB nrOfKeys = %d Errmess=%s\n", *nrOfKeys, db_strerror(ret)); Log(msg); } else { *nrOfEvents = *nrOfEvents - 1; } elimlink(&lanklank); *nrOfKeys = *nrOfKeys - 1; } } if(*nrOfKeys > 0) { lanklank = firstlink(listhead); if(lanklank != 0) { writeInfo(*nrOfEvents+nrOfInsertsSinceLastTime, 0, &lanklank->data.EventTime); } else { writeInfo(*nrOfEvents+nrOfInsertsSinceLastTime, 0, NULL); } } else { writeInfo(*nrOfEvents+nrOfInsertsSinceLastTime, 0, NULL); } }
void hammer_cmd_pseudofs_destroy(char **av, int ac) { struct hammer_ioc_pseudofs_rw pfs; char *linkpath; int fd; int i; if (ac == 0) pseudofs_usage(1); fd = getpfs(&pfs, av[0]); if (pfs.pfs_id == HAMMER_ROOT_PFSID) { fprintf(stderr, "You cannot destroy PFS#0\n"); exit(1); } printf("You have requested that PFS#%d (%s) be destroyed\n", pfs.pfs_id, pfs.ondisk->label); printf("This will irrevocably destroy all data on this PFS!!!!!\n"); printf("Do you really want to do this? [y/n] "); fflush(stdout); if (getyn() == 0) { fprintf(stderr, "No action taken on PFS#%d\n", pfs.pfs_id); exit(1); } if (hammer_is_pfs_master(pfs.ondisk)) { printf("This PFS is currently setup as a MASTER!\n"); printf("Are you absolutely sure you want to destroy it? [y/n] "); fflush(stdout); if (getyn() == 0) { fprintf(stderr, "No action taken on PFS#%d\n", pfs.pfs_id); exit(1); } } printf("Destroying PFS#%d (%s)", pfs.pfs_id, pfs.ondisk->label); if (DebugOpt) { printf("\n"); } else { printf(" in"); for (i = 5; i; --i) { printf(" %d", i); fflush(stdout); sleep(1); } printf(".. starting destruction pass\n"); } /* * Remove the softlink on success. */ if (ioctl(fd, HAMMERIOC_RMR_PSEUDOFS, &pfs) == 0) { printf("pfs-destroy of PFS#%d succeeded!\n", pfs.pfs_id); linkpath = getlink(av[0]); if (linkpath) { if (remove(linkpath) < 0) { fprintf(stderr, "Unable to remove softlink %s: %s\n", linkpath, strerror(errno)); /* exit status 0 anyway */ } free(linkpath); } } else { printf("pfs-destroy of PFS#%d failed: %s\n", pfs.pfs_id, strerror(errno)); } relpfs(fd, &pfs); }
/* Algorithm A of Knuth 6.2.3, balanced tree. key is pointer to a user data area containing the key and possibly more. We could recurse on this routine, but instead we iterate (like Knuth does, but using for(;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* head, int (*compar)(const void *, const void *), int*inserted, struct ts_entry **nullme, int * comparres) { /* t points to parent of p */ struct ts_entry *t = head; /* p moves down tree, p starts as root. */ struct ts_entry *p = head->rlink; /* s points where rebalancing may be needed. */ struct ts_entry *s = p; struct ts_entry *r = 0; struct ts_entry *q = 0; int a = 0; int kc = 0; for(;;) { /* A2. */ kc = compar(key,p->keyptr); if(kc) { /* A3 and A4 handled here. */ q = getlink(p,kc); if(!q) { /* Does step A5. */ q = tsearch_inner_do_insert(key,kc,inserted,p); if (!q) { /* Out of memory. */ return q; } break; /* to A5. */ } if(q->balance) { t = p; s = q; } p = q; continue; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* A5: work already done. */ /* A6: */ { /* Balance factors on nodes betwen S and Q need to be changed from zero to +-1 */ int kc2 = compar(key,s->keyptr); if (kc2 < 0) { a = -1; } else { a = 1; } r = p = getlink(s,a); while (p != q) { int kc3 = compar(key,p->keyptr); if(kc3 < 0) { p->balance = -1; p = p->llink; } else if (kc3 > 0) { p->balance = 1; p = p->rlink; } else { /* ASSERT: p == q */ break; } } } /* A7: */ { if(! s->balance) { /* Tree has grown higher. */ s->balance = a; /* Counting in pointers, not integers. Ugh. */ head->llink = head->llink + 1; return q; } if(s->balance == -a) { /* Tree is more balanced */ s->balance = 0; return q; } if (s->balance == a) { /* Rebalance. */ if(r->balance == a) { /* single rotation, step A8. */ p = r; setlink(s,a,getlink(r,-a)); setlink(r,-a,s); s->balance = 0; r->balance = 0; } else if (r->balance == -a) { /* double rotation, step A9. */ p = getlink(r,-a); setlink(r,-a,getlink(p,a)); setlink(p,a,r); setlink(s,a,getlink(p,-a)); setlink(p,-a,s); if(p->balance == a) { s->balance = -a; r->balance = 0; } else if (p->balance == 0) { s->balance = 0; r->balance = 0; } else if (p->balance == -a) { s->balance = 0; r->balance = a; } p->balance = 0; } else { fprintf(stderr,"Impossible balanced tree situation!\n"); /* Impossible. Cannot be here. */ exit(1); } } else { fprintf(stderr,"Impossible balanced tree situation!!\n"); /* Impossible. Cannot be here. */ exit(1); } } /* A10: */ if (s == t->rlink) { t->rlink = p; } else { t->llink = p; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return q; }
LINK* addlink (char* fun,char ev,char* str, char* str2,ALLEGRO_DISPLAY *dis) { LINK* clon; if (!strcmp(str,str2)) { al_show_native_message_box(dis, "ERROR!", "ERROR!", "Cannot create this kind of link",NULL, ALLEGRO_MESSAGEBOX_ERROR); return NULL; } if (linkdir==NULL) { if(getstate(str)==NULL) { return NULL; } if(getstate(str2)==NULL) { return NULL; } if(getlink(str,str2)!=NULL) { return NULL; } linkdir=calloc(1,sizeof(LINK)); linkdir->p2next=NULL; strcpy(linkdir->origen, str); strcpy(linkdir->destino, str2); strcpy(linkdir->fun_transf,fun); (linkdir->evento)=ev; ++linknumb; al_show_native_message_box(dis, "SUCCESS!", "Link created successfully", "",NULL, ALLEGRO_MESSAGEBOX_WARN); return(linkdir); } else { for(clon=linkdir;clon->p2next!=NULL;clon=clon->p2next); if(getstate(str)==NULL) { al_show_native_message_box(dis, "ERROR!", "ERROR!", "That link does not exist!",NULL, ALLEGRO_MESSAGEBOX_ERROR); return NULL; } if(getstate(str2)==NULL) { al_show_native_message_box(dis, "ERROR!", "ERROR!", "El estado de origen no existe(Linkdir).",NULL, ALLEGRO_MESSAGEBOX_ERROR); return NULL; } // if(getlink(str,str2)!=NULL) // { // al_show_native_message_box(dis, "ERROR!", "ERROR!", "El enlace ya existe!",NULL, ALLEGRO_MESSAGEBOX_ERROR); // return NULL; // } clon->p2next=calloc(1,sizeof(LINK)); clon->p2next->p2next=NULL; strcpy(clon->p2next->origen, str); strcpy(clon->p2next->destino, str2); strcpy(clon->p2next->fun_transf,fun); clon->p2next->evento=ev; ++linknumb; al_show_native_message_box(dis, "SUCCESS!", "Link created successfully", "",NULL, ALLEGRO_MESSAGEBOX_WARN); return(clon->p2next); } }
/* Returns deleted node parent unless the head changed. Returns NULL if wanted node not found or the tree is now empty or the head node changed. Sets *did_delete if it found and deleted a node. Sets *tree_empty if there are no more user nodes present. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *head, int (*compar)(const void *, const void *), int *tree_empty, int *did_delete ) { struct ts_entry *p = 0; struct ts_entry *pp = 0; struct pkrecord * pkarray = 0; int depth = head->llink - (struct ts_entry *)0; unsigned k = 0; /* Allocate extra, head is on the stack we create here and the depth might increase. */ depth = depth + 4; pkarray = calloc(sizeof(struct pkrecord),depth); if(!pkarray) { /* Malloc fails, we could abort... */ return NULL; } k = 0; pkarray[k].pk=head; pkarray[k].ak=1; p = head->rlink; while(p) { int kc = 0; k++; kc = compar(key,p->keyptr); pkarray[k].pk = p; pkarray[k].ak = kc; if(!kc) { break; } p = getlink(p,kc); } if(!p) { /* Node to delete never found. */ free(pkarray); return NULL; } { struct ts_entry *p = 0; struct ts_entry *t = 0; struct ts_entry *r = 0; int pak = 0; int ppak = 0; p = pkarray[k].pk; pak = pkarray[k].ak; pp = pkarray[k-1].pk; ppak = pkarray[k-1].ak; /* Found a match. p to be deleted. */ t = p; *did_delete = 1; if(!t->rlink) { if(k == 1 && !t->llink) { *tree_empty = 1; /* upper level will fix up head node. */ free(t); free(pkarray); return NULL; } /* t->llink might be NULL. */ setlink(pp,ppak,t->llink); /* ASSERT: t->llink NULL or t->llink has no children, balance zero and balance of t->llink not changing. */ k--; /* Step D4. */ free(t); goto balance; } #ifdef IMPLEMENTD15 /* Step D1.5 */ if(!t->llink) { setlink(pp,ppak,t->rlink); /* we change the left link off ak */ k--; /* Step D4. */ free(t); goto balance; } #endif /* IMPLEMENTD15 */ /* Step D2 */ r = t->rlink; if (!r->llink) { /* We decrease the height of the right tree. */ r->llink = t->llink; setlink(pp,ppak,r); pkarray[k].pk = r; pkarray[k].ak = 1; /* The following essential line not mentioned in Knuth AFAICT. */ r->balance = t->balance; /* Step D4. */ free(t); goto balance; } /* Step D3, we rearrange the tree and pkarray so the balance step can work. step D2 is insufficient so not done. */ k = rearrange_tree_so_p_llink_null(pkarray,k, head,r, p,pak,pp,ppak); goto balance; } /* Now use pkarray decide if rebalancing needed and, if needed, to rebalance. k here matches l-1 in Knuth. */ balance: { unsigned k2 = k; /* We do not want a test in the for() itself. */ for( ; 1 ; k2--) { struct ts_entry *pk = 0; int ak = 0; int bk = 0; if (k2 == 0) { /* decreased in height */ head->llink--; goto cleanup; } pk = pkarray[k2].pk; if (!pk) { /* Nothing here to work with. Move up. */ continue; } ak = pkarray[k2].ak; bk = pk->balance; if(bk == ak) { pk->balance = 0; continue; } if(bk == 0) { pk->balance = -ak; goto cleanup; } /* ASSERT: bk == -ak. We will use bk == adel here (just below). */ /* Rebalancing required. Here we use (1) and (2) in 6.2.3 to adjust the nodes */ { /* Rebalance. We use s for what is called A in Knuth Case 1, Case 2 page 461. r For what is called B. So the link movement logic looks similar to the tsearch insert case.*/ struct ts_entry *r = 0; struct ts_entry *s = 0; struct ts_entry *pa = 0; int pak = 0; int adel = -ak; s = pk; r = getlink(s,adel); pa = pkarray[k2-1].pk; pak = pkarray[k2-1].ak; if(r->balance == adel) { /* case 1. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,r); s->balance = 0; r->balance = 0; continue; } else if (r->balance == -adel) { /* case 2 */ /* x plays the role of p in step A9 */ struct ts_entry*x = getlink(r,-adel); setlink(r,-adel,getlink(x,adel)); setlink(x,adel,r); setlink(s,adel,getlink(x,-adel)); setlink(x,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,x); if(x->balance == adel) { s->balance = -adel; r->balance = 0; } else if (x->balance == 0) { s->balance = 0; r->balance = 0; } else if (x->balance == -adel) { s->balance = 0; r->balance = adel; } x->balance = 0; continue; } else { /* r->balance == 0 case 3 we do a single rotation and we are done. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); setlink(pa,pak,r); r->balance = -adel; /*s->balance = r->balance = 0; */ goto cleanup; } } } } cleanup: free(pkarray); #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return pp; }
/* * Set an individual arp entry */ static int set(int argc, char **argv) { struct sockaddr_inarp *sina; struct sockaddr_dl *sdl; struct rt_msghdr *rtm; char *host = argv[0], *eaddr; struct sockaddr_inarp sin_m = blank_sin; /* struct copy */ struct sockaddr_dl sdl_m = blank_sdl; /* struct copy */ int s; eaddr = argv[1]; s = getsocket(); argc -= 2; argv += 2; if (getinetaddr(host, &sin_m.sin_addr) == -1) return (1); if (atosdl(eaddr, &sdl_m)) warnx("invalid link-level address '%s'", eaddr); doing_proxy = flags = export_only = expire_time = 0; for (; argc-- > 0; argv++) { if (strncmp(argv[0], "temp", 4) == 0) { struct timeval timev; (void)gettimeofday(&timev, 0); expire_time = timev.tv_sec + 20 * 60; } else if (strncmp(argv[0], "pub", 3) == 0) { flags |= RTF_ANNOUNCE; doing_proxy = SIN_PROXY; if (argc && strncmp(argv[1], "pro", 3) == 0) { export_only = 1; argc--; argv++; } } else if (strncmp(argv[0], "trail", 5) == 0) { warnx("%s: Sending trailers is no longer supported", host); } else if (strcmp(argv[0], "ifscope") == 0) { if (argc == 0) { warnx("missing interface for ifscope"); continue; } argc--; argv++; if (!getlink(argv[0], &sdl_m)) warnx("cannot get link address for %s", argv[0]); } } if (memcmp(&sdl_m, &blank_sdl, sizeof(blank_sdl))) goto out; tryagain: rtm = rtmsg(s, RTM_GET, &sin_m, &sdl_m); if (rtm == NULL) { warn("%s", host); return (1); } sina = (struct sockaddr_inarp *)(void *)(rtm + 1); sdl = (struct sockaddr_dl *)(void *)(RT_ROUNDUP(sina->sin_len) + (char *)(void *)sina); if (sina->sin_addr.s_addr == sin_m.sin_addr.s_addr) { if (is_llinfo(sdl, rtm->rtm_flags)) goto overwrite; if (doing_proxy == 0) { warnx("set: can only proxy for %s", host); return (1); } if (sin_m.sin_other & SIN_PROXY) { warnx("set: proxy entry exists for non 802 device"); return (1); } sin_m.sin_other = SIN_PROXY; export_only = 1; goto tryagain; } overwrite: if (sdl->sdl_family != AF_LINK) { warnx("cannot intuit interface index and type for %s", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; out: sin_m.sin_other = 0; if (doing_proxy && export_only) sin_m.sin_other = SIN_PROXY; rtm = rtmsg(s, RTM_ADD, &sin_m, &sdl_m); if (vflag) (void)printf("%s (%s) added\n", host, eaddr); return (rtm == NULL) ? 1 : 0; }