]>
Commit | Line | Data |
---|---|---|
b562f484 | 1 | |
2 | #include "faimtest.h" | |
3 | #include <readline/readline.h> | |
4 | #include <readline/history.h> | |
5 | ||
6 | static int cmd_help(char *arg); | |
7 | static int cmd_quit(char *arg); | |
8 | static int cmd_login(char *arg); | |
9 | static int cmd_logout(char *arg); | |
10 | static int cmd_connlist(char *arg); | |
d2587300 | 11 | static int cmd_goodday(char *arg); |
12 | static int cmd_warn(char *arg); | |
13 | static int cmd_anonwarn(char *arg); | |
14 | static int cmd_sendmsg(char *arg); | |
b562f484 | 15 | |
16 | struct { | |
17 | char *name; | |
18 | Function *func; | |
19 | char *doc; | |
20 | } cmdlist[] = { | |
21 | { "help", cmd_help, "Help"}, | |
22 | { "quit", cmd_quit, "Quit"}, | |
23 | { "login", cmd_login, "Log into AIM"}, | |
d2587300 | 24 | { "logout", cmd_logout, "Log out of AIM"}, |
b562f484 | 25 | { "connlist", cmd_connlist, "List open connections"}, |
d2587300 | 26 | { "goodday", cmd_goodday, "Say goodday to arg"}, |
27 | { "warn", cmd_warn, "Warn arg"}, | |
28 | { "anonwarn", cmd_anonwarn, "Anonymously warn arg"}, | |
29 | { "sendmsg", cmd_sendmsg, "Send arg[0] bytes to arg[1]"}, | |
b562f484 | 30 | { (char *)NULL, (Function *)NULL, (char *)NULL } |
31 | }; | |
32 | ||
33 | static char *stripwhite (char *string) | |
34 | { | |
35 | char *s, *t; | |
36 | ||
37 | for (s = string; whitespace(*s); s++) | |
38 | ; | |
39 | ||
40 | if (*s == 0) | |
41 | return (s); | |
42 | ||
43 | t = s + strlen (s) - 1; | |
44 | while (t > s && whitespace (*t)) | |
45 | t--; | |
46 | *++t = '\0'; | |
47 | ||
48 | return s; | |
49 | } | |
50 | ||
51 | static char *cmdgenerator(char *text, int state) | |
52 | { | |
53 | static int list_index, len; | |
54 | char *name; | |
55 | ||
56 | if (!state) { | |
57 | list_index = 0; | |
58 | len = strlen (text); | |
59 | } | |
60 | ||
61 | while ((name = cmdlist[list_index].name)) { | |
62 | list_index++; | |
63 | if (strncmp (name, text, len) == 0) | |
64 | return (strdup(name)); | |
65 | } | |
66 | ||
67 | /* If no names matched, then return NULL. */ | |
68 | return (char *)NULL; | |
69 | } | |
70 | ||
71 | static char **cmdcomplete(char *text, int start, int end) | |
72 | { | |
73 | char **matches; | |
74 | ||
75 | matches = (char **)NULL; | |
76 | ||
77 | /* | |
78 | * If this word is at the start of the line, then it is a command | |
79 | * to complete. Otherwise it is the name of a file in the current | |
80 | * directory. | |
81 | */ | |
82 | if (start == 0) | |
83 | matches = completion_matches(text, cmdgenerator); | |
84 | ||
85 | return matches; | |
86 | } | |
87 | ||
88 | static Function *cmdfind(char *name) | |
89 | { | |
90 | int i; | |
91 | ||
92 | for (i = 0; cmdlist[i].name; i++) | |
93 | if (strcmp (name, cmdlist[i].name) == 0) | |
94 | return cmdlist[i].func; | |
95 | ||
96 | return NULL; | |
97 | } | |
98 | ||
99 | static int cmdexec(char *line) | |
100 | { | |
101 | int i; | |
102 | Function *cmd; | |
103 | char *word; | |
104 | ||
105 | /* Isolate the command word. */ | |
106 | i = 0; | |
107 | while (line[i] && whitespace (line[i])) | |
108 | i++; | |
109 | word = line + i; | |
110 | ||
111 | while (line[i] && !whitespace (line[i])) | |
112 | i++; | |
113 | ||
114 | if (line[i]) | |
115 | line[i++] = '\0'; | |
116 | ||
117 | if (!(cmd = cmdfind(word))) { | |
118 | fprintf(stderr, "%s: invalid command\n", word); | |
119 | return -1; | |
120 | } | |
121 | /* Get argument to command, if any. */ | |
122 | while (whitespace (line[i])) | |
123 | i++; | |
124 | ||
125 | word = line + i; | |
126 | ||
127 | /* Call the function. */ | |
128 | return cmd(word); | |
129 | } | |
130 | ||
131 | static void fullline(void) | |
132 | { | |
133 | char *stripped; | |
134 | ||
135 | stripped = stripwhite(rl_line_buffer); | |
136 | ||
137 | if (*stripped) { | |
138 | add_history(stripped); | |
139 | cmdexec(stripped); | |
140 | } | |
141 | ||
142 | return; | |
143 | } | |
144 | ||
145 | void cmd_init(void) | |
146 | { | |
147 | ||
148 | rl_attempted_completion_function = cmdcomplete; | |
149 | ||
150 | printf("Welcome to faimtest.\n"); | |
151 | ||
d2587300 | 152 | rl_callback_handler_install("faimtest> ", fullline); |
b562f484 | 153 | |
154 | return; | |
155 | } | |
156 | ||
157 | void cmd_gotkey(void) | |
158 | { | |
159 | ||
160 | rl_callback_read_char(); | |
161 | ||
162 | return; | |
163 | } | |
164 | ||
165 | static int cmd_help(char *arg) | |
166 | { | |
167 | int i; | |
168 | ||
169 | for (i = 0; cmdlist[i].name; i++) | |
170 | printf("%16s\t\t%s\n", cmdlist[i].name, cmdlist[i].doc); | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
175 | static int cmd_quit(char *arg) | |
176 | { | |
177 | keepgoing = 0; | |
178 | ||
179 | return 0; | |
180 | } | |
181 | ||
182 | static int cmd_login(char *arg) | |
183 | { | |
184 | char *sn = NULL, *passwd = NULL; | |
185 | ||
186 | if (arg) { | |
187 | sn = arg; | |
188 | if ((passwd = index(sn, ' '))) { | |
189 | *(passwd) = '\0'; | |
190 | passwd++; | |
191 | } | |
192 | } | |
193 | ||
194 | if (login(sn, passwd) != 0) | |
195 | printf("login failed\n"); | |
196 | ||
197 | return 0; | |
198 | } | |
199 | ||
200 | static int cmd_logout(char *arg) | |
201 | { | |
202 | logout(); | |
203 | ||
204 | return 0; | |
205 | } | |
206 | ||
207 | static int cmd_connlist(char *arg) | |
208 | { | |
b562f484 | 209 | struct aim_conn_t *cur; |
210 | ||
211 | printf("Open connections:\n"); | |
212 | for (cur = aimsess.connlist; cur; cur = cur->next) { | |
213 | printf(" fd=%d type=0x%02x\n", cur->fd, cur->type); | |
214 | } | |
215 | ||
216 | return 0; | |
217 | } | |
218 | ||
d2587300 | 219 | static int cmd_goodday(char *arg) |
220 | { | |
221 | if (arg && strlen(arg) && (strlen(arg) < MAXSNLEN)) | |
a2244dd9 | 222 | aim_send_im(&aimsess, aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS), arg, AIM_IMFLAGS_ACK, "Good day to you too.", strlen("Good day to you too.")); |
d2587300 | 223 | else |
224 | printf("no one to say hello to!\n"); | |
225 | ||
226 | return 0; | |
227 | } | |
228 | ||
229 | static int cmd_warn(char *arg) | |
230 | { | |
231 | if (arg && strlen(arg) && (strlen(arg) < MAXSNLEN)) | |
232 | aim_send_warning(&aimsess, aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS), arg, 0); | |
233 | else | |
234 | printf("no one to warn!\n"); | |
235 | ||
236 | return 0; | |
237 | } | |
238 | ||
239 | static int cmd_anonwarn(char *arg) | |
240 | { | |
241 | if (arg && strlen(arg) && (strlen(arg) < MAXSNLEN)) | |
242 | aim_send_warning(&aimsess, aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS), arg, AIM_WARN_ANON); | |
243 | else | |
244 | printf("no one to anonwarn!\n"); | |
245 | ||
246 | return 0; | |
247 | } | |
248 | ||
249 | static int cmd_sendmsg(char *arg) | |
250 | { | |
251 | int len = 0, z; | |
252 | char sn[MAXSNLEN+1], *newbuf = NULL; | |
253 | ||
254 | if ((sscanf(arg, "%d %32s", &len, sn) != 2) || | |
255 | (len >= 10000) || (strlen(sn) > MAXSNLEN)) { | |
256 | printf("invalid args\n"); | |
257 | return 0; | |
258 | } | |
259 | ||
260 | printf("sending %d bytes to %s\n", len, sn); | |
261 | ||
262 | if (!(newbuf = malloc(len+1))) | |
263 | return 0; | |
264 | ||
265 | for (z = 0; z < len; z++) | |
266 | newbuf[z] = (z % 10)+0x30; | |
267 | newbuf[len] = '\0'; | |
268 | ||
a2244dd9 | 269 | aim_send_im(&aimsess, aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS), sn, AIM_IMFLAGS_ACK, newbuf, strlen(newbuf)); |
d2587300 | 270 | |
271 | free(newbuf); | |
272 | ||
273 | return 0; | |
274 | } | |
275 | ||
b562f484 | 276 | void cmd_uninit(void) |
277 | { | |
278 | ||
279 | rl_callback_handler_remove(); | |
280 | ||
281 | return; | |
282 | } |