ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/process.c
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (9 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 4366 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# Content
1 /* Main processing code for Services.
2 *
3 * IRC Services is copyright (c) 1996-2009 Andrew Church.
4 * E-mail: <achurch@achurch.org>
5 * Parts written by Andrew Kempe and others.
6 * This program is free but copyrighted software; see the file GPL.txt for
7 * details.
8 */
9
10 #include "services.h"
11 #include "modules.h"
12 #include "messages.h"
13
14 static int cb_recvmsg = -1;
15
16 /*************************************************************************/
17 /*************************************************************************/
18
19 /* split_buf: Split a buffer into arguments and store a pointer to the
20 * argument vector in argv_ptr; return the argument count.
21 * The argument vector will point to a static buffer;
22 * subsequent calls will overwrite this buffer.
23 * If colon_special is non-zero, then treat a parameter with a
24 * leading ':' as the last parameter of the line, per the IRC
25 * RFC. Destroys the buffer by side effect.
26 */
27
28 static char **sbargv = NULL; /* File scope so process_cleanup() can free it */
29
30 int split_buf(char *buf, char ***argv_ptr, int colon_special)
31 {
32 static int argvsize = 8;
33 int argc;
34 char *s;
35
36 if (!sbargv)
37 sbargv = smalloc(sizeof(char *) * argvsize);
38 argc = 0;
39 while (*buf) {
40 if (argc == argvsize) {
41 argvsize += 8;
42 sbargv = srealloc(sbargv, sizeof(char *) * argvsize);
43 }
44 if (*buf == ':' && colon_special) {
45 sbargv[argc++] = buf+1;
46 *buf = 0;
47 } else {
48 s = strpbrk(buf, " ");
49 if (s) {
50 *s++ = 0;
51 while (*s == ' ')
52 s++;
53 } else {
54 s = buf + strlen(buf);
55 }
56 sbargv[argc++] = buf;
57 buf = s;
58 }
59 }
60 *argv_ptr = sbargv;
61 return argc;
62 }
63
64 /*************************************************************************/
65 /*************************************************************************/
66
67 int process_init(int ac, char **av)
68 {
69 cb_recvmsg = register_callback("receive message");
70 if (cb_recvmsg < 0) {
71 log("process_init: register_callback() failed\n");
72 return 0;
73 }
74 return 1;
75 }
76
77 /*************************************************************************/
78
79 void process_cleanup(void)
80 {
81 unregister_callback(cb_recvmsg);
82 free(sbargv);
83 sbargv = NULL;
84 }
85
86 /*************************************************************************/
87
88 /* process: Main processing routine. Takes the string in inbuf (global
89 * variable) and does something appropriate with it. */
90
91 void process(void)
92 {
93 char source[64];
94 char cmd[64];
95 char buf[512]; /* Longest legal IRC command line */
96 char *s;
97 int ac; /* Parameters for the command */
98 char **av;
99
100
101 /* If debugging, log the buffer. */
102 log_debug(1, "Received: %s", inbuf);
103
104 /* First make a copy of the buffer so we have the original in case we
105 * crash - in that case, we want to know what we crashed on. */
106 strbcpy(buf, inbuf);
107
108 /* Split the buffer into pieces. */
109 if (*buf == ':') {
110 s = strpbrk(buf, " ");
111 if (!s)
112 return;
113 *s = 0;
114 while (isspace(*++s))
115 ;
116 strbcpy(source, buf+1);
117 strmove(buf, s);
118 } else {
119 *source = 0;
120 }
121 if (!*buf)
122 return;
123 s = strpbrk(buf, " ");
124 if (s) {
125 *s = 0;
126 while (isspace(*++s))
127 ;
128 } else
129 s = buf + strlen(buf);
130 strbcpy(cmd, buf);
131 ac = split_buf(s, &av, 1);
132
133 /* Do something with the message. */
134 if (call_callback_4(cb_recvmsg, source, cmd, ac, av) <= 0) {
135 Message *m = find_message(cmd);
136 if (m) {
137 if (m->func)
138 m->func(source, ac, av);
139 } else {
140 log("unknown message from server (%s)", inbuf);
141 }
142 }
143
144 /* Finally, clear the first byte of `inbuf' to signal that we're
145 * finished processing. */
146 *inbuf = 0;
147 }
148
149 /*************************************************************************/
150
151 /*
152 * Local variables:
153 * c-file-style: "stroustrup"
154 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
155 * indent-tabs-mode: nil
156 * End:
157 *
158 * vim: expandtab shiftwidth=4:
159 */