moxattyd/000075500000000000003000000000001154315164200126225ustar00rootsys00167770000001moxattyd/VERSION.TXT000075500000000000003000000037661143362611500143670ustar00rootsys00167770000001Product: NPort/Async Server Fixed TTY driver Version: 3.5 Build 11032510 Date: 03/25/2011 Company: bob手机在线登陆 Inc. Release Note: Ver3.5 Build 11032510 1. Bugfix: Fixed the zombie process problem in Freebsd 8. Ver3.4 Buile 09120111 1. New: Support Mac OS X v10.3 later. 2. New: Support MAC. 3. Bugfix: Fixed pseudo tty write with resource temporarily unavailable. 4. Bugfix: Fixed the zombie process problem in HP-Unix. Ver3.3 Build 08090315 1. New: Support Solaris 10 in Sparc Machine, IBM AIX 5.3. 2. New: support Alpha Server. 3. Bugfix: Fixed driver connection problem in QNX4. 4. Bugfix: when NPort restart, the driver reset connection fail in big-endian machine. 5. Bugfix: fixed moxattyd closed when user uses terminal to open port. 6. Bugfix: fixed -t parameter can not work in 64-bits machine. 7. Bugfix: Fixed NPort polling mechnism bug in QNX6. 8. Bugfix: fixed "Invalid Argument" message for using stty command in Solaris. 9. Bugfix: The driver buffer size is changed to 8192 bytes for AIX. 10. Bugfix: moxattyd disappeared in big-endian machine. 11. Bugfix: zombie processes being generated on QNX4 when device server is disconnected. ver3.2 (11/27/2006) 1. New: Support FreeBSD. 2. New: Support QNX4.25. 3. New: Support QNX6. 4. New: Support SCO OpenServer 6. 5. New: Add -u parameter and user_defined.cf for user self-defined pseudo-tty. 6. New: Add -x parameter to disable log function. 7. Improve: Update README.TXT. 8. Bugfix: Fix pts can not create problem for other users. 9. Bugfix: When user open port, it would cause "permission denied" error. Ver3.1 (8/18/2005) 1. New: Support NPort IA model. 2. New: Support HP-UX. 3. New: Add -f parameter to specify configuration file. 4. Bugfix: Can not bind UDP Port when moxattyd daemon install over 9 target machine. Ver3.0 (5/3/2005) 1. New: Further verified bob手机在线登陆 products. 2. New: Add an FAQ.TXT into the driver package. 3. Bugfix: Re-initialize tty table when moxattyd daemon is informed of moxattyd.cf's changes.gfix: Whenmoxattyd/COPYING-MOXA.TXT000075500000000000003000000034301143362611500151000ustar00rootsys00167770000001 MOXA LICENSE Version 1, 29 November 2007 Copyright (c) MOXA Inc. All rights reserved. The SOFTWARE is copyrighted and is protected by all applicable national laws. Any duplication of the SOFTWARE other than for archival purposes is a violation of law, i.e., redistribution of this SOFTWARE in source and binary form are prohibited. You agree to prevent any unauthorized copying of the SOFTWARE. LIMITED WARRANTY: MOXA Inc. or its distributors, depending on which party sold the SOFTWARE, warrants that the media on which the SOFTWARE is installed will be free from defects in materials under normal use. MOXA or its distributor warrants, for your benefit alone, that during the Warranty Period the SOFTWARE, shall operate substantially in accordance with the functional specifications in the User's Manual. If, during the Warranty Period, a defect in the SOFTWARE, appears, you may obtain a replacement of the SOFTWARE. Any replacement SOFTWARE will be warranted for the reminder of the Warranty Period. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOXA OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. TS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS moxattyd/FAQ.TXT000075500000000000003000000050631143362611500136410ustar00rootsys00167770000001 Frequently Asked Questions Product: NPort/Async Server Fixed tty driver Company: bob手机在线登陆 Inc. Revision date: 5/3/2005 Q. Open ports might fail under SCO UnixWare and SCO OpenServer if the maximum number of file descriptors is reached. How can I increase the maximum number of file descriptors to solve this problem? A. When opening more than around 50 ports, the system resources might not be enough in SCO Open Server and SCO UnixWare. The problem can be solved by increasing the maximum number of the system's file descriptors. Follow the below steps to rebuild the kernel of the Operating System in order to increase the maximum number of file descriptors. Step 1: Locate the stune file in /etc/conf/cf.d. # cd /etc/conf/cf.d # ls stune Step 2: The stune file contains local system settings for tunable parameters. (The parameter settings in the stune file are used to override the default values specified in the mtune file.) Modify NOFILES parameter of the stune file in SCO Open Server, or SFNOLIM parameter of the same file in SCO UnixWare, as shown below. This will change the maximum number of file descriptors. (Add the parameter by yourself if it is not in the stune file.) In SCO Open Server: NOFILES xxx or, in SCO UnixWare, SFNOLIM xxx !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Note: 'xxx' represents the maximum number of file descriptors allowed by the Operating Systems. The value of the parameter to be used depends on your applications. You should increase the value by twice the number of mapping tty ports you intend to use, since each mapping tty port consumes two pseudo tty ports: master port and slave port. Besides, if your application also consumes file descriptors, you should count that number as well. For instance, if you want to use 200 mapping ports, NOFILES must be set to more than 400 (200 * 2 = 400). Furthermore, if you use getty, you must set the value to more than 600 (200 * 3 = 600). !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Step 3: Rebuild the kernel. # /etc/conf/bin/idbuild Step 4: Reboot the system. # reboot or # shutdown ============================================================================ f you want to use 200 mapping ports, NOFILES must be set to more than 400 (200 * 2 = 400). Furthermore, if you use getty, you must set the value to more than 600 (200 * 3 = 600). !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Step 3: Rebuild the kernel. # /etc/conf/bin/idbuild Step 4: Reboot the system. # reboot or # shutdown ===========================moxattyd/Makefile000075500000000000003000000017361143362611500142740ustar00rootsys00167770000001 sco: moxattyd.c cc -O -DSCO -o moxattyd moxattyd.c -lsocket linux: moxattyd.c cc -O -DLINUX -o moxattyd moxattyd.c svr42: moxattyd.c cc -O -DSTREAM -o moxattyd moxattyd.c -lx -lsocket svr5: moxattyd.c cc -O -DSTREAM -o moxattyd moxattyd.c -lsocket sco6: moxattyd.c cc -O -DSTREAM -o moxattyd moxattyd.c -lsocket -lnsl aix: moxattyd.c cc -DAIX -o moxattyd moxattyd.c hpunix: moxattyd.c cc -O -DHPUX -o moxattyd moxattyd.c sun: moxattyd.c gcc -O -DSTREAM moxattyd.c -o moxattyd -lnsl -lsocket -laio qnx6: moxattyd.c cc -O -DQNX6 -o moxattyd moxattyd.c -lsocket qnx4: moxattyd.c cc -O -DQNX4 -o moxattyd moxattyd.c -lsocket -lunix alpha: moxattyd.c cc -O -DQNX4 -o moxattyd moxattyd.c freebsd: moxattyd.c cc -O -DFREEBSD -o moxattyd moxattyd.c freebsd8: moxattyd.c cc -O -DBSD8 -o moxattyd moxattyd.c mac: moxattyd.c cc -O -DMAC -o moxattyd moxattyd.c clean: moxattyd.c rm -rf moxattyd rm -rf *.o cleanlog: rm -rf *.log rm -rf logindex oxattyd.c -o moxattyd -lnsl -lsockmoxattyd/moxattyd.c000075500000000000003000001372221143362614700146560ustar00rootsys00167770000001/* Copyright (C) MOXA Inc. All rights reserved. This software is distributed under the terms of the MOXA License. See the file COPYING-MOXA for details. */ /* moxattyd.c Routines to support networking ................ 2008-09-03 James Wang Release version 3.3 2009-09-09 James Wang Release version 3.4 2011-03-18 Ken Huang Release version 3.5 */ /* bob手机在线登陆 NPort/Async Server UNIX Fixed TTY daemon program. Usage: moxattyd [-t reset-time] [-f file-name] [-d alarm-flag] [-k] [-x] [-u user_defined.cf] reset-time : reconnection successful time file-name : Fixed TTY program configuration file name. alarm-flag : enable(1)/disable(0) read/write/select alarm(10) -k : multi-sessions for terminal users -x : disable log function user_defined.cf : User self-defined master/slave tty name configuration file. Compilation instructions: SCO: cc -O -DSCO -o moxattyd moxattyd.c -lsocket LINUX: cc -O -DLINUX -o moxattyd moxattyd.c ALPHA: cc -O -DQNX4 -o moxattyd moxattyd.c SVR4.2: cc -O -DSTREAM -o moxattyd moxattyd.c -lx -lsocket SVR5: cc -O -DSTREAM -o moxattyd moxattyd.c -lsocket SCO6: cc -O -DSTREAM -o moxattyd moxattyd.c -lsocket -lnsl AIX: cc -DAIX -o moxattyd moxattyd.c HP-UX 11i: cc -O -DHPUX -o moxattyd moxattyd.c Solaris: cc -O -DSTREAM moxattyd.c -o moxattyd -lnsl -lsocket -laio QNX6: cc -O -DQNX6 -o moxattyd moxattyd.c -lsocket QNX4: cc -O -DQNX4 -o moxattyd moxattyd.c -lsocket -lunix FREEBSD: cc -O -DFREEBSD -o moxattyd moxattyd.c FREEBSD8: cc -O -DBSD8 -o moxattyd moxattyd.c MAC: cc -O -DMAC -o moxattyd moxattyd.c */ #define VERSION "3.5 Build 11032510" #define FD_SETSIZE 768 /* system define 150 fd available,now set 768 fd can be used.*/ #include #include #include #include #include #ifdef QNX4 #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef BSD8 #define FREEBSD #endif #ifndef QNX4 #ifndef QNX6 #ifndef FREEBSD #ifndef MAC #include #endif #endif #endif #endif #ifdef STREAM #ifndef AIX #include #endif #endif /* * bob手机在线登陆 tty definition */ typedef struct _TTYINFO { char mpt_name[40]; /* Master pseudo TTY name */ u_long ip_addr; /* Server IP address */ int tcp_port; /* Server TCP port number */ int mpt_fd; /* Master pseudo tty file handle */ int sock_fd; /* TCP Socket handle */ int state; /* TCP connection state */ char * mpt_bufptr; /* Master pseudo TTY data buffer*/ int mpt_datakeep; int mpt_dataofs; char * sock_bufptr; /* TCP socket data buffer */ int sock_datakeep; int sock_dataofs; int error_flags; int time_out; /* Using for TCP connection check */ int serv_index; int tcp_state; int tty_opens; int tcp_opens; time_t last_state_time; time_t last_t2s_time; time_t last_s2t_time; time_t wait_id; int tflag; int sameflag; #ifdef STREAM int slave_fd; #endif } TTYINFO; typedef struct _ConnMsg { TTYINFO * infop; int status; time_t wait_id; } ConnMsg; typedef struct _SERVERINFO { u_long ip_addr; u_short dev_type; u_short serial_no; time_t last_servertime; time_t next_sendtime; int retry; /* for power off check.Add by ying */ /* Below is for DSCI protocol. */ u_int ap_id; u_short hw_id; unsigned char mac[6]; } SERVINFO; typedef struct _DSCI_HEADER { unsigned char opcode; unsigned char result; u_short length; u_int id; } DSCI_HEADER; typedef struct _DSCI_RET_HEADER { u_int ap_id; u_short hw_id; unsigned char mac[6]; } DSCI_RET_HEADER; typedef struct _DSCI_DA_DATA { u_int ap_id; u_short hw_id; unsigned char mac[6]; } DSCI_DA_DATA; typedef struct _DSCI_NET_STAT { u_int remote_ip; u_int local_ip; u_short remote_port; u_short local_port; char sock_type; unsigned char status; unsigned char reverse[2]; } DSCI_NET_STAT; #define STATE_INIT 0 #define STATE_MPT_OPEN 1 #define STATE_CONN_FAIL 2 #define STATE_TCP_OPEN 3 #define STATE_TCP_CONN 4 #define STATE_TCP_CLOSE 5 #define STATE_TCP_WAIT 6 #define STATE_MPT_REOPEN 7 #define STATE_RW_DATA 8 #define STATE_REMOTE_LISTEN 9 #define CONNECT_OK 0 #define CONNECT_FAIL 1 #define CLOSE_OK 2 #define TCP_LISTEN 1 #define TCP_CONNECTED 4 #define ERROR_MPT_OPEN 0x0001 #define ERROR_TCP_OPEN 0x0002 #define ERROR_TCP_CONN 0x0004 #define ERROR_FORK 0x0008 #ifdef AIX #define BUFFER_SIZE 8192 /* temporary data buffer size for AIX */ #else #define BUFFER_SIZE 1024 /* temporary data buffer size */ #endif #define MAX_TTYS 256 /* max. handling TTYs number */ #define MAX_PORTS 16 /* max. port of server is 16 */ int ttys, servers; TTYINFO ttys_info[MAX_TTYS]; TTYINFO chttys_info[MAX_TTYS]; SERVINFO serv_info[MAX_TTYS]; char EventLog[160]; /* Event log file name */ char StateLog[160]; /* State log file name */ int pipefd[2]; int maxfd; int timeout_time = 0; int polling_time=0; /* default disable polling function */ int reconn_time; int polling_fd; int polling_nport_fd; int Restart_daemon; int Multi_session=0; /* for multi-session. add by ying */ static int No_tty_defined; #ifdef STREAM int fds; extern char *ptsname(); #endif time_t last_log_time; int err1_count, err2_count; int task_state; int log_tty_state[16], log_tcp_state[16]; int Alarm_Flag = 0; int ConfigFile_Flag = 0; int UserDefine_Flag = 0; int Log_Enable = 1; time_t last_rw_time; int Timeout = 0; /*time_t chlasttime;*/ /* time of last modification in moxattyd.cf 2004/5/17 */ char cffile[160]; /* moxattyd.cf file path 2004/5/17 */ int Config_changed; char filename[50]; #ifndef STREAM void restart_handle (); void wait_handle (); void timeout_handle (); void config_changed_handle (); #endif #ifdef STREAM void restart_handle (int); void wait_handle (int); void timeout_handle (int); void config_changed_handle (int); #endif void OpenTty(TTYINFO *infop); void OpenTcpSocket(TTYINFO *infop); void ConnectTcp(TTYINFO *infop); void CloseTcp(TTYINFO *infop); void ConnectCheck(void); u_long lib_name2ip(char * ipaddr); int moxattyd_read_config(char * cmdpath); int poll_async_server_init(void); void poll_async_server_send(SERVINFO *servp); int poll_async_server_recv(void); void log_state(void); void log_event(char * msg); void statelog_fname(char *logfname,char *workpath); void state_change(TTYINFO *infop, int new_state); int stream_pty_open(char *pts_name); void recv_fail_message(TTYINFO *infop); void moxattyd_daemon_start(void); void moxattyd_handle_ttys(void); /* * MOXA TTY daemon main program */ main(int argc, char * argv[]) { TTYINFO * infop; int i; char buf[80]; for ( i=0; i<16; i++ ) log_tty_state[i] = log_tcp_state[i] = -1; task_state = 0; Restart_daemon = 0; No_tty_defined = 0; polling_fd = -1; polling_nport_fd = -1; while ( 1 ) { task_state = 10; if ( Restart_daemon ) { close(pipefd[0]); close(pipefd[1]); infop = ttys_info; if ( polling_fd >= 0 ) { close (polling_fd); polling_fd = -1; } /* Scott 2004-11-01 */ if (polling_nport_fd >= 0) { close(polling_nport_fd); polling_nport_fd = -1; } for ( i=0; isock_fd >= 0 ){ close (infop->sock_fd); infop->sock_fd = -1; } if ( infop->mpt_fd >= 0 ){ close (infop->mpt_fd); infop->mpt_fd = -1; } infop++; } } task_state = 20; if ( Restart_daemon == 1 ) { #ifndef STREAM signal (SIGTERM, ( (void (*)()) wait_handle) ); #else signal (SIGTERM, wait_handle); #endif task_state = 21; log_state(); pause(); } task_state = 30; for(i = 1; i < argc; i++){ if(strcmp(argv[i], "-t") == 0){ i++; reconn_time = 60 * atoi(argv[i]); timeout_time = reconn_time; if ( reconn_time >= 60 ) { polling_time = (reconn_time - 20) / 4; reconn_time -= (polling_time + 20); } } else if(strcmp(argv[i], "-f") == 0){ i++; ConfigFile_Flag = 1; strcpy(filename, argv[i]); } else if(strcmp(argv[i], "-d") == 0){ i++; if(atoi(argv[i]) == 1) Alarm_Flag = 1; } else if(strcmp(argv[i], "-k") == 0){ Multi_session = 1; } else if(strcmp(argv[i], "-x") == 0){ Log_Enable = 0; } else if(strcmp(argv[i], "-u") == 0){ i++; UserDefine_Flag = 1; strcpy(filename, argv[i]); } else { break; } } task_state = 40; if ( moxattyd_read_config(argv[0]) <= 0 ) { if (!No_tty_defined) { sprintf(buf,"Not any pseudo tty defined"); log_event (buf); No_tty_defined = 1; } log_state(); continue; } No_tty_defined = 0; task_state = 50; if ( !Restart_daemon ) { log_state(); moxattyd_daemon_start(); task_state = 51; log_state(); } task_state = 60; if ( polling_time && (poll_async_server_init() < 0) ) { log_state(); continue; } task_state = 70; if ( pipe(pipefd) < 0 ) { sprintf(buf,"pipe error"); log_event(buf); log_state(); continue; } #ifdef O_NDELAY fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL) | O_NDELAY); #elif defined(QNX4) || defined(QNX6) fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); #endif #ifndef QNX4 #ifndef FREEBSD #ifndef MAC #ifndef HPUX signal(SIGCLD, SIG_IGN); #endif #else signal(SIGCHLD, SIG_IGN); /* Because QNX4/FreeBSD no SIGCLD */ #endif #endif #endif Restart_daemon = 0; Timeout = 0; sprintf(buf,"MOXA Fixed TTY daemon program starting (Ver%s) ...", VERSION); log_event(buf); #ifndef STREAM signal (SIGTERM, ( (void (*)())restart_handle) ); if (Alarm_Flag) signal (SIGALRM, ( (void (*)())timeout_handle) ); #endif #ifdef STREAM signal (SIGTERM, restart_handle); if (Alarm_Flag) signal (SIGALRM, timeout_handle); #endif log_state(); task_state = 80; #ifndef STREAM signal (SIGUSR1, ( (void (*)()) config_changed_handle) ); #endif #ifdef STREAM signal (SIGUSR1, config_changed_handle); #endif Config_changed = 0; moxattyd_handle_ttys(); } } u_long lib_name2ip(char * ipaddr) { struct hostent *host; u_long ip; host = gethostbyname(ipaddr); if ( host ){ ip = ((struct in_addr *)host->h_addr)->s_addr; } else{ ip = inet_addr(ipaddr); } return(ip); } int moxattyd_read_config(char * cmdpath) { int n; FILE * ConfigFd; struct hostent *host; TTYINFO * infop; char workpath[160], buf[160], curpath[160],showbuf[80]; char ttyname[160], ipaddr[160], tcpport[160]; getcwd(curpath, sizeof(curpath)); strcpy(buf, cmdpath); n = strlen(buf) - 1; while ( n > 0 ) { if ( buf[n] == '/' ) break; n--; } buf[n] = 0; if ( n ) chdir(buf); getcwd(workpath, sizeof(workpath)); chdir(curpath); if(ConfigFile_Flag || UserDefine_Flag) sprintf(buf,"%s/%s", workpath, filename); /* Config file name */ else sprintf(buf,"%s/moxattyd.cf", workpath); /* Config file name */ sprintf(EventLog,"%s/moxattyd.log", workpath); /* Log file name */ if(Log_Enable) statelog_fname(StateLog, workpath); /* stat(buf, &filestat);*/ /* Add for moxattyd.cf changed 2004/5/17 */ strcpy(cffile, buf); /* chlasttime = filestat.st_mtime;*/ ConfigFd = fopen(buf, "r"); if ( ConfigFd == NULL ) { if(ConfigFile_Flag || UserDefine_Flag) sprintf(showbuf,"Can't open configuration file (%s) !", buf); else sprintf(showbuf,"Can't open configuration file (moxattyd.cf) !"); log_event(showbuf); exit(0); } ttys = 0; infop = ttys_info; while ( ttys < MAX_TTYS ) { if ( fgets(buf, sizeof(buf), ConfigFd) == NULL ) break; if(UserDefine_Flag){ if ( sscanf(buf, "%s%s%s%s", ttyname, ttyname, ipaddr, tcpport) != 4 ) continue; }else{ if ( sscanf(buf, "%s%s%s", ttyname, ipaddr, tcpport) != 3 ) continue; } if(UserDefine_Flag){ strcpy(infop->mpt_name, ttyname); } else { #ifndef STREAM #ifdef HPUX if ( strncmp(ttyname, "pty/tty", 7) == 0 ){ strcpy(infop->mpt_name, "ptym/pty"); strcat(infop->mpt_name, &ttyname[7]); } else if(strncmp(ttyname, "tty", 3) == 0){ ttyname[0] = 'p'; strcpy(infop->mpt_name, ttyname); } else continue; #else if ( strncmp(ttyname, "tty", 3) != 0 ) continue; ttyname[0] = 'p'; strcpy(infop->mpt_name, ttyname); #endif #endif #ifdef STREAM if ( strncmp(ttyname, "pts", 3) != 0 ) continue; sprintf (infop->mpt_name, "/dev/%s", ttyname); #endif } infop->ip_addr = lib_name2ip(ipaddr); if ( infop->ip_addr == (u_long)0xFFFFFFFF ) continue; if ( (n = atoi(tcpport)) <= 0 || n >= 10000 ) continue; if ( n >= 1 && n <= 16 ) n += 949; infop->tcp_port = n; infop->mpt_fd = -1; infop->sock_fd = -1; infop->state = STATE_INIT; infop->mpt_bufptr = (char *)malloc(BUFFER_SIZE * 2); if ( infop->mpt_bufptr == (char *)NULL ) { sprintf(showbuf,"Alocate memory fail !"); log_event(showbuf); break; } infop->sock_bufptr = infop->mpt_bufptr + BUFFER_SIZE; infop->mpt_datakeep = 0; infop->mpt_dataofs = 0; infop->sock_datakeep = 0; infop->sock_dataofs = 0; infop->error_flags = 0; infop->tcp_state = 0; infop->tty_opens = 0; infop->tcp_opens = 0; infop->last_state_time = time(0); infop->tflag = 0; infop->sameflag = 0; infop++; ttys++; } fclose(ConfigFd); return(ttys); } int moxattyd_change_config(){ int i, j, n, chttys; FILE * ConfigFd; TTYINFO *infop, *orip; char buf[160], showbuf[80]; char ttyname[160], ipaddr[160], tcpport[160]; ConfigFd = fopen(cffile, "r"); if ( ConfigFd == NULL ) { if(ConfigFile_Flag || UserDefine_Flag) sprintf(showbuf,"Can't open configuration file (%s) !", buf); else sprintf(showbuf,"Can't open configuration file (moxattyd.cf) !"); log_event(showbuf); return(-1); } chttys = 0; infop = chttys_info; while ( chttys < MAX_TTYS ) { if ( fgets(buf, sizeof(buf), ConfigFd) == NULL ) break; if ( sscanf(buf, "%s%s%s", ttyname, ipaddr, tcpport) != 3 ) continue; #ifndef STREAM #ifdef HPUX if ( strncmp(ttyname, "pty/tty", 7) == 0 ){ strcpy(infop->mpt_name, "ptym/pty"); strcat(infop->mpt_name, &ttyname[7]); } else if(strncmp(ttyname, "tty", 3) == 0){ ttyname[0] = 'p'; strcpy(infop->mpt_name, ttyname); } else continue; #else if ( strncmp(ttyname, "tty", 3) != 0 ) continue; ttyname[0] = 'p'; strcpy(infop->mpt_name, ttyname); #endif #endif #ifdef STREAM if ( strncmp(ttyname, "pts", 3) != 0 ) continue; sprintf (infop->mpt_name, "/dev/%s", ttyname); #endif infop->ip_addr = lib_name2ip(ipaddr); if ( infop->ip_addr == (u_long)0xFFFFFFFF ) continue; if ( (n = atoi(tcpport)) <= 0 || n >= 10000 ) continue; if ( n >= 1 && n <= 16 ) n += 949; infop->tcp_port = n; infop->mpt_fd = -1; infop->sock_fd = -1; infop->state = STATE_INIT; infop->mpt_bufptr = (char *)malloc(BUFFER_SIZE * 2); if ( infop->mpt_bufptr == (char *)NULL ) { sprintf(showbuf,"Alocate memory fail !"); log_event(showbuf); break; } infop->sock_bufptr = infop->mpt_bufptr + BUFFER_SIZE; infop->mpt_datakeep = 0; infop->mpt_dataofs = 0; infop->sock_datakeep = 0; infop->sock_dataofs = 0; infop->error_flags = 0; infop->tcp_state = 0; infop->tty_opens = 0; infop->tcp_opens = 0; infop->last_state_time = time(0); infop->tflag = 0; infop->sameflag = 0; infop++; chttys++; } fclose(ConfigFd); orip = ttys_info; for(i = 0; i < ttys; i++, orip++){ infop = chttys_info; for(j = 0; j < chttys; j++, infop++){ if(strcmp(orip->mpt_name, infop->mpt_name) == 0){ if(orip->ip_addr == infop->ip_addr){ if(orip->tcp_port == infop->tcp_port){ free(chttys_info[j].mpt_bufptr); memcpy(&chttys_info[j], &ttys_info[i], sizeof(TTYINFO)); orip->sameflag = 1; /* sprintf(buf,"not changed %d", i); log_event(buf); */ break; } } } } } orip = ttys_info; for(i = 0; i < ttys; i++, orip++){ if(orip->sameflag != 1){ free(orip->mpt_bufptr); #ifdef STREAM close(orip->slave_fd); #endif close(orip->mpt_fd); close(orip->sock_fd); } } for(i = 0; i < chttys; i++){ memcpy(&ttys_info[i], &chttys_info[i], sizeof(TTYINFO)); } ttys = chttys; return(chttys); } void moxattyd_daemon_start(void) { register int childpid, fd; char buf[80]; if ( getppid() == 1 ) goto next; #ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); #endif #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); #endif if ( (childpid = fork()) < 0 ) { sprintf(buf,"Can't fork first child !"); log_event(buf); exit(0); } else if ( childpid > 0 ) exit(0); #ifdef TIOCNOTTY if ( (fd = open("/dev/tty", O_RDWR)) >= 0 ) { ioctl(fd, TIOCNOTTY, (char *)NULL); close(fd); } #else if ( setpgrp() == -1 ) { sprintf(buf,"Can't change process group !"); log_event(buf); exit(0); } signal(SIGHUP, SIG_IGN); if ( (childpid = fork()) < 0 ) { sprintf(buf,"Can't fork second child !"); log_event(buf); exit(0); } else if ( childpid > 0 ) exit(0); #endif next: close(0); close(1); close(2); errno = 0; chdir("/"); umask(0); } int poll_async_server_init(void) { int i, n, udp_port; struct sockaddr_in sin; char buf[80]; servers = 0; for ( i=0; iap_id) return; #ifndef STREAM bzero(msg, 28); #endif #ifdef STREAM memset (msg, 0, 28); #endif t = time(0); if ( servp->dev_type == 0 ) { servp->next_sendtime = t + 5; msg[0] = 1; msg[3] = 6; len = 6; } else { servp->next_sendtime = t + polling_time; msg[0] = 0x71; msg[3] = 30; *(u_short *)&msg[22] = servp->dev_type; *(u_short *)&msg[24] = servp->serial_no; *(u_int *)&msg[26] = htonl(t); len = 30; } to.sin_family = AF_INET; to.sin_port = htons(0x405); to.sin_addr.s_addr = servp->ip_addr; sendto(polling_fd, msg, len, 0, (struct sockaddr *)&to, sizeof(to)); } int poll_async_server_recv(void) { struct sockaddr_in from; int len, n, m, i, connected, listening; time_t t; SERVINFO * servp; TTYINFO * infop; unsigned char msg[100]; len = sizeof(from); #ifdef AIX if ( recvfrom(polling_fd, msg, 86, 0, (struct sockaddr *)&from, (socklen_t *)&len) #else #ifdef SCO if ( recvfrom(polling_fd, msg, 86, 0, (struct sockaddr *)&from, &len) #endif #ifndef SCO #ifdef HPUX if ( recvfrom(polling_fd, msg, 86, 0, (void *)&from, &len) #else #ifdef MAC if ( recvfrom(polling_fd, msg, 86, 0, (struct sockaddr *)&from, (socklen_t*)&len) #else #ifdef BSD8 if ( recvfrom(polling_fd, msg, 86, 0, (struct sockaddr *)&from, (socklen_t*)&len) #else if ( recvfrom(polling_fd, msg, 86, 0, (struct sockaddr *)&from, (size_t*)&len) #endif #endif #endif #endif #endif != 86 ) { err2_count++; return 1; } if ( ((msg[0] != 0x81) && (msg[0] != 0xF1)) || (msg[3] != 86) ) return 2; if ( msg[1] || msg[2] || msg[4] || msg[5] || (from.sin_port != ntohs(0x405)) ) return 3; for ( n=0, servp=serv_info; nip_addr ) break; } if ( n == servers ) return 4; if ( msg[0] == 0x81 ) { n = 0; if ( (msg[10]==0x08 && msg[11]==0x21) || (msg[10]==0x16 && msg[11]==0x21) ) { if ( (msg[25] > 1) || (msg[24] > (unsigned char)0x25) ) { servp->dev_type = *(u_short *)&msg[10]; servp->serial_no = *(u_short *)&msg[12]; servp->last_servertime = time(0) - 1; n = 1; } }else{ servp->dev_type = *(u_short *)&msg[10]; servp->serial_no = *(u_short *)&msg[12]; servp->last_servertime = time(0) - 1; n = 1; } if ( (servp->serial_no == 0) || (n == 1) ) { /*Casper change*/ servp->serial_no = *(u_short *)&msg[12]; *(u_long *)(&msg[96]) = servp->ip_addr; msg[93] = msg[23]; msg[94] = msg[24]; msg[95] = msg[25]; if(msg[93]) /* x.x.[x] */ sprintf((char *)msg, "IP=%d.%d.%d.%d, Ver=%x.%x.%x(0x%02x%02x%02x) is alive.", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99]), (int)(msg[95]), (int)(msg[94]), (int)(msg[93]), (int)(msg[95]), (int)(msg[94]), (int)(msg[93])); else sprintf((char *)msg, "IP=%d.%d.%d.%d, Ver=%x.%x(0x%02x%02x) is alive.", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99]), (int)(msg[95]), (int)(msg[94]), (int)(msg[95]), (int)(msg[94])); log_event((char *)msg); /* if (msg[94] < 0x10) sprintf((char *)msg, "NPort(Async) Server (%d.%d.%d.%d) firmware version is %d.%02x .", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99]), (int)(msg[95]), (int)(msg[94])); else sprintf((char *)msg, "NPort(Async) Server (%d.%d.%d.%d) firmware version is %d.%2x .", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99]), (int)(msg[95]), (int)(msg[94])); */ } return 5; } t = ntohl(*(int *)&msg[18]); if ( (int)(t - servp->last_servertime) <= 0 ) { err1_count++; return 6; } if ( (servp->dev_type != *(u_short *)&msg[10]) || (servp->serial_no != *(u_short *)&msg[12]) ) { servp->dev_type = 0; servp->next_sendtime = time(0) - 1; servp->retry = 0; return 7; } m = 0; servp->last_servertime = t; for ( n=0, infop=ttys_info; nip_addr != servp->ip_addr ){ continue; } for(i=0, connected=0, listening=0; itcp_port != ntohs(*(u_short *)&msg[22+i*2])) continue; /*infop->tcp_state = (int)msg[54+i];*/ if ( msg[54+i] == TCP_CONNECTED) { connected = 1; break; } if ( msg[54+i] == TCP_LISTEN ) { if ( infop->state == STATE_RW_DATA ) listening = 1; } } if ( !connected && listening == 1 ) { m++; state_change(infop, STATE_REMOTE_LISTEN); infop->time_out = time(0); /* for Multi sessions reconnetion */ if ( Multi_session ) { servp->retry = 6; return 9; } } } if ( m ) { *(u_long *)(&msg[96]) = servp->ip_addr; sprintf((char *)msg,"Ports reset of Async Server %d.%d.%d.%d !", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99])); log_event((char *)msg); } servp->retry = 0; return 8; } void poll_nport_send(servp) SERVINFO *servp; { struct sockaddr_in to; int len; unsigned char msg[32]; DSCI_HEADER *dsci_headerp; DSCI_DA_DATA *dscidata_p; if (servp->dev_type) return; #ifndef STREAM bzero(msg, 28); #endif #ifdef STREAM memset (msg, 0, 28); #endif if ( servp->ap_id == 0 ) { /* send dsc_search */ servp->next_sendtime = time(0) + 5; dsci_headerp=(DSCI_HEADER*)&msg[0]; dsci_headerp->opcode = 0x01; /* dsc_search */ dsci_headerp->result = 0; dsci_headerp->length = htons(8); dsci_headerp->id = 0; len = 8; } else { /* send dsc_GetNetstat */ servp->next_sendtime = time(0) + polling_time; dsci_headerp=(DSCI_HEADER*)&msg[0]; dsci_headerp->opcode = 0x14; /* dsc_GetNetstat */ dsci_headerp->result = 0; dsci_headerp->length = htons(22); dsci_headerp->id = htonl(time(0)); dscidata_p=(DSCI_DA_DATA*)&msg[8]; dscidata_p->ap_id = htonl(servp->ap_id); dscidata_p->hw_id = htons(servp->hw_id); memcpy((void*)dscidata_p->mac, (void*)servp->mac, 6); *(u_short *)(&msg[20]) = 128; /* max number of sockets */ len = 22; } to.sin_family = AF_INET; to.sin_port = htons(4800); to.sin_addr.s_addr = servp->ip_addr; sendto(polling_nport_fd, msg, len, 0, (struct sockaddr *)&to, sizeof(to)); } void poll_nport_recv() { struct sockaddr_in from; int retlen, len, n, m, i, nstat, connected, listening; time_t t; SERVINFO * servp; TTYINFO * infop; unsigned char msg[2100]; u_short tmp_ip; DSCI_HEADER *dsci_headerp; DSCI_RET_HEADER *dsci_retp; DSCI_NET_STAT *dsci_netstatp; len = sizeof(from); #ifdef AIX if ( (retlen=recvfrom(polling_nport_fd, msg, sizeof(msg), 0, (struct sockaddr *)&from, (socklen_t *)&len)) #else #ifdef SCO if ( (retlen=recvfrom(polling_nport_fd, msg, sizeof(msg), 0, (struct sockaddr *)&from, &len)) #endif #ifndef SCO #ifdef HPUX if ( (retlen=recvfrom(polling_nport_fd, msg, sizeof(msg), 0, (void *)&from, &len)) #else #ifdef MAC if ( (retlen=recvfrom(polling_nport_fd, msg, sizeof(msg), 0, (struct sockaddr *)&from, (socklen_t *)&len)) #else #ifdef BSD8 if ( (retlen=recvfrom(polling_nport_fd, msg, sizeof(msg), 0, (struct sockaddr *)&from, (socklen_t *)&len)) #else if ( (retlen=recvfrom(polling_nport_fd, msg, sizeof(msg), 0, (struct sockaddr *)&from, (size_t *)&len)) #endif #endif #endif #endif #endif != 24 && ((retlen-24)%16)) return; dsci_headerp=(DSCI_HEADER*)&msg[0]; if ( (dsci_headerp->opcode == 0x81 && (ntohs(dsci_headerp->length) != 24 && ntohs(dsci_headerp->length) != 40)) || (dsci_headerp->opcode == 0x94 && ((ntohs(dsci_headerp->length)-24)%16) != 0) ) return; if ( dsci_headerp->result!=0 || (from.sin_port != ntohs(4800)) ) return; for ( n=0, servp=serv_info; nip_addr ) break; } if ( n == servers ) return; dsci_retp=(DSCI_RET_HEADER*)&msg[8]; if ( dsci_headerp->opcode == 0x81 ) { /* dsc_search respons */ servp->ap_id = ntohl(dsci_retp->ap_id); servp->hw_id = ntohs(dsci_retp->hw_id); memcpy((void*)servp->mac, (void*)dsci_retp->mac, 6); servp->last_servertime = time(0) - 1; *(u_long *)(&msg[96]) = servp->ip_addr; sprintf((char *)msg, "IP=%d.%d.%d.%d is alive.", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99])); log_event((char*)msg); return; } t = ntohl(dsci_headerp->id); if ( (int)(t - servp->last_servertime) <= 0 ) return; if ( (servp->ap_id != ntohl(dsci_retp->ap_id)) || (servp->hw_id != ntohs(dsci_retp->hw_id)) ) { servp->ap_id = 0; servp->next_sendtime = time(0) - 1; return; } m = 0; servp->last_servertime = t; /* nstat = *(u_short*)(&msg[20]);*/ nstat = (int)msg[21]; /* for big&little endian machine */ nstat = (nstat << 8) | ((int)msg[20] & 0xff); if(nstat > 128){ /* the value can not over 128 */ nstat = 128; } for ( n=0, infop=ttys_info; nip_addr != servp->ip_addr ) continue; for(i=0, connected = 0, listening = 0; ilocal_port = (tmp_ip << 8) | ((u_short)msg[24+i*16+10] & 0xff); if ( infop->tcp_port != dsci_netstatp->local_port ) continue; if ( dsci_netstatp->status == TCP_CONNECTED ) { connected = 1; break; } if ( dsci_netstatp->status == TCP_LISTEN ) { if ( infop->state == STATE_RW_DATA ) listening = 1; } } if ( !connected && listening == 1) { m++; state_change(infop, STATE_REMOTE_LISTEN); infop->time_out = time(0); } } if ( m ) { *(u_long *)(&msg[96]) = servp->ip_addr; sprintf((char *)msg, "Ports reset of NPort(Async) Server %d.%d.%d.%d !", (int)(msg[96]), (int)(msg[97]), (int)(msg[98]), (int)(msg[99])); log_event((char*)msg); } } void moxattyd_handle_ttys(void) { int i, n, m, maxfd, maxfd2, t0, j; TTYINFO * infop; SERVINFO * servp; fd_set rfd, wfd; struct timeval tm, polltm; char buf[80]; /* struct stat filestat;*/ /* Terence add 2004/5/17 */ double tmpval; last_log_time = time(0) - 50; last_rw_time = time(0); err1_count = err2_count = 0; signal(SIGPIPE, SIG_IGN); /* add for "broken pipe" error 2004/1/7*/ while ( 1 ) { if ( Restart_daemon ) return; log_state(); tm.tv_sec = 3; tm.tv_usec = 0; polltm.tv_sec = 0; polltm.tv_usec = 0; FD_ZERO(&rfd); FD_ZERO(&wfd); maxfd = -1; if(Config_changed > 0){ Config_changed = 0; /* sprintf(buf,"file changed !"); log_event(buf);*/ } /* Modify for power off check */ if ( polling_time ) { for (i=0; i 0) { poll_async_server_send(&serv_info[i]); poll_nport_send(&serv_info[i]); serv_info[i].retry++; } FD_SET(polling_fd, &rfd); FD_SET(polling_nport_fd, &rfd); if (polling_fd > polling_nport_fd) maxfd2=polling_fd; else maxfd2=polling_nport_fd; if (select(maxfd2+1, &rfd, &wfd, NULL, &polltm)> 0) { if (FD_ISSET(polling_fd, &rfd)) poll_async_server_recv(); if (FD_ISSET(polling_nport_fd, &rfd)) poll_nport_recv(); } if ((time(0)-serv_info[i].last_servertime)>timeout_time) { /* if (serv_info[i].retry > 3) { */ serv_info[i].retry = 0; for (j=0,infop=ttys_info; jip_addr != serv_info[i].ip_addr) continue; if (infop->state==STATE_RW_DATA) { state_change(infop, STATE_REMOTE_LISTEN); infop->time_out = time(0); } } } } } t0 = time(0); for ( i=0, infop=ttys_info; istate == STATE_INIT || infop->state == STATE_MPT_OPEN || infop->state == STATE_MPT_REOPEN ) { OpenTty(infop); } if ( infop->state == STATE_CONN_FAIL ) { if ( (t0 - infop->time_out) >= 5 ) state_change(infop, STATE_TCP_OPEN); } if ( infop->state == STATE_TCP_OPEN ) { OpenTcpSocket(infop); } if ( infop->state == STATE_TCP_CONN ) ConnectTcp(infop); if ( infop->state == STATE_TCP_CLOSE ) CloseTcp(infop); if ( infop->state == STATE_TCP_WAIT ) ConnectCheck(); if ( infop->state < STATE_TCP_WAIT ) { /*Terence change STATE_RW_DATA to STATE_TCP_WAIT*/ tm.tv_sec = 1; /*2004/1/2*/ continue; } else if ( (infop->state == STATE_REMOTE_LISTEN) /*&& ((t0 - infop->time_out) >= reconn_time) */) { CloseTcp(infop); continue; } if ( infop->mpt_fd > maxfd ) maxfd = infop->mpt_fd; if ( infop->sock_fd > maxfd ) maxfd = infop->sock_fd; if ( infop->mpt_datakeep ){ if(infop->tflag == 0){ FD_SET(infop->sock_fd, &wfd); } }else { if( infop->mpt_fd >= 0) FD_SET(infop->mpt_fd, &rfd); } if ( infop->sock_datakeep ) { if( infop->mpt_fd >= 0) FD_SET(infop->mpt_fd, &wfd); }else { if(infop->tflag == 0) FD_SET(infop->sock_fd, &rfd); } } if ( maxfd < 0 ) { task_state = 81; sleep(1); task_state = 82; continue; } if (Alarm_Flag) { Timeout = 0; alarm(10); } if ( select(maxfd+1, &rfd, &wfd, NULL, &tm) <= 0 ) { /*SVR5: Terence change &efd -> NULL*/ if (Alarm_Flag) { alarm(0); if (Timeout) { sprintf(buf,"Warning: select don't complete for 10 seconds, its timeout is %ld seconds\n",tm.tv_sec); log_event(buf); } } continue; } if (Alarm_Flag) { alarm(0); } last_rw_time = time(0); for ( i=0, infop=ttys_info; i 0) break; if ( infop->state < STATE_TCP_WAIT ) /*Terence change STATE_RW_DATA to STATE_TCP_WAIT*/ continue; /*2004/1/2*/ /* Scott add if condition 04-05-2005 Prevent program halt error when infop->mpt_fd=-1. */ if ( infop->state != STATE_MPT_REOPEN ) { if ( FD_ISSET(infop->mpt_fd, &rfd) ) { infop->last_t2s_time = time(0); m = infop->mpt_datakeep + infop->mpt_dataofs; if (Alarm_Flag) { Timeout = 0; alarm(10); } n = read(infop->mpt_fd, infop->mpt_bufptr + m, BUFFER_SIZE - m); if (Alarm_Flag) { alarm (0); if (Timeout) { sprintf(buf,"Warning: %s read tty timeout for 10 seconds\n",infop->mpt_name); log_event(buf); } } if ( n > 0 ){ if(infop->tflag == 0) infop->mpt_datakeep += n; /* Scott: 04-05-2005 */ /* When read()=0, don't reopen the master tty */ /* }else if ( n <= 0 ) { */ /*Add "=" for SCO,Ying*/ }else if ( n < 0 ) { state_change(infop, STATE_MPT_REOPEN); continue; } #if defined(FREEBSD) || defined(SCO) || defined(QNX6) || defined(MAC) else usleep(100); #endif } } if ( infop->state != STATE_TCP_WAIT ) { /*Terence add if condition 2004/1/6*/ if ( FD_ISSET(infop->sock_fd, &rfd) ) { m = infop->sock_datakeep + infop->sock_dataofs; if (Alarm_Flag) { Timeout = 0; alarm (10); } infop->last_s2t_time = time(0); n = read(infop->sock_fd, infop->sock_bufptr + m, BUFFER_SIZE - m); if (Alarm_Flag) { alarm (0); if (Timeout) { sprintf(buf,"Warning: %s read socket timeout for 10 seconds\n",infop->mpt_name); log_event(buf); } } if ( n > 0 ) { infop->sock_datakeep += n; if ( infop->state != STATE_MPT_REOPEN ) state_change(infop, STATE_RW_DATA); /* when mpt_fd < 0, it could not be change to STATE_RW_DATA */ } else { state_change(infop, STATE_TCP_OPEN); /*Terence change MPT->TCP 2004/1/2*/ continue; } } } /* Scott add if condition 04-05-2005 Prevent program halt error when infop->mpt_fd=-1. */ if ( infop->state != STATE_MPT_REOPEN ) { if ( FD_ISSET(infop->mpt_fd, &wfd) ) { if (Alarm_Flag) { Timeout = 0; alarm(10); } n = write(infop->mpt_fd, infop->sock_bufptr+infop->sock_dataofs, infop->sock_datakeep); if (Alarm_Flag) { alarm (0); if (Timeout) { sprintf(buf,"Warning: %s write tty timeout for 10 seconds\n",infop->mpt_name); log_event(buf); } } if ( n > 0 ) { infop->sock_datakeep -= n; if ( infop->sock_datakeep ) infop->sock_dataofs += n; else infop->sock_dataofs = 0; } else { /*SVR5: Terence add else{} */ #ifndef QNX4 /* Terence add. QNX4 does not have I_FLUSH & FLUSHRW 2004/5/6 */ #ifndef QNX6 /* Terence add for QNX6 2004/4/21 */ #ifndef FREEBSD #ifndef MAC // ioctl(infop->sock_fd, I_FLUSH, FLUSHRW); #endif #endif #endif #endif // infop->sock_datakeep = 0; // infop->sock_dataofs = 0; } } } if ( infop->state != STATE_TCP_WAIT ) { /*Terence add if condition 2004/1/6*/ if ( FD_ISSET(infop->sock_fd, &wfd) ) { if (Alarm_Flag) { Timeout = 0; alarm(10); } n = write(infop->sock_fd, infop->mpt_bufptr+infop->mpt_dataofs, infop->mpt_datakeep); if (Alarm_Flag) { alarm (0); if (Timeout) { sprintf(buf,"Warning: %s write tty timeout for 10 seconds\n",infop->mpt_name); log_event(buf); } } if ( n > 0 ) { infop->mpt_datakeep -= n; if ( infop->mpt_datakeep ) infop->mpt_dataofs += n; else infop->mpt_dataofs = 0; } else { /*Terence add else{} 2003/12/30*/ state_change(infop, STATE_TCP_OPEN); continue; } } } } } } void OpenTty(TTYINFO * infop) { char ttyname[160], buf[160]; int flag; infop->tty_opens++; flag = 0; if ( infop->mpt_fd >= 0 ) { if(infop->state == STATE_MPT_REOPEN) { /* Terence add if{}-else & flag=2, 2004/1/5 */ close(infop->mpt_fd); infop->mpt_fd = -1; /* Add by Ying */ flag = 2; } else flag = 1; } else flag = 0; if ( infop->mpt_fd < 0 ) { /* Terence add if{} 2004/1/5 */ #ifndef STREAM sprintf(ttyname, "/dev/%s", infop->mpt_name); #ifdef O_NOCTTY #ifndef QNX4 /* Terence add for QNX4 2004/5/6 */ infop->mpt_fd = open(ttyname, O_RDWR | O_NDELAY | O_NOCTTY); #else infop->mpt_fd = open(ttyname, O_RDWR | O_NONBLOCK | O_NOCTTY); #endif #else infop->mpt_fd = open(ttyname, O_RDWR | O_NDELAY); #endif #endif #ifdef STREAM infop->mpt_fd = stream_pty_open (infop->mpt_name); if(infop->mpt_fd) infop->slave_fd = fds; #endif } if ( infop->mpt_fd >= 0 ) { if ( infop->state == STATE_MPT_REOPEN ) { if(infop->tflag == 0) /* Terence add if & else{} 2004/1/5*/ state_change(infop, STATE_RW_DATA); else state_change(infop, STATE_TCP_WAIT); }else{ state_change(infop, STATE_TCP_OPEN); } } else if ( (flag == 0) || (flag == 2) ) { /*Terence add flag == 2 2004/1/5*/ if ( !(infop->error_flags & ERROR_MPT_OPEN) ) { sprintf(ttyname, "Master pseudo tty open fail (%s) !", infop->mpt_name); log_event(ttyname); infop->error_flags |= ERROR_MPT_OPEN; } } } void OpenTcpSocket(TTYINFO * infop) { char buf[80]; int on=1; if( infop->sock_fd >= 0 ){ /*Terence add if{} 2004/1/6*/ close(infop->sock_fd); infop->sock_fd = -1; } infop->tflag = 1; infop->tcp_opens++; infop->sock_fd = socket(AF_INET, SOCK_STREAM, 0); if ( infop->sock_fd >= 0 ) { /* if ( setsockopt(infop->sock_fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0 ) log_event("Set TCP keep alive fail !"); */ state_change(infop, STATE_TCP_CONN); } else { if ( !(infop->error_flags & ERROR_TCP_OPEN) ) { struct in_addr tmp_addr; tmp_addr.s_addr = infop->ip_addr; sprintf(buf, "Socket open fail (%s, TCP port %d) !", inet_ntoa(tmp_addr), infop->tcp_port); log_event(buf); infop->error_flags |= ERROR_TCP_OPEN; } } } void ConnectTcp(TTYINFO * infop) { struct sockaddr_in sin; int childpid; ConnMsg msg; char buf[80]; state_change(infop, STATE_TCP_WAIT); infop->wait_id = time(0); if ( (childpid = fork()) == 0 ) { close(pipefd[0]); sin.sin_family = AF_INET; sin.sin_addr.s_addr = infop->ip_addr; sin.sin_port = htons(infop->tcp_port); if ( connect(infop->sock_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0 ) { msg.status = CONNECT_FAIL; }else{ msg.status = CONNECT_OK; } msg.infop = infop; msg.wait_id = infop->wait_id; write(pipefd[1], (char *)&msg, sizeof(ConnMsg)); close(pipefd[1]); exit(0); } else if ( childpid < 0 ) { state_change(infop, STATE_TCP_CONN); if ( !(infop->error_flags & ERROR_FORK) ) { sprintf(buf,"Can't fork child process !"); log_event(buf); infop->error_flags |= ERROR_FORK; } } } void CloseTcp(TTYINFO * infop) { struct sockaddr_in sin; int childpid; ConnMsg msg; char buf[80]; state_change(infop, STATE_TCP_WAIT); infop->wait_id = time(0); if ( (childpid = fork()) == 0 ) { close(pipefd[0]); close(infop->sock_fd); /*2004/1/5 fork can not set sock-fd = -1*/ sleep(1); msg.status = CLOSE_OK; msg.infop = infop; msg.wait_id = infop->wait_id; write(pipefd[1], (char *)&msg, sizeof(ConnMsg)); close(pipefd[1]); exit(0); } else if ( childpid < 0 ) { state_change(infop, STATE_TCP_CLOSE); if ( !(infop->error_flags & ERROR_FORK) ) { sprintf(buf,"Can't fork child process !"); log_event(buf); infop->error_flags |= ERROR_FORK; } } if ( infop->state != STATE_TCP_CLOSE ){ close(infop->sock_fd); } } void ConnectCheck(void) { ConnMsg msg; TTYINFO * infop; if (read(pipefd[0], (char *)&msg, sizeof(ConnMsg)) == sizeof(ConnMsg)) { infop = msg.infop; if ( (infop->state == STATE_TCP_WAIT) && (infop->wait_id == msg.wait_id) ) { if ( msg.status == CONNECT_OK ) { state_change(infop, STATE_RW_DATA); infop->tflag = 0; infop->error_flags = 0; infop->last_s2t_time = time(0); infop->last_t2s_time = time(0); #if defined(QNX4) || defined (HPUX) || defined(FREEBSD) wait(0); #endif } else if ( msg.status == CLOSE_OK ) { infop->error_flags = 0; infop->sock_fd = -1; /*state_change(infop, STATE_MPT_OPEN);*/ state_change(infop, STATE_TCP_OPEN); /*Terence "mark MPT" & "change TCP"*/ #if defined(QNX4) || defined (HPUX) || defined(FREEBSD) wait(0); #endif } else { #if defined(QNX4) || defined (HPUX) || defined(FREEBSD) wait(0); #endif recv_fail_message(infop); } } } } void recv_fail_message(TTYINFO *infop) { char buf[80]; close(infop->sock_fd); infop->sock_fd = -1; state_change(infop, STATE_CONN_FAIL); infop->time_out = time(0); if ( !(infop->error_flags & ERROR_TCP_CONN) ) { struct in_addr tmp_addr; tmp_addr.s_addr = infop->ip_addr; sprintf(buf, "Socket connect fail (%s, TCP port %d) !", inet_ntoa(tmp_addr), infop->tcp_port); log_event(buf); infop->error_flags |= ERROR_TCP_CONN; } } void log_event(char * msg) { FILE * fd; time_t t; struct tm *tt; char tmp[80]; if ( Restart_daemon ) return; if(Log_Enable){ t = time(0); tt = localtime(&t); fd = fopen(EventLog, "a+"); if ( fd ) { sprintf(tmp, "%02d-%02d-%4d %02d:%02d:%02d ", tt->tm_mon + 1, tt->tm_mday, tt->tm_year+1900, tt->tm_hour, tt->tm_min, tt->tm_sec); fputs(tmp, fd); fputs(msg, fd); fputs("\n", fd); fclose(fd); } } } #ifdef STREAM int stream_pty_open (char *pts_name) { int i, j, fdm[MAX_TTYS]; char slavename[40], buf[160]; i = 0; while (i < MAX_TTYS) { #ifdef O_NOCTTY #ifdef AIX fdm[i] = open ("/dev/ptc", O_RDWR | O_NDELAY | O_NOCTTY); #else fdm[i] = open ("/dev/ptmx", O_RDWR | O_NDELAY | O_NOCTTY); #endif #else #ifdef AIX fdm[i] = open ("/dev/ptc", O_RDWR | O_NDELAY); #else fdm[i] = open ("/dev/ptmx", O_RDWR | O_NDELAY); #endif #endif if (fdm[i] < 0) break; grantpt (fdm[i]); unlockpt (fdm[i]); sprintf (slavename, "%s", ptsname (fdm[i])); chmod (slavename, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (!strcmp (slavename ,pts_name)) { #if 1 if ( (fds = open(slavename,O_RDWR)) < 0 ) { sprintf(buf,"stream_pty_open fail"); log_event(buf); } else { ioctl(fds, I_PUSH, "ptem"); ioctl(fds, I_PUSH, "ldterm"); } #endif break; } i++; } for (j = i-1;j >= 0;j--) close (fdm[j]); if(i >= MAX_TTYS) return -1; else return (fdm[i]); } #endif #ifndef STREAM void restart_handle () #endif #ifdef STREAM void restart_handle (int sig) #endif { Restart_daemon = 1; #ifndef STREAM signal (SIGTERM, ( (void (*)()) wait_handle) ); #endif #ifdef STREAM sig = sig; signal (SIGTERM, wait_handle); #endif } #ifndef STREAM void timeout_handle () #endif #ifdef STREAM void timeout_handle (int sig) #endif { Timeout = 1; #ifndef STREAM signal (SIGALRM, ( (void (*)()) timeout_handle) ); #endif #ifdef STREAM sig = sig; signal (SIGALRM, timeout_handle); #endif } #ifndef STREAM void wait_handle () #endif #ifdef STREAM void wait_handle (int sig) #endif { Restart_daemon = 2; #ifndef STREAM signal (SIGTERM, ( (void (*)()) wait_handle) ); #endif #ifdef STREAM sig = sig; signal (SIGTERM, wait_handle); #endif } #ifndef STREAM void config_changed_handle () #endif #ifdef STREAM void config_changed_handle (int sig) #endif { moxattyd_change_config(); poll_async_server_init(); Config_changed = 1; #ifndef STREAM signal (SIGUSR1, ( (void (*)()) config_changed_handle) ); #endif #ifdef STREAM sig = sig; signal (SIGUSR1, config_changed_handle); #endif } /* #ifndef STREAM void chld_handle () #endif #ifdef STREAM void chld_handle (int sig) #endif { pid_t pid; int stat; while((pid = waitpid(-1, &stat, WNOHANG)) > 0) }*/ void statelog_fname(char *logfname, char *workpath) { FILE * fd; char tmp[8], fname[256], tttt[80]; sprintf(fname, "%s/logindex", workpath); if ( (fd = fopen(fname, "r+")) == NULL ) { sprintf(logfname,"%s/state_0.log", workpath); if ( (fd = fopen(fname, "w+")) != NULL ) { fputs("1\n", fd); fclose(fd); } return; } fgets(tmp, 2, fd); if ( tmp[0] < '0' || tmp[0] > '9' ) tmp[0] = '0'; tmp[1] = tmp[0] + 1; tmp[2] = '\n'; tmp[3] = 0; if ( tmp[1] > '9' ) tmp[1] = '0'; rewind(fd); fputs(&tmp[1], fd); fclose(fd); sprintf(logfname,"%s/state_%c.log", workpath, tmp[0]); } void state_change(TTYINFO *infop, int new_state) { if ( infop->state != new_state ) { infop->state = new_state; infop->last_state_time = time(0); if ( new_state == STATE_RW_DATA ) { infop->tty_opens = 0; infop->tcp_opens = 0; } } } void log_state(void) { int i, dttys; TTYINFO * infop; FILE * fd; time_t t, t2; struct tm *tt; char tmp[128]; if(Log_Enable){ t = time(0); if ( ((t - last_log_time) < 60) && (task_state >= 80) ) { if ( (dttys = ttys) > 16 ) dttys = 16; infop = ttys_info; for ( i=0; istate ) break; if ( log_tcp_state[i] != infop->tcp_state ) break; } if ( i >= dttys ) return; } if ( (fd = fopen(StateLog, "w+")) == NULL ) return; last_log_time = t; tt = localtime(&t); sprintf(tmp, "%02d-%02d-%4d %02d:%02d:%02d ", tt->tm_mon + 1, tt->tm_mday, tt->tm_year+1900, tt->tm_hour, tt->tm_min, tt->tm_sec); fputs(tmp, fd); sprintf(tmp, "Total_ttys=%d ", ttys); fputs(tmp, fd); sprintf(tmp, "Err1_count=%d Err2_count=%d\n", err1_count, err2_count); fputs(tmp, fd); sprintf(tmp, "Task state = %d\n", task_state); fputs(tmp, fd); sprintf(tmp, "Last rw for %d seconds\n", t - last_rw_time); fputs(tmp, fd); if ( task_state < 80 ) dttys = 0; else dttys = ttys; infop = ttys_info; for ( i=0; istate == STATE_CONN_FAIL || infop->state == STATE_REMOTE_LISTEN ) t2 = t - infop->time_out; else t2 = 0; sprintf(tmp, "%s state=%1d o1=%d o2=%d tcp=%d ts=%d tout=%04d time=%d tk=%d/%d sk=%d/%d\n", infop->mpt_name, infop->state, infop->tty_opens, infop->tcp_opens, infop->tcp_port, infop->tcp_state, (int)t2, t - infop->last_state_time, infop->mpt_datakeep, t - infop->last_t2s_time, infop->sock_datakeep, t - infop->last_s2t_time ); if ( i < 16 ) { log_tty_state[i] = infop->state; log_tcp_state[i] = infop->tcp_state; } fputs(tmp, fd); } fclose(fd); } } =%d/%d sk=%d/%d\n", infop->mpt_name, infop->state, infop->tty_opens, infop->tcp_opens, infop->tcp_port, infop->tcp_state, (int)t2, t - infop->last_state_time, infop->mpt_datakeep, t - infop->last_t2s_time, infop->sock_datakeep, t - infop->last_s2t_time )moxattyd/moxattyd.cf000075500000000000003000000043231143362611500150120ustar00rootsys00167770000001# # MOXA NPort/Async Server UNIX Fixed TTY program configuration file # (The configured data line start with '#' character is the comment line.) # # Usage --> [TTY Name] [IP Address] [TCP Port Number] # # [TTY Name]: # For UnixWare, SVR4.2, Solaris, SCO OpenServer 6 # pts/[n] # n = 0-255 # # For HP-UX # pty/tty[a-ce-z][0-9a-f] # or # tty[p-r][0-9a-f] # # For QNX4, QNX6 # tty[p-s][0-9a-f] # # For FreeBSD, FreeBSD8 # tty[p-sP-S][0-9a-v] # # For AIX # tty[p-zA-Z][0-9a-f] # # For MAC # tty[p-w][0-9a-f] # # For SCO OpenServer(not including SCO OpenServer 6) # ttyp[n] # # The value of n should be equal or larger than 11 to prevent from # conflicting with the device names of functional keys in some Unix # systems. # # [IPAddress]: # The NPort/Async Server IP Address # # [TCP Port Number]: # The relative TCP listen port of the NPort/Async Server serial port. # # Ex1 (For Host Based/Driver Mode or Real COM Mode): # The TCP listen port of NPort in this mode is starting from 950 for # serial port 1. # If you would like to map the "ttyp1" to the first serial port of # NPort, you need to set this field to "950", and set [TTY Name] to # "ttyp1". # # Ex2 (For TCP Server Mode): # The default value of TCP listen port of NPort in this mode # is starting from 4001 for serial port 1. # If you would like to map the "ttyp1" to the first serial port of # NPort, you need to set this field to "4001", and set [TTY Name] to # "ttyp1". # You can configure your NPort to change the values of the TCP # listen ports under TCP Server Mode, if needed. # # # !!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # The NPort/Async Server OP_Mode MUST be set correctly. # !!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # # SCO OpenServer 5 configuration example: # # ttyp11 192.168.1.1 950 # ttyp12 192.168.1.1 951 # ttyp13 192.168.1.1 952 # ttyp14 192.168.1.1 953 # # Unixware configuration example: # # pts/11 192.168.1.1 950 # pts/12 192.168.1.1 951 # pts/13 192.168.1.1 952 # pts/14 192.168.1.1 953 # # HP-UX configuration example: # # pty/ttyq0 192.168.1.1 950 # pty/ttyq1 192.168.1.1 951 # pty/ttyq2 192.168.1.1 952 # pty/ttyq3 192.168.1.1 953 # SCO OpenServer 5 configuration example: # # ttyp11 192.168.1.1 950 # ttyp12 192.168.1.1 951 # ttyp13 192.168.1.1 952 # ttyp14 192.168.1.1 953 # # Unixware configuration example: # # pts/11 192.168.1.1 950 # pts/12 192.168.1.1 951 # pts/13 192.168.1.1 9moxattyd/README.TXT000075500000000000003000000146101143362656500141760ustar00rootsys00167770000001======================================================================== MOXA UNIX Fixed TTY Program (moxattyd) README File Date: 08-28-2008 Copyright (C) 2000-2007, MOXA Technologies Co., Ltd. All rights reserved. ======================================================================== Content 1. Introduction 2. Supported Operating Mode 3. OS Supports 4. Installation and Configuration 5. Device Naming Rule 6. bob手机在线登陆 ttyd Parameter 7. Add Additional Server 8. Technical Support ------------------------------------------------------------------------ 1. Introduction The purpose of bob手机在线登陆 Fixed TTY program, moxattyd, is to redirect UNIX tty device to MOXA NPort/Async Server RS-232 port. 2. Supported Operating Mode 1. [Fixed TTY] - [RAW] 2. [Multi-Host TTY] - [FIXTTY] [Device Control] - [RAW] 3. [Host Based/Driver Mode] [Real COM Mode] [TCP Server Mode] You may always find and download the latest driver at http://www.moxa.com and http://www.moxa.com.tw 3. OS Supports bob手机在线登陆 ttyd program supports the following OS: 1. SCO UNIX, SCO OpenServer 5, SCO OpenServer 6 2. UnixWare 7 3. Solaris 10 x86/Sparc 4. QNX4.25, QNX6 5. FreeBSD 5.x, FreeBSD 6, FreeBSD 7, FreeBSD 8 6. AIX 5.3 7. Mac OS X 4. Installation and Configuration Step 1 : Login to UNIX and create a directory for MOXA Fixed TTY. E.g., to create a directory named /usr/etc, execute the command: # mkdir /usr/etc Step 2 : Copy moxattyd.tar to the /usr/etc directory by executing the commands: # cp moxattyd.tar /usr/etc # cd /usr/etc Step 3 : Extract source files from tar-file by executing the command: # tar xvf moxattyd.tar # cd /usr/etc/moxattyd The following files will be extracted: README.TXT moxattyd.c --> source code moxattyd.cf --> an empty configuration file Makefile --> makefile VERSION.TXT --> Fixed TTY driver version SUPPORT.TXT --> Fixed TTY support MOXA product and OP_mode FAQ.TXT --> FAQ Step 4 : Compile and Link : For QNX4: # make qnx4 For QNX6: # make qnx6 For SCO OpenServer 6 # make sco6 For SCO UNIX, OpenServer 5: # make sco For Solaris # make sun For FreeBSD # make freebsd For FreeBSD8 # make freebsd8 For UnixWare 7: # make svr5 For AIX # make aix For HP-Unix # make hpunix Step 5 : Modify the configuration: The configuration used by the moxattyd program is defined in the text file moxattyd.cf, which is in the same directory that contains the program moxattyd. You may use vi, or any text editor to modify the file. E.g., ttyp11 192.168.1.1 950 For more configuration information, look at the file moxattyd.cf, which contains detailed descriptions of the various configuration parameters. (If you would like to use self-defined master/slave tty, look at the file user_defined.cf.) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! The "Device Name" depends on the OS. See the "5. Device Naming Rule" section for more information. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Step 6 : To start the moxattyd daemon, you configured in moxattyd.cf. If you would like to set the connection timeout, you can add a "-t min" parameter to specify the connection timeout value in minute. E.g., # /usr/etc/moxattyd/moxattyd -t 1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Now, you are able to use tty which is configured in moxattyd.cf if you complete Step 1 to Step 6. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Step 7 : To start the moxattyd daemon after system bootup, you configured in moxattyd.cf. E.g., for SCO Openserver, Unixware, AIX and Solaris add an entry into /etc/inittab ts:234:respawn:/usr/etc/moxattyd/moxattyd -t 1 For QNX4 add an entry into /etc/config/sysinit.1 /usr/etc/moxattyd/moxattyd -t 1 For QNX6 add an entry into /etc/rc.d/rc.local /usr/etc/moxattyd/moxattyd -t 1 For FreeBSD add an entry into /etc/rc.local /usr/etc/moxattyd/moxattyd -t 1 This completes the process of adding an additional server. 5. Device Naming Rule For UnixWare, Solaris, SCO OpenServer 6 pts/[n] For HP-UX pty/tty[a-ce-z][0-9a-f] or tty[p-r][0-9a-f] For QNX4, QNX6 tty[p-s][0-9a-f] For FreeBSD, FreeBSD 8 tty[p-sP-S][0-9a-v] For AIX tty[p-zA-Z][0-9a-f] For all other UNIX operating systems, use: ttyp[n] The value of n should be equal or larger than 11 to prevent from conflicting with the device names of functional keys in some UNIX systems. 6. bob手机在线登陆 ttyd Parameter Usage : moxattyd [-t reset-time] [-f file-name] [-x] [-u user_defined.cf] reset-time : reconnection successful time. file-name : Fixed TTY program configuration file. t : If you would like to set the connection timeout, you can add a "-t min" parameter to specify the connection timeout value in minute. E.g., # moxattyd -t 1 f : If you would like to every target machines have configuration file themself, you can add a "-f file-name" to specify configuration file. E.g. If one of configuration file is com.cf, you can type # moxattyd -f com.cf x : Disable log function. u : If you would like to use self-defined tty name, you can add a "-u user_defined.cf" to use them. E.g., # moxattyd -u user_defined.cf 7. Add Additional Server Step 1 : Modify the text file moxattyd.cf to add an additional server. User may use vi or any text editor to modify the file. For more configuration information, look at the file moxattyd.cf, which contains detailed descriptions of the various configuration parameters. Step 2 : Find the process id (PID) of program "moxattyd". # ps -ef | grep moxattyd Step 3 : Update configuration of moxattyd program. # kill -USR1 PID (e.g., if "moxattyd" PID = 404, "kill -USR1 404") This completes the process of adding an additional server. 8. Technical Support If you have any technical questions, please send your question by the following ways with detail description of the symptom. Email: support@moxa.com.tw Tel : +886 2 89191230 ext.300 -End- Step 2 : Find the process id (PID) of program "moxattyd". # ps -ef | grep moxattyd Step 3 : Update configuramoxattyd/user_defined.cf000075500000000000003000000026731143362611500156030ustar00rootsys00167770000001# # MOXA NPort/Async Server UNIX Fixed TTY program configuration file # (The configured data line start with '#' character is the comment line.) # # If you would like to use self-defined master/slave pseudo-tty, please follow # the Usage description to modify your configuration file. # # Usage --> [Slave TTY Name] [Master TTY Name] [IP Address] [TCP Port Number] # # [Slave TTY Name]: # Slave pseudo-tty name. # # [Master TTY Name]: # Master pseudo-tty name. # # [IPAddress]: # The NPort/Async Server IP Address # # [TCP Port Number]: # The relative TCP listen port of the NPort/Async Server serial port. # # Ex: # If you use QNX4 system, type the two commands to create master pseudo- # tty /dev/pseudo/m0-/dev/pseudo/m1f and slave pseduo tty # /dev/pseudo/s0-/dev/pseudo/s1f. # # Dev -N /dev/pseudo -n65 & # # Dev.pty -n32 -N /dev/pseudo/m,/dev/pseudo/s & # # The setting example is: # # pseudo/s0 pseudo/m0 192.168.1.1 950 # pseudo/s1 pseudo/m1 192.168.1.1 951 # pseudo/s2 pseudo/m2 192.168.1.1 952 # pseudo/s3 pseudo/m3 192.168.1.1 953 # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # To start the moxattyd daemon, you configured in # user_defined.cf. If you would like to set the connection # timeout, you can add a "-t min" parameter to specify # the connection timeout value in minute. E.g., # # /usr/etc/moxattyd/moxattyd -u user_defined.cf -t 1 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # seudo/m1 192.168.1.1 951 # pseudo/s2 pseudo/m2 192.168.1.1 952 # ps