update to b2
[mpls-ppp.git] / scripts / chatchat / chatchat.c
blob4534fb9e3ebcac8c650363e6e10faeedeff5d817
1 /* *************************************************************************
2 * NAME: chatchat.c
4 * DESCRIPTION:
6 * This program creates a pipe for the chat process to read. The user
7 * can supply information (like a password) that will be picked up
8 * by chat and sent just like the regular contents of a chat script.
10 * Usage is:
12 * chatchat <filename>
14 * where <filename> matches the option given in the chat script.
16 * for instance the chat script fragment:
18 * ...
19 * name: \\dmyname \
20 * word: @/var/tmp/p \
21 * ...
22 * ^
23 * (note: leave some whitespace after the filename)
25 * expect "name:", reply with a delay followed by "myname"
26 * expect "word:", reply with the data read from the pipe /var/tmp/p
28 * the matching usage of chatchat would be:
30 * chatchat /var/tmp/p
32 * eg:
34 * $chatchat /var/tmp/p
35 * ...
36 * some other process eventually starts:
37 * chat ...
38 * chat parses the "@/var/tmp/p" option and opens
39 * /var/tmp/p
40 * (chatchat prompts:)
42 * type PIN into SecurID card
43 * enter resulting passcode: [user inputs something]
45 * chat reads /var/tmp/p & gets what the
46 * user typed at chatchat's "enter string" prompt
47 * chat removes the pipe file
48 * chat sends the user's input as a response in
49 * place of "@/var/tmp/p"
51 * PROCESS:
53 * gcc -g -o chatchat chatchat.c
56 * GLOBALS: none
58 * REFERENCES:
60 * see the man pages and documentation that come with the 'chat' program
61 * (part of the ppp package). you will need to use the modified chat
62 * program that accepts the '@' operator.
64 * LIMITATIONS:
66 * REVISION HISTORY:
68 * STR Description Author
70 * 23-Mar-99 initial coding gpk
71 * 12-May-99 unlink the pipe after closing paulus
73 * TARGET: ANSI C
74 * This program is in the public domain.
77 * ************************************************************************* */
82 #include <sys/time.h>
83 #include <stdio.h>
84 #include <sys/types.h>
85 #include <sys/stat.h>
86 #include <fcntl.h>
87 #include <unistd.h>
88 #include <string.h>
90 /* MAXINPUT - the data typed into chatchat must be fewer */
91 /* characters than this. */
93 #define MAXINPUT 80
100 /* *************************************************************************
103 NAME: main
106 USAGE:
108 int argc;
109 char * argv[];
111 main(argc, argv[]);
113 returns: int
115 DESCRIPTION:
116 if the pipe file name is given on the command line,
117 create the pipe, prompt the user and put whatever
118 is typed into the pipe.
120 returns -1 on error
121 else # characters entered
122 REFERENCES:
124 LIMITATIONS:
126 GLOBAL VARIABLES:
128 accessed: none
130 modified: none
132 FUNCTIONS CALLED:
134 REVISION HISTORY:
136 STR Description of Revision Author
138 25-Mar-99 initial coding gpk
140 ************************************************************************* */
142 int main(int argc, char * argv[])
144 int retval;
146 int create_and_write_pipe(char * pipename);
148 if (argc != 2)
150 fprintf(stderr, "usage: %s pipename\n", argv[0]);
151 retval = -1;
153 else
155 retval = create_and_write_pipe(argv[1]);
157 return (retval);
163 /* *************************************************************************
166 NAME: create_and_write_pipe
169 USAGE:
171 int some_int;
172 char * pipename;
174 some_int = create_and_write_pipe(pipename);
176 returns: int
178 DESCRIPTION:
179 given the pipename, create the pipe, open it,
180 prompt the user for a string to put into the
181 pipe, write the string, and close the pipe
183 on error, print out an error message and return -1
185 returns -1 on error
186 else #bytes written into the pipe
187 REFERENCES:
189 LIMITATIONS:
191 GLOBAL VARIABLES:
193 accessed: none
195 modified: none
197 FUNCTIONS CALLED:
199 REVISION HISTORY:
201 STR Description of Revision Author
203 25-Mar-99 initial coding gpk
204 12-May-99 remove pipe after closing paulus
206 ************************************************************************* */
208 int create_and_write_pipe(char * pipename)
210 int retval, created, pipefd, nread, nwritten;
211 char input[MAXINPUT];
212 char errstring[180];
214 int create_pipe(char * pipename);
215 int write_to_pipe(int pipefd, char * input, int nchar);
217 created = create_pipe(pipename);
219 if (-1 == created)
221 sprintf(errstring, "unable to create pipe '%s'", pipename);
222 perror(errstring);
223 retval = -1;
225 else
228 /* note: this open won't succeed until chat has the pipe */
229 /* open and ready to read. this makes for nice timing. */
231 pipefd = open(pipename, O_WRONLY);
233 if (-1 == pipefd)
235 sprintf(errstring, "unable to open pipe '%s'", pipename);
236 perror(errstring);
237 retval = -1;
239 else
241 fprintf(stderr, "%s \n %s",
242 "type PIN into SecurID card and",
243 "enter resulting passcode:");
244 nread = read(STDIN_FILENO, (void *)input, MAXINPUT);
247 if (0 >= nread)
249 perror("unable to read from stdin");
250 retval = -1;
252 else
254 /* munch off the newline character, chat supplies */
255 /* a return when it sends the string out. */
256 input[nread -1] = 0;
257 nread--;
258 nwritten = write_to_pipe(pipefd, input, nread);
259 /* printf("wrote [%d]: '%s'\n", nwritten, input); */
260 retval = nwritten;
262 close(pipefd);
264 /* Now make the pipe go away. It won't actually go away
265 completely until chat closes it. */
266 if (unlink(pipename) < 0)
267 perror("Warning: couldn't remove pipe");
270 return(retval);
279 /* *************************************************************************
282 NAME: create_pipe
285 USAGE:
287 int some_int;
288 char * pipename;
290 some_int = create_pipe(pipename);
292 returns: int
294 DESCRIPTION:
295 create a pipe of the given name
297 if there is an error (like the pipe already exists)
298 print an error message and return
300 return -1 on failure else success
302 REFERENCES:
304 LIMITATIONS:
306 GLOBAL VARIABLES:
308 accessed: none
310 modified: none
312 FUNCTIONS CALLED:
314 REVISION HISTORY:
316 STR Description of Revision Author
318 25-Mar-99 initial coding gpk
320 ************************************************************************* */
322 int create_pipe(char * pipename)
324 mode_t old_umask;
325 int created;
327 /* hijack the umask temporarily to get the mode I want */
328 /* on the pipe. */
330 old_umask = umask(000);
332 created = mknod(pipename, S_IFIFO | S_IRWXU | S_IWGRP | S_IWOTH,
333 (dev_t)NULL);
335 /* now restore umask. */
337 (void)umask(old_umask);
339 if (-1 == created)
341 perror("unable to create pipe");
344 return(created);
352 /* *************************************************************************
355 NAME: write_to_pipe
358 USAGE:
360 int some_int;
361 int pipefd;
362 char * input;
363 int nchar;
365 some_int = write_to_pipe(pipefd, input, nchar);
367 returns: int
369 DESCRIPTION:
370 write nchars of data from input to pipefd
372 on error print a message to stderr
374 return -1 on error, else # bytes written
375 REFERENCES:
377 LIMITATIONS:
379 GLOBAL VARIABLES:
381 accessed: none
383 modified: none
385 FUNCTIONS CALLED:
387 REVISION HISTORY:
389 STR Description of Revision Author
391 25-Mar-99 initial coding gpk
392 12-May-99 don't write count word first paulus
394 ************************************************************************* */
396 int write_to_pipe(int pipefd, char * input, int nchar)
398 int nwritten;
400 /* nwritten = write(pipefd, (void *)&nchar, sizeof(nchar)); */
401 nwritten = write(pipefd, (void *)input, nchar);
403 if (-1 == nwritten)
405 perror("unable to write to pipe");
408 return(nwritten);