Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/dll/nap/dragonap/napi/napi.c
1074 views
1
/*
2
napster code base by Drago ([email protected])
3
released: 11-30-99
4
*/
5
6
#include <stdlib.h>
7
#include <string.h>
8
#include <netinet/in.h>
9
#include <sys/socket.h>
10
#include <netdb.h>
11
#include <stdarg.h>
12
#include <time.h>
13
#include <sys/time.h>
14
#include <assert.h>
15
16
#include "napi.h"
17
18
19
_N_SERVER *n_GetServer(void) {
20
char serverline[1024], *server;
21
int fd, r, port;
22
struct sockaddr_in socka;
23
static _N_SERVER theserver;
24
25
fd=socket(AF_INET, SOCK_STREAM, 0);
26
socka.sin_addr.s_addr=inet_addr(n_nslookup(N_DISTRO_SERVER));
27
socka.sin_family=AF_INET;
28
socka.sin_port=htons(N_DISTRO_SERVER_PORT);
29
30
if (connect(fd, (struct sockaddr *)&socka, sizeof(struct sockaddr))!=0) {
31
n_Error("connect()");
32
close(fd);
33
return NULL;
34
}
35
36
r=read(fd, serverline, sizeof(serverline));
37
if (r==-1) {
38
n_Error("read()");
39
close(fd);
40
return NULL;
41
}
42
server=strstr(serverline, ":");
43
if (!server) {
44
n_Error("No port token?");
45
close(fd);
46
return NULL;
47
}
48
49
*server='\0';
50
server++;
51
port=atoi(server);
52
server=serverline;
53
54
strncpy(theserver.address, server, sizeof(theserver.address));
55
theserver.port=port;
56
57
n_Debug("Server: %s Port: %d", theserver.address, theserver.port);
58
close(fd);
59
return &theserver;
60
}
61
62
char *n_nslookup(char *addr) {
63
struct hostent *h;
64
if ((h=gethostbyname(addr)) == NULL) {
65
return addr;
66
}
67
return (char *)inet_ntoa(*((struct in_addr *)h->h_addr));
68
}
69
70
int n_Connect(_N_SERVER *s, _N_AUTH *a) {
71
int r, port;
72
struct sockaddr_in socka;
73
74
n_serverfd=socket(AF_INET, SOCK_STREAM, 0);
75
socka.sin_addr.s_addr=inet_addr(n_nslookup(s->address));
76
socka.sin_family=AF_INET;
77
socka.sin_port=htons(s->port);
78
79
if (connect(n_serverfd, (struct sockaddr *)&socka, sizeof(struct sockaddr))!=0) {
80
n_Error("connect()");
81
close(n_serverfd);
82
return 0;
83
}
84
85
n_Debug("Connected");
86
87
n_SendCommand(CMDS_LOGIN, "%s %s %d \"v2.0 BETA 3\" %d", a->username, a->password, n_dataport, n_connectionspeed);
88
{
89
_N_COMMAND *cmd;
90
cmd=n_GetCommand();
91
if (cmd->cmd[2]==CMDR_ERROR) {
92
n_Error("%s", cmd->data);
93
return 0;
94
} else {
95
n_HandleCommand(cmd);
96
}
97
}
98
return 1;
99
}
100
101
void n_HandleCommand(_N_COMMAND *cmd) {
102
switch (cmd->cmd[2]) {
103
case CMDR_MOTD:
104
if (n_HookMotd) {
105
n_HookMotd(cmd->data);
106
} else {
107
n_Debug("No motd hook installed");
108
}
109
break;
110
case CMDR_STATS:
111
/*
112
D:napi.c:n_GetCommand():171:Data: 2104 197246 798
113
2104==Libraries
114
197246==songs
115
798==gigs
116
*/
117
if (n_HookStats) {
118
_N_STATS s;
119
if (sscanf(cmd->data, "%d %d %d",
120
&s.libraries, &s.songs, &s.gigs)!=3) {
121
n_Error("Too few args");
122
}
123
else n_HookStats(&s);
124
} else {
125
n_Debug("No stats hook installed");
126
}
127
break;
128
}
129
}
130
131
void n_SendCommand(_N_CMD ncmd, char *fmt, ...) {
132
char buff[2048];
133
_N_COMMAND command;
134
va_list ap;
135
136
va_start(ap, fmt);
137
138
command.cmd[0]=vsnprintf(buff, sizeof(buff), fmt, ap);
139
va_end(ap);
140
141
command.cmd[1]='\0';
142
command.cmd[2]=ncmd;
143
command.cmd[3]='\0';
144
145
n_Debug("Flags: %d %d %d %d", command.cmd[0], command.cmd[1], command.cmd[2], command.cmd[3]);
146
n_Debug("Data: %s", buff);
147
148
n_Send(command.cmd, sizeof(command.cmd));
149
n_Send(buff, command.cmd[0]);
150
}
151
152
int n_Send(char *data, int s) {
153
return write(n_serverfd, data, s);
154
}
155
156
int n_Loop(void) {
157
int sret;
158
struct timeval tv;
159
fd_set rfd;
160
FD_ZERO(&rfd);
161
FD_SET(n_serverfd, &rfd);
162
tv.tv_sec=0;
163
tv.tv_usec=0;
164
165
sret = select(n_serverfd+1, &rfd, NULL, NULL, &tv);
166
if (sret>0) {
167
if (FD_ISSET(n_serverfd, &rfd)) {
168
n_DoCommand();
169
return 1;
170
}
171
}
172
}
173
174
_N_COMMAND *n_GetCommand(void) {
175
static char rbuff[1024];
176
static _N_COMMAND command;
177
read(n_serverfd, command.cmd, sizeof(command.cmd));
178
if (command.cmd[1]==0) {
179
int r;
180
assert(sizeof(rbuff) > command.cmd[0]);
181
r=n_ReadCount(rbuff, command.cmd[0]);
182
} else {
183
int r=0;
184
int cc=command.cmd[3]+1;
185
while(cc>0) {
186
assert(sizeof(rbuff) > r);
187
if (read(n_serverfd, &rbuff[r], sizeof(char))==1) r++;
188
if (rbuff[r-1]=='.') cc--;
189
}
190
rbuff[r]=0;
191
}
192
command.data=rbuff;
193
n_Debug("Flags: %d %d %d %d", command.cmd[0], command.cmd[1], command.cmd[2], command.cmd[3]);
194
n_Debug("Data: %s", command.data);
195
return &command;
196
}
197
198
void n_DoCommand(void) {
199
_N_COMMAND *cmd;
200
cmd=n_GetCommand();
201
n_HandleCommand(cmd);
202
}
203
204
int n_ReadCount(char *buff, int c) {
205
int rc=0;
206
while (c>rc) {
207
if (read(n_serverfd, &buff[rc], sizeof(char))==1) rc++;
208
}
209
buff[rc]=0;
210
}
211
212
void n_SetMotdHook(void (*f)(char *)) {
213
n_HookMotd=f;
214
n_Debug("Installed motd hook");
215
}
216
217
void n_SetStatsHook(void (*f)(_N_STATS *)) {
218
n_HookStats=f;
219
n_Debug("Installed stats hook");
220
}
221
222
223