GettyBSD.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:7k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: GettyBSD.c++,v 1.1.1.1 2005/11/11 21:32:02 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1993-1996 Sam Leffler
  4.  * Copyright (c) 1993-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. /*
  27.  * FAX Server BSD Getty Support.
  28.  */
  29. #include "GettyBSD.h"
  30. #include <stddef.h>
  31. #include <termios.h>
  32. #include <sys/ioctl.h>
  33. #include <utmp.h>
  34. #include "Sys.h"
  35. #include "config.h"
  36. /*
  37.  * FAX Server BSD-style Getty&co. Support.
  38.  */
  39. /*
  40.  * BSD subprocess support; used by getty-style processes.
  41.  */
  42. BSDSubProc::BSDSubProc(const char* path, const fxStr& l, const fxStr& s) : Getty(path,l,s)
  43. {
  44. }
  45. BSDSubProc::~BSDSubProc()
  46. {
  47. }
  48. /*
  49.  * ``Open'' the device and setup the initial tty state
  50.  * so that the normal stdio routines can be used.
  51.  */
  52. void
  53. BSDSubProc::setupSession(int modemFd)
  54. {
  55.     int fd;
  56.     /*
  57.      * Close everything down except the modem so
  58.      * that the remote side doesn't get hung up on.
  59.      */
  60.     for (fd = Sys::getOpenMax()-1; fd >= 0; fd--)
  61. if (fd != modemFd)
  62.     (void) Sys::close(fd);
  63.      
  64.     fd = Sys::open("tty", 0); // NB: assumes we're in /dev
  65.     if (fd >= 0) {
  66. ioctl(fd, TIOCNOTTY, 0);
  67. Sys::close(fd);
  68.     }
  69.     fd = Sys::open(getLine(), O_RDWR|O_NONBLOCK);
  70.     if (fd != STDIN_FILENO)
  71. fatal("Can not setup "%s" as stdin", getLine());
  72.     if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) &~ O_NONBLOCK))
  73. fatal("Can not reset O_NONBLOCK: %m");
  74.     Sys::close(modemFd); // done with this, pitch it
  75.     /*
  76.      * Setup descriptors for stdout, and stderr.
  77.      * Establish the initial line termio settings and set
  78.      * protection on the device file.
  79.      */
  80.     Getty::setupSession(fd);
  81. }
  82. /*
  83.  * BSD getty/login-specific subprocess support.
  84.  */
  85. BSDGetty::BSDGetty(const char* path, const fxStr& l, const fxStr& s) : BSDSubProc(path,l,s)
  86. {
  87. }
  88. BSDGetty::~BSDGetty()
  89. {
  90. }
  91. #define lineEQ(a,b) (strncmp(a,b,sizeof(a)) == 0)
  92. /*
  93.  * ``Open'' the device and setup the initial tty state
  94.  * so that the normal stdio routines can be used.
  95.  */
  96. void
  97. BSDGetty::setupSession(int modemFd)
  98. {
  99.     int fd;
  100.     /*
  101.      * Close everything down except the modem so
  102.      * that the remote side doesn't get hung up on.
  103.      */
  104.     for (fd = Sys::getOpenMax()-1; fd >= 0; fd--)
  105.         if (fd != modemFd)
  106.             (void) Sys::close(fd);
  107.     /*
  108.      * Now make the line be the controlling tty
  109.      * and create a new process group/session for
  110.      * the login process that follows.
  111.      */
  112.     fd = Sys::open("tty", 0); // NB: assumes we're in /dev
  113.     if (fd >= 0) {
  114. ioctl(fd, TIOCNOTTY, 0);
  115. Sys::close(fd);
  116.     }
  117.     setsid();
  118.     fd = Sys::open(getLine(), O_RDWR|O_NONBLOCK);
  119.     if (fd != STDIN_FILENO)
  120. fatal("Can not setup "%s" as stdin", getLine());
  121.     if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) &~ O_NONBLOCK))
  122. fatal("Can not reset O_NONBLOCK: %m");
  123.     Sys::close(modemFd); // done with this, pitch it
  124. #ifdef TIOCSCTTY
  125.     if (ioctl(fd, TIOCSCTTY, 0))
  126. fatal("Cannot set controlling tty: %m");
  127. #endif
  128. #ifdef TIOCGETDFLT
  129.     /*
  130.      * FaxServer::setBaudRate forces CLOCAL on for BSDi.  However
  131.      * getty resets the terminal to the system default, if one exists,
  132.      * prior to execing login, but preserves CLOCAL, if it is on.
  133.      * Thus, if a system default setting exists for the tty, we
  134.      * set the CLOCAL state from it; otherwise, we leave CLOCAL on.
  135.      */
  136.     struct termios term, dflt;
  137.     if (ioctl(fd, TIOCGETDFLT, &dflt) == 0 && (dflt.c_cflag & CLOCAL) == 0) {
  138. tcgetattr(fd, &term);
  139. term.c_cflag &= ~CLOCAL;
  140. tcsetattr(fd, TCSAFLUSH, &term);
  141.     }
  142. #else
  143.     /*
  144.      * Turn off CLOCAL so that SIGHUP is sent on modem disconnect.
  145.      */
  146.     struct termios term;
  147.     if (tcgetattr(fd, &term) == 0) {
  148. term.c_cflag &= ~CLOCAL;
  149. tcsetattr(fd, TCSAFLUSH, &term);
  150.     }
  151. #endif
  152.     /*
  153.      * Setup descriptors for stdout, and stderr.
  154.      * Establish the initial line termio settings and set
  155.      * protection on the device file.
  156.      */
  157.     Getty::setupSession(fd);
  158. }
  159. void
  160. BSDGetty::writeWtmp(utmp* ut)
  161. {
  162. #if HAS_LOGWTMP
  163.     logwtmp(ut->ut_line, "", "");
  164. #else
  165.     int wfd = Sys::open(_PATH_WTMP, O_WRONLY|O_APPEND);
  166.     if (wfd >= 0) {
  167. struct stat buf;
  168. if (Sys::fstat(wfd, buf) == 0) {
  169.     memset(ut->ut_name, 0, sizeof (ut->ut_name));
  170.     memset(ut->ut_host, 0, sizeof (ut->ut_host));
  171.     ut->ut_time = Sys::now();
  172.     if (Sys::write(wfd, (char *)ut, sizeof (*ut)) != sizeof (*ut))
  173. ftruncate(wfd, buf.st_size);
  174. }
  175. Sys::close(wfd);
  176.     }
  177. #endif
  178. }
  179. void
  180. BSDGetty::logout(const char* line)
  181. {
  182. #if HAS_LOGOUT
  183.     ::logout(line);
  184. #else
  185.     int ufd = Sys::open(_PATH_UTMP, O_RDWR);
  186.     if (ufd >= 0) {
  187. struct utmp ut;
  188. while (Sys::read(ufd, (char *)&ut, sizeof (ut)) == sizeof (ut))
  189.     if (ut.ut_name[0] && lineEQ(ut.ut_line, line)) {
  190. memset(ut.ut_name, 0, sizeof (ut.ut_name));
  191. memset(ut.ut_host, 0, sizeof (ut.ut_host));
  192. ut.ut_time = time(0);
  193. lseek(ufd, -(long) sizeof (ut), SEEK_CUR);
  194. Sys::write(ufd, (char *)&ut, sizeof (ut));
  195.     }
  196. Sys::close(ufd);
  197.     }
  198. #endif
  199. }
  200. void
  201. BSDGetty::hangup()
  202. {
  203.     // at this point we're root and we can reset state
  204.     int ufd = Sys::open(_PATH_UTMP, O_RDONLY);
  205.     if (ufd >= 0) {
  206. struct utmp ut;
  207. while (Sys::read(ufd, (char *)&ut, sizeof (ut)) == sizeof (ut))
  208.     if (ut.ut_name[0] && lineEQ(ut.ut_line, getLine())) {
  209. writeWtmp(&ut);
  210. break;
  211.     }
  212. Sys::close(ufd);
  213.     }
  214.     logout(getLine());
  215.     Getty::hangup();
  216. }
  217. /*
  218.  * Public Interfaces.
  219.  */
  220. Getty*
  221. OSnewGetty(const fxStr& dev, const fxStr& speed)
  222. {
  223.     return (new BSDGetty(_PATH_GETTY, dev, speed));
  224. }
  225. Getty*
  226. OSnewVGetty(const fxStr& dev, const fxStr& speed)
  227. {
  228.     return (new BSDSubProc(_PATH_VGETTY, dev, speed));
  229. }
  230. Getty*
  231. OSnewEGetty(const fxStr& dev, const fxStr& speed)
  232. {
  233.     return (new BSDSubProc(_PATH_EGETTY, dev, speed));
  234. }