long hunt(char *name) { char *cp; sig_t f; int res; f = signal(SIGALRM, dead); while ((cp = getremote(name))) { deadfl = 0; if ((uucplock = strrchr(cp, '/')) == NULL) uucplock = cp; else ++uucplock; if ((res = uu_lock(uucplock)) != UU_LOCK_OK) { if (res != UU_LOCK_INUSE) fprintf(stderr, "uu_lock: %s\n", uu_lockerr(res)); continue; } /* * Straight through call units, such as the BIZCOMP, * VADIC and the DF, must indicate they're hardwired in * order to get an open file descriptor placed in FD. * Otherwise, as for a DN-11, the open will have to * be done in the "open" routine. */ if (!HW) break; if (setjmp(deadline) == 0) { alarm(10); FD = open(cp, O_RDWR); } alarm(0); if (FD < 0) { warn("%s", cp); deadfl = 1; } if (!deadfl) { ioctl(FD, TIOCEXCL, 0); { struct termios t; if (tcgetattr(FD, &t) == 0) { t.c_cflag |= HUPCL; (void)tcsetattr(FD, TCSANOW, &t); } } signal(SIGALRM, SIG_DFL); return ((long)cp); } (void)uu_unlock(uucplock); } signal(SIGALRM, f); return (deadfl ? -1 : (long)cp); }
long hunt(char *name) { char *cp; sig_t f; f = signal(SIGALRM, dead); while ((cp = getremote(name))) { deadfl = 0; uucplock = strrchr(cp, '/'); if (uucplock == NULL) uucplock = cp; else uucplock++; if (uu_lock(uucplock) < 0) continue; /* * Straight through call units, such as the BIZCOMP, * VADIC and the DF, must indicate they're hardwired in * order to get an open file descriptor placed in FD. * Otherwise, as for a DN-11, the open will have to * be done in the "open" routine. */ if (!HW) break; if (setjmp(deadline) == 0) { alarm(10); FD = open(cp, (O_RDWR | (boolean(value(DC)) ? O_NONBLOCK : 0))); } alarm(0); if (FD < 0) { perror(cp); deadfl = 1; } if (!deadfl) { struct termios cntrl; tcgetattr(FD, &cntrl); if (!boolean(value(DC))) cntrl.c_cflag |= HUPCL; tcsetattr(FD, TCSAFLUSH, &cntrl); ioctl(FD, TIOCEXCL, 0); signal(SIGALRM, SIG_DFL); return ((long)cp); } (void)uu_unlock(uucplock); } signal(SIGALRM, f); return (deadfl ? -1 : (long)cp); }
int trackfile(int sockfd, char *filename, char *range, uint16_t num_trackers, in_addr_t *trackers, uint16_t maxpeers, uint16_t num_pkg_servers, in_addr_t *pkg_servers, CURL *curlhandle) { #ifdef TIMEIT struct timeval start_time, end_time; unsigned long long s, e; #endif CURLcode curlcode; uint64_t hash; uint16_t i; tracker_info_t *tracker_info, *infoptr; int info_count; char success; #ifdef TIMEIT gettimeofday(&start_time, NULL); #endif hash = hashit(filename); #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time1: %lld usec file (%s)\n", (e - s), filename); #endif #ifdef DEBUG { int j; struct in_addr in; for (j = 0 ; j < num_trackers ; ++j) { in.s_addr = trackers[j]; logmsg("trackfile:trackers[%d] = (%s)\n", j, inet_ntoa(in)); } for (j = 0 ; j < num_pkg_servers ; ++j) { in.s_addr = pkg_servers[j]; logmsg("trackfile:pkg_servers[%d] = (%s)\n", j, inet_ntoa(in)); } } #endif #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time2: %lld usec file (%s)\n", (e - s), filename); #endif /* * see if there is a prediction for this file */ tracker_info = NULL; info_count = getprediction(hash, &tracker_info); #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time3: %lld usec file (%s)\n", (e - s), filename); #endif #ifdef DEBUG if (info_count == 0) { logmsg("trackfile:pred miss (0x%016llx)\n", hash); } else { logmsg("trackfile:pred hit (0x%016llx)\n", hash); } #endif if (info_count == 0) { /* * no prediction. need to ask a tracker for peer info for * this file. */ for (i = 0 ; i < num_trackers; ++i) { #ifdef DEBUG struct in_addr in; in.s_addr = trackers[i]; logmsg("trackfile:sending lookup to tracker (%s)\n", inet_ntoa(in)); #endif info_count = lookup(sockfd, &trackers[i], hash, &tracker_info); if (info_count > 0) { break; } /* * lookup() mallocs space for 'tracker_info', so need to * free it here since we'll call lookup() again in the * next iteration */ if (tracker_info != NULL) { free(tracker_info); tracker_info = NULL; } } } #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time4: %lld usec file (%s)\n", (e - s), filename); #endif #ifdef DEBUG logmsg("trackfile:info_count (%d)\n", info_count); #endif success = 0; infoptr = tracker_info; if ((info_count > 0) && (infoptr->hash == hash)) { /* * write the prediction info to a file */ save_prediction_info(tracker_info, info_count); #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time5: %lld usec file (%s)\n", (e - s), filename); #endif #ifdef DEBUG logmsg("trackfile:hash (0x%llx) : numpeers (%d)\n", infoptr->hash, infoptr->numpeers); logmsg("trackfile:peers:\n"); for (i = 0 ; i < infoptr->numpeers; ++i) { struct in_addr in; in.s_addr = infoptr->peers[i].ip; logmsg("\t%s : %c %d\n", inet_ntoa(in), (infoptr->peers[i].state == DOWNLOADING ? 'd' : 'r'), infoptr->peers[i].state); } #endif #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time6: %lld usec file (%s)\n", (e - s), filename); #endif for (i = 0 ; i < infoptr->numpeers; ++i) { #ifdef DEBUG { struct in_addr in; int k; in.s_addr = infoptr->peers[i].ip; if (strncmp(inet_ntoa(in), "10.", 3)) { for (k = 0 ; i < num_trackers; ++k) { send_msg(sockfd, &trackers[k], STOP_SERVER); } logmsg("trackfile:bogus IP (%s)\n", inet_ntoa(in)); exit(-1); } } #endif if (getremote(filename, &infoptr->peers[i], range, curlhandle) == 0) { /* * successful download, exit this loop */ success = 1; break; } else { /* * mark the peer as 'bad'. we do this by * telling the tracker server to 'unregister' * this hash. */ tracker_info_t *info; int len; int j; len = sizeof(*info) + sizeof(peer_t); if ((info = (tracker_info_t *)malloc(len)) != NULL) { bzero(info, len); info->hash = hash; info->numpeers = 1; info->peers[0].ip = infoptr->peers[i].ip; for (j = 0 ; j < num_trackers; ++j) { unregister_hash(sockfd, &trackers[j], 1, info); } free(info); } } } } #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time7: %lld usec file (%s)\n", (e - s), filename); #endif if (!success) { /* * unable to download the file from a peer, need to * get it from one of the package servers */ for (i = 0 ; i < num_pkg_servers ; ++i) { peer_t pkgpeer; pkgpeer.ip = pkg_servers[i]; pkgpeer.state = READY; /* * if this is the last package server, then * disable the connection timeout -- this is our * last hope of getting the package. */ if (i == (num_pkg_servers - 1)) { if ((curlcode = curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, 0)) != CURLE_OK) { logmsg("getremote:curl_easy_setopt():failed:(%d)\n", curlcode); } } if (getremote(filename, &pkgpeer, range, curlhandle) == 0) { success = 1; } /* * reset the connection timeout */ if (i == (num_pkg_servers - 1)) { if ((curlcode = curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, 2)) != CURLE_OK) { logmsg("getremote:curl_easy_setopt():failed:(%d)\n", curlcode); } } if (success) { break; } } } #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time8: %lld usec file (%s)\n", (e - s), filename); #endif if (success) { tracker_info_t info[1]; bzero(info, sizeof(info)); info[0].hash = hash; info[0].numpeers = 0; for (i = 0 ; i < num_trackers; ++i) { register_hash(sockfd, &trackers[i], 1, info); } } /* * lookup() and getprediction() mallocs tracker_info */ if (tracker_info != NULL) { free(tracker_info); } #ifdef TIMEIT gettimeofday(&end_time, NULL); s = (start_time.tv_sec * 1000000) + start_time.tv_usec; e = (end_time.tv_sec * 1000000) + end_time.tv_usec; logmsg("trackfile:svc time: %lld usec file (%s)\n", (e - s), filename); #endif if (success) { return(0); } return(-1); }