📄 cmds.c
字号:
j++; continue; } tok = form_toks(t, &cnt); if (tok[0] && *tok[0] == '#') { if (b[j]) j++; for (i=0;i<cnt;i++) free(tok[i]); free(tok); continue; } if (*tok && *tok[0] == '.') { bc = 1; memmove(tok[0], tok[0]+1, strlen(tok[0]+1)+1); memmove(t, t+1, strlen(t+1)+1); f++; } for (cur=alhead;;cur=cur->next) { if (!cur || !tok[0]) { if (sw && tok[0] && !bc) { js = 0; tok = fxv(tok, cnt, &cnt); for (i=0;i<cnt;i++) { if (*tok[i] == '$' && tok[i][1] && tok[i][1] != '+') { p = dovars(tok[i]+1); if (p) { free(tok[i]); tok[i] = p; js = 1; } } } /* for i */ for (i=0; i<cnt; i++) { if (*tok[i] == '$' && tok[i][1] == '+' && !tok[i][2]) { if (i > 0 && tok[i-1] && tok[i+1]) { for (x=1;tok[i-x]&&!(*tok[i-x]);x++); for (y=1;tok[i+y]&&!(*tok[i+y]);y++); if (!tok[i-x]) x--; if (!tok[i+y]) y--; tok[i] = (char *)realloc(tok[i], strlen(tok[i-x])+strlen(tok[i+y])+1); if (strcmp(tok[i-x], "$+")) strcpy(tok[i], tok[i-x]); else *tok[i] = 0; if (strcmp(tok[i+y], "$+")) strcat(tok[i], tok[i+y]); *tok[i-x] = 0; *tok[i+y] = 0; } else *tok[i] = 0; js = 1; } } /* for i */ if (js) { memset(nb, 0, sizeof(nb)); for (i=0;tok[i];i++) { if (*tok[i]) { strcat(nb, tok[i]); strcat(nb, " "); } } nb[strlen(nb)-1] = 0; p = ins(b, nb, j-strlen(t), j); j = f; free(b); b = p; break; } } /* if (sw && tok[0] && !bc) */ if (b[j]) j++; break; } if (!strcasecmp(tok[0], cur->nm)) { st = doalias(cur, tok, cnt); /* doalias just does the substitution */ if (!st) { wp(win, "%s* Error: insufficient parameters%s\n", RED, WHITE); drw(win); free(b); free(st); for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(1); } p = ins(b, st, j-strlen(t), j); free(b); b = p; free(st); j = f; sw = 1; break; } /* if */ } /* for (cur=alhead;;cur=cur->next) */ for (i=0;i<cnt;i++) free(tok[i]); free(tok); if (j != f) { for (i=f,k=0;i<j;i++,k++) t[k] = b[i]; t[k] = 0; if (sw) { if (t[strlen(t)-1] == '|' || t[strlen(t)-1] == '\n') t[strlen(t)-1] = 0; for (i=strlen(t)-1;t[i]==' '&&i>=0;i--) t[i] = 0; } rn = parseoutn(s, t, win); if (rn == -3 || rn == -4 || rn == 2 ) { /* see block comment above */ free(b); return(rn); } if (bc == 1) bc = 0; } /* if (j != f) */ } /* while (1) */ free(b); return(1);}/* parseoutn: parse and execute a (user) command, but do not do alias expansion. Try whether it's a usercmd, irc stuff, or a regular built-in command from out[]. */int parseoutn(int s, char *buf, WINDOW *win){ int i, cnt, r = 0; char **tok; unsigned char *t = buf, f=0; tok = form_toks(t, &cnt); if (!tok[0]) { for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(1); } if (ircmode && strcasecmp(tok[0], "server")) { if (!ircsock) { for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(1); } if (!checkouts(ircsock, t, tok, cnt, win)) f = 1; else { for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(1); } } for (i=0;;i++) { if (out[i].func == NULL) { if (!r && !f) { wp(win, "%s* Unknown command: %s. Try /help.%s\n", RED, tok[0], WHITE); drw(win); return(-3); } else if (f) ssock(ircsock, "%s\n", t); for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(1); } if ((!f || out[i].a) && !strcasecmp(tok[0], out[i].nm)) { r = out[i].func(s, t, tok, cnt, win); for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(r); } } for (i=0;i<cnt;i++) free(tok[i]); free(tok); return(r);}/* return a unique connection name for an upload or a download connection. Upload connections must start with "u" and download connections with "d" (the functions in scheck.c rely on this). Never use the same name twice. The result of this function is a pointer to a static string, which will be overwritten with the next call. t==1 for uploads, t==0 for downloads. *//* Added t==2 for outgoing direct browse connections (there can be * several outgoing direct browse connections (multiple remote clients * simultaneously browsing our files), but there can only be one incoming * direct browse connection (we can only browse one client at a time) */char *gnum(int t){ static int count[3] = { 0, 0, 0 }; static const char *template[3] = {"d %i", "u %i", "b %i"}; static char buf[10]; sprintf(buf, template[t], count[t]++); return buf;}/* skip n space-delimited tokens, and return a copy of the remainder of the string. Each call frees the string that was returned by the previous call. */char *cstr(char *str, int n){ static char *ctbuf = NULL; int i=0, c; if (ctbuf) free(ctbuf); while (str[i] == ' ' && str[i]) i++; if (!str[i]) { ctbuf = strdup(""); return(ctbuf); } for (c=0; str[i] && c!=n; i++) { if (str[i] == ' ') { c++; while (str[i] == ' ' && str[i]) i++; if (c == n) break; if (!str[i]) break; } } if (!str[i]) ctbuf = strdup(""); else ctbuf = strdup(str+i); return(ctbuf);}/* concatenates tok[beg]..tok[cnt-1] into a space-delimited string. Each call frees the string that was returned by the previous call. */char *cspstr(char **tok, int cnt, int beg){ static char *ctbuf = NULL; int size, i; if (ctbuf) free(ctbuf); if (beg >= cnt) { ctbuf = strdup(""); return(ctbuf); } size = 0; for (i=beg; i<cnt; i++) { size += strlen(tok[i]) + 1; /* including a space or '\0' */ } ctbuf = (char *)malloc(size); strcpy(ctbuf, tok[beg]); for (i=beg+1; i<cnt; i++) { strcat(ctbuf, " "); strcat(ctbuf, tok[i]); } return(ctbuf);}/* delete an upload from the upload list. Frees all the resources associated with this upload, including deleting any timer set for it. Also delete the item's socket, if any. Return -1 if item was not in list, else 0. */int dupload(upload_t *task) { list_unlink(upload_t, up, task); if (!task) { /* ?? not found */ return(-1); } free(task->nick); free(task->rfn); free(task->fn); free(task->lfn); if (task->state == CONNECTING || task->state == CONNECTING1 || task->state == IN_PROGRESS) { if (task->sk) delsock(task->sk->fd); } if (task->state == IN_PROGRESS) { if (task->f) fclose(task->f); } free(task); return(0);}/* delete an element from the download task lists. Also close this download's file (if any), move the file to the appropriate place or delete turds. Also delete the item's socket, if any. Return -1 if item was not in list, 0 on success */int ddownload(WINDOW *win, download_t *task){ int r; list_unlink(download_t, down, task); if (!task) /* ?? task was not in the list */ return(-1); if (task->state == IN_PROGRESS) { r = interrupt_download(win, task); if (r==2) { wp(win, "* Removed turd \"%s\" (%d bytes)\n", task->fn, task->pos); drw(win); } if (task->sk) delsock(task->sk->fd); } switch (task->state) { case CONNECTING: if (task->sk) delsock(task->sk->fd); /* fall through to next case*/ case WAITING: free(task->check); /* fall through to next case */ default: free(task->nick); free(task->rfn); free(task->fn); free(task); } return(0);}/* move a task from IN_PROGRESS to either INCOMPLETE or COMPLETE, depending on which is the case. Free all resources that would be inappropriate for a stopped task. I.e., close the download's file (if any), move the file to the appropriate place or delete turds. However, do not delete the item's socket. Return 1 if an incomplete file was saved, 2 if it was a turd, 3 if a complete file was saved. */int interrupt_download(WINDOW *win, download_t *task){ int turdsize; int ret = 0; int r; rqueued_hook(task->nick); if (task->f) { fclose(task->f); turdsize = nvar_default("turdsize", TURDSIZE); if (task->pos >= task->size) { /* completed download */ move_to_downloaddir(win, task); task->state = COMPLETE; task->d_time = time(0); ret = 3; } else if ((ssize_t)(task->pos) <= turdsize) { /* turd */ r = unlink(task->lfn); task->state = INCOMPLETE; task->d_time = time(0); ret = (r == -1 ? 1 : 2); } else { /* prepare incomplete for later resume */ mark_incomplete(win, task); task->state = INCOMPLETE; task->d_time = time(0); ret = 1; } } free(task->lfn); free(task->check); return(ret);}/* move a completed download to dir, renaming it as appropriate. Return >=0 on success. Return -1 on error with errno set. Return >0 if the file was renamed. Also, if lfn!=NULL, set *lfn to the new filename (on success as well as -1). */int move_to_dir(WINDOW *win, download_t *task, const char *dir, char **lfnp) { char *lfn, *newfn; int r, s; r = unused_filename(dir, task->fn, NULL, &lfn, &newfn); s = move_file(task->lfn, lfn); free(newfn); if (lfnp) { *lfnp = lfn; } else { free(lfn); } if (s==-1) { return(-1); } return(0);}/* move a completed download from the incomplete directory to the download directory, renaming it as appropriate. Do this silently unless there is an error */void move_to_downloaddir(WINDOW *win, download_t *task) { char *path, *suffix; char *lfn; int r; /* figure out the filename to move it to. */ path = getval("download"); /* if no download path given, use CWD, not HOME */ if (path) { path = home_file(path); } else { path = strdup("."); } r = move_to_dir(win, task, path, &lfn); free(path); if (r==0) { free(lfn); return; } else if (r>0) { wp(win, "* File \"%s\" exists. Download saved as \"%s\" instead.\n", task->fn, lfn); drw(win); free(lfn); return; } else if (r==-1) { wp(win, ""RED"* Error: could not move download to \"%s\": %s"WHITE"\n", lfn, strerror(errno)); drw(win); free(lfn); } /* if move failed, at least attempt to remove the "incomplete" suffix */ suffix = getval("incompletesuffix"); if (!suffix) { suffix = ".incomplete"; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -