FILE *wget_open(struct wgetfile *finfo, char *mode) { if(finfo->outname){ extern struct cfg global_cfg; FILE *ret; if(strlen(finfo->outname) > PATH_MAX) finfo->outname[PATH_MAX - 1] = '\0'; else if(!*finfo->outname){ free(finfo->outname); finfo->outname = xstrdup("index.html"); } /* if not explicitly specified, check for finfo->outname overwrites */ if(!global_cfg.out_fname && !global_cfg.partial && !global_cfg.overwrite && !access(finfo->outname, F_OK)){ output_err(OUT_ERR, "%s: file exists", finfo->outname); return NULL; } ret = fopen(finfo->outname, mode ? mode : (global_cfg.partial ? "a+" : "w+")); if(!ret) output_err(OUT_ERR, "open: \"%s\": %s", finfo->outname, strerror(errno)); return ret; }else{ return stdout; } }
int dial(const char *host, const char *port) { extern struct cfg global_cfg; extern const char *argv0; FILE *errfile = global_cfg.logf; struct addrinfo hints, *list = NULL, *iter; struct sockaddr *last_addr = NULL; int sock, last_err; if(!errfile) errfile = stderr; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; fprintf(errfile, "%s: resolving %s:%s...", argv0, host, port); if((last_err = getaddrinfo(host, port, &hints, &list))){ fputc('\n', errfile); output_err(OUT_ERR, "getaddrinfo(): \"%s:%s\": %s", host, port, gai_strerror(last_err)); return -1; } for(iter = list; iter; iter = iter->ai_next){ sock = socket(iter->ai_family, iter->ai_socktype, iter->ai_protocol); if(sock == -1) continue; last_addr = iter->ai_addr; retry: if(connect(sock, iter->ai_addr, iter->ai_addrlen) == 0){ break; }else if(errno == EINTR){ goto retry; } if(errno) last_err = errno; close(sock); sock = -1; } if(last_addr) fprintf(errfile, " %s", inet_ntoa(((struct sockaddr_in *)last_addr)->sin_addr)); fputc('\n', errfile); freeaddrinfo(list); if(sock == -1){ errno = last_err; output_err(OUT_ERR, "connect to %s:%s: %s", host, port, strerror(errno)); } return sock; }
void do_mmap() { size_t memsize; off_t off = 0; int fd; char *arg; arg = nextarg(); if (!arg) { memsize = last_memsize; fd = last_fd; goto doit; } memsize = atoi(arg); arg = nextarg(); if (!arg) { fd = last_fd; goto doit; } fd = atoi(arg); arg = nextarg(); if (arg) { off = (off_t)atol(arg); } doit: last_mmap_addr = mmap(0, memsize, PROT_WRITE | PROT_READ, MAP_SHARED, fd, off); if (last_access_addr == NULL) last_access_addr = last_mmap_addr; output_err(last_mmap_addr == MAP_FAILED ? -1 : 0, "mmap(0, %zu, PROT_WRITE|PROT_READ, MAP_SHARED, %d, %jd)=%p", memsize, fd, (intmax_t)off, last_mmap_addr); }
char *fdreadline(int sock) { static char buffer[BSIZ]; char *pos; #define RECV(len, flags, lbl_restart) \ lbl_restart: \ switch(recv(sock, buffer, len, flags)){ \ case -1: \ if(errno == EINTR) \ goto lbl_restart; \ output_perror("recv()"); \ return NULL; \ case 0: /* unexpected here - need \r\n\r\n */ \ return NULL; \ } RECV(sizeof buffer, MSG_PEEK, recv_1); if((pos = strchr(buffer, '\n'))){ int len = pos - buffer + 1; RECV(len, 0, recv_2); if(pos > buffer && pos[-1] == '\r') pos[-1] = '\0'; else *pos = '\0'; /* just \n, not \r\n, deal with it */ return strdup(buffer); } output_err(OUT_ERR, "util::readline(): buffer too small"); return NULL; }
void do_regif() { int ret; char *arg, *name; int fd = last_fd; name = nextarg(); if (!name) { name = nmr_name; goto doit; } bzero(&curr_nmr, sizeof(curr_nmr)); curr_nmr.nr_version = NETMAP_API; curr_nmr.nr_flags = NR_REG_ALL_NIC; strncpy(curr_nmr.nr_name, name, sizeof(curr_nmr.nr_name)); arg = nextarg(); if (!arg) { goto doit; } fd = atoi(arg); arg = nextarg(); parse_nmr_config(arg, &curr_nmr); doit: ret = ioctl(fd, NIOCREGIF, &curr_nmr); last_memsize = curr_nmr.nr_memsize; output_err(ret, "ioctl(%d, NIOCREGIF) for %s: region %d memsize=%zu", fd, name, curr_nmr.nr_arg2, last_memsize); }
void do_getinfo() { int ret; char *arg, *name; int fd; bzero(&curr_nmr, sizeof(curr_nmr)); curr_nmr.nr_version = NETMAP_API; name = nextarg(); if (name) { strncpy(curr_nmr.nr_name, name, sizeof(curr_nmr.nr_name)); } else { name = "any"; } arg = nextarg(); if (!arg) { fd = last_fd; goto doit; } fd = atoi(arg); arg = nextarg(); parse_nmr_config(arg, &curr_nmr); doit: ret = ioctl(fd, NIOCGINFO, &curr_nmr); last_memsize = curr_nmr.nr_memsize; output_err(ret, "ioctl(%d, NIOCGINFO) for %s: region %d memsize=%zu", fd, name, curr_nmr.nr_arg2, last_memsize); }
int wget_connect(struct wgetfile *finfo) { extern struct cfg global_cfg; const char *host, *port; if(finfo->proto == HTTP && global_cfg.http_proxy){ host = global_cfg.http_proxy; port = global_cfg.http_proxy_port; }else{ host = finfo->host_name; port = finfo->host_port; } finfo->sock = connection_fd(host, port); if(finfo->sock == -1){ finfo->sock = dial(host, port); if(finfo->sock == -1) return 1; /* dial() prints the error */ connection_add(finfo->sock, host, port); }else{ output_err(OUT_INFO, "Reusing connection to %s:%s", host, port); } return 0; }
void do_poll() { /* timeout fd fd... */ nfds_t nfds = 0, allocated_fds = 10, i; struct pollfd *fds; int timeout = 500; /* 1/2 second */ char *arg; int ret; arg = nextarg(); if (arg) timeout = atoi(arg); fds = malloc(allocated_fds * sizeof(struct pollfd)); if (fds == NULL) { output_err(-1, "out of memory"); return; } while ( (arg = nextarg()) ) { if (nfds >= allocated_fds) { struct pollfd *new_fds; allocated_fds *= 2; new_fds = realloc(fds, allocated_fds * sizeof(struct pollfd)); if (new_fds == NULL) { free(fds); output_err(-1, "out of memory"); return; } fds = new_fds; } fds[nfds].fd = atoi(arg); fds[nfds].events = POLLIN; nfds++; } ret = poll(fds, nfds, timeout); for (i = 0; i < nfds; i++) { output("poll(%d)=%s%s%s%s%s", fds[i].fd, (fds[i].revents & POLLIN) ? "IN " : "- ", (fds[i].revents & POLLOUT)? "OUT " : "- ", (fds[i].revents & POLLERR)? "ERR " : "- ", (fds[i].revents & POLLHUP)? "HUP " : "- ", (fds[i].revents & POLLNVAL)?"NVAL" : "-"); } output_err(ret, "poll(...)=%d", ret); free(fds); }
void do_rxsync() { char *arg = nextarg(); int fd = arg ? atoi(arg) : last_fd; int ret = ioctl(fd, NIOCRXSYNC, NULL); output_err(ret, "ioctl(%d, NIOCRXSYNC)=%d", fd, ret); }
void do_close() { int ret, fd; char *arg = nextarg(); fd = arg ? atoi(arg) : last_fd; ret = close(fd); output_err(ret, "close(%d)=%d", fd, ret); }
char* xstrdup(const char* s) { char* result = strdup(s); if (result == NULL) { output_err("strdup failed\n"); abort(); } return result; }
void do_expr() { unsigned long stack[11]; int top = 10; char *arg; int err = 0; stack[10] = ULONG_MAX; while ( (arg = nextarg()) ) { errno = 0; char *rest; unsigned long n = strtoul(arg, &rest, 0); if (!errno && rest != arg) { if (top <= 0) { err = -1; break; } stack[--top] = n; continue; } if (top <= 8) { unsigned long n1 = stack[top++]; unsigned long n2 = stack[top++]; unsigned long r = 0; switch (arg[0]) { case '+': r = n1 + n2; break; case '-': r = n1 - n2; break; case '*': r = n1 * n2; break; case '/': if (n2) r = n1 / n2; else { errno = EDOM; err = -1; } break; default: err = -1; break; } stack[--top] = r; continue; } err = -1; break; } output_err(err, "expr=%lu", stack[top]); }
void* xrealloc(void *ptr, size_t sz) { if (sz == 0) sz = 1; void* result = realloc(ptr, sz); if (result == NULL) { output_err("realloc failed\n"); abort(); } return result; }
void* xmalloc(size_t sz) { if (sz == 0) sz = 1; void* result = malloc(sz); if (result == NULL) { output_err("malloc failed\n"); abort(); } return result; }
void do_dup() { char *arg = nextarg(); int fd = last_fd; int ret; if (arg) { fd = atoi(arg); } ret = dup(fd); output_err(ret, "dup(%d)=%d", fd, ret); }
void* xcalloc(size_t nmemb, size_t size) { if (nmemb == 0 || size == 0) { nmemb = 1; size = 1; } void* result = calloc(nmemb, size); if (result == NULL) { output_err("calloc failed\n"); abort(); } return result; }
int fdprintf(int fd, const char *fmt, ...) { char buffer[512]; va_list l; unsigned int n; va_start(l, fmt); n = vsnprintf(buffer, sizeof buffer, fmt, l); va_end(l); if(n >= sizeof(buffer)) output_err(OUT_ERR, "fdprintf() warning: buffer not large enough - FIXME"); return write(fd, buffer, n); }
void do_munmap() { void *mmap_addr; size_t memsize; char *arg; int ret; arg = nextarg(); if (!arg) { mmap_addr = last_mmap_addr; memsize = last_memsize; goto doit; } mmap_addr = (void*)strtoul(arg, NULL, 0); arg = nextarg(); if (!arg) { memsize = last_memsize; goto doit; } memsize = (size_t)strtoul(arg, NULL, 0); doit: ret = munmap(mmap_addr, memsize); output_err(ret, "munmap(%p, %zu)=%d", mmap_addr, memsize, ret); }
int cookies_load(const char *fname) { #define MAL_LINE(s) \ { \ /*fputs(s "\n", stderr); */ \ continue; \ } FILE *f = fopen(fname, "r"); char buffer[256]; struct cookie **cur_cookie = &cookies; if(!f){ output_err(OUT_WARN, "Couldn't load cookie file \"%s\"", fname); return 1; } while(fgets(buffer, sizeof buffer, f)){ struct cookie *c; char *iter; int i; if((iter = strchr(buffer, '\n'))) *iter = '\0'; iter = strchr(buffer, '\t'); if(iter){ char *host, *nam, *val; char *prev; *iter = '\0'; host = buffer; if(!*host) MAL_LINE("Empty host"); for(i = 0; i < 5 && iter; i++){ prev = iter + 1; iter = strchr(prev, '\t'); } if(iter){ nam = prev; iter = strchr(nam, '\t'); if(iter){ /* val */ *iter = '\0'; val = iter + 1; NEW_COOKIE(*cur_cookie); c = *cur_cookie; c->host = xstrdup(host); c->nam = xstrdup(nam); c->val = xstrdup(val); }else{ MAL_LINE("No value"); } }else{ MAL_LINE("No name"); } }else{ MAL_LINE("No host"); } cur_cookie = &c->next; } if(ferror(f)){ output_perror("read()"); goto bail; } fclose(f); return 0; bail: fclose(f); cookies_free(cookies, 1); return 1; }
static void alloc_die(unsigned int len) { output_err(OUT_ERR, "Couldn't allocate %ud bytes", len); exit(1); }
int generic_transfer(struct wgetfile *finfo, FILE *out, size_t len, size_t sofar, int closefd) { #define RET(n) do{ ret = n; goto fin; }while(0) int ret = 0; long last_progress, last_speed_calc; long chunk = 0; /* for bps */ long speed = 0; last_progress = last_speed_calc = mstime(); if(!len) progress_unknown(sofar, 0); do{ ssize_t nread; char buffer[BSIZ]; long t; switch((nread = recv(finfo->sock, buffer, sizeof buffer, 0))){ case -1: if(errno == EINTR) continue; /* TODO: retry */ if(len && sofar == len) goto end_of_stream; connection_close_fd(finfo->sock); output_perror("recv()"); RET(1); case 0: end_of_stream: connection_close_fd(finfo->sock); if(len){ if(sofar == len){ RET(0); }else{ /* TODO: goto retry */ progress_incomplete(); RET(1); } }else{ /* no length, assume we have the whole file */ RET(0); } /* unreachable */ default: { int trunc = 0; if(len && sofar + nread > len){ output_err(OUT_WARN, "too much data, truncating by %zu bytes", sofar + nread - len); trunc = 1; nread = len - sofar; sofar = len; }else{ sofar += nread; } while(fwrite(buffer, sizeof(buffer[0]), nread, out) != (unsigned)nread){ if(errno == EINTR) continue; output_perror("fwrite()"); RET(1); } if(sofar == len) RET(0); /* don't wait for more, maybe be pipelining */ chunk += nread; if(trunc) goto end_of_stream; } } t = mstime(); if(last_progress + 250 < t){ if(last_speed_calc + 1000 < t){ long tdiff = t - last_speed_calc; if(tdiff){ speed = 1000.0f /* kbps */ * (float)chunk / (float)tdiff; chunk = 0; last_speed_calc = t; } } last_progress = t; if(len) progress_show(sofar, len, speed); else progress_unknown(sofar, speed); } }while(1); fin: if(len) progress_fin(sofar, len); else progress_fin(0, 0); if(closefd) { ret |= wget_close(finfo, out); if(ret) wget_failure(finfo); else wget_success(finfo); } return ret; }
static int Command(void *_context, OutputCmd_t command, void * argument) { Context_t *context = (Context_t*) _context; int ret = cERR_OUTPUT_NO_ERROR; output_printf(10, "%s::%s Command %d\n", FILENAME, __FUNCTION__, command); switch(command) { case OUTPUT_OPEN: { if (context && context->playback ) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_OPEN, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_OPEN, "audio"); } if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_OPEN, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_CLOSE: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio"); } if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_ADD: { OutputAdd(context, (char*) argument); break; } case OUTPUT_DEL: { OutputDel(context, (char*) argument); break; } case OUTPUT_CAPABILITIES: { printOutputCapabilities(); break; } case OUTPUT_PLAY: { // 4 if (context && context->playback ) { if (context->playback->isVideo) { ret = context->output->video->Command(context, OUTPUT_PLAY, "video"); } // success or not executed, dunn care if (!ret) { if (context->playback->isAudio) { ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio"); } } if (!ret) { if (context->playback->isSubtitle) { ret = context->output->subtitle->Command(context, OUTPUT_PLAY, "subtitle"); } } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_STOP: { if (context && context->playback ) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_STOP, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio"); } if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_FLUSH: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio"); } if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_PAUSE: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio"); } if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_FASTFORWARD: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_REVERSE: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_CONTINUE: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio"); } if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_AVSYNC: { if (context && context->playback ) { if (context->playback->isVideo && context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_AVSYNC, "audio"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_CLEAR: { if (context && context->playback ) { if (context->playback->isVideo && (argument == NULL || *(char *) argument == 'v')) { ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video"); } if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a')) { ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio"); } if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's')) { ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_PTS: { if (context && context->playback ) { if (context->playback->isVideo) { return context->output->video->Command(context, OUTPUT_PTS, argument); } if (context->playback->isAudio) { return context->output->audio->Command(context, OUTPUT_PTS, argument); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_SWITCH: { if (context && context->playback ) { if (context->playback->isAudio) { return context->output->audio->Command(context, OUTPUT_SWITCH, "audio"); } if (context->playback->isVideo) { return context->output->video->Command(context, OUTPUT_SWITCH, "video"); } if (context->playback->isSubtitle) { return context->output->subtitle->Command(context, OUTPUT_SWITCH, "subtitle"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_SLOWMOTION: { if (context && context->playback ) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video"); } if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio"); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_AUDIOMUTE: { if (context && context->playback) { if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_AUDIOMUTE, (char*) argument); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_DISCONTINUITY_REVERSE: { if (context && context->playback) { if (context->playback->isVideo) { ret |= context->output->video->Command(context, OUTPUT_DISCONTINUITY_REVERSE, (void*) argument); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } case OUTPUT_GET_FRAME_COUNT: { if (context && context->playback) { if (context->playback->isVideo) { return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument); } if (context->playback->isAudio) { return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; case OUTPUT_GET_PROGRESSIVE: { if (context && context->playback) { if (context->playback->isVideo) { return context->output->video->Command(context, OUTPUT_GET_PROGRESSIVE, (void*) argument); } } else { ret = cERR_OUTPUT_INTERNAL_ERROR; } break; } } default: output_err("%s::%s OutputCmd %d not supported!\n", FILENAME, __FUNCTION__, command); ret = cERR_OUTPUT_INTERNAL_ERROR; break; } output_printf(10, "%s::%s exiting with value %d\n", FILENAME, __FUNCTION__, ret); return ret; }
void wget_failure(struct wgetfile *finfo) { output_err(OUT_WARN, "Partial data saved to '%s'", SAVE_FILE); }
void wget_success(struct wgetfile *finfo) { output_err(OUT_INFO, "Saved '%s' -> '%s'", finfo->host_file, SAVE_FILE); }
int wget(const char *url, int redirect_no) { extern struct cfg global_cfg; struct wgetfile finfo; int ret; char *outname = NULL; char *host, *file, *proto, *port; char *urlcpy = alloca(strlen(url) + 2); strcpy(urlcpy, url); memset(&finfo, 0, sizeof finfo); finfo.redirect_no = redirect_no; if(!strchr(urlcpy, '/')) strcat(urlcpy, "/"); if(parseurl(url, &host, &file, &proto, &port)) return 1; if(!host || !port){ output_err(OUT_ERR, "invalid url \"%s\"", url); goto bail; } if( !strcmp(proto, "http")) finfo.proto = HTTP; else if(!strcmp(proto, "ftp")) finfo.proto = FTP; else if(!strcmp(proto, "gopher")) finfo.proto = GOPHER; else{ ret = 1; output_err(OUT_ERR, "unknown protocol: %s", proto); goto bail; } free(proto); if(global_cfg.out_fname){ if(!strcmp(global_cfg.out_fname, "-")) outname = NULL; else outname = xstrdup(global_cfg.out_fname); finfo.namemode = NAME_FORCE; }else{ char *the_last_slash_rated_pg_for_parental_guidance; the_last_slash_rated_pg_for_parental_guidance = strrchr(file, '/'); if(the_last_slash_rated_pg_for_parental_guidance) outname = xstrdup(the_last_slash_rated_pg_for_parental_guidance + 1); else outname = xstrdup(file); finfo.namemode = NAME_GUESS; /* TODO: urldecode outname (except for %3f) */ } finfo.sock = -1; finfo.host_file = file; finfo.host_name = host; finfo.host_port = port; finfo.outname = outname; if(wget_connect(&finfo)) goto bail; switch(finfo.proto) { default: case HTTP: ret = http_GET(&finfo); break; case FTP: ret = ftp_RETR(&finfo); break; case GOPHER: ret = gopher_retrieve(&finfo); break; } fin: /* don't close the connection - let connection_* handle it */ /* free the struct's members, since they might be changed */ free(finfo.host_file); free(finfo.host_name); free(finfo.host_port); free(finfo.outname ); return ret; bail: ret = 1; goto fin; }
void do_open() { last_fd = open("/dev/netmap", O_RDWR); output_err(last_fd, "open(\"/dev/netmap\", O_RDWR)=%d", last_fd); }