18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty.c - code for handling serial ports in pppd. 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (C) 2000-2004 Paul Mackerras. All rights reserved. 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met: 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * notice, this list of conditions and the following disclaimer. 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. The name(s) of the authors of this software must not be used to 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * endorse or promote products derived from this software without 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * prior written permission. 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. Redistributions of any form whatsoever must retain the following 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * acknowledgment: 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "This product includes software developed by Paul Mackerras 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * <paulus@samba.org>". 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Portions derived from main.c, which is: 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met: 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * notice, this list of conditions and the following disclaimer. 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * notice, this list of conditions and the following disclaimer in 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the documentation and/or other materials provided with the 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * distribution. 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. The name "Carnegie Mellon University" must not be used to 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * endorse or promote products derived from this software without 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * prior written permission. For permission or any legal 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * details, please contact 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Office of Technology Transfer 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Carnegie Mellon University 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 5000 Forbes Avenue 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Pittsburgh, PA 15213-3890 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * (412) 268-4387, fax: (412) 268-7395 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tech-transfer@andrew.cmu.edu 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4. Redistributions of any form whatsoever must retain the following 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * acknowledgment: 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "This product includes software developed by Computing Services 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID "$Id: tty.c,v 1.22 2004/11/13 12:07:29 paulus Exp $" 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h> 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <ctype.h> 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h> 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <signal.h> 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h> 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <fcntl.h> 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <syslog.h> 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netdb.h> 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <utmp.h> 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <pwd.h> 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <setjmp.h> 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/param.h> 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h> 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/wait.h> 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/time.h> 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/resource.h> 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stat.h> 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/socket.h> 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netinet/in.h> 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <arpa/inet.h> 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h" 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h" 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "lcp.h" 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_process_extra_options __P((void)); 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_check_options __P((void)); 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint connect_tty __P((void)); 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid disconnect_tty __P((void)); 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_close_fds __P((void)); 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid cleanup_tty __P((void)); 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_do_send_config __P((int, u_int32_t, int, int)); 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setdevname __P((char *, char **, int)); 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setspeed __P((char *, char **, int)); 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setxonxoff __P((char **)); 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int setescape __P((char **)); 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void printescape __P((option_t *, void (*)(void *, char *,...),void *)); 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void finish_tty __P((void)); 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int start_charshunt __P((int, int)); 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void stop_charshunt __P((void *, int)); 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void charshunt_done __P((void *)); 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void charshunt __P((int, int, char *)); 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int record_write __P((FILE *, int code, u_char *buf, int nb, 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval *)); 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int open_socket __P((char *)); 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void maybe_relock __P((void *, int)); 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int pty_master; /* fd for master side of pty */ 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int pty_slave; /* fd for slave side of pty */ 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int real_ttyfd; /* fd for actual serial port (not pty) */ 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int ttyfd; /* Serial port file descriptor */ 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char speed_str[16]; /* Serial port speed as string */ 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectmode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */ 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint baud_rate; /* Actual bits/second for serial device */ 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *callback_script; /* script for doing callback */ 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint charshunt_pid; /* Process ID for charshunt */ 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint locked; /* lock() has succeeded */ 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct stat devstat; /* result of stat() on devnam */ 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* option variables */ 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint crtscts = 0; /* Use hardware flow control */ 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool modem = 1; /* Use modem control lines */ 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint inspeed = 0; /* Input/Output speed requested */ 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool lockflag = 0; /* Create lock file to lock the serial dev */ 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *initializer = NULL; /* Script to initialize physical link */ 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *connect_script = NULL; /* Script to establish physical link */ 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *disconnect_script = NULL; /* Script to disestablish physical link */ 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *welcomer = NULL; /* Script to run after phys link estab. */ 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *ptycommand = NULL; /* Command to run on other side of pty */ 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool notty = 0; /* Stdin/out is not a tty */ 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *record_file = NULL; /* File to record chars sent/received */ 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint max_data_rate; /* max bytes/sec through charshunt */ 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbool sync_serial = 0; /* Device is synchronous serial device */ 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *pty_socket = NULL; /* Socket to connect to pty */ 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint using_pty = 0; /* we're allocating a pty as the device */ 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern uid_t uid; 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern int kill_link; 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern int asked_to_quit; 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern int got_sigterm; 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* XXX */ 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern int privopen; /* don't lock, open device as root */ 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_int32_t xmit_accm[8]; /* extended transmit ACCM */ 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* option descriptors */ 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectoption_t tty_options[] = { 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* device name must be first, or change connect_tty() below! */ 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "device name", o_wild, (void *) &setdevname, 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Serial port device name", 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project devnam}, 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "tty speed", o_wild, (void *) &setspeed, 1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Baud rate for serial port", 1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIO | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, speed_str }, 1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "lock", o_bool, &lockflag, 1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Lock serial device with UUCP-style lock file", OPT_PRIO | 1 }, 1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "nolock", o_bool, &lockflag, 1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Don't lock serial device", OPT_PRIOSUB | OPT_PRIV }, 1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "init", o_string, &initializer, 1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "A program to initialize the device", OPT_PRIO | OPT_PRIVFIX }, 1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "connect", o_string, &connect_script, 1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "A program to set up a connection", OPT_PRIO | OPT_PRIVFIX }, 1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "disconnect", o_string, &disconnect_script, 1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Program to disconnect serial device", OPT_PRIO | OPT_PRIVFIX }, 1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "welcome", o_string, &welcomer, 1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Script to welcome client", OPT_PRIO | OPT_PRIVFIX }, 1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "pty", o_string, &ptycommand, 1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Script to run on pseudo-tty master side", 1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIO | OPT_PRIVFIX | OPT_DEVNAM }, 1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "notty", o_bool, ¬ty, 1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Input/output is not a tty", OPT_DEVNAM | 1 }, 1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "socket", o_string, &pty_socket, 2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Send and receive over socket, arg is host:port", 2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIO | OPT_DEVNAM }, 2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "record", o_string, &record_file, 2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Record characters sent/received to file", OPT_PRIO }, 2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "crtscts", o_int, &crtscts, 2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Set hardware (RTS/CTS) flow control", 2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIO | OPT_NOARG | OPT_VAL(1) }, 2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "cdtrcts", o_int, &crtscts, 2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Set alternate hardware (DTR/CTS) flow control", 2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIOSUB | OPT_NOARG | OPT_VAL(2) }, 2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "nocrtscts", o_int, &crtscts, 2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Disable hardware flow control", 2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, 2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "-crtscts", o_int, &crtscts, 2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Disable hardware flow control", 2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, 2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "nocdtrcts", o_int, &crtscts, 2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Disable hardware flow control", 2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, 2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "xonxoff", o_special_noarg, (void *)setxonxoff, 2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Set software (XON/XOFF) flow control", OPT_PRIOSUB }, 2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "modem", o_bool, &modem, 2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Use modem control lines", OPT_PRIO | 1 }, 2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "local", o_bool, &modem, 2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Don't use modem control lines", OPT_PRIOSUB | 0 }, 2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "sync", o_bool, &sync_serial, 2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Use synchronous HDLC serial encoding", 1 }, 2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "datarate", o_int, &max_data_rate, 2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Maximum data rate in bytes/sec (with pty, notty or record option)", 2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_PRIO }, 2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "escape", o_special, (void *)setescape, 2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "List of character codes to escape on transmission", 2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_A2PRINTER, (void *)printescape }, 2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { NULL } 2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct channel tty_channel = { 2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tty_options, 2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_process_extra_options, 2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_check_options, 2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &connect_tty, 2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &disconnect_tty, 2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_establish_ppp, 2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_disestablish_ppp, 2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_do_send_config, 2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_recv_config, 2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &cleanup_tty, 2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project &tty_close_fds 2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * setspeed - Set the serial port baud rate. 2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If doit is 0, the call is to check whether this option is 2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * potentially a speed value. 2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetspeed(arg, argv, doit) 2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *arg; 2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char **argv; 2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int doit; 2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *ptr; 2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int spd; 2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project spd = strtol(arg, &ptr, 0); 2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ptr == arg || *ptr != 0 || spd == 0) 2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (doit) { 2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project inspeed = spd; 2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project slprintf(speed_str, sizeof(speed_str), "%d", spd); 2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * setdevname - Set the device name. 2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If doit is 0, the call is to check whether this option is 2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * potentially a device name. 2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetdevname(cp, argv, doit) 2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *cp; 2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char **argv; 2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int doit; 2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct stat statbuf; 2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char dev[MAXPATHLEN]; 2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (*cp == 0) 2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (*cp != '/') { 3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strlcpy(dev, "/dev/", sizeof(dev)); 3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strlcat(dev, cp, sizeof(dev)); 3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cp = dev; 3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Check if there is a character device by this name. 3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (stat(cp, &statbuf) < 0) { 3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!doit) 3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return errno != ENOENT; 3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("Couldn't stat %s: %m", cp); 3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!S_ISCHR(statbuf.st_mode)) { 3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (doit) 3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s is not a character device", cp); 3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (doit) { 3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strlcpy(devnam, cp, sizeof(devnam)); 3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project devstat = statbuf; 3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default_device = 0; 3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetxonxoff(argv) 3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char **argv; 3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ 3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lcp_wantoptions[0].neg_asyncmap = 1; 3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project crtscts = -2; 3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * setescape - add chars to the set we escape on transmission. 3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetescape(argv) 3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char **argv; 3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int n, ret; 3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *p, *endp; 3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = *argv; 3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ret = 1; 3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (*p) { 3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = strtol(p, &endp, 16); 3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (p == endp) { 3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("escape parameter contains invalid hex number '%s'", 3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p); 3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = endp; 3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (n < 0 || n == 0x5E || n > 0xFF) { 3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("can't escape character 0x%x", n); 3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ret = 0; 3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project xmit_accm[n >> 5] |= 1 << (n & 0x1F); 3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (*p == ',' || *p == ' ') 3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ++p; 3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lcp_allowoptions[0].asyncmap = xmit_accm[0]; 3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return ret; 3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectprintescape(opt, printer, arg) 3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_t *opt; 3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void (*printer) __P((void *, char *, ...)); 3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void *arg; 3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int n; 3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int first = 1; 3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (n = 0; n < 256; ++n) { 3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (n == 0x7d) 3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n += 2; /* skip 7d, 7e */ 3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (xmit_accm[n >> 5] & (1 << (n & 0x1f))) { 3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!first) 3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, ","); 3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project first = 0; 3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, "%x", n); 3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (first) 3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printer(arg, "oops # nothing escaped"); 3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_init - do various tty-related initializations. 3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_init() 4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project add_notifier(&pidchange, maybe_relock, 0); 4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project the_channel = &tty_channel; 4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project xmit_accm[3] = 0x60000000; 4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_process_extra_options - work out which tty device we are using 4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and read its options file. 4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_process_extra_options() 4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project using_pty = notty || ptycommand != NULL || pty_socket != NULL; 4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (using_pty) 4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (default_device) { 4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *p; 4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!isatty(0) || (p = ttyname(0)) == NULL) { 4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("no device specified and stdin is not a tty"); 4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strlcpy(devnam, p, sizeof(devnam)); 4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (stat(devnam, &devstat) < 0) 4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("Couldn't stat default device %s: %m", devnam); 4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Parse the tty options file. 4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * The per-tty options file should not change 4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ptycommand, pty_socket, notty or devnam. 4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * options_for_tty doesn't override options set on the command line, 4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * except for some privileged options. 4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!options_for_tty()) 4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_check_options - do consistency checks on the options we were given. 4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_check_options() 4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct stat statbuf; 4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fdflags; 4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (demand && notty) { 4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("demand-dialling is incompatible with notty"); 4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (demand && connect_script == 0 && ptycommand == NULL 4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project && pty_socket == NULL) { 4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("connect script is required for demand-dialling\n"); 4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* default holdoff to 0 if no connect script has been given */ 4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (connect_script == 0 && !holdoff_specified) 4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project holdoff = 0; 4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (using_pty) { 4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!default_device) { 4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s option precludes specifying device name", 4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_socket? "socket": notty? "notty": "pty"); 4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ptycommand != NULL && notty) { 4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("pty option is incompatible with notty option"); 4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pty_socket != NULL && (ptycommand != NULL || notty)) { 4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("socket option is incompatible with pty and notty"); 4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(EXIT_OPTION_ERROR); 4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default_device = notty; 4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lockflag = 0; 4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project modem = 0; 4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (notty && log_to_fd <= 1) 4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project log_to_fd = -1; 4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the user has specified a device which is the same as 4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the one on stdin, pretend they didn't specify any. 4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the device is already open read/write on stdin, 4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * we assume we don't need to lock it, and we can open it 4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * as root. 4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) 4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project && statbuf.st_rdev == devstat.st_rdev) { 4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default_device = 1; 4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fdflags = fcntl(0, F_GETFL); 4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR) 4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project privopen = 1; 4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (default_device) 4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nodetach = 1; 4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Don't send log messages to the serial port, it tends to 5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * confuse the peer. :-) 5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0 5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) 5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project log_to_fd = -1; 5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * connect_tty - get the serial port ready to start doing PPP. 5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * That is, open the serial port, set its speed and mode, and run 5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the connector and/or welcomer. 5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint connect_tty() 5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *connector; 5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fdflags; 5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef __linux__ 5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct stat statbuf; 5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char numbuf[16]; 5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Get a pty master/slave pair if the pty, notty, socket, 5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * or record options were specified. 5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); 5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_master = -1; 5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_slave = -1; 5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project real_ttyfd = -1; 5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (using_pty || record_file != NULL) { 5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) { 5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Couldn't allocate pseudo-tty"); 5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_FATAL_ERROR; 5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project set_up_tty(pty_slave, 1); 5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Lock the device if we've been asked to. 5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_LOCK_FAILED; 5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (lockflag && !privopen) { 5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (lock(devnam) < 0) 5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project locked = 1; 5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Open the serial device and set it up to be the ppp interface. 5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * First we open it in non-blocking mode so we can set the 5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * various termios flags appropriately. If we aren't dialling 5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * out and we want to use the modem lines, we reopen it later 5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * in order to wait for the carrier detect signal from the modem. 5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hungup = 0; 5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project got_sigterm = 0; 5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project connector = doing_callback? callback_script: connect_script; 5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (devnam[0] != 0) { 5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (;;) { 5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* If the user specified the device name, become the 5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project user before opening it. */ 5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int err, prio; 5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project prio = privopen? OPRIO_ROOT: tty_options[0].priority; 5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (prio < OPRIO_ROOT) 5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project seteuid(uid); 5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); 5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project err = errno; 5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (prio < OPRIO_ROOT) 5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project seteuid(0); 5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd >= 0) 5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project errno = err; 5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (err != EINTR) { 5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Failed to open %s: %m", devnam); 5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_OPEN_FAILED; 5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!persist || err != EINTR) 5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ttyfd = real_ttyfd; 5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("Couldn't reset non-blocking mode on device: %m"); 5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef __linux__ 5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Linux 2.4 and above blocks normal writes to the tty 5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * when it is in PPP line discipline, so this isn't needed. 5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Do the equivalent of `mesg n' to stop broadcast messages. 5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fstat(ttyfd, &statbuf) < 0 5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { 5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("Couldn't restrict write permissions to %s: %m", devnam); 5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tty_mode = statbuf.st_mode; 6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* __linux__ */ 6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Set line speed, flow control, etc. 6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If we have a non-null connection or initializer script, 6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * on most systems we set CLOCAL for now so that we can talk 6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * to the modem before carrier comes up. But this has the 6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * side effect that we might miss it if CD drops before we 6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get to clear CLOCAL below. On systems where we can talk 6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * successfully to the modem with CLOCAL clear and CD down, 6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * we could clear CLOCAL at this point. 6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0) 6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project || initializer != NULL)); 6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If the pty, socket, notty and/or record option was specified, 6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * start up the character shunt now. 6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_PTYCMD_FAILED; 6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ptycommand != NULL) { 6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (record_file != NULL) { 6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int ipipe[2], opipe[2], ok; 6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pipe(ipipe) < 0 || pipe(opipe) < 0) 6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("Couldn't create pipes for record option: %m"); 6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* don't leak these to the ptycommand */ 6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) fcntl(ipipe[0], F_SETFD, FD_CLOEXEC); 6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) fcntl(opipe[1], F_SETFD, FD_CLOEXEC); 6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0 6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project && start_charshunt(ipipe[0], opipe[1]); 6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(ipipe[0]); 6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(ipipe[1]); 6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(opipe[0]); 6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(opipe[1]); 6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!ok) 6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (device_script(ptycommand, pty_master, pty_master, 1) < 0) 6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (pty_socket != NULL) { 6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fd = open_socket(pty_socket); 6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fd < 0) 6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!start_charshunt(fd, fd)) 6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(fd); 6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (notty) { 6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!start_charshunt(0, 1)) 6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dup2(fd_devnull, 0); 6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dup2(fd_devnull, 1); 6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (log_to_fd == 1) 6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project log_to_fd = -1; 6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (log_to_fd != 2) 6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dup2(fd_devnull, 2); 6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (record_file != NULL) { 6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fd = dup(ttyfd); 6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!start_charshunt(fd, fd)) 6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (using_pty || record_file != NULL) { 6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ttyfd = pty_slave; 6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(pty_master); 6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_master = -1; 6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* run connection script */ 6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((connector && connector[0]) || initializer) { 6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd != -1) { 6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* XXX do this if doing_callback == CALLBACK_DIALIN? */ 6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!default_device && modem) { 6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project setdtr(real_ttyfd, 0); /* in case modem is off hook */ 6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sleep(1); 6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project setdtr(real_ttyfd, 1); 6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (initializer && initializer[0]) { 6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (device_script(initializer, ttyfd, ttyfd, 0) < 0) { 6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Initializer script failed"); 6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_INIT_FAILED; 6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (got_sigterm) { 6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project disconnect_tty(); 6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Serial port initialized."); 6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (connector && connector[0]) { 6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (device_script(connector, ttyfd, ttyfd, 0) < 0) { 6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Connect script failed"); 6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_CONNECT_FAILED; 7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (got_sigterm) { 7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project disconnect_tty(); 7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Serial connection established."); 7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* set line speed, flow control, etc.; 7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clear CLOCAL if modem option */ 7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd != -1) 7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project set_up_tty(real_ttyfd, 0); 7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (doing_callback == CALLBACK_DIALIN) 7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project connector = NULL; 7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* reopen tty if necessary to wait for carrier */ 7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (connector == NULL && modem && devnam[0] != 0) { 7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (;;) { 7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((i = open(devnam, O_RDWR)) >= 0) 7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno != EINTR) { 7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Failed to reopen %s: %m", devnam); 7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project status = EXIT_OPEN_FAILED; 7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!persist || errno != EINTR || hungup || got_sigterm) 7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project goto errret; 7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(i); 7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project slprintf(numbuf, sizeof(numbuf), "%d", baud_rate); 7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project script_setenv("SPEED", numbuf, 0); 7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* run welcome script, if any */ 7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (welcomer && welcomer[0]) { 7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (device_script(welcomer, ttyfd, ttyfd, 0) < 0) 7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("Welcome script failed"); 7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * If we are initiating this connection, wait for a short 7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * time for something from the peer. This can avoid bouncing 7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * our packets off his tty before he has it set up. 7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (connector != NULL || ptycommand != NULL || pty_socket != NULL) 7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project listen_time = connect_delay; 7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return ttyfd; 7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project errret: 7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pty_master >= 0) { 7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(pty_master); 7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_master = -1; 7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pty_slave >= 0) { 7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(pty_slave); 7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_slave = -1; 7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd >= 0) { 7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(real_ttyfd); 7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project real_ttyfd = -1; 7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ttyfd = -1; 7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (got_sigterm) 7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project asked_to_quit = 1; 7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid disconnect_tty() 7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (disconnect_script == NULL || hungup) 7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd >= 0) 7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project set_up_tty(real_ttyfd, 1); 7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) { 7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("disconnect script failed"); 7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Serial link disconnected."); 7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid tty_close_fds() 7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pty_slave >= 0) 7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(pty_slave); 7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd >= 0) { 7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(real_ttyfd); 7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project real_ttyfd = -1; 7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* N.B. ttyfd will == either pty_slave or real_ttyfd */ 7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid cleanup_tty() 7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (real_ttyfd >= 0) 8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project finish_tty(); 8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tty_close_fds(); 8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (locked) { 8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unlock(); 8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project locked = 0; 8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_do_send_config - set transmit-side PPP configuration. 8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * We set the extended transmit ACCM here as well. 8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_do_send_config(mtu, accm, pcomp, accomp) 8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int mtu; 8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_int32_t accm; 8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int pcomp, accomp; 8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tty_set_xaccm(xmit_accm); 8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tty_send_config(mtu, accm, pcomp, accomp); 8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * finish_tty - restore the terminal device to its original settings 8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectfinish_tty() 8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* drop dtr to hang up */ 8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!default_device && modem) { 8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project setdtr(real_ttyfd, 0); 8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This sleep is in case the serial port has CLOCAL set by default, 8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and consequently will reassert DTR when we close the device. 8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sleep(1); 8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project restore_tty(real_ttyfd); 8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef __linux__ 8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (tty_mode != (mode_t) -1) { 8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fchmod(real_ttyfd, tty_mode) != 0) 8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Couldn't restore tty permissions"); 8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* __linux__ */ 8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(real_ttyfd); 8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project real_ttyfd = -1; 8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * maybe_relock - our PID has changed, maybe update the lock file. 8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectmaybe_relock(arg, pid) 8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void *arg; 8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int pid; 8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (locked) 8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project relock(pid); 8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * open_socket - establish a stream socket connection to the nominated 8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * host and port. 8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectopen_socket(dest) 8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *dest; 8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *sep, *endp = NULL; 8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int sock, port = -1; 8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_int32_t host; 8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct hostent *hent; 8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr_in sad; 8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* parse host:port and resolve host to an IP address */ 8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sep = strchr(dest, ':'); 8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (sep != NULL) 8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project port = strtol(sep+1, &endp, 10); 8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (port < 0 || endp == sep+1 || sep == dest) { 8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Can't parse host:port for socket destination"); 8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *sep = 0; 8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project host = inet_addr(dest); 8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (host == (u_int32_t) -1) { 8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hent = gethostbyname(dest); 8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (hent == NULL) { 8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("%s: unknown host in socket option", dest); 8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *sep = ':'; 8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project host = *(u_int32_t *)(hent->h_addr_list[0]); 8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *sep = ':'; 8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* get a socket and connect it to the other end */ 8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sock = socket(PF_INET, SOCK_STREAM, 0); 9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (sock < 0) { 9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Can't create socket: %m"); 9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(&sad, 0, sizeof(sad)); 9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sad.sin_family = AF_INET; 9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sad.sin_port = htons(port); 9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sad.sin_addr.s_addr = host; 9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) < 0) { 9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Can't connect to %s: %m", dest); 9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(sock); 9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return sock; 9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * start_charshunt - create a child process to run the character shunt. 9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstart_charshunt(ifd, ofd) 9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int ifd, ofd; 9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int cpid; 9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cpid = safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); 9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (cpid == -1) { 9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Can't fork process for character shunt: %m"); 9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (cpid == 0) { 9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* child */ 9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project reopen_log(); 9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!nodetach) 9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project log_to_fd = -1; 9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else if (log_to_fd >= 0) 9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project log_to_fd = 2; 9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project setgid(getgid()); 9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project setuid(uid); 9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (getuid() != uid) 9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("setuid failed"); 9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project charshunt(0, 1, record_file); 9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(0); 9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project charshunt_pid = cpid; 9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project add_notifier(&sigreceived, stop_charshunt, 0); 9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project record_child(cpid, "pppd (charshunt)", charshunt_done, NULL); 9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcharshunt_done(arg) 9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void *arg; 9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project charshunt_pid = 0; 9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstop_charshunt(arg, sig) 9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void *arg; 9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int sig; 9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (charshunt_pid) 9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM)); 9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * charshunt - the character shunt, which passes characters between 9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the pty master side and the serial port (or stdin/stdout). 9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This runs as the user (not as root). 9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * (We assume ofd >= ifd which is true the way this gets called. :-). 9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcharshunt(ifd, ofd, record_file) 9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int ifd, ofd; 9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *record_file; 9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int n, nfds; 9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fd_set ready, writey; 9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_char *ibufp, *obufp; 9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int nibuf, nobuf; 9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int pty_readable, stdin_readable; 9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval lasttime; 9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FILE *recordf = NULL; 9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int ilevel, olevel, max_level; 9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval levelt, tout, *top; 9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project extern u_char inpacket_buf[]; 9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Reset signal handlers. 9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGHUP, SIG_IGN); /* Hangup */ 9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGINT, SIG_DFL); /* Interrupt */ 9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGTERM, SIG_DFL); /* Terminate */ 9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGCHLD, SIG_DFL); 9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGUSR1, SIG_DFL); 9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGUSR2, SIG_DFL); 10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGABRT, SIG_DFL); 10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGALRM, SIG_DFL); 10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGFPE, SIG_DFL); 10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGILL, SIG_DFL); 10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGPIPE, SIG_DFL); 10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGQUIT, SIG_DFL); 10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGSEGV, SIG_DFL); 10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGBUS 10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGBUS, SIG_DFL); 10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGEMT 10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGEMT, SIG_DFL); 10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGPOLL 10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGPOLL, SIG_DFL); 10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGPROF 10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGPROF, SIG_DFL); 10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGSYS 10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGSYS, SIG_DFL); 10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGTRAP 10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGTRAP, SIG_DFL); 10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGVTALRM 10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGVTALRM, SIG_DFL); 10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGXCPU 10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGXCPU, SIG_DFL); 10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIGXFSZ 10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project signal(SIGXFSZ, SIG_DFL); 10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Check that the fds won't overrun the fd_sets 10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ifd >= FD_SETSIZE || ofd >= FD_SETSIZE || pty_master >= FD_SETSIZE) 10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("internal error: file descriptor too large (%d, %d, %d)", 10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifd, ofd, pty_master); 10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Open the record file if required. 10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (record_file != NULL) { 10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recordf = fopen(record_file, "a"); 10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (recordf == NULL) 10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Couldn't create record file %s: %m", record_file); 10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* set all the fds to non-blocking mode */ 10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = fcntl(pty_master, F_GETFL); 10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (flags == -1 10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project || fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1) 10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("couldn't set pty master to nonblock: %m"); 10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = fcntl(ifd, F_GETFL); 10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (flags == -1 10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project || fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1) 10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty")); 10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ofd != ifd) { 10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = fcntl(ofd, F_GETFL); 10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (flags == -1 10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1) 10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("couldn't set stdout to nonblock: %m"); 10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf = nobuf = 0; 10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ibufp = obufp = NULL; 10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_readable = stdin_readable = 1; 10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ilevel = olevel = 0; 10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gettimeofday(&levelt, NULL); 10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (max_data_rate) { 10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project max_level = max_data_rate / 10; 10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (max_level < 100) 10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project max_level = 100; 10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project max_level = PPP_MRU + PPP_HDRLEN + 1; 10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nfds = (ofd > pty_master? ofd: pty_master) + 1; 10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (recordf != NULL) { 10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gettimeofday(&lasttime, NULL); 10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(7, recordf); /* put start marker */ 10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(lasttime.tv_sec >> 24, recordf); 10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(lasttime.tv_sec >> 16, recordf); 10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(lasttime.tv_sec >> 8, recordf); 10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(lasttime.tv_sec, recordf); 10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project lasttime.tv_usec = 0; 10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) { 10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project top = 0; 10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tout.tv_sec = 0; 10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tout.tv_usec = 10000; 10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_ZERO(&ready); 10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_ZERO(&writey); 10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (nibuf != 0) { 10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ilevel >= max_level) 10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project top = &tout; 11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET(pty_master, &writey); 11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (stdin_readable) 11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET(ifd, &ready); 11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (nobuf != 0) { 11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (olevel >= max_level) 11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project top = &tout; 11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET(ofd, &writey); 11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (pty_readable) 11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET(pty_master, &ready); 11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (select(nfds, &ready, &writey, NULL, top) < 0) { 11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno != EINTR) 11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatal("select"); 11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (max_data_rate) { 11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project double dt; 11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int nbt; 11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval now; 11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gettimeofday(&now, NULL); 11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dt = (now.tv_sec - levelt.tv_sec 11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project + (now.tv_usec - levelt.tv_usec) / 1e6); 11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nbt = (int)(dt * max_data_rate); 11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt; 11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt; 11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project levelt = now; 11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ilevel = olevel = 0; 11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (FD_ISSET(ifd, &ready)) { 11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ibufp = inpacket_buf; 11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf = read(ifd, ibufp, PPP_MRU + PPP_HDRLEN); 11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (nibuf < 0 && errno == EIO) 11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf = 0; 11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (nibuf < 0) { 11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!(errno == EINTR || errno == EAGAIN)) { 11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Error reading standard input: %m"); 11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf = 0; 11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (nibuf == 0) { 11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* end of file from stdin */ 11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project stdin_readable = 0; 11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (recordf) 11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!record_write(recordf, 4, NULL, 0, &lasttime)) 11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recordf = NULL; 11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET(pty_master, &writey); 11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (recordf) 11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!record_write(recordf, 2, ibufp, nibuf, &lasttime)) 11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recordf = NULL; 11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (FD_ISSET(pty_master, &ready)) { 11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project obufp = outpacket_buf; 11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nobuf = read(pty_master, obufp, PPP_MRU + PPP_HDRLEN); 11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (nobuf < 0 && errno == EIO) 11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nobuf = 0; 11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (nobuf < 0) { 11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!(errno == EINTR || errno == EAGAIN)) { 11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Error reading pseudo-tty master: %m"); 11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nobuf = 0; 11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (nobuf == 0) { 11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* end of file from the pty - slave side has closed */ 11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_readable = 0; 11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project stdin_readable = 0; /* pty is not writable now */ 11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf = 0; 11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(ofd); 11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (recordf) 11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!record_write(recordf, 3, NULL, 0, &lasttime)) 11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recordf = NULL; 11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FD_SET(ofd, &writey); 11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (recordf) 11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!record_write(recordf, 1, obufp, nobuf, &lasttime)) 11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recordf = NULL; 11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (!stdin_readable) 11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_readable = 0; 11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (FD_ISSET(ofd, &writey)) { 11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = nobuf; 11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (olevel + n > max_level) 11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = max_level - olevel; 11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = write(ofd, obufp, n); 11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (n < 0) { 11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno == EIO) { 11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pty_readable = 0; 11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nobuf = 0; 11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (errno != EAGAIN && errno != EINTR) { 11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Error writing standard output: %m"); 11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project obufp += n; 11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nobuf -= n; 11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project olevel += n; 11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (FD_ISSET(pty_master, &writey)) { 12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = nibuf; 12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ilevel + n > max_level) 12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = max_level - ilevel; 12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project n = write(pty_master, ibufp, n); 12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (n < 0) { 12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno == EIO) { 12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project stdin_readable = 0; 12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf = 0; 12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else if (errno != EAGAIN && errno != EINTR) { 12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Error writing pseudo-tty master: %m"); 12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ibufp += n; 12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project nibuf -= n; 12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ilevel += n; 12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(0); 12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int 12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectrecord_write(f, code, buf, nb, tp) 12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FILE *f; 12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int code; 12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_char *buf; 12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int nb; 12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval *tp; 12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct timeval now; 12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int diff; 12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gettimeofday(&now, NULL); 12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project now.tv_usec /= 100000; /* actually 1/10 s, not usec now */ 12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec); 12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (diff > 0) { 12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (diff > 255) { 12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(5, f); 12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(diff >> 24, f); 12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(diff >> 16, f); 12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(diff >> 8, f); 12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(diff, f); 12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(6, f); 12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(diff, f); 12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *tp = now; 12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(code, f); 12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (buf != NULL) { 12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(nb >> 8, f); 12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project putc(nb, f); 12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fwrite(buf, nb, 1, f); 12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fflush(f); 12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ferror(f)) { 12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Error writing record file: %m"); 12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1264