-
Notifications
You must be signed in to change notification settings - Fork 0
/
finger.c
99 lines (92 loc) · 2.22 KB
/
finger.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* finger.c
* finger:// processing
* (c) 2002 Mikulas Patocka
* This file is a part of the Links program, released under GPL.
*/
#include "links.h"
static void finger_send_request(struct connection *);
static void finger_sent_request(struct connection *);
static void finger_get_response(struct connection *, struct read_buffer *);
static void finger_end_request(struct connection *, int);
void finger_func(struct connection *c)
{
int p;
if ((p = get_port(c->url)) == -1) {
setcstate(c, S_BAD_URL);
abort_connection(c);
return;
}
c->from = 0;
make_connection(c, p, &c->sock1, finger_send_request);
}
static void finger_send_request(struct connection *c)
{
unsigned char *req = init_str();
int rl = 0;
unsigned char *user;
add_to_str(&req, &rl, cast_uchar "/W");
if ((user = get_user_name(c->url))) {
add_chr_to_str(&req, &rl, ' ');
add_to_str(&req, &rl, user);
mem_free(user);
}
add_to_str(&req, &rl, cast_uchar "\r\n");
write_to_socket(c, c->sock1, req, rl, finger_sent_request);
mem_free(req);
setcstate(c, S_SENT);
}
static void finger_sent_request(struct connection *c)
{
struct read_buffer *rb;
set_connection_timeout(c);
if (!(rb = alloc_read_buffer(c))) return;
rb->close = 1;
read_from_socket(c, c->sock1, rb, finger_get_response);
}
static void finger_get_response(struct connection *c, struct read_buffer *rb)
{
int l;
int a;
set_connection_timeout(c);
if (!c->cache) {
if (get_connection_cache_entry(c)) {
setcstate(c, S_OUT_OF_MEM);
abort_connection(c);
return;
}
c->cache->refcount--;
}
if (rb->close == 2) {
finger_end_request(c, S__OK);
return;
}
l = rb->len;
if ((off_t)(0UL + c->from + l) < 0) {
setcstate(c, S_LARGE_FILE);
abort_connection(c);
return;
}
c->received += l;
a = add_fragment(c->cache, c->from, rb->data, l);
if (a < 0) {
setcstate(c, a);
abort_connection(c);
return;
}
if (a == 1) c->tries = 0;
c->from += l;
kill_buffer_data(rb, l);
read_from_socket(c, c->sock1, rb, finger_get_response);
setcstate(c, S_TRANS);
}
static void finger_end_request(struct connection *c, int state)
{
if (state == S__OK) {
if (c->cache) {
truncate_entry(c->cache, c->from, 1);
c->cache->incomplete = 0;
}
}
setcstate(c, state);
abort_connection(c);
}