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 * 196f8e9f0aSBrian Somers * $Id: physical.c,v 1.5 1998/08/07 18:42:50 brian Exp $ 2063b73463SBrian Somers * 2163b73463SBrian Somers */ 2263b73463SBrian Somers 2363b73463SBrian Somers #include <stdio.h> 246f384573SBrian Somers #include <stdlib.h> 2563b73463SBrian Somers #include <string.h> 26fc1141b2SBrian Somers #include <time.h> 2763b73463SBrian Somers #include <unistd.h> 28fc1141b2SBrian Somers #include <utmp.h> 296f384573SBrian Somers #include <sys/tty.h> 3063b73463SBrian Somers 3163b73463SBrian Somers #include "defs.h" 3263b73463SBrian Somers #include "mbuf.h" 3363b73463SBrian Somers #include "timer.h" 34879ed6faSBrian Somers #include "lqr.h" 3563258dccSBrian Somers #include "hdlc.h" 3663b73463SBrian Somers #include "throughput.h" 376140ba11SBrian Somers #include "fsm.h" 386140ba11SBrian Somers #include "lcp.h" 396140ba11SBrian Somers #include "async.h" 403b0f8d2eSBrian Somers #include "ccp.h" 418c07a7b2SBrian Somers #include "link.h" 4242d4d396SBrian Somers #include "descriptor.h" 4363b73463SBrian Somers #include "physical.h" 4442d4d396SBrian Somers #include "log.h" 45fc1141b2SBrian Somers #include "id.h" 4663b73463SBrian Somers 4763b73463SBrian Somers /* External calls - should possibly be moved inline */ 4863b73463SBrian Somers extern int IntToSpeed(int); 4963b73463SBrian Somers 5063b73463SBrian Somers 5163b73463SBrian Somers int 52dd7e2610SBrian Somers physical_GetFD(struct physical *phys) { 5363b73463SBrian Somers return phys->fd; 5463b73463SBrian Somers } 5563b73463SBrian Somers 5663b73463SBrian Somers int 57dd7e2610SBrian Somers physical_IsATTY(struct physical *phys) { 5863b73463SBrian Somers return isatty(phys->fd); 5963b73463SBrian Somers } 6063b73463SBrian Somers 6163b73463SBrian Somers int 62dd7e2610SBrian Somers physical_IsSync(struct physical *phys) { 63d585f8f5SBrian Somers return phys->cfg.speed == 0; 6463b73463SBrian Somers } 6563b73463SBrian Somers 66dd7e2610SBrian Somers const char *physical_GetDevice(struct physical *phys) 673bf710a4SBrian Somers { 683bf710a4SBrian Somers return phys->name.full; 6963b73463SBrian Somers } 7063b73463SBrian Somers 7163b73463SBrian Somers void 72dd7e2610SBrian Somers physical_SetDeviceList(struct physical *p, int argc, const char *const *argv) 7399294c8bSBrian Somers { 7499294c8bSBrian Somers int f, pos; 7599294c8bSBrian Somers 7699294c8bSBrian Somers p->cfg.devlist[sizeof p->cfg.devlist - 1] = '\0'; 7799294c8bSBrian Somers for (f = 0, pos = 0; f < argc && pos < sizeof p->cfg.devlist - 1; f++) { 7899294c8bSBrian Somers if (pos) 7999294c8bSBrian Somers p->cfg.devlist[pos++] = ' '; 8099294c8bSBrian Somers strncpy(p->cfg.devlist + pos, argv[f], sizeof p->cfg.devlist - pos - 1); 8199294c8bSBrian Somers pos += strlen(p->cfg.devlist + pos); 8299294c8bSBrian Somers } 8363b73463SBrian Somers } 8463b73463SBrian Somers 8563b73463SBrian Somers 8663b73463SBrian Somers int 87dd7e2610SBrian Somers physical_SetSpeed(struct physical *phys, int speed) { 8863b73463SBrian Somers if (IntToSpeed(speed) != B0) { 89d585f8f5SBrian Somers phys->cfg.speed = speed; 9063b73463SBrian Somers return 1; 9163b73463SBrian Somers } else { 9263b73463SBrian Somers return 0; 9363b73463SBrian Somers } 9463b73463SBrian Somers } 9563b73463SBrian Somers 9663b73463SBrian Somers void 97dd7e2610SBrian Somers physical_SetSync(struct physical *phys) { 98d585f8f5SBrian Somers phys->cfg.speed = 0; 9963b73463SBrian Somers } 10063b73463SBrian Somers 10163b73463SBrian Somers 10263b73463SBrian Somers int 103dd7e2610SBrian Somers physical_SetRtsCts(struct physical *phys, int enable) { 104b762af4fSBrian Somers phys->cfg.rts_cts = enable ? 1 : 0; 10563b73463SBrian Somers return 1; 10663b73463SBrian Somers } 10763b73463SBrian Somers 10863b73463SBrian Somers /* Encapsulation for a read on the FD. Avoids some exposure, and 10963b73463SBrian Somers concentrates control. */ 11063b73463SBrian Somers ssize_t 111dd7e2610SBrian Somers physical_Read(struct physical *phys, void *buf, size_t nbytes) { 11263b73463SBrian Somers return read(phys->fd, buf, nbytes); 11363b73463SBrian Somers } 11463b73463SBrian Somers 11563b73463SBrian Somers ssize_t 116dd7e2610SBrian Somers physical_Write(struct physical *phys, const void *buf, size_t nbytes) { 11763b73463SBrian Somers return write(phys->fd, buf, nbytes); 11863b73463SBrian Somers } 119ecd5172aSBrian Somers 120ecd5172aSBrian Somers int 121dd7e2610SBrian Somers physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, 122b6dec9f0SBrian Somers int *n, int force) 12342d4d396SBrian Somers { 12442d4d396SBrian Somers struct physical *p = descriptor2physical(d); 12542d4d396SBrian Somers int sets; 12642d4d396SBrian Somers 12742d4d396SBrian Somers sets = 0; 128b6dec9f0SBrian Somers if (p->fd >= 0) { 129b6dec9f0SBrian Somers if (r) { 130b6dec9f0SBrian Somers FD_SET(p->fd, r); 13124989c68SBrian Somers log_Printf(LogTIMER, "%s: fdset(r) %d\n", p->link.name, p->fd); 132b6dec9f0SBrian Somers sets++; 133b6dec9f0SBrian Somers } 134b6dec9f0SBrian Somers if (e) { 135b6dec9f0SBrian Somers FD_SET(p->fd, e); 13624989c68SBrian Somers log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, p->fd); 137b6dec9f0SBrian Somers sets++; 138b6dec9f0SBrian Somers } 1390f2f3eb3SBrian Somers if (w && (force || link_QueueLen(&p->link) || p->out)) { 140b6dec9f0SBrian Somers FD_SET(p->fd, w); 14124989c68SBrian Somers log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, p->fd); 142b6dec9f0SBrian Somers sets++; 143b6dec9f0SBrian Somers } 144b6dec9f0SBrian Somers if (sets && *n < p->fd + 1) 145b6dec9f0SBrian Somers *n = p->fd + 1; 146b6dec9f0SBrian Somers } 14742d4d396SBrian Somers 14842d4d396SBrian Somers return sets; 14942d4d396SBrian Somers } 15042d4d396SBrian Somers 15142d4d396SBrian Somers int 152ea722969SBrian Somers physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e) 153ea722969SBrian Somers { 154ea722969SBrian Somers int sets; 155ea722969SBrian Somers 156ea722969SBrian Somers sets = 0; 157ea722969SBrian Somers if (p->fd >= 0) { 158ea722969SBrian Somers if (r && FD_ISSET(p->fd, r)) { 159ea722969SBrian Somers FD_CLR(p->fd, r); 160ea722969SBrian Somers log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd); 161ea722969SBrian Somers sets++; 162ea722969SBrian Somers } 163ea722969SBrian Somers if (e && FD_ISSET(p->fd, e)) { 164ea722969SBrian Somers FD_CLR(p->fd, e); 165ea722969SBrian Somers log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd); 166ea722969SBrian Somers sets++; 167ea722969SBrian Somers } 168ea722969SBrian Somers if (w && FD_ISSET(p->fd, w)) { 169ea722969SBrian Somers FD_CLR(p->fd, w); 170ea722969SBrian Somers log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd); 171ea722969SBrian Somers sets++; 172ea722969SBrian Somers } 173ea722969SBrian Somers } 174ea722969SBrian Somers 175ea722969SBrian Somers return sets; 176ea722969SBrian Somers } 177ea722969SBrian Somers 178ea722969SBrian Somers int 179dd7e2610SBrian Somers physical_IsSet(struct descriptor *d, const fd_set *fdset) 18042d4d396SBrian Somers { 18142d4d396SBrian Somers struct physical *p = descriptor2physical(d); 18242d4d396SBrian Somers return p->fd >= 0 && FD_ISSET(p->fd, fdset); 18342d4d396SBrian Somers } 18442d4d396SBrian Somers 18542d4d396SBrian Somers void 186dd7e2610SBrian Somers physical_Login(struct physical *phys, const char *name) 187fc1141b2SBrian Somers { 188dd7e2610SBrian Somers if (phys->type == PHYS_DIRECT && physical_IsATTY(phys)) { 189fc1141b2SBrian Somers if (phys->Utmp) 190dd7e2610SBrian Somers log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base); 191fc1141b2SBrian Somers else { 192fc1141b2SBrian Somers struct utmp ut; 1931fa75dc1SBrian Somers const char *connstr; 194fc1141b2SBrian Somers 195fc1141b2SBrian Somers memset(&ut, 0, sizeof ut); 196fc1141b2SBrian Somers time(&ut.ut_time); 197fc1141b2SBrian Somers strncpy(ut.ut_name, name, sizeof ut.ut_name); 1981fa75dc1SBrian Somers strncpy(ut.ut_line, phys->name.base, sizeof ut.ut_line); 1991fa75dc1SBrian Somers if ((connstr = getenv("CONNECT"))) 2001fa75dc1SBrian Somers /* mgetty sets this to the connection speed */ 2011fa75dc1SBrian Somers strncpy(ut.ut_host, connstr, sizeof ut.ut_host); 202fc1141b2SBrian Somers ID0login(&ut); 203fc1141b2SBrian Somers phys->Utmp = 1; 204fc1141b2SBrian Somers } 205fc1141b2SBrian Somers } 206e43ebac1SBrian Somers } 207fc1141b2SBrian Somers 208fc1141b2SBrian Somers void 209dd7e2610SBrian Somers physical_Logout(struct physical *phys) 210fc1141b2SBrian Somers { 211fc1141b2SBrian Somers if (phys->Utmp) { 212fc1141b2SBrian Somers ID0logout(phys->name.base); 213fc1141b2SBrian Somers phys->Utmp = 0; 214fc1141b2SBrian Somers } 215fc1141b2SBrian Somers } 216dd0645c5SBrian Somers 217dd0645c5SBrian Somers int 218dd0645c5SBrian Somers physical_SetMode(struct physical *p, int mode) 219dd0645c5SBrian Somers { 22092b09558SBrian Somers if ((p->type & (PHYS_DIRECT|PHYS_DEDICATED) || 22192b09558SBrian Somers mode & (PHYS_DIRECT|PHYS_DEDICATED)) && 22292b09558SBrian Somers (!(p->type & PHYS_DIRECT) || !(mode & PHYS_BACKGROUND))) { 223dd0645c5SBrian Somers log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name, 224dd0645c5SBrian Somers mode2Nam(p->type), mode2Nam(mode)); 225dd0645c5SBrian Somers return 0; 226dd0645c5SBrian Somers } 227dd0645c5SBrian Somers p->type = mode; 228dd0645c5SBrian Somers return 1; 229dd0645c5SBrian Somers } 2306f8e9f0aSBrian Somers 2316f8e9f0aSBrian Somers void 2326f8e9f0aSBrian Somers physical_DeleteQueue(struct physical *p) 2336f8e9f0aSBrian Somers { 2346f8e9f0aSBrian Somers if (p->out) { 2356f8e9f0aSBrian Somers mbuf_Free(p->out); 2366f8e9f0aSBrian Somers p->out = NULL; 2376f8e9f0aSBrian Somers } 2386f8e9f0aSBrian Somers link_DeleteQueue(&p->link); 2396f8e9f0aSBrian Somers } 240