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 (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 4366 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# User Rev Content
1 michael 3389 /* 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     */