1 /* modem - Put modem into DIALIN or DIALOUT mode. Author: F. van Kempen */
3 /* Exit: 0 OK, suspended/restarted GETTY
6 * Version: 1.3 12/30/89
8 * Author: F. van Kempen, MicroWalt Corporation
10 * All fancy stuff removed, see getty.c. Kees J. Bot.
16 #include <sys/types.h>
26 #include <minix/paths.h>
28 char PATH_UTMP
[] = _PATH_UTMP
; /* current logins */
30 _PROTOTYPE(void usage
, (void));
31 _PROTOTYPE(int main
, (int argc
, char *argv
[]));
32 _PROTOTYPE(void sendcodes
, (char *tty
, char *codes
));
38 "Usage: modem [-sio] [-I in-codes] [-O out-codes] line [command args ...]\n");
48 char devtty
[1024], *tty
;
51 int fd
, i
, slot
, getty
;
53 enum { TOGGLE
, DIALIN
, DIALOUT
} mode
= TOGGLE
;
55 _PROTOTYPE(void (*hsig
), (int));
56 _PROTOTYPE(void (*isig
), (int));
57 _PROTOTYPE(void (*qsig
), (int));
58 _PROTOTYPE(void (*tsig
), (int));
63 char *in_codes
, *out_codes
;
66 while (i
< argc
&& argv
[i
][0] == '-') {
67 char *opt
= argv
[i
++] + 1;
69 if (opt
[0] == '-' && opt
[1] == 0) break;
73 case 's': /* silent mode */
76 case 'i': /* DIAL-IN mode: suspend GETTY */
79 case 'o': /* DIAL-OUT mode: restart GETTY */
82 case 'I': /* code to switch modem to dial-in */
84 if (i
== argc
) usage();
90 case 'O': /* code to switch modem to dial-out */
92 if (i
== argc
) usage();
104 if (i
== argc
) usage();
105 tty
= argv
[i
++]; /* Modem line */
107 if (mode
!= TOGGLE
&& i
!= argc
) usage();
108 command
= argv
+ i
; /* Command to execute (if any). */
110 if (strchr(tty
, '/') == NULL
) {
111 strcpy(devtty
, "/dev/");
112 strncat(devtty
, tty
, 1024 - 6);
116 if (stat(tty
, &st
) < 0) {
117 fprintf(stderr
, "modem: %s: %s\n", tty
, strerror(errno
));
121 if (!S_ISCHR(st
.st_mode
)) {
122 fprintf(stderr
, "%s is not a tty\n", tty
);
126 /* Find the utmp slot number for the line. */
127 if ((fd
= open(tty
, O_RDONLY
)) < 0 || (slot
= fttyslot(fd
)) == 0) {
128 fprintf(stderr
, "modem: %s: %s\n", tty
, strerror(errno
));
133 /* Read the UTMP file to find out the PID and STATUS of the GETTY. */
135 if ((fd
= open(PATH_UTMP
, O_RDONLY
)) < 0
136 || lseek(fd
, (off_t
) slot
* sizeof(entry
), SEEK_SET
) < 0
137 || read(fd
, &entry
, sizeof(entry
)) < 0
139 fprintf(stderr
, "modem: cannot read UTMP !\n");
144 hsig
= signal(SIGHUP
, SIG_IGN
);
145 isig
= signal(SIGINT
, SIG_IGN
);
146 qsig
= signal(SIGQUIT
, SIG_IGN
);
147 tsig
= signal(SIGTERM
, SIG_IGN
);
149 /* Process the terminal entry if we got one. */
150 switch (entry
.ut_type
) {
151 case LOGIN_PROCESS
: /* getty waiting for a call */
154 case USER_PROCESS
: /* login or user-shell */
155 if (!silent
) fprintf(stderr
, "modem: line is busy.\n");
162 for (i
= (mode
== TOGGLE
) ? 0 : 1; i
< 2; i
++) {
163 /* Now perform the desired action (DIALIN or DIALOUT). */
167 if (getty
) kill(entry
.ut_pid
, SIGUSR1
); /* suspend getty */
168 chown(tty
, uid
, st
.st_gid
); /* give line to user */
170 if (out_codes
!= NULL
) sendcodes(tty
, out_codes
);
171 if (!silent
) printf("modem on %s set for dialout.\n", tty
);
174 if (in_codes
!= NULL
) sendcodes(tty
, in_codes
);
175 chown(tty
, 0, st
.st_gid
); /* revoke access */
177 if (getty
) kill(entry
.ut_pid
, SIGUSR2
); /* restart getty */
178 if (!silent
) printf("modem on %s set for dialin.\n", tty
);
180 if (mode
== TOGGLE
) {
181 /* Start the command to run */
185 switch ((pid
= fork())) {
187 fprintf(stderr
, "modem: fork(): %s\n", strerror(errno
));
193 (void) signal(SIGHUP
, hsig
);
194 (void) signal(SIGINT
, isig
);
195 (void) signal(SIGQUIT
, qsig
);
196 (void) signal(SIGTERM
, tsig
);
197 execvp(command
[0], command
);
198 fprintf(stderr
, "modem: %s: %s\n",
199 command
[0], strerror(errno
));
202 while ((r
= wait(&status
)) != pid
) {
203 if (r
== -1 && errno
!= EINTR
) break;
205 if (r
== -1 || status
!= 0) ex_code
= 1;
213 void sendcodes(tty
, codes
)
218 char buf
[1024], *bp
= buf
;
220 if ((fd
= open(tty
, O_RDWR
|O_NONBLOCK
)) < 0) {
221 fprintf(stderr
, "modem: can't send codes to %s: %s\n",
222 tty
, strerror(errno
));
225 while ((c
= *codes
++) != 0) {
226 fprintf(stderr
, "%d\n", __LINE__
);
228 if ((c
= *codes
++) == 0) break;
229 if (c
== 'r') c
= '\r';
230 if (c
== 'n') c
= '\n';
233 if (bp
== buf
+ sizeof(buf
) || c
== '\r' || c
== '\n') {
234 fprintf(stderr
, "%d\n", __LINE__
);
235 write(fd
, buf
, bp
- buf
);
236 fprintf(stderr
, "%d\n", __LINE__
);
238 fprintf(stderr
, "%d\n", __LINE__
);
239 fprintf(stderr
, "%d\n", read(fd
, buf
, sizeof(buf
)));
240 }while (read(fd
, buf
, sizeof(buf
)) > 0);
241 fprintf(stderr
, "%d\n", __LINE__
);
246 fprintf(stderr
, "%d\n", __LINE__
);
247 write(fd
, buf
, bp
- buf
);
248 fprintf(stderr
, "%d\n", __LINE__
);
249 do sleep(1); while (read(fd
, buf
, sizeof(buf
)) > 0);
250 fprintf(stderr
, "%d\n", __LINE__
);