📄 cmds.c
字号:
if (r==0) { *errmsg = hstrerror(h_errno); return NULL; } r = connect_t(s, (struct sockaddr *)&dst, sizeof(dst), timeout); if (r==-1) { *errmsg = strerror(errno); return NULL; } setkeepalive(s); r = ssock(s, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", path, urlhost); if (r==-1) { *errmsg = strerror(errno); return NULL; } free(host); free(path); f = fdopen(s, "r"); b = nap_getline(f); /* expect something like "HTTP/1.1 200 OK" */ if (!b) { fclose(f); *errmsg = "empty document"; return NULL; } tok = form_tokso(b, &cnt); if (cnt<2) { for (i=0; i<cnt; i++) free(tok[i]); free(tok); free(b); fclose(f); *errmsg = "ill-formed document"; return NULL; } if (atoi(tok[1]) != 200) { /* HTTP error */ for (i=0; i<cnt; i++) free(tok[i]); free(tok); fclose(f); *errmsg = cstr(b, 1); free(b); return NULL; } free(b); for (i=0; i<cnt; i++) free(tok[i]); free(tok); /* skip remaining HTTP headers */ while ((b = nap_getline(f)) != NULL) { if (*b==0) break; free(b); } free(b); return f;}/* format a time as a string, for instance, "1h 5m 24s". The time is given in seconds. Return a statically allocated string. */char *format_time(time_t t) { static char buf[100]; time_t s = t>=0 ? t : -t; char *sign = t>=0 ? "" : "-"; if (s>=3600) { sprintf(buf, "%s%ldh %ldm %lds", sign, s/3600, (s/60)%60, s%60); } else if (s>=60) { sprintf(buf, "%s%ldm %lds", sign, (s/60)%60, s%60); } else { sprintf(buf, "%s%lds", sign, s%60); } return buf;}/* ---------------------------------------------------------------------- *//* begin user commands */O_NAP_FUNC(dquit){ int n, m; download_t *dtask; upload_t *utask; if (num > 1 && !strcasecmp(tok[1], "yes")) { quit_now = 1; return(-3); /* jump out of all nested loops */ } list_count(down, n, dtask, !STOPPED(dtask->state)); list_count(up, m, utask, !STOPPED(utask->state)); if (m || n) { wp(win, m+n==1 ? ""RED"* There is " : ""RED"* There are "); if (m) { wp(win, m==1 ? "%d upload" : "%d uploads", m); } if (m && n) { wp(win, " and "); } if (n) { wp(win, n==1 ? "%d download" : "%d downloads", n); } wp(win, " pending. Use \"/quit yes\" if you want to quit immediately, and \"/tquit\" if you want to quit after pending transfers have finished."WHITE"\n"); drw(win); return(1); } quit_now = 1; return(-3); /* return to top level */}/* conditional quit: quit when all pending transfers have been completed */O_NAP_FUNC(dtquit){ int n, m; download_t *dtask; upload_t *utask; quit_after_transfers = 1; list_count(down, n, dtask, !STOPPED(dtask->state)); list_count(up, m, utask, !STOPPED(utask->state)); wp(win, ""RED"* Scheduled to quit after %d uploads and %d downloads have completed."WHITE"\n", m, n); drw(win); /* note that a tquit does not cause execution of a macro to be aborted. */ return(1);}O_NAP_FUNC(dunquit) { quit_after_transfers = 0; wp(win, "* Effect of /tquit was canceled\n"); drw(win); return(1);}O_NAP_FUNC(djoin){ chans_t *t; if (num < 2) /* no argument: print list of channels */ { sendpack(s, CHANNEL_LIST2, NULL); wp(win, ""BOLD"Channel"WHITE" | Users | Topic\n"); wp(win, "-----------------------\n"); return(1); } /* else join the channel */ t = findchan(chanl, tok[1]); if (t && !t->p) { curchan = t; return(1); } sendpack(s, NAP_JOIN, "%s", tok[1]); return(1);}O_NAP_FUNC(dpart){ chans_t *pt; if (num == 1) pt = curchan; else pt = findchan(chanl, tok[1]); if (!pt && num > 1) { wp(win, "%s* You are not on channel %s%s\n", RED, tok[1], WHITE); drw(win); return(1); } else if (!pt) { wp(win, "%s* You are not on a channel %s\n", RED, WHITE); drw(win); return(1); } if (!pt->q) { sendpack(s, NAP_PART, "%s", pt->nm); pt->p |= 1; return(1); } else if (pt->q == 2) { ssock(ircsock, "PART %s\n", pt->nm); pt->p |= 1; return(1); } wp(win, "%s* Ended query with %s%s\n", GREEN, pt->nm, WHITE); drw(win); /* remove the channel pt from the channel list */ delchan(pt); if (wmode) { dscr(win); drw(win); } return(1);}void usage(WINDOW *win, char *cmd) { int i; char *help, *p; for (i=0; out[i].nm; i++) { if (!strcasecmp(out[i].nm, cmd)) { break; } } if (!out[i].nm || !out[i].help) { wp(win, ""RED"* /%s: Invalid usage (no help available)"WHITE"\n", cmd); } else { help = strdup(out[i].help); p = strstr(help, " - "); if (p) { *p = 0; } wp(win, ""RED"* Usage: /%s %s"WHITE"\n", cmd, help); free(help); } drw(win);}O_NAP_FUNC(dtell){ char *msg; if (num < 3) { usage(win, tok[0]); return(-3); } msg = fixquotes(cstr(str, 2)); sendpack(s, NAP_TELL, "%s %s", tok[1], msg); recent = findquery(chanl, tok[1]); wp(win, "%s* --> (%s%s%s)%s %s\n", GREEN, WHITE, tok[1], GREEN, WHITE, msg); drw(win); recent = NULL; return(1);}O_NAP_FUNC(dwhois){ if (num < 2) sendpack(s, NAP_WHOIS, "%s", info.user); else sendpack(s, NAP_WHOIS, "%s", tok[1]); return(1);}O_NAP_FUNC(dfup){ stringlist_t *l = NULL; /* a list of nicks to avoid duplicate requests */ stringlist_t *elt; upload_t *task; int n; if (num < 2) { usage(win, tok[0]); return(-3); } for (n=parse_range(cstr(str, 1)); n!=-1; n=parse_range(NULL)) { /* find the n-th element in the upload list */ list_nth(task, up, n-1); if (!task) { wp(win, "* Upload number %d does not exist\n", n); drw(win); } else { list_find(elt, l, !strcasecmp(elt->s, task->nick)); if (!elt) { wp(win, "* Requesting information on %s\n", task->nick); drw(win); sendpack(s, NAP_WHOIS, "%s", task->nick); elt = (stringlist_t *)malloc(sizeof(stringlist_t)); elt->s = task->nick; if (elt) { list_prepend(l, elt); } } } } /* clear the list */ list_forall_unlink(elt, l) { free(elt); } return(1);}O_NAP_FUNC(dfdown){ stringlist_t *l = NULL; /* a list of nicks to avoid duplicate requests */ stringlist_t *elt; download_t *task; int n; if (num < 2) { usage(win, tok[0]); return(-3); } for (n=parse_range(cstr(str, 1)); n!=-1; n=parse_range(NULL)) { /* find the n-th element in the download list */ list_nth(task, down, n-1); if (!task) { wp(win, "* Download number %d does not exist\n", n); drw(win); } else { list_find(elt, l, !strcasecmp(elt->s, task->nick)); if (!elt) { wp(win, "* Requesting information on %s\n", task->nick); drw(win); sendpack(s, NAP_WHOIS, "%s", task->nick); elt = (stringlist_t *)malloc(sizeof(stringlist_t)); elt->s = task->nick; if (elt) { list_prepend(l, elt); } } } } return(1);}/* parses a range of non-negative numbers, e.g. "1,3-4,5" or "1 3-4 5". The first time this is called, RANGE should be a string representing the range of numbers to be parsed. Each subsequent call should pass RANGE=NULL. Each call will return the next available integer, or -1 when done. */int parse_range(char *range) { static char *ran=NULL; /* next subrange */ static int i=0; /* next number to return */ static int e=-1; /* last number in current subrange to return */ if (range) { ran = strtok(range, ", "); i = 0; e = -1; } while (1) { if (i<=e) { i++; return i-1; } if (!ran) return -1; if (*ran && strchr(ran+1, '-')) /* assume token is a subrange */ sscanf(ran, "%i-%i", &i, &e); else /* token is a single number */ i = e = atoi(ran); if (i<0) i=0; ran = strtok(NULL, ", "); }}/* get files by number e.g. "/g 1,3-4,5" or "/g 1 3-4 5" */O_NAP_FUNC(dg){ ssearch_t *cur=search; int n; int r; if (num < 2) { usage(win, tok[0]); return(-3); } if (!search) { wp(win, "%s* No search performed yet%s\n", RED, WHITE); drw(win); return(1); } for (n = parse_range(cstr(str, 1)); n != -1; n = parse_range(NULL)) { list_nth(cur, search, n-1); if (cur == NULL) { /* no matching item */ wp(win, ""RED"* Error: no search result numbered %d"WHITE"\n", n); drw(win); return(1); /* skip rest of range */ } r = requestdownload(s, cur); switch(r) { case 0: wp(win, "* Getting \"%s\" from %s\n", cur->song, cur->nick); break; case 1: case 2: wp(win, "* Queued download of \"%s\" from %s\n", cur->song, cur->nick); break; case 3: wp(win, "* Remotely queued download of \"%s\" from %s\n", cur->song, cur->nick); break; case -1: wp(win, "* Already getting \"%s\" from %s\n", cur->song, cur->nick); break; case -2: wp(win, "* Download of \"%s\" from %s is already queued\n", cur->song, cur->nick); break; case -3: wp(win, "* You can't get \"%s\" from yourself\n", cur->song); break; default: break; } drw(win); } drw(win); return(1);}/* request to download the given search item. Returns: 0 on success, -1 if we are already getting this item, -2 if the item is already queued, -3 if we can't get this item because we are the user offering it, 1 if this item was queued because the per-user download limit was reached, 2 if it was queued because the overall download limit was reached, 3 if it was rqueued because there is already an rqueued or rrqueued item by this nick. */int requestdownload(int s, ssearch_t *sitem) { download_t *task; int r; /* see if the user offering this item is us */ if (!strcasecmp(sitem->nick, info.user)) { return -3; } /* create item for the download list */ task = (download_t *)malloc(sizeof(download_t)); task->nick = strdup(sitem->nick); task->rfn = strdup(sitem->rfn); task->fn = strdup(sitem->song); r = retrydownload(s, task); /* failure? */ if (r==-1 || r==-2) { free(task->nick); free(task->rfn); free(task->fn); free(task); return r; } /* else: append item to the download list */ list_append(download_t, down, task); return r;}/* request to download the given search item. Returns: 0 on success, -1 if we are already getting this item, -2 if the item is already queued, 1 if this item was queued because the per-user download limit was reached, 2 if it was queued because the overall download limit was reached, 3 if it was rqueued because there is already an
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -