physical.c revision 36314
1/* 2 * Written by Eivind Eklund <eivind@yes.no> 3 * for Yes Interactive 4 * 5 * Copyright (C) 1998, Yes Interactive. All rights reserved. 6 * 7 * Redistribution and use in any form is permitted. Redistribution in 8 * source form should include the above copyright and this set of 9 * conditions, because large sections american law seems to have been 10 * created by a bunch of jerks on drugs that are now illegal, forcing 11 * me to include this copyright-stuff instead of placing this in the 12 * public domain. The name of of 'Yes Interactive' or 'Eivind Eklund' 13 * may not be used to endorse or promote products derived from this 14 * software without specific prior written permission. 15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 18 * 19 * $Id: physical.c,v 1.2 1998/05/21 21:47:37 brian Exp $ 20 * 21 */ 22 23#include <sys/types.h> 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <time.h> 29#include <unistd.h> 30#include <utmp.h> 31#include <sys/tty.h> 32 33#include "defs.h" 34#include "mbuf.h" 35#include "timer.h" 36#include "lqr.h" 37#include "hdlc.h" 38#include "throughput.h" 39#include "fsm.h" 40#include "lcp.h" 41#include "async.h" 42#include "ccp.h" 43#include "link.h" 44#include "descriptor.h" 45#include "physical.h" 46#include "log.h" 47#include "id.h" 48 49/* External calls - should possibly be moved inline */ 50extern int IntToSpeed(int); 51 52 53int 54physical_GetFD(struct physical *phys) { 55 return phys->fd; 56} 57 58int 59physical_IsATTY(struct physical *phys) { 60 return isatty(phys->fd); 61} 62 63int 64physical_IsSync(struct physical *phys) { 65 return phys->cfg.speed == 0; 66} 67 68const char *physical_GetDevice(struct physical *phys) 69{ 70 return phys->name.full; 71} 72 73void 74physical_SetDeviceList(struct physical *p, int argc, const char *const *argv) 75{ 76 int f, pos; 77 78 p->cfg.devlist[sizeof p->cfg.devlist - 1] = '\0'; 79 for (f = 0, pos = 0; f < argc && pos < sizeof p->cfg.devlist - 1; f++) { 80 if (pos) 81 p->cfg.devlist[pos++] = ' '; 82 strncpy(p->cfg.devlist + pos, argv[f], sizeof p->cfg.devlist - pos - 1); 83 pos += strlen(p->cfg.devlist + pos); 84 } 85} 86 87 88int 89physical_SetSpeed(struct physical *phys, int speed) { 90 if (IntToSpeed(speed) != B0) { 91 phys->cfg.speed = speed; 92 return 1; 93 } else { 94 return 0; 95 } 96} 97 98void 99physical_SetSync(struct physical *phys) { 100 phys->cfg.speed = 0; 101} 102 103 104int 105physical_SetRtsCts(struct physical *phys, int enable) { 106 phys->cfg.rts_cts = enable ? 1 : 0; 107 return 1; 108} 109 110/* Encapsulation for a read on the FD. Avoids some exposure, and 111 concentrates control. */ 112ssize_t 113physical_Read(struct physical *phys, void *buf, size_t nbytes) { 114 return read(phys->fd, buf, nbytes); 115} 116 117ssize_t 118physical_Write(struct physical *phys, const void *buf, size_t nbytes) { 119 return write(phys->fd, buf, nbytes); 120} 121 122int 123physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, 124 int *n, int force) 125{ 126 struct physical *p = descriptor2physical(d); 127 int sets; 128 129 sets = 0; 130 if (p->fd >= 0) { 131 if (r) { 132 FD_SET(p->fd, r); 133 log_Printf(LogTIMER, "%s: fdset(r) %d\n", p->link.name, p->fd); 134 sets++; 135 } 136 if (e) { 137 FD_SET(p->fd, e); 138 log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, p->fd); 139 sets++; 140 } 141 if (w && (force || link_QueueLen(&p->link) || p->out)) { 142 FD_SET(p->fd, w); 143 log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, p->fd); 144 sets++; 145 } 146 if (sets && *n < p->fd + 1) 147 *n = p->fd + 1; 148 } 149 150 return sets; 151} 152 153int 154physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) 155{ 156 int sets; 157 158 sets = 0; 159 if (p->fd >= 0) { 160 if (r && FD_ISSET(p->fd, r)) { 161 FD_CLR(p->fd, r); 162 log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd); 163 sets++; 164 } 165 if (e && FD_ISSET(p->fd, e)) { 166 FD_CLR(p->fd, e); 167 log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd); 168 sets++; 169 } 170 if (w && FD_ISSET(p->fd, w)) { 171 FD_CLR(p->fd, w); 172 log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd); 173 sets++; 174 } 175 } 176 177 return sets; 178} 179 180int 181physical_IsSet(struct descriptor *d, const fd_set *fdset) 182{ 183 struct physical *p = descriptor2physical(d); 184 return p->fd >= 0 && FD_ISSET(p->fd, fdset); 185} 186 187void 188physical_Login(struct physical *phys, const char *name) 189{ 190 if (phys->type == PHYS_DIRECT && physical_IsATTY(phys)) { 191 if (phys->Utmp) 192 log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base); 193 else { 194 struct utmp ut; 195 const char *connstr; 196 197 memset(&ut, 0, sizeof ut); 198 time(&ut.ut_time); 199 strncpy(ut.ut_name, name, sizeof ut.ut_name); 200 strncpy(ut.ut_line, phys->name.base, sizeof ut.ut_line); 201 if ((connstr = getenv("CONNECT"))) 202 /* mgetty sets this to the connection speed */ 203 strncpy(ut.ut_host, connstr, sizeof ut.ut_host); 204 ID0login(&ut); 205 phys->Utmp = 1; 206 } 207 } 208} 209 210void 211physical_Logout(struct physical *phys) 212{ 213 if (phys->Utmp) { 214 ID0logout(phys->name.base); 215 phys->Utmp = 0; 216 } 217} 218 219int 220physical_SetMode(struct physical *p, int mode) 221{ 222 if (p->type & (PHYS_DIRECT|PHYS_DEDICATED) 223 || mode & (PHYS_DIRECT|PHYS_DEDICATED)) { 224 log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name, 225 mode2Nam(p->type), mode2Nam(mode)); 226 return 0; 227 } 228 p->type = mode; 229 return 1; 230} 231