📄 scmds.c
字号:
/* Copyright (c) 2000 Kevin Sullivan <nite@gis.net> * * Please refer to the COPYRIGHT file for more information. *//* server commands - i.e. standard "handlers" that react to server packages in the client-server part of the napster protocol. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <pwd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <errno.h>#include <unistd.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <time.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <math.h>#include <ctype.h>#include <fcntl.h>#include <ncurses.h>#include "getopt.h"#include "defines.h"#include "colors.h"#include "codes.h"#include "lists.h"#include "handlers.h"#include "alias.h"#include "nap.h"#include "sscr.h"#include "event.h"#include "winio.h"#include "timer.h"#include "scheck.h"#include "irc.h"#include "scmds.h"#include "mp3s.h"#include "missing.h"#ifdef MEMWATCH #include "memwatch.h"#endifextern info_t info;extern chans_t *chanl, *curchan, *recent;extern int tind, ircsock;extern int noprint, ircmode;extern int ipcs[2];extern char *mnick;extern hotlist_t *hlist;extern void *hnd;extern alias_t *alhead;extern handler_t *hndhead;extern int quit_now, quit_after_transfers, upsocks, downsocks;extern ssearch_t *search;extern int srch;extern int noping;extern upload_t *up;extern download_t *down;extern struct inbrowse_s directbrowse;extern int wmode;extern unsigned char *dwi;extern int fl;/* names of the different connection types, 0-10 */const char *conns[] = { "Unknown", "14.4", "28.8", "33.6", "56k", "ISDN-64K", "ISDN-128K", "Cable", "DSL", "T1", "T3" };/* how many simultaneous uploads we allow by default, for each connection type */int ups[] = { 3, 2, 3, 3, 4, 5, 5, 7, 7, 9, 9 };/* what kind of minimal download speed we expect, roughly, from each connection type. Note: this is in kilobytes/second, not kilobits/second. The only place this is used is in nap.c:connection(). */int speeds[] = { 0, 1, 1, 2, 3, 4, 8, 8, 8, 125, 2500 };int tin = 0;scount_t scount; /* libraries / songs / gigs */in_nap_cmd_t in[] = { { NAP_SRET, ssret }, { NAP_SEND, ssend }, { NAP_RBROWSE, srbrowse }, { NAP_DBROWSE, sdbrowse }, { NAP_SGET, sget }, { NAP_NGET, snget }, { NAP_NACC, snacc }, { NAP_RQLIMIT, sqlimit }, { NAP_FREQ, sfreq }, { NAP_SSF, ssf }, { NAP_COUNT, sscount }, { NAP_BROWSE2ACC, sbrowse2acc }, { NAP_BROWSE2ERR, sbrowse2err }, { NAP_BROWSE2, sbrowse2req }, { NAP_SWHOIS, swhois }, { NAP_SOFF, soff }, { NAP_UON, suon }, { NAP_UOFF, suoff }, { NAP_NOTICE, snotice }, { NAP_RY, sry }, { NAP_SJOIN, sjoin }, { NAP_SPART, spart }, { NAP_PART, smpart }, { NAP_TOPIC, stopic }, { NAP_SAID, ssay }, { NAP_NCHAN, snchan }, { NAP_JCHAN, sjchan }, { NAP_MNAME, snend }, { NAP_MNAME2, snend }, { NAP_TELL, stell }, { NAP_USER, suser }, { NAP_SOP, sop }, { NAP_PCHANGE, spchange }, { NAP_BPORT, sbport }, { NAP_ANNOUNCE, sannounce }, { NAP_SBANLIST, sbanlist }, { NAP_SBANLISTU, sbanlist }, { SERVER_PING, ssping }, { CLIENT_PING, scping }, { CLIENT_PONG, scpong }, { CLIENT_REDIRECT, sredir }, { CLIENT_CYCLE, scycle }, { NAP_SCLIST, sclist }, { CHANNEL_ENTRY2, sclist2 }, { NAP_NAMES, suser }, { NAP_SBLOCKLIST, sblocklist }, { IGNORE_LIST, signoreend }, { IGNORE_ENTRY, signorelist }, { IGNORE_ADD, signoreadd }, { IGNORE_REMOVE, signoreremove }, { IGNORE_UNKNOWN, signoreunknown }, { IGNORE_EXISTS, signoreexists }, { IGNORE_CLEAR, signoreclear }, { IGNORE_FAIL, signorefail }, { CHANNEL_BAN_ENTRY, scbanlist }, { NOTIFY_UNKNOWN, snerr }, { NOTIFY_EXISTS, snadd }, { CHAN_EMOTE, sme }, { 0x0, NULL },};/* return the part of the filename with all the (unix or dos) directory components removed. Note: we return a pointer into the original string */char *ud_basename(char *fn) { char *p; p = strrchr(fn, '/'); if (!p) p = strrchr(fn, '\\'); if (!p) p = fn; else p++; return p;}intin_cksum(u_short *addr, int len){ register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer);}voidtvsub(register struct timeval *out, register struct timeval *in){ if ((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; out->tv_usec += 1000000; } out->tv_sec -= in->tv_sec;}/* receive ping response from "napping" process */int icmpin(WINDOW *win, sock_t *m){ ssearch_t *cur; char *line, *p; struct in_addr addr; long ms; int r; line = nap_getline(m->f); if (!line || line[0]==0) { fclose(m->f); delsock(m->fd); showresults(wchan, 2); free(line); return(1); } if (strncmp(line, "IP", 2) == 0) { wp(win, "* Waiting for ping results...\n"); drw(win); for (cur=search; cur!=NULL; cur=cur->next) { cur->ping = -1; } free(line); return(1); } p = strchr(line, ' '); if (!p) { /* syntax error from napping, ignore */ return(1); } *p = 0; p++; r = inet_aton(line, &addr); free(line); if (!r) { /* syntax error from napping, ignore */ return(1); } ms = strtol(p, NULL, 10); for (cur=search; cur!=NULL; cur=cur->next) { if (cur->nip == addr.s_addr && cur->ping == -1) { cur->ping = ms/1000; } } return(1);}/* receive error message from "napping" process */int icmperr(WINDOW *win, sock_t *m){ char *line; line = nap_getline(m->f); if (line) { wp(win, "* Could not obtain ping results: %s\n", line); drw(win); free(line); } fclose(m->f); delsock(m->fd); return(1);}char **form_toks(char *buf, int *cnt){ int i, j, k, l = 0, c=0; char **ret; ret = (char **)malloc(4096); ret[0] = NULL; for (j=0,i=0;buf[j];i++) { while (buf[j] == ' ') j++; if (!buf[j]) break; ret[i] = (char *)malloc(2048); memset(ret[i], 0, 2048); if (buf[j] == '\\') { for (k=0,j++;buf[j]!=' '&&buf[j]&&k!=2048;k++,j++) ret[i][k] = buf[j]; ret[i][k] = 0; } else if (buf[j] == '\'') { j++; while (buf[j] && buf[j] == ' ') j++; for (k=0;buf[j]!='\''&&buf[j]&&k!=2048;k++,j++) ret[i][k] = buf[j]; ret[i][k--] = 0; while (k >= 0 && ret[i][k] == ' ') ret[i][k--] = 0; j++; } else if (buf[j] == '\"') { for (k=0,j++;buf[j]!='\"'&&buf[j]&&k!=2048;k++,j++) ret[i][k] = buf[j]; ret[i][k] = 0; j++; } else if (buf[j] == '(') { for (k=0,c=0;buf[j]&&k!=2047;k++,j++) { if (buf[j] == ')' && c == 1) break; if (c < 0) c = 0; if (buf[j] == '(') c++; else if (buf[j] == ')') c--; ret[i][k] = buf[j]; } if (buf[j]) { ret[i][k] = ')'; ret[i][k+1] = 0; j++; } } else if (buf[j] == '{') { for (k=0,c=0;buf[j]&&k!=2047;k++,j++) { if (buf[j] == '}' && c == 1) break; if (c < 0) c = 0; if (buf[j] == '{') c++; else if (buf[j] == '}') c--; ret[i][k] = buf[j]; } if (buf[j]) { ret[i][k] = '}'; ret[i][k+1] = 0; j++; } } else { for (k=0;buf[j]!=' '&&buf[j]&&k!=2048;k++,j++) ret[i][k] = buf[j]; ret[i][k] = 0; } ret[i] = (char *)realloc(ret[i], strlen(ret[i])+1); l+=strlen(ret[i])+1; } ret[i] = NULL; *cnt = i; return(ret);}/* break up the contents of a server packet (or remote client packet) * into an array of tokens */char **form_tokso(char *buf, int *cnt){ int i, j, k, l = 0; char **ret; ret = (char **)malloc(4096); ret[0] = NULL; for (j=0,i=0;buf[j];i++) { while (buf[j] == ' ') j++; if (!buf[j]) break; ret[i] = (char *)malloc(2048); memset(ret[i], 0, 2048); if (buf[j] == '\"') { /* tokens in double quotes (e.g filenames) get copied without the * double quotes */ for (k=0,j++;buf[j]!='\"'&&buf[j]&&k!=2048;k++,j++) ret[i][k] = buf[j]; ret[i][k] = 0; j++; } else { for (k=0;buf[j]!=' '&&buf[j]&&k!=2048;k++,j++) ret[i][k] = buf[j]; ret[i][k] = 0; } ret[i] = (char *)realloc(ret[i], strlen(ret[i])+1); l+=strlen(ret[i])+1; } ret[i] = NULL; /* ret = (char **)realloc(ret, l+sizeof(char *)); */ *cnt = i; return(ret);}int parsein(int s, unsigned short op, char *buf, WINDOW *win){ int i, cnt, r=0; char **tok, *b, *t=NULL; handler_t *cur; for (cur=hndhead;cur;cur=cur->next) { if (op == cur->op) { msprintf(&t, "%i %s", op, buf); tok = form_toks(t, &cnt); free(t); t = NULL; b = dohandler(cur, tok, cnt); for (i=0;b[i]=='\n'||b[i]==' ';i++); msprintf(&t, "/%s", b+i); free(b); r = parseout(s, t, win); free(t); for (i=0;i<cnt;i++) free(tok[i]); free(tok); break; } } if (r == 2) return(1); if (noprint) noprint = 2; for (i=0;;i++) { if (in[i].func == NULL) { if (nvar("debug") == 1) { wp(win, ""RED"UNKNOWN OP: (0x%x - %i) |%s|"WHITE"\n", op, op, buf); drw(win); } return(1); } if (in[i].op == op) { if (strlen(buf)) { tok = form_tokso(buf, &cnt); r = in[i].func(s, buf, tok, cnt, win); for (i=0;i<cnt;i++) free(tok[i]); free(tok); } else r = in[i].func(s, NULL, NULL, 0, win); return(r); } }}/* 0x193 <channel> <nick> <text> [SERVER]: public message *//* a message arrived. Color code it based on whether it was from us, and whether it is on the current channel or some other channel. */I_NAP_FUNC(ssay){ char *hilit; if (!(recent = findchan(chanl, tok[0]))) return(1); /* ?? we don't seem to be on that channel */ /* highlight our own messages in MAGENTA, all others in BLUE */ if (!strcasecmp(info.user, tok[1])) { hilit = MAGENTA; } else { hilit = BLUE; } if (recent == curchan || wmode) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -