163b73463SBrian Somers /* 263b73463SBrian Somers * Written by Eivind Eklund <eivind@yes.no> 363b73463SBrian Somers * for Yes Interactive 463b73463SBrian Somers * 563b73463SBrian Somers * Copyright (C) 1998, Yes Interactive. All rights reserved. 663b73463SBrian Somers * 763b73463SBrian Somers * Redistribution and use in any form is permitted. Redistribution in 863b73463SBrian Somers * source form should include the above copyright and this set of 963b73463SBrian Somers * conditions, because large sections american law seems to have been 1063b73463SBrian Somers * created by a bunch of jerks on drugs that are now illegal, forcing 1163b73463SBrian Somers * me to include this copyright-stuff instead of placing this in the 1263b73463SBrian Somers * public domain. The name of of 'Yes Interactive' or 'Eivind Eklund' 1363b73463SBrian Somers * may not be used to endorse or promote products derived from this 1463b73463SBrian Somers * software without specific prior written permission. 1563b73463SBrian Somers * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1663b73463SBrian Somers * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1763b73463SBrian Somers * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1863b73463SBrian Somers * 191fa75dc1SBrian Somers * $Id: physical.c,v 1.1.2.33 1998/05/15 23:58:25 brian Exp $ 2063b73463SBrian Somers * 2163b73463SBrian Somers */ 2263b73463SBrian Somers 232764b86aSBrian Somers #include <sys/types.h> 2463b73463SBrian Somers 2563b73463SBrian Somers #include <stdio.h> 266f384573SBrian Somers #include <stdlib.h> 2763b73463SBrian Somers #include <string.h> 28fc1141b2SBrian Somers #include <time.h> 2963b73463SBrian Somers #include <unistd.h> 30fc1141b2SBrian Somers #include <utmp.h> 316f384573SBrian Somers #include <sys/tty.h> 3263b73463SBrian Somers 3363b73463SBrian Somers #include "defs.h" 3463b73463SBrian Somers #include "mbuf.h" 3563b73463SBrian Somers #include "timer.h" 36879ed6faSBrian Somers #include "lqr.h" 3763258dccSBrian Somers #include "hdlc.h" 3863b73463SBrian Somers #include "throughput.h" 396140ba11SBrian Somers #include "fsm.h" 406140ba11SBrian Somers #include "lcp.h" 416140ba11SBrian Somers #include "async.h" 423b0f8d2eSBrian Somers #include "ccp.h" 438c07a7b2SBrian Somers #include "link.h" 4442d4d396SBrian Somers #include "descriptor.h" 4563b73463SBrian Somers #include "physical.h" 4642d4d396SBrian Somers #include "log.h" 47fc1141b2SBrian Somers #include "id.h" 4863b73463SBrian Somers 4963b73463SBrian Somers /* External calls - should possibly be moved inline */ 5063b73463SBrian Somers extern int IntToSpeed(int); 5163b73463SBrian Somers 5263b73463SBrian Somers 5363b73463SBrian Somers int 54dd7e2610SBrian Somers physical_GetFD(struct physical *phys) { 5563b73463SBrian Somers return phys->fd; 5663b73463SBrian Somers } 5763b73463SBrian Somers 5863b73463SBrian Somers int 59dd7e2610SBrian Somers physical_IsATTY(struct physical *phys) { 6063b73463SBrian Somers return isatty(phys->fd); 6163b73463SBrian Somers } 6263b73463SBrian Somers 6363b73463SBrian Somers int 64dd7e2610SBrian Somers physical_IsSync(struct physical *phys) { 65d585f8f5SBrian Somers return phys->cfg.speed == 0; 6663b73463SBrian Somers } 6763b73463SBrian Somers 68dd7e2610SBrian Somers const char *physical_GetDevice(struct physical *phys) 693bf710a4SBrian Somers { 703bf710a4SBrian Somers return phys->name.full; 7163b73463SBrian Somers } 7263b73463SBrian Somers 7363b73463SBrian Somers void 74dd7e2610SBrian Somers physical_SetDeviceList(struct physical *p, int argc, const char *const *argv) 7599294c8bSBrian Somers { 7699294c8bSBrian Somers int f, pos; 7799294c8bSBrian Somers 7899294c8bSBrian Somers p->cfg.devlist[sizeof p->cfg.devlist - 1] = '\0'; 7999294c8bSBrian Somers for (f = 0, pos = 0; f < argc && pos < sizeof p->cfg.devlist - 1; f++) { 8099294c8bSBrian Somers if (pos) 8199294c8bSBrian Somers p->cfg.devlist[pos++] = ' '; 8299294c8bSBrian Somers strncpy(p->cfg.devlist + pos, argv[f], sizeof p->cfg.devlist - pos - 1); 8399294c8bSBrian Somers pos += strlen(p->cfg.devlist + pos); 8499294c8bSBrian Somers } 8563b73463SBrian Somers } 8663b73463SBrian Somers 8763b73463SBrian Somers 8863b73463SBrian Somers int 89dd7e2610SBrian Somers physical_SetSpeed(struct physical *phys, int speed) { 9063b73463SBrian Somers if (IntToSpeed(speed) != B0) { 91d585f8f5SBrian Somers phys->cfg.speed = speed; 9263b73463SBrian Somers return 1; 9363b73463SBrian Somers } else { 9463b73463SBrian Somers return 0; 9563b73463SBrian Somers } 9663b73463SBrian Somers } 9763b73463SBrian Somers 9863b73463SBrian Somers void 99dd7e2610SBrian Somers physical_SetSync(struct physical *phys) { 100d585f8f5SBrian Somers phys->cfg.speed = 0; 10163b73463SBrian Somers } 10263b73463SBrian Somers 10363b73463SBrian Somers 10463b73463SBrian Somers int 105dd7e2610SBrian Somers physical_SetRtsCts(struct physical *phys, int enable) { 106b762af4fSBrian Somers phys->cfg.rts_cts = enable ? 1 : 0; 10763b73463SBrian Somers return 1; 10863b73463SBrian Somers } 10963b73463SBrian Somers 11063b73463SBrian Somers /* Encapsulation for a read on the FD. Avoids some exposure, and 11163b73463SBrian Somers concentrates control. */ 11263b73463SBrian Somers ssize_t 113dd7e2610SBrian Somers physical_Read(struct physical *phys, void *buf, size_t nbytes) { 11463b73463SBrian Somers return read(phys->fd, buf, nbytes); 11563b73463SBrian Somers } 11663b73463SBrian Somers 11763b73463SBrian Somers ssize_t 118dd7e2610SBrian Somers physical_Write(struct physical *phys, const void *buf, size_t nbytes) { 11963b73463SBrian Somers return write(phys->fd, buf, nbytes); 12063b73463SBrian Somers } 121ecd5172aSBrian Somers 122ecd5172aSBrian Somers int 123dd7e2610SBrian Somers physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, 124b6dec9f0SBrian Somers int *n, int force) 12542d4d396SBrian Somers { 12642d4d396SBrian Somers struct physical *p = descriptor2physical(d); 12742d4d396SBrian Somers int sets; 12842d4d396SBrian Somers 12942d4d396SBrian Somers sets = 0; 130b6dec9f0SBrian Somers if (p->fd >= 0) { 131b6dec9f0SBrian Somers if (r) { 132b6dec9f0SBrian Somers FD_SET(p->fd, r); 13324989c68SBrian Somers log_Printf(LogTIMER, "%s: fdset(r) %d\n", p->link.name, p->fd); 134b6dec9f0SBrian Somers sets++; 135b6dec9f0SBrian Somers } 136b6dec9f0SBrian Somers if (e) { 137b6dec9f0SBrian Somers FD_SET(p->fd, e); 13824989c68SBrian Somers log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, p->fd); 139b6dec9f0SBrian Somers sets++; 140b6dec9f0SBrian Somers } 141b6dec9f0SBrian Somers if (w && (force || link_QueueLen(&p->link))) { 142b6dec9f0SBrian Somers FD_SET(p->fd, w); 14324989c68SBrian Somers log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, p->fd); 144b6dec9f0SBrian Somers sets++; 145b6dec9f0SBrian Somers } 146b6dec9f0SBrian Somers if (sets && *n < p->fd + 1) 147b6dec9f0SBrian Somers *n = p->fd + 1; 148b6dec9f0SBrian Somers } 14942d4d396SBrian Somers 15042d4d396SBrian Somers return sets; 15142d4d396SBrian Somers } 15242d4d396SBrian Somers 15342d4d396SBrian Somers int 154ea722969SBrian Somers physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) 155ea722969SBrian Somers { 156ea722969SBrian Somers int sets; 157ea722969SBrian Somers 158ea722969SBrian Somers sets = 0; 159ea722969SBrian Somers if (p->fd >= 0) { 160ea722969SBrian Somers if (r && FD_ISSET(p->fd, r)) { 161ea722969SBrian Somers FD_CLR(p->fd, r); 162ea722969SBrian Somers log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd); 163ea722969SBrian Somers sets++; 164ea722969SBrian Somers } 165ea722969SBrian Somers if (e && FD_ISSET(p->fd, e)) { 166ea722969SBrian Somers FD_CLR(p->fd, e); 167ea722969SBrian Somers log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd); 168ea722969SBrian Somers sets++; 169ea722969SBrian Somers } 170ea722969SBrian Somers if (w && FD_ISSET(p->fd, w)) { 171ea722969SBrian Somers FD_CLR(p->fd, w); 172ea722969SBrian Somers log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd); 173ea722969SBrian Somers sets++; 174ea722969SBrian Somers } 175ea722969SBrian Somers } 176ea722969SBrian Somers 177ea722969SBrian Somers return sets; 178ea722969SBrian Somers } 179ea722969SBrian Somers 180ea722969SBrian Somers int 181dd7e2610SBrian Somers physical_IsSet(struct descriptor *d, const fd_set *fdset) 18242d4d396SBrian Somers { 18342d4d396SBrian Somers struct physical *p = descriptor2physical(d); 18442d4d396SBrian Somers return p->fd >= 0 && FD_ISSET(p->fd, fdset); 18542d4d396SBrian Somers } 18642d4d396SBrian Somers 18742d4d396SBrian Somers void 188dd7e2610SBrian Somers physical_Login(struct physical *phys, const char *name) 189fc1141b2SBrian Somers { 190dd7e2610SBrian Somers if (phys->type == PHYS_DIRECT && physical_IsATTY(phys)) { 191fc1141b2SBrian Somers if (phys->Utmp) 192dd7e2610SBrian Somers log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base); 193fc1141b2SBrian Somers else { 194fc1141b2SBrian Somers struct utmp ut; 1951fa75dc1SBrian Somers const char *connstr; 196fc1141b2SBrian Somers 197fc1141b2SBrian Somers memset(&ut, 0, sizeof ut); 198fc1141b2SBrian Somers time(&ut.ut_time); 199fc1141b2SBrian Somers strncpy(ut.ut_name, name, sizeof ut.ut_name); 2001fa75dc1SBrian Somers strncpy(ut.ut_line, phys->name.base, sizeof ut.ut_line); 2011fa75dc1SBrian Somers if ((connstr = getenv("CONNECT"))) 2021fa75dc1SBrian Somers /* mgetty sets this to the connection speed */ 2031fa75dc1SBrian Somers strncpy(ut.ut_host, connstr, sizeof ut.ut_host); 204fc1141b2SBrian Somers ID0login(&ut); 205fc1141b2SBrian Somers phys->Utmp = 1; 206fc1141b2SBrian Somers } 207fc1141b2SBrian Somers } 208e43ebac1SBrian Somers } 209fc1141b2SBrian Somers 210fc1141b2SBrian Somers void 211dd7e2610SBrian Somers physical_Logout(struct physical *phys) 212fc1141b2SBrian Somers { 213fc1141b2SBrian Somers if (phys->Utmp) { 214fc1141b2SBrian Somers ID0logout(phys->name.base); 215fc1141b2SBrian Somers phys->Utmp = 0; 216fc1141b2SBrian Somers } 217fc1141b2SBrian Somers } 218dd0645c5SBrian Somers 219dd0645c5SBrian Somers int 220dd0645c5SBrian Somers physical_SetMode(struct physical *p, int mode) 221dd0645c5SBrian Somers { 222dd0645c5SBrian Somers if (p->type & (PHYS_DIRECT|PHYS_DEDICATED) 223dd0645c5SBrian Somers || mode & (PHYS_DIRECT|PHYS_DEDICATED)) { 224dd0645c5SBrian Somers log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name, 225dd0645c5SBrian Somers mode2Nam(p->type), mode2Nam(mode)); 226dd0645c5SBrian Somers return 0; 227dd0645c5SBrian Somers } 228dd0645c5SBrian Somers p->type = mode; 229dd0645c5SBrian Somers return 1; 230dd0645c5SBrian Somers } 231