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