/[cvs]/eggdrop1.9/testcode/linemode.c
ViewVC logotype

Contents of /eggdrop1.9/testcode/linemode.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Tue Jan 8 00:09:09 2002 UTC (18 years, 3 months ago) by stdarg
Branch: MAIN
File MIME type: text/x-chdr
Err, I don't know if I already added these files or not, so I'll add them again.

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5
6 #include "sockbuf.h"
7
8 static int linemode_read(int idx, int event, int level, sockbuf_iobuf_t *new_data, sockbuf_iobuf_t *old_data)
9 {
10 unsigned char *line, *stop, *save, *data;
11 int linelen, savelen, datalen;
12 sockbuf_iobuf_t my_iobuf;
13
14 data = new_data->data;
15 datalen = new_data->len;
16
17 while (1) {
18 /* If there's a cr or lf, we have a line. */
19 stop = memchr(data, '\n', datalen);
20 if (!stop) {
21 stop = memchr(data, '\r', datalen);
22 if (!stop) {
23 /* No line, save the whole thing. */
24 save = data;
25 savelen = datalen;
26 break;
27 }
28 }
29
30 /* Terminate the line and get the length. */
31 *stop = 0;
32 linelen = stop - data;
33 save = stop+1;
34 savelen = data + datalen - save;
35
36 /* Check for crlf. */
37 if (stop > data && *(stop-1) == '\r') linelen--;
38
39 /* If there is buffered data, concat it all. */
40 if (old_data->len) {
41 int newmax = old_data->len + linelen + 1;
42
43 if (newmax > old_data->max) {
44 /* Buffer is too small -- enlarge it. */
45 old_data->data = (unsigned char *)realloc(old_data->data, newmax);
46 old_data->max = newmax;
47 }
48
49 /* Add the new data to the end. */
50 memcpy(old_data->data+old_data->len, data, linelen+1);
51
52 /* Our line is: */
53 line = old_data->data;
54 linelen += old_data->len;
55
56 /* Reset stored data. */
57 old_data->len = 0;
58 }
59 else {
60 line = data;
61 /* And linelen is still correct. */
62 }
63
64 my_iobuf.data = line;
65 my_iobuf.len = linelen;
66 my_iobuf.max = linelen;
67 sockbuf_filter(idx, event, level, &my_iobuf);
68
69 /* If we're out of data, we're done. */
70 if (savelen <= 0) return(0);
71 /* Otherwise, do this again to check for another line. */
72 data = save;
73 datalen = savelen;
74 }
75
76 /* No cr/lf, so we save the remaining data for next time. */
77 if (savelen + old_data->len > old_data->max) {
78 /* Expand the buffer with room for next time. */
79 old_data->data = (unsigned char *)realloc(old_data->data, savelen + old_data->len + 512);
80 old_data->max = savelen + old_data->len + 512;
81 }
82 memmove(old_data->data + old_data->len, save, savelen);
83 old_data->len += savelen;
84 return(0);
85 }
86
87 static int linemode_eof_and_err(int idx, int event, int level, void *ignore, sockbuf_iobuf_t *old_data)
88 {
89 /* If there is any buffered data, do one more on->read callback. */
90 if (old_data->len) {
91 old_data->data[old_data->len] = 0;
92 sockbuf_filter(idx, SOCKBUF_READ, level, old_data);
93 }
94
95 /* And now continue the EOF/ERR event chain. */
96 sockbuf_filter(idx, event, level, old_data);
97 return(0);
98 }
99
100 static sockbuf_event_t linemode_filter = {
101 (Function) 4,
102 (Function) "line-mode",
103 linemode_read,
104 NULL,
105 linemode_eof_and_err,
106 linemode_eof_and_err
107 };
108
109 int linemode_on(int idx)
110 {
111 sockbuf_iobuf_t *iobuf;
112
113 iobuf = (sockbuf_iobuf_t *)calloc(sizeof(*iobuf), 0);
114 sockbuf_attach_filter(idx, linemode_filter, iobuf);
115 return(0);
116 }
117
118 int linemode_off(int idx)
119 {
120 sockbuf_iobuf_t *iobuf;
121
122 sockbuf_detach_filter(idx, linemode_filter, &iobuf);
123 if (iobuf) {
124 if (iobuf->data) free(iobuf->data);
125 free(iobuf);
126 }
127 return(0);
128 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23