rcmds, inetd, ftpd and ntp are gone. leaving the files in the cvs head for now.
====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================
rcmds, inetd, ftpd and ntp are gone. in 1.4, files also go away.
jafsadm: libjafsadm
-finale: project cmd comerr afsd allrcmds butc tbutc @ENABLE_KERNEL_MODULE@ libuafs audit kauth log package \
+finale: project cmd comerr afsd butc tbutc @ENABLE_KERNEL_MODULE@ libuafs audit kauth log package \
ptserver scout bu_utils ubik uss bozo vfsck volser tvolser \
venus update xstat afsmonitor dauth rxdebug libafsrpc \
libafsauthent shlibafsrpc shlibafsauthent libadmin
${COMPILE_PART1} finale ${COMPILE_PART2}
-finale_nolibafs: project cmd comerr afsd allrcmds butc tbutc libuafs audit kauth log package \
+finale_nolibafs: project cmd comerr afsd butc tbutc libuafs audit kauth log package \
ptserver scout bu_utils ubik uss bozo vfsck volser tvolser \
venus update xstat afsmonitor dauth rxdebug libafsrpc \
libafsauthent shlibafsrpc shlibafsauthent libadmin
+++ /dev/null
-#
-# Copyright (c) 1988 Regents of the University of California.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are permitted
-# provided that the above copyright notice and this paragraph are
-# duplicated in all such forms and that any documentation,
-# advertising materials, and other materials related to such
-# distribution and use acknowledge that the software was developed
-# by the University of California, Berkeley. The name of the
-# University may not be used to endorse or promote products derived
-# from this software without specific prior written permission.
-# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-#
-
-srcdir=@srcdir@
-include @TOP_OBJDIR@/src/config/Makefile.config
-
-include ../config/Makefile.version
-
-AFSLIBS=${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libprot.a ${TOP_LIBDIR}/libubik.a \
- ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/libdes.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a \
- ${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a \
- ${TOP_LIBDIR}/libaudit.a
-
-LIBS = ${AFSLIBS}
-LIBC= /lib/libc.a
-SRCS= ftpd.c ftpcmd.c getusershell.c glob.c logwtmp.c popen.c vers.c
-OBJS= ftpd.o ftpcmd.o getusershell.o glob.o logwtmp.o popen.o vers.o
-MAN= ftpd.8
-
-
-noversion: install
-
-all: ${MAN}
-
-ftpd: ${OBJS} ${LIBS}
- case ${SYS_NAME} in \
- sun4c_53 | sun4m_53 | sun4_53 | sun4_54 | sun4c_54 | sun4m_54 | sun4x_5? | sunx86_*) \
- ${CC} -o $@ ${OBJS} ${LIBS} ${XLIBS} -lsocket -lnsl -lauth -ldl ;; \
- rs_aix*) \
- ${CC} -o $@ ${OBJS} ${LIBS} ${XLIBS} -ls ;; \
- * ) ${CC} -o $@ ${OBJS} ${LIBS} ${XLIBS} ;; \
- esac
-
-ftpd.o: ftpd.c AFS_component_version_number.c
-
-vers.o: ftpd.c ftpcmd.y
- ${CC} ${CFLAGS} -c vers.c
-# sh newvers.sh
-
-clean:
- $(RM) -f ${OBJS} ftpd core ftpcmd.c AFS_component_version_number.c
-
-cleandir: clean
- $(RM) -f ${MAN} .depend
-
-depend: ${SRCS}
- mkdep ${CFLAGS} ${SRCS}
-
-install: ${DESTDIR}${sbindir}/ftpd
-
-${DEST}/etc/ftpd: ftpd
- ${INSTALL} $? $@
-
-${DESTDIR}${sbindir}/ftpd: ftpd
- ${INSTALL} $? $@
-
-
-dest: ${DEST}/etc/ftpd
-
+++ /dev/null
-/*
- * Copyright (c) 1983, 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)ftp.h 5.4 (Berkeley) 2/21/89
- */
-
-/*
- * Definitions for FTP
- * See RFC-765
- */
-
-/*
- * Reply codes.
- */
-#define PRELIM 1 /* positive preliminary */
-#define COMPLETE 2 /* positive completion */
-#define CONTINUE 3 /* positive intermediate */
-#define TRANSIENT 4 /* transient negative completion */
-#define ERROR 5 /* permanent negative completion */
-
-/*
- * Type codes
- */
-#define TYPE_A 1 /* ASCII */
-#define TYPE_E 2 /* EBCDIC */
-#define TYPE_I 3 /* image */
-#define TYPE_L 4 /* local byte size */
-
-#ifdef FTP_NAMES
-char *typenames[] = { "0", "ASCII", "EBCDIC", "Image", "Local" };
-#endif
-
-/*
- * Form codes
- */
-#define FORM_N 1 /* non-print */
-#define FORM_T 2 /* telnet format effectors */
-#define FORM_C 3 /* carriage control (ASA) */
-#ifdef FTP_NAMES
-char *formnames[] = { "0", "Nonprint", "Telnet", "Carriage-control" };
-#endif
-
-/*
- * Structure codes
- */
-#define STRU_F 1 /* file (no record structure) */
-#define STRU_R 2 /* record structure */
-#define STRU_P 3 /* page structure */
-#ifdef FTP_NAMES
-char *strunames[] = { "0", "File", "Record", "Page" };
-#endif
-
-/*
- * Mode types
- */
-#define MODE_S 1 /* stream */
-#define MODE_B 2 /* block */
-#define MODE_C 3 /* compressed */
-#ifdef FTP_NAMES
-char *modenames[] = { "0", "Stream", "Block", "Compressed" };
-#endif
-
-/*
- * Record Tokens
- */
-#define REC_ESC '\377' /* Record-mode Escape */
-#define REC_EOR '\001' /* Record-mode End-of-Record */
-#define REC_EOF '\002' /* Record-mode End-of-File */
-
-/*
- * Block Header
- */
-#define BLK_EOR 0x80 /* Block is End-of-Record */
-#define BLK_EOF 0x40 /* Block is End-of-File */
-#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
-#define BLK_RESTART 0x10 /* Block is Restart Marker */
-
-#define BLK_BYTECOUNT 2 /* Bytes in this block */
+++ /dev/null
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89
- */
-
-/*
- * Grammar for FTP commands.
- * See RFC 959.
- */
-
-%{
-
-#include <afs/param.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#ifndef AFS_HPUX_ENV
-#include <arpa/ftp.h>
-#else
-#include "ftp.h"
-#endif
-
-#define unix
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <setjmp.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#ifdef AFS_AIX32_ENV
-#ifdef _CSECURITY
-#include "tcpip_audit.h"
-#define tcpip_auditlog null
-void null()
-{
- return;
-}
-/* Security New Stuff */
-#include <sys/id.h>
-#include <sys/priv.h>
-extern afs_uint32 remote_addr;
-extern uid_t saved_uid, effective_uid;
-extern priv_t priv;
-
-/* Restore privs and set the invoker back to uid saved_uid */
-#define GET_PRIV(a) \
- getpriv(PRIV_MAXIMUM, &priv,sizeof(priv_t)); \
- setpriv(PRIV_SET|PRIV_EFFECTIVE|PRIV_BEQUEATH, &priv,sizeof(priv_t)); \
- setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, (a));
-
-/* Drop privs and set the invoker to uid a */
-#define DROP_PRIV(a) \
- priv.pv_priv[0] = 0; \
- priv.pv_priv[1] = 0; \
- setpriv(PRIV_SET|PRIV_EFFECTIVE|PRIV_BEQUEATH, &priv,sizeof(priv_t)); \
- setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, (a));
-
-#endif /* _CSECURITY */
-
-#define MSGSTR(n,s) s
-#endif /* AFS_AIX32_ENV */
-
-extern struct sockaddr_in data_dest;
-extern int logged_in;
-extern struct passwd *pw;
-extern int guest;
-extern int logging;
-extern int type;
-extern int form;
-extern int debug;
-extern int timeout;
-extern int maxtimeout;
-extern int pdata;
-extern char hostname[], remotehost[];
-extern char proctitle[];
-extern char *globerr;
-extern int usedefault;
-extern int transflag;
-extern char tmpline[];
-extern int allowPortAttack;
-extern struct sockaddr_in his_addr;
-char **glob();
-
-#ifdef AFS_OSF_ENV
-off_t restart_point;
-#endif
-
-static unsigned short cliport = 0;
-static struct sockaddr_in cliaddr;
-static int cmd_type;
-static int cmd_form;
-static int cmd_bytesz;
-char cbuf[512];
-char *fromname;
-
-char *index();
-#define CMD 0 /* beginning of command */
-#define ARGS 1 /* expect miscellaneous arguments */
-#define STR1 2 /* expect SP followed by STRING */
-#define STR2 3 /* expect STRING */
-#define OSTR 4 /* optional SP then STRING */
-#define ZSTR1 5 /* SP then optional STRING */
-#define ZSTR2 6 /* optional STRING after SP */
-#define SITECMD 7 /* SITE command */
-#define NSTR 8 /* Number followed by a string */
-
-#if defined(AFS_AIX41_ENV) || defined(AFS_LINUX20_ENV)
-struct tab {
- char *name;
- short token;
- short state;
- short implemented; /* 1 if command is implemented */
- char *help;
-};
-struct tab cmdtab[];
-struct tab sitetab[];
-#endif /* AFS_AIX41_ENV || AFS_LINUX20_ENV */
-%}
-
-%token
- A B C E F I
- L N P R S T
-
- SP CRLF COMMA STRING NUMBER
-
- USER PASS ACCT REIN QUIT PORT
- PASV TYPE STRU MODE RETR STOR
- APPE MLFL MAIL MSND MSOM MSAM
- MRSQ MRCP ALLO REST RNFR RNTO
- ABOR DELE CWD LIST NLST SITE
- STAT HELP NOOP MKD RMD PWD
- CDUP STOU SMNT SYST SIZE MDTM
-
- UMASK IDLE CHMOD
-
- LEXERR
-
-%start cmd_list
-
-%%
-
-cmd_list: /* empty */
- | cmd_list cmd
- = {
- fromname = (char *) 0;
-#ifdef AFS_OSF_ENV
- restart_point = (off_t) 0;
-#endif
- }
- | cmd_list rcmd
- ;
-
-cmd: USER SP username CRLF
- = {
- user((char *) $3);
- free((char *) $3);
- }
- | PASS SP password CRLF
- = {
- pass((char *) $3);
- free((char *) $3);
- }
- | PORT SP host_port CRLF
- = {
- usedefault = 0;
- if (pdata >= 0) {
- (void) close(pdata);
- pdata = -1;
- }
- if (allowPortAttack) {
- /* full RFC conformant */
- }
- else if ( cliaddr.sin_addr.s_addr != his_addr.sin_addr.s_addr ) {
- reply(500, "PORT host addr must be %s",
- inet_ntoa(his_addr.sin_addr));
- break;
- }
- else if ((cliport<IPPORT_RESERVED) && (cliport!=20)) {
- /*
- ** port 20 is the ftp data port. We allow the
- ** ftp server to connect to any non-reserved
- ** port and port 20
- */
- reply(500, "PORT argument must be ",
- "%u or greater.",
- IPPORT_RESERVED);
- break;
- }
- data_dest = cliaddr;
- data_dest.sin_port = cliport;
- reply(200, "PORT command ",
- "successful.");
- }
- | PASV CRLF
- = {
- passive();
- }
- | TYPE SP type_code CRLF
- = {
- switch (cmd_type) {
-
- case TYPE_A:
- if (cmd_form == FORM_N) {
- reply(200, "Type set to A.");
- type = cmd_type;
- form = cmd_form;
- } else
- reply(504, "Form must be N.");
- break;
-
- case TYPE_E:
- reply(504, "Type E not implemented.");
- break;
-
- case TYPE_I:
- reply(200, "Type set to I.");
- type = cmd_type;
- break;
-
- case TYPE_L:
-#if NBBY == 8
- if (cmd_bytesz == 8) {
- reply(200,
- "Type set to L (byte size 8).");
- type = cmd_type;
- } else
- reply(504, "Byte size must be 8.");
-#else /* NBBY == 8 */
- UNIMPLEMENTED for NBBY != 8
-#endif /* NBBY == 8 */
- }
- }
- | STRU SP struct_code CRLF
- = {
- switch ($3) {
-
- case STRU_F:
- reply(200, "STRU F ok.");
- break;
-
- default:
- reply(504, "Unimplemented STRU type.");
- }
- }
- | MODE SP mode_code CRLF
- = {
- switch ($3) {
-
- case MODE_S:
- reply(200, "MODE S ok.");
- break;
-
- default:
- reply(502, "Unimplemented MODE type.");
- }
- }
- | ALLO SP NUMBER CRLF
- = {
- reply(202, "ALLO command ignored.");
- }
- | ALLO SP NUMBER SP R SP NUMBER CRLF
- = {
- reply(202, "ALLO command ignored.");
- }
- | RETR check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- retrieve((char *) 0, (char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | STOR check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- store((char *) $4, "w", 0);
- if ($4 != NULL)
- free((char *) $4);
- }
- | APPE check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- store((char *) $4, "a", 0);
- if ($4 != NULL)
- free((char *) $4);
- }
- | NLST check_login CRLF
- = {
- if ($2)
- retrieve("/bin/ls", "");
- }
- | NLST check_login SP STRING CRLF
- = {
- if ($2 && $4 != NULL)
- retrieve("/bin/ls %s", (char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | LIST check_login CRLF
- = {
- if ($2)
- retrieve("/bin/ls -lgA", "");
- }
- | LIST check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- retrieve("/bin/ls -lgA %s", (char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | STAT check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- statfilecmd((char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | STAT CRLF
- = {
- statcmd();
- }
- | DELE check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- delete((char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | RNTO SP pathname CRLF
- = {
- if (fromname) {
- renamecmd(fromname, (char *) $3);
- free(fromname);
- fromname = (char *) 0;
- } else {
- reply(503, "Bad sequence of commands.");
- }
- free((char *) $3);
- }
- | ABOR CRLF
- = {
- reply(225, "ABOR command successful.");
- }
- | CWD check_login CRLF
- = {
- if ($2)
- cwd(pw->pw_dir);
- }
- | CWD check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- cwd((char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | HELP CRLF
- = {
- help(cmdtab, (char *) 0);
- }
- | HELP SP STRING CRLF
- = {
- register char *cp = (char *)$3;
-
- if (strncasecmp(cp, "SITE", 4) == 0) {
- cp = (char *)$3 + 4;
- if (*cp == ' ')
- cp++;
- if (*cp)
- help(sitetab, cp);
- else
- help(sitetab, (char *) 0);
- } else
- help(cmdtab, (char *) $3);
- }
- | NOOP CRLF
- = {
- reply(200, "NOOP command successful.");
- }
- | MKD check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- makedir((char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | RMD check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- removedir((char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
- | PWD check_login CRLF
- = {
- if ($2)
- pwd();
- }
- | CDUP check_login CRLF
- = {
- if ($2)
- cwd("..");
- }
- | SITE SP HELP CRLF
- = {
- help(sitetab, (char *) 0);
- }
- | SITE SP HELP SP STRING CRLF
- = {
- help(sitetab, (char *) $5);
- }
- | SITE SP UMASK check_login CRLF
- = {
- int oldmask;
-
- if ($4) {
- oldmask = umask(0);
- (void) umask(oldmask);
- reply(200, "Current UMASK is %03o", oldmask);
- }
- }
- | SITE SP UMASK check_login SP octal_number CRLF
- = {
- int oldmask;
-
- if ($4) {
- if (($6 == -1) || ($6 > 0777)) {
- reply(501, "Bad UMASK value");
- } else {
- oldmask = umask($6);
- reply(200,
- "UMASK set to %03o (was %03o)",
- $6, oldmask);
- }
- }
- }
- | SITE SP CHMOD check_login SP octal_number SP pathname CRLF
- = {
- if ($4 && ($8 != NULL)) {
- if ($6 > 0777)
- reply(501,
- "CHMOD: Mode value must be between 0 and 0777");
- else if (chmod((char *) $8, $6) < 0)
- perror_reply(550, (char *) $8);
- else
- reply(200, "CHMOD command successful.");
- }
- if ($8 != NULL)
- free((char *) $8);
- }
- | SITE SP IDLE CRLF
- = {
- reply(200,
- "Current IDLE time limit is %d seconds; max %d",
- timeout, maxtimeout);
- }
- | SITE SP IDLE SP NUMBER CRLF
- = {
- if ($5 < 30 || $5 > maxtimeout) {
- reply(501,
- "Maximum IDLE time must be between 30 and %d seconds",
- maxtimeout);
- } else {
- timeout = $5;
- (void) alarm((unsigned) timeout);
- reply(200,
- "Maximum IDLE time set to %d seconds",
- timeout);
- }
- }
- | STOU check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- store((char *) $4, "w", 1);
- if ($4 != NULL)
- free((char *) $4);
- }
- | SYST CRLF
- = {
-#ifdef unix
-#if defined(BSD) && !defined(AFS_SUN5_ENV)
- reply(215, "UNIX Type: L%d Version: BSD-%d (afs-@sys: %s)",
- NBBY, BSD, SYS_NAME);
-#else /* BSD */
- reply(215, "UNIX Type: L%d (afs-@sys: %s)", NBBY, SYS_NAME);
-#endif /* BSD */
-#else /* unix */
- reply(215, "UNKNOWN Type: L%d (afs-@sys: %s)", NBBY, SYS_NAME);
-#endif /* unix */
- }
-
- /*
- * SIZE is not in RFC959, but Postel has blessed it and
- * it will be in the updated RFC.
- *
- * Return size of file in a format suitable for
- * using with RESTART (we just count bytes).
- */
- | SIZE check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL)
- sizecmd((char *) $4);
- if ($4 != NULL)
- free((char *) $4);
- }
-
- /*
- * MDTM is not in RFC959, but Postel has blessed it and
- * it will be in the updated RFC.
- *
- * Return modification time of file as an ISO 3307
- * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx
- * where xxx is the fractional second (of any precision,
- * not necessarily 3 digits)
- */
- | MDTM check_login SP pathname CRLF
- = {
- if ($2 && $4 != NULL) {
- struct stat stbuf;
- if (stat((char *) $4, &stbuf) < 0)
- perror_reply(550, "%s", (char *) $4);
- else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
- reply(550, "%s: not a plain file.",
- (char *) $4);
- } else {
- register struct tm *t;
- struct tm *gmtime();
- t = gmtime(&stbuf.st_mtime);
- if (t->tm_year>=100) /* after 2000 */
- reply(213,
- "%04d%02d%02d%02d%02d%02d",
- t->tm_year+1900, t->tm_mon+1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
- else if (0<=t->tm_year && t->tm_year<=68)
- reply(213,
- "20%02d%02d%02d%02d%02d%02d",
- t->tm_year, t->tm_mon+1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
- else if (69<=t->tm_year && t->tm_year<=99)
- reply(213,
- "19%02d%02d%02d%02d%02d%02d",
- t->tm_year, t->tm_mon+1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
- }
- }
- if ($4 != NULL)
- free((char *) $4);
- }
- | QUIT CRLF
- = {
- reply(221, "Goodbye.");
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr,"ftp/tcp","close",
- MSGSTR(GOODBYE1, "Goodbye."),0);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- dologout(0);
- }
- | error CRLF
- = {
- yyerrok;
- }
- ;
-rcmd: RNFR check_login SP pathname CRLF
- = {
- char *renamefrom();
-
-#ifdef AFS_OSF_ENV
- restart_point = (off_t) 0;
-#endif
- if ($2 && $4) {
- fromname = renamefrom((char *) $4);
- if (fromname == (char *) 0 && $4) {
- free((char *) $4);
- }
- }
- }
-/*
- | REST SP byte_size CRLF
- = {
- long atol();
-
- fromname = (char *) 0;
- restart_point = $3;
- reply(350, MSGSTR( FTPD_RESTARTING,
- "Restarting at %ld. %s"), restart_point,
- "Send STORE or RETRIEVE to initiate transfer.");
- }
-*/
- ;
-
-username: STRING
- ;
-
-password: /* empty */
- = {
- *(char **)&($$) = "";
- }
- | STRING
- ;
-
-byte_size: NUMBER
- ;
-
-host_port: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
- NUMBER COMMA NUMBER
- = {
- register char *a;
-
- a = (char *)&cliaddr.sin_addr;
- a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
-
- cliport = ($9 << 8) + $11;
- cliaddr.sin_family = AF_INET;
- }
- ;
-
-form_code: N
- = {
- $$ = FORM_N;
- }
- | T
- = {
- $$ = FORM_T;
- }
- | C
- = {
- $$ = FORM_C;
- }
- ;
-
-type_code: A
- = {
- cmd_type = TYPE_A;
- cmd_form = FORM_N;
- }
- | A SP form_code
- = {
- cmd_type = TYPE_A;
- cmd_form = $3;
- }
- | E
- = {
- cmd_type = TYPE_E;
- cmd_form = FORM_N;
- }
- | E SP form_code
- = {
- cmd_type = TYPE_E;
- cmd_form = $3;
- }
- | I
- = {
- cmd_type = TYPE_I;
- }
- | L
- = {
- cmd_type = TYPE_L;
- cmd_bytesz = NBBY;
- }
- | L SP byte_size
- = {
- cmd_type = TYPE_L;
- cmd_bytesz = $3;
- }
- /* this is for a bug in the BBN ftp */
- | L byte_size
- = {
- cmd_type = TYPE_L;
- cmd_bytesz = $2;
- }
- ;
-
-struct_code: F
- = {
- $$ = STRU_F;
- }
- | R
- = {
- $$ = STRU_R;
- }
- | P
- = {
- $$ = STRU_P;
- }
- ;
-
-mode_code: S
- = {
- $$ = MODE_S;
- }
- | B
- = {
- $$ = MODE_B;
- }
- | C
- = {
- $$ = MODE_C;
- }
- ;
-
-pathname: pathstring
- = {
- /*
- * Problem: this production is used for all pathname
- * processing, but only gives a 550 error reply.
- * This is a valid reply in some cases but not in others.
- */
- if (logged_in && $1 && strncmp((char *) $1, "~", 1) == 0) {
- *(char **)&($$) = *glob((char *) $1);
- if (globerr != NULL) {
- reply(550, globerr);
- $$ = NULL;
- }
- free((char *) $1);
- } else
- $$ = $1;
- }
- ;
-
-pathstring: STRING
- ;
-
-octal_number: NUMBER
- = {
- register int ret, dec, multby, digit;
-
- /*
- * Convert a number that was read as decimal number
- * to what it would be if it had been read as octal.
- */
- dec = $1;
- multby = 1;
- ret = 0;
- while (dec) {
- digit = dec%10;
- if (digit > 7) {
- ret = -1;
- break;
- }
- ret += digit * multby;
- multby *= 8;
- dec /= 10;
- }
- $$ = ret;
- }
- ;
-
-check_login: /* empty */
- = {
- if (logged_in)
- $$ = 1;
- else {
- reply(530, "Please login with USER and PASS.");
- $$ = 0;
- }
- }
- ;
-
-%%
-#if !defined(AFS_AIX41_ENV) && !defined(AFS_LINUX20_ENV)
-struct tab {
- char *name;
- short token;
- short state;
- short implemented; /* 1 if command is implemented */
- char *help;
-};
-#endif /* !AFS_AIX41_ENV */
-
-struct tab cmdtab[] = { /* In order defined in RFC 765 */
- { "USER", USER, STR1, 1, "<sp> username" },
- { "PASS", PASS, ZSTR1, 1, "<sp> password" },
- { "ACCT", ACCT, STR1, 0, "(specify account)" },
- { "SMNT", SMNT, ARGS, 0, "(structure mount)" },
- { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
- { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
- { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
- { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
- { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
- { "STRU", STRU, ARGS, 1, "(specify file structure)" },
- { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
- { "RETR", RETR, STR1, 1, "<sp> file-name" },
- { "STOR", STOR, STR1, 1, "<sp> file-name" },
- { "APPE", APPE, STR1, 1, "<sp> file-name" },
- { "MLFL", MLFL, OSTR, 0, "(mail file)" },
- { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
- { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
- { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
- { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
- { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
- { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
- { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
- { "REST", REST, ARGS, 0, "(restart command)" },
- { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
- { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
- { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
- { "DELE", DELE, STR1, 1, "<sp> file-name" },
- { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
- { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
- { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
- { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
- { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
- { "SYST", SYST, ARGS, 1, "(get type of operating system)" },
- { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" },
- { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- { "NOOP", NOOP, ARGS, 1, "" },
- { "MKD", MKD, STR1, 1, "<sp> path-name" },
- { "XMKD", MKD, STR1, 1, "<sp> path-name" },
- { "RMD", RMD, STR1, 1, "<sp> path-name" },
- { "XRMD", RMD, STR1, 1, "<sp> path-name" },
- { "PWD", PWD, ARGS, 1, "(return current directory)" },
- { "XPWD", PWD, ARGS, 1, "(return current directory)" },
- { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" },
- { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" },
- { "STOU", STOU, STR1, 1, "<sp> file-name" },
- { "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
- { "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
- { NULL, 0, 0, 0, 0 }
-};
-
-struct tab sitetab[] = {
- { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
- { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
- { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
- { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- { NULL, 0, 0, 0, 0 }
-};
-
-extern jmp_buf errcatch;
-
-
-struct tab *
-lookup(p, cmd)
- register struct tab *p;
- char *cmd;
-{
-
- for (; p->name != NULL; p++)
- if (strcmp(cmd, p->name) == 0)
- return (p);
- return (0);
-}
-
-#ifndef AFS_HPUX_ENV
-#include <arpa/telnet.h>
-#else
-#include "telnet.h"
-#endif
-
-/*
- * getline - a hacked up version of fgets to ignore TELNET escape codes.
- */
-char *
-getline(s, n, iop)
- char *s;
- register FILE *iop;
-{
- register c;
- register char *cs;
-
- cs = s;
-/* tmpline may contain saved command from urgent mode interruption */
- for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
- *cs++ = tmpline[c];
- if (tmpline[c] == '\n') {
- *cs++ = '\0';
- if (debug)
- syslog(LOG_DEBUG, "command: %s", s);
- tmpline[0] = '\0';
- return(s);
- }
- if (c == 0)
- tmpline[0] = '\0';
- }
- while ((c = getc(iop)) != EOF) {
- c &= 0377;
- if (c == IAC) {
- if ((c = getc(iop)) != EOF) {
- c &= 0377;
- switch (c) {
- case WILL:
- case WONT:
- c = getc(iop);
- printf("%c%c%c", IAC, DONT, 0377&c);
- (void) fflush(stdout);
- continue;
- case DO:
- case DONT:
- c = getc(iop);
- printf("%c%c%c", IAC, WONT, 0377&c);
- (void) fflush(stdout);
- continue;
- case IAC:
- break;
- default:
- continue; /* ignore command */
- }
- }
- }
- *cs++ = c;
- if (--n <= 0 || c == '\n')
- break;
- }
- if (c == EOF && cs == s)
- return (NULL);
- *cs++ = '\0';
- if (debug)
- syslog(LOG_DEBUG, "command: %s", s);
- return (s);
-}
-
-static void
-toolong(x)
-{
- time_t now;
-
- reply(421,
- "Timeout (%d seconds): closing control connection.", timeout);
- (void) time(&now);
- if (logging) {
- syslog(LOG_INFO,
- "User %s timed out after %d seconds at %s",
- (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
- }
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr, "ftp/tcp", "close",
- "Control connection timeout", -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- dologout(1);
-}
-
-yylex()
-{
- static int cpos, state;
- register char *cp, *cp2;
- register struct tab *p;
- int n;
- char c, *strpbrk();
- char *copy();
-
- for (;;) {
- switch (state) {
-
- case CMD:
- (void) signal(SIGALRM, toolong);
- (void) alarm((unsigned) timeout);
- if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
- reply(221, "You could at least say goodbye.");
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr, "ftp/tcp", "close",
- MSGSTR(GOODBY, "You could at least say goodbye."), -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- dologout(0);
- }
- (void) alarm(0);
-#ifdef SETPROCTITLE
- if (strncasecmp(cbuf, "PASS", 4) != NULL)
- setproctitle("%s: %s", proctitle, cbuf);
-#endif /* SETPROCTITLE */
- if ((cp = strchr(cbuf, '\r'))) {
- *cp++ = '\n';
- *cp = '\0';
- }
- if ((cp = strpbrk(cbuf, " \n")))
- cpos = cp - cbuf;
- if (cpos == 0)
- cpos = 4;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- upper(cbuf);
- p = lookup(cmdtab, cbuf);
- cbuf[cpos] = c;
- if (p != 0) {
- if (p->implemented == 0) {
- nack(p->name);
- longjmp(errcatch,0);
- /* NOTREACHED */
- }
- state = p->state;
- *(char **)&yylval = p->name;
- return (p->token);
- }
- break;
-
- case SITECMD:
- if (cbuf[cpos] == ' ') {
- cpos++;
- return (SP);
- }
- cp = &cbuf[cpos];
- if ((cp2 = strpbrk(cp, " \n")))
- cpos = cp2 - cbuf;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- upper(cp);
- p = lookup(sitetab, cp);
- cbuf[cpos] = c;
- if (p != 0) {
- if (p->implemented == 0) {
- state = CMD;
- nack(p->name);
- longjmp(errcatch,0);
- /* NOTREACHED */
- }
- state = p->state;
- *(char **)&yylval = p->name;
- return (p->token);
- }
- state = CMD;
- break;
-
- case OSTR:
- if (cbuf[cpos] == '\n') {
- state = CMD;
- return (CRLF);
- }
- /* FALLTHROUGH */
-
- case STR1:
- case ZSTR1:
- dostr1:
- if (cbuf[cpos] == ' ') {
- cpos++;
- state = state == OSTR ? STR2 : ++state;
- return (SP);
- }
- break;
-
- case ZSTR2:
- if (cbuf[cpos] == '\n') {
- state = CMD;
- return (CRLF);
- }
- /* FALLTHROUGH */
-
- case STR2:
- cp = &cbuf[cpos];
- n = strlen(cp);
- cpos += n - 1;
- /*
- * Make sure the string is nonempty and \n terminated.
- */
- if (n > 1 && cbuf[cpos] == '\n') {
- cbuf[cpos] = '\0';
- *(char **)&yylval = copy(cp);
- cbuf[cpos] = '\n';
- state = ARGS;
- return (STRING);
- }
- break;
-
- case NSTR:
- if (cbuf[cpos] == ' ') {
- cpos++;
- return (SP);
- }
- if (isdigit(cbuf[cpos])) {
- cp = &cbuf[cpos];
- while (isdigit(cbuf[++cpos]))
- ;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- yylval = atoi(cp);
- cbuf[cpos] = c;
- state = STR1;
- return (NUMBER);
- }
- state = STR1;
- goto dostr1;
-
- case ARGS:
- if (isdigit(cbuf[cpos])) {
- cp = &cbuf[cpos];
- while (isdigit(cbuf[++cpos]))
- ;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- yylval = atoi(cp);
- cbuf[cpos] = c;
- return (NUMBER);
- }
- switch (cbuf[cpos++]) {
-
- case '\n':
- state = CMD;
- return (CRLF);
-
- case ' ':
- return (SP);
-
- case ',':
- return (COMMA);
-
- case 'A':
- case 'a':
- return (A);
-
- case 'B':
- case 'b':
- return (B);
-
- case 'C':
- case 'c':
- return (C);
-
- case 'E':
- case 'e':
- return (E);
-
- case 'F':
- case 'f':
- return (F);
-
- case 'I':
- case 'i':
- return (I);
-
- case 'L':
- case 'l':
- return (L);
-
- case 'N':
- case 'n':
- return (N);
-
- case 'P':
- case 'p':
- return (P);
-
- case 'R':
- case 'r':
- return (R);
-
- case 'S':
- case 's':
- return (S);
-
- case 'T':
- case 't':
- return (T);
-
- }
- break;
-
- default:
- fatal("Unknown state in scanner.");
- }
- yyerror((char *) 0);
- state = CMD;
- longjmp(errcatch,0);
- }
-}
-
-upper(s)
- register char *s;
-{
- while (*s != '\0') {
- if (islower(*s))
- *s = toupper(*s);
- s++;
- }
-}
-
-char *
-copy(s)
- char *s;
-{
- char *p;
- extern char *strcpy();
-
- p = malloc((unsigned) strlen(s) + 1);
- if (p == NULL)
- fatal("Ran out of memory.");
- (void) strcpy(p, s);
- return (p);
-}
-
-help(ctab, s)
- struct tab *ctab;
- char *s;
-{
- register struct tab *c;
- register int width, NCMDS;
- char *type;
-
- if (ctab == sitetab)
- type = "SITE ";
- else
- type = "";
- width = 0, NCMDS = 0;
- for (c = ctab; c->name != NULL; c++) {
- int len = strlen(c->name);
-
- if (len > width)
- width = len;
- NCMDS++;
- }
- width = (width + 8) &~ 7;
- if (s == 0) {
- register int i, j, w;
- int columns, lines;
-
- lreply(214, "The following %scommands are recognized %s.",
- type, "(* =>'s unimplemented)");
- columns = 76 / width;
- if (columns == 0)
- columns = 1;
- lines = (NCMDS + columns - 1) / columns;
- for (i = 0; i < lines; i++) {
- printf(" ");
- for (j = 0; j < columns; j++) {
- c = ctab + j * lines + i;
- printf("%s%c", c->name,
- c->implemented ? ' ' : '*');
- if (c + lines >= &ctab[NCMDS])
- break;
- w = strlen(c->name) + 1;
- while (w < width) {
- putchar(' ');
- w++;
- }
- }
- printf("\r\n");
- }
- (void) fflush(stdout);
- reply(214, "Direct comments to ftp-bugs@%s.", hostname);
- return;
- }
- upper(s);
- c = lookup(ctab, s);
- if (c == (struct tab *)0) {
- reply(502, "Unknown command %s.", s);
- return;
- }
- if (c->implemented)
- reply(214, "Syntax: %s%s %s", type, c->name, c->help);
- else
- reply(214, "%s%-*s\t%s; unimplemented.", type, width,
- c->name, c->help);
-}
-
-sizecmd(filename)
-char *filename;
-{
- switch (type) {
- case TYPE_L:
- case TYPE_I: {
- struct stat stbuf;
- if (stat(filename, &stbuf) < 0 ||
- (stbuf.st_mode&S_IFMT) != S_IFREG)
- reply(550, "%s: not a plain file.", filename);
- else
- reply(213, "%lu", stbuf.st_size);
- break;}
- case TYPE_A: {
- FILE *fin;
- register int c, count;
- struct stat stbuf;
- fin = fopen(filename, "r");
- if (fin == NULL) {
- perror_reply(550, filename);
- return;
- }
- if (fstat(fileno(fin), &stbuf) < 0 ||
- (stbuf.st_mode&S_IFMT) != S_IFREG) {
- reply(550, "%s: not a plain file.", filename);
- (void) fclose(fin);
- return;
- }
-
- count = 0;
- while((c=getc(fin)) != EOF) {
- if (c == '\n') /* will get expanded to \r\n */
- count++;
- count++;
- }
- (void) fclose(fin);
-
- reply(213, "%ld", count);
- break;}
- default:
- reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
- }
-}
+++ /dev/null
-.\" Copyright (c) 1985, 1988 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)ftpd.8 6.7.1.1 (Berkeley) 3/2/89
-.\"
-.TH FTPD 8 "February 23, 1989"
-.UC 5
-.SH NAME
-ftpd \- DARPA Internet File Transfer Protocol server
-.SH SYNOPSIS
-.B /etc/ftpd
-[
-.B \-d
-] [
-.B \-l
-] [
-.BR \-t timeout
-] [
-.BR \-T maxtimeout
-]
-.SH DESCRIPTION
-.I Ftpd
-is the DARPA Internet File Transfer Protocol
-server process. The server uses the TCP protocol
-and listens at the port specified in the ``ftp''
-service specification; see
-.IR services (5).
-.PP
-If the
-.B \-d
-option is specified,
-debugging information is written to the syslog.
-.PP
-If the
-.B \-l
-option is specified,
-each ftp session is logged in the syslog.
-.PP
-The ftp server
-will timeout an inactive session after 15 minutes.
-If the
-.B \-t
-option is specified,
-the inactivity timeout period will be set to
-.I timeout
-seconds.
-A client may also request a different timeout period;
-the maximum period allowed may be set to
-.I timeout
-seconds with the
-.B \-T
-option.
-The default limit is 2 hours.
-.PP
-The ftp server currently supports the following ftp
-requests; case is not distinguished.
-.PP
-.nf
-.ta \w'Request 'u
-\fBRequest Description\fP
-ABOR abort previous command
-ACCT specify account (ignored)
-ALLO allocate storage (vacuously)
-APPE append to a file
-CDUP change to parent of current working directory
-CWD change working directory
-DELE delete a file
-HELP give help information
-LIST give list files in a directory (``ls -lgA'')
-MKD make a directory
-MDTM show last modification time of file
-MODE specify data transfer \fImode\fP
-NLST give name list of files in directory
-NOOP do nothing
-PASS specify password
-PASV prepare for server-to-server transfer
-PORT specify data connection port
-PWD print the current working directory
-QUIT terminate session
-RETR retrieve a file
-RMD remove a directory
-RNFR specify rename-from file name
-RNTO specify rename-to file name
-SITE non-standard commands (see next section)
-SIZE return size of file
-STAT return status of server
-STOR store a file
-STOU store a file with a unique name
-STRU specify data transfer \fIstructure\fP
-SYST show operating system type of server system
-TYPE specify data transfer \fItype\fP
-USER specify user name
-XCUP change to parent of current working directory (deprecated)
-XCWD change working directory (deprecated)
-XMKD make a directory (deprecated)
-XPWD print the current working directory (deprecated)
-XRMD remove a directory (deprecated)
-.fi
-.PP
-The following non-standard or UNIX specific commands are supported
-by the SITE request.
-.PP
-.nf
-.ta \w'Request 'u
-\fBRequest Description\fP
-UMASK change umask. \fIE.g.\fP SITE UMASK 002
-IDLE set idle-timer. \fIE.g.\fP SITE IDLE 60
-CHMOD change mode of a file. \fIE.g.\fP SITE CHMOD 755 filename
-HELP give help information. \fIE.g.\fP SITE HELP
-.fi
-.PP
-The remaining ftp requests specified in Internet RFC 959 are
-recognized, but not implemented.
-MDTM and SIZE are not specified in
-RFC 959, but will appear in the next updated FTP RFC.
-.PP
-The ftp server will abort an active file transfer only when the
-ABOR command is preceded by a Telnet "Interrupt Process" (IP)
-signal and a Telnet "Synch" signal in the command Telnet stream,
-as described in Internet RFC 959.
-If a STAT command is received during a data transfer, preceded by a Telnet IP
-and Synch, transfer status will be returned.
-.PP
-.I Ftpd
-interprets file names according to the ``globbing''
-conventions used by
-.IR csh (1).
-This allows users to utilize the metacharacters ``*?[]{}~''.
-.PP
-.I Ftpd
-authenticates users according to three rules.
-.IP 1)
-The user name must be in the password data base,
-.IR /etc/passwd ,
-and not have a null password. In this case a password
-must be provided by the client before any file operations
-may be performed.
-.IP 2)
-The user name must not appear in the file
-.IR /etc/ftpusers .
-.IP 3)
-The user must have a standard shell returned by
-.IR getusershell (3).
-.IP 4)
-If the user name is ``anonymous'' or ``ftp'', an
-anonymous ftp account must be present in the password
-file (user ``ftp''). In this case the user is allowed
-to log in by specifying any password (by convention this
-is given as the client host's name).
-.PP
-In the last case,
-.I ftpd
-takes special measures to restrict the client's access privileges.
-The server performs a
-.IR chroot (2)
-command to the home directory of the ``ftp'' user.
-In order that system security is not breached, it is recommended
-that the ``ftp'' subtree be constructed with care; the following
-rules are recommended.
-.IP ~ftp)
-Make the home directory owned by ``ftp'' and unwritable by anyone.
-.IP ~ftp/bin)
-Make this directory owned by the super-user and unwritable by
-anyone. The program
-.IR ls (1)
-must be present to support the list command. This
-program should have mode 111.
-.IP ~ftp/etc)
-Make this directory owned by the super-user and unwritable by
-anyone. The files
-.IR passwd (5)
-and
-.IR group (5)
-must be present for the
-.I ls
-command to be able to produce owner names rather than numbers.
-The password field in
-.I passwd
-is not used, and should not contain real encrypted passwords.
-These files should be mode 444.
-.IP ~ftp/pub)
-Make this directory mode 777 and owned by ``ftp''. Users
-should then place files which are to be accessible via the
-anonymous account in this directory.
-.SH "SEE ALSO"
-ftp(1), getusershell(3), syslogd(8)
-.SH BUGS
-The anonymous account is inherently dangerous and should
-avoided when possible.
-.PP
-The server must run as the super-user
-to create sockets with privileged port numbers. It maintains
-an effective user id of the logged in user, reverting to
-the super-user only when binding addresses to sockets. The
-possible security holes have been extensively
-scrutinized, but are possibly incomplete.
+++ /dev/null
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * FTP server.
- */
-
-#include <afs/param.h>
-#ifdef AFS_AIX32_ENV
-#define _CSECURITY 1 /* XXX */
-#endif
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#ifdef _CSECURITY
-/* Security New Stuff */
-#include <sys/id.h>
-#include <sys/priv.h>
-#endif /* _CSECURITY */
-#include <netinet/in.h>
-
-#define FTP_NAMES
-#include "ftp.h"
-#include <arpa/inet.h>
-#ifndef AFS_HPUX_ENV
-#include <arpa/telnet.h>
-#endif
-#include <ctype.h>
-#include <stdio.h>
-#include <signal.h>
-#include <pwd.h>
-#include <setjmp.h>
-#include <netdb.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-#if defined(AIX)
-#include <sys/syslog.h>
-#else /* defined(AIX) */
-#include <syslog.h>
-#endif /* defined(AIX) */
-#if defined(AFS_SUN5_ENV) && !defined(_STDARG_H)
-#include <varargs.h>
-#endif
-#if defined(AFS_SUN53_ENV)
-#include <shadow.h>
-#include <security/ia_appl.h>
-char *shadow_pass();
-#endif /* AFS_SUN53_ENV */
-
-#ifdef AFS_AIX32_ENV
-#include <usersec.h>
-#include <userconf.h>
-
-#ifdef _CSECURITY
-#define tcpip_auditlog null
-void
-null()
-{
- return;
-}
-
-#include "tcpip_audit.h"
-#endif /* _CSECURITY */
-
-#define MSGSTR(n,s) s
-
-#ifdef _CSECURITY
-int remote_addr;
-char *audit_tail[TCPIP_MAX_TAIL_FIELDS];
-uid_t saved_uid, effective_uid;
-priv_t priv;
-
-/* Restore privs and set the invoker back to uid saved_uid */
-#define GET_PRIV(a) \
- getpriv(PRIV_MAXIMUM, &priv,sizeof(priv_t)); \
- setpriv(PRIV_SET|PRIV_EFFECTIVE|PRIV_BEQUEATH, &priv,sizeof(priv_t)); \
- setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, (a));
-
-/* Drop privs and set the invoker to uid 100 */
-#define DROP_PRIV(a) \
- priv.pv_priv[0] = 0; \
- priv.pv_priv[1] = 0; \
- setpriv(PRIV_SET|PRIV_EFFECTIVE|PRIV_BEQUEATH, &priv,sizeof(priv_t)); \
- setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, (a));
-
-#endif /* _CSECURITY */
-#if defined(NLS) || defined(KJI)
-#include <locale.h>
-#endif
-
-int tracing = 0;
-#endif /* AFS_AIX32_ENV */
-
-/*
- * File containing login names
- * NOT to be used on this machine.
- * Commonly used to disallow uucp.
- */
-#define FTPUSERS "/etc/ftpusers"
-
-#ifndef AFS_LINUX20_ENV
-extern int errno;
-extern char *sys_errlist[];
-extern int sys_nerr;
-#endif
-extern char *crypt();
-extern char version[];
-extern char *home; /* pointer to home directory for glob */
-extern FILE *ftpd_popen(), *fopen(), *freopen();
-extern int ftpd_pclose(), fclose();
-extern char *getline();
-extern char cbuf[];
-
-struct sockaddr_in ctrl_addr;
-struct sockaddr_in data_source;
-struct sockaddr_in data_dest;
-struct sockaddr_in his_addr;
-struct sockaddr_in pasv_addr;
-
-int data;
-jmp_buf errcatch, urgcatch;
-int logged_in;
-struct passwd *pw;
-int debug;
-int timeout = 900; /* timeout after 15 minutes of inactivity */
-int maxtimeout = 7200; /* don't allow idle time to be set beyond 2 hours */
-int logging;
-int guest;
-int type;
-int form;
-int stru; /* avoid C keyword */
-int mode;
-int usedefault = 1; /* for data transfers */
-int pdata = -1; /* for passive mode */
-int transflag;
-off_t file_size;
-off_t byte_count;
-#if !defined(CMASK) || CMASK == 0
-#undef CMASK
-#define CMASK 027
-#endif
-int defumask = CMASK; /* default umask value */
-char tmpline[7];
-char hostname[32];
-char remotehost[32];
-
-#ifndef FD_SETSIZE
-/* Yuck - we should have a AFS_BSD42 macro for these stuff */
-typedef u_short uid_t;
-typedef u_short gid_t;
-#endif
-
-/* disallow ftp PORT command to connect to a third host */
-int allowPortAttack = 0;
-
-/*
- * Timeout intervals for retrying connections
- * to hosts that don't accept PORT cmds. This
- * is a kludge, but given the problems with TCP...
- */
-#define SWAITMAX 90 /* wait at most 90 seconds */
-#define SWAITINT 5 /* interval between retries */
-
-int swaitmax = SWAITMAX;
-int swaitint = SWAITINT;
-
-void lostconn();
-void myoob();
-FILE *getdatasock(), *dataconn();
-
-#ifdef AFS_OSF_ENV
-#include <sia.h>
-#include <paths.h>
-#define _PATH_FTPUSERS "/etc/ftpusers"
-extern off_t restart_point;
-int sia_argc; /* SIA */
-char **sia_argv; /* SIA */
-SIAENTITY *entity = NULL; /* SIA */
-#endif
-
-#ifdef SETPROCTITLE
-char **Argv = NULL; /* pointer to argument vector */
-char *LastArgv = NULL; /* end of argv */
-char proctitle[BUFSIZ]; /* initial part of title */
-#endif /* SETPROCTITLE */
-
-#if defined(AFS_HPUX_ENV)
-/* HPUX uses a different call to set[res][gu]ids: */
-#define seteuid(newEuid) setresuid(-1, (newEuid), -1)
-#define setegid(newEgid) setresgid(-1, (newEgid), -1)
-#endif /* defined(AFS_HPUX_ENV) */
-
-#ifdef AFS_AIX_ENV
-#define setegid(newEgid) setgid(newEgid)
-#endif
-
-main(argc, argv, envp)
- int argc;
- char *argv[];
- char **envp;
-{
- int addrlen, on = 1;
- char *cp;
-#ifdef AFS_AIX32_ENV
- struct sigaction sa;
- void trace_handler();
- int pid;
-#ifdef _CSECURITY
- char AllClass[] = "ALL\0";
-#endif /* _CSECURITY */
-
-#ifdef notdef
- /*
- * If we're being called as a non-afs version of the program, and if AFS
- * extensions have been loaded, run the AFS version of the program.
- */
- check_and_run_afs_vers(argv);
-#endif
-
-#if defined(NLS) || defined(KJI)
- setlocale(LC_ALL, "");
-#endif
- /* New Security Code */
- saved_uid = getuidx(ID_SAVED);
-#ifdef MSG
- catd = NLcatopen(MF_FTPD, 0);
-#endif
-#ifdef _CSECURITY
- if ((auditproc(0, AUDIT_STATUS, AUDIT_SUSPEND, 0)) < 0) {
- syslog(LOG_ALERT, "ftpd: auditproc: %m");
- exit(1);
- }
- if (auditproc(0, AUDIT_EVENTS, AllClass, 5) < 0) {
- syslog(LOG_ALERT, "ftpd: auditproc: %m");
- exit(1);
- }
-#endif /* _CSECURITY */
-#endif /* AFS_AIX32_ENV */
-
-#ifdef AFS_OSF_ENV
- sia_argc = argc; /* SIA */
- sia_argv = argv; /* SIA */
-#endif
- addrlen = sizeof(his_addr);
- if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
- syslog(LOG_ERR, "getpeername (%s): %m", argv[0]);
- exit(1);
- }
-#ifdef _CSECURITY
- remote_addr = his_addr.sin_addr.s_addr;
-#endif /* _CSECURITY */
- addrlen = sizeof(ctrl_addr);
- if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
- syslog(LOG_ERR, "getsockname (%s): %m", argv[0]);
- exit(1);
- }
- data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
- debug = 0;
- openlog("ftpd", LOG_PID, LOG_DAEMON);
-#ifdef SETPROCTITLE
- /*
- * Save start and extent of argv for setproctitle.
- */
- Argv = argv;
- while (*envp)
- envp++;
- LastArgv = envp[-1] + strlen(envp[-1]);
-#endif /* SETPROCTITLE */
-
-
- argc--, argv++;
- while (argc > 0 && *argv[0] == '-') {
- for (cp = &argv[0][1]; *cp; cp++)
- switch (*cp) {
- case 'd':
- case 'v':
- debug = 1;
- break;
-
- case 'l':
- logging = 1;
- break;
-
-#ifdef AFS_AIX32_ENV
- case 's':
- tracing = 1;
- break;
-#endif
- case 't':
- timeout = atoi(++cp);
- if (maxtimeout < timeout)
- maxtimeout = timeout;
- goto nextopt;
-
- case 'T':
- maxtimeout = atoi(++cp);
- if (timeout > maxtimeout)
- timeout = maxtimeout;
- goto nextopt;
-
- case 'u':
- {
- int val = 0;
-
- while (*++cp && *cp >= '0' && *cp <= '9')
- val = val * 8 + *cp - '0';
- if (*cp)
- fprintf(stderr, "ftpd: Bad value for -u\n");
- else
- defumask = val;
- goto nextopt;
- }
-
- case 'z': /* allow ftp PORT command to connect to a
- ** third-party host */
- allowPortAttack = 1;
- break;
-
- default:
- fprintf(stderr, "ftpd: Unknown flag -%c ignored.\n", *cp);
- break;
- }
- nextopt:
- argc--, argv++;
- }
-#ifdef AFS_AIX32_ENV
- if (tracing
- && setsockopt(0, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR, MSGSTR(SOCKOPT, "setsockopt: %m"));
-
- /* set-up signal handler routines for SRC TRACE ON/OFF support */
- memset((char *)&sa, 0, sizeof(sa));
- sa.sa_mask.losigs = sigmask(SIGUSR2);
- sa.sa_handler = trace_handler;
- sigaction(SIGUSR1, &sa, NULL);
- sa.sa_mask.losigs = sigmask(SIGUSR1);
- sa.sa_handler = trace_handler;
- sigaction(SIGUSR2, &sa, NULL);
-#endif /* AFS_AIX32_ENV */
-
-#ifdef AFS_OSF_ENV
- (void)freopen(_PATH_DEVNULL, "w", stderr);
-#else
- (void)freopen("/dev/null", "w", stderr);
-#endif
- (void)signal(SIGPIPE, lostconn);
- (void)signal(SIGCHLD, SIG_IGN);
- if ((int)signal(SIGURG, myoob) < 0)
- syslog(LOG_ERR, "signal: %m");
-
- /* handle urgent data inline */
- /* Sequent defines this, but it doesn't work */
-#ifdef SO_OOBINLINE
- if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR, "setsockopt: %m");
-#endif
-#ifdef AFS_AIX32_ENV
- pid = getpid();
- if (ioctl(fileno(stdin), SIOCSPGRP, (char *)&pid) == -1)
- syslog(LOG_ERR, MSGSTR(EIOCTL, "ioctl SIOCSPGRP: %m"));
-#endif
-#ifdef F_SETOWN
- if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
- syslog(LOG_ERR, "fcntl F_SETOWN: %m");
-#endif
- dolog(&his_addr);
- /*
- * Set up default state
- */
- data = -1;
- type = TYPE_A;
- form = FORM_N;
- stru = STRU_F;
- mode = MODE_S;
- tmpline[0] = '\0';
- (void)gethostname(hostname, sizeof(hostname));
- reply(220, "%s FTP server (%s) ready.", hostname, version);
- (void)setjmp(errcatch);
- for (;;)
- (void)yyparse();
- /* NOTREACHED */
-}
-
-
-#ifdef AFS_AIX32_ENV
-/*
- * trace_handler - SRC TRACE ON/OFF signal handler
- */
-void
-trace_handler(sig)
- int sig;
-{
- int onoff;
-
- onoff = (sig == SIGUSR1) ? 1 : 0;
- if (setsockopt(0, SOL_SOCKET, SO_DEBUG, &onoff, sizeof(onoff)) < 0)
- syslog(LOG_ERR, MSGSTR(SOCKOPT, "setsockopt: %m"));
-}
-#endif
-
-
-void
-lostconn()
-{
-
- if (debug)
- syslog(LOG_DEBUG, "lost connection");
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr, "ftp/tcp", "close",
- MSGSTR(LOSTCONN, "Lost connection"), -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- dologout(-1);
-}
-
-static char ttyline[20];
-#ifdef AFS_OSF_ENV
-extern void *malloc();
-#else
-extern char *malloc();
-#endif
-/*
- * Helper function for sgetpwnam().
- */
-char *
-sgetsave(s)
- char *s;
-{
- char *new = malloc((unsigned)strlen(s) + 1);
-
- if (new == NULL) {
- perror_reply(421, "Local resource failure: malloc");
- dologout(1);
- /* NOTREACHED */
- }
- (void)strcpy(new, s);
- return (new);
-}
-
-/*
- * Save the result of a getpwnam. Used for USER command, since
- * the data returned must not be clobbered by any other command
- * (e.g., globbing).
- */
-struct passwd *
-sgetpwnam(name)
- char *name;
-{
- static struct passwd save;
- register struct passwd *p;
- struct passwd *getpwnam();
- char *sgetsave();
-
-#ifdef AFS_AIX32_ENV
- void getnonflatname();
-
- getnonflatname(name);
-#endif
- if ((p = getpwnam(name)) == NULL)
- return (p);
-
- if (save.pw_name) {
- free(save.pw_name);
- free(save.pw_passwd);
- free(save.pw_gecos);
- free(save.pw_dir);
- free(save.pw_shell);
- }
- save = *p;
- save.pw_name = sgetsave(p->pw_name);
- save.pw_passwd = sgetsave(p->pw_passwd);
- save.pw_gecos = sgetsave(p->pw_gecos);
- save.pw_dir = sgetsave(p->pw_dir);
- save.pw_shell = sgetsave(p->pw_shell);
- return (&save);
-}
-
-#ifdef AFS_AIX32_ENV
-/*
- * NAME: getnonflatname()
- *
- * FUNCTION: gets the name in /etc/passwd and replaces the
- * flattened name that might have been passed in.
- *
- * EXECUTION ENVIRONMENT: static
- *
- * RETURNS: none.
- *
- */
-
-void
-getnonflatname(char *user)
-{
- struct passwd *pw; /* return from getpwent() */
- char currflat[16]; /* name we are looking for */
- char dataflat[16]; /* name from data base */
- register int siz;
- register int members = 0;
-
-#ifdef _KJI
- setpwent();
- while ((pw = getpwent()) != NULL) {
- /* Map NLS characters in name to ascii */
- NLflatstr(user, currflat, 16);
- NLflatstr(pw->pw_name, dataflat, 16);
- if (strcmp(currflat, dataflat) == 0) {
- strcpy(user, pw->pw_name);
- break;
- }
- }
- endpwent();
-#endif
-}
-#endif
-
-int login_attempts; /* number of failed login attempts */
-int askpasswd; /* had user command, ask for passwd */
-
-/*
- * USER command.
- * Sets global passwd pointer pw if named account exists
- * and is acceptable; sets askpasswd if a PASS command is
- * expected. If logged in previously, need to reset state.
- * If name is "ftp" or "anonymous" and ftp account exists,
- * set guest and pw, then just return.
- * If account doesn't exist, ask for passwd anyway.
- * Otherwise, check user requesting login privileges.
- * Disallow anyone who does not have a standard
- * shell returned by getusershell() (/etc/shells).
- * Disallow anyone mentioned in the file FTPUSERS
- * to allow people such as root and uucp to be avoided.
- */
-user(name)
- char *name;
-{
- register char *cp = NULL;
- FILE *fd;
- char *shell, *validshells = NULL;
- char line[BUFSIZ], *getusershell();
-
-
- if (logged_in) {
- if (guest) {
- reply(530, "Can't change user from guest login.");
- return;
- }
- end_login();
- }
-
- guest = 0;
- if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
-#ifdef AFS_OSF_ENV
- if (checkuser("ftp") || checkuser("anonymous")) {
- reply(530, "User %s access denied.", name);
- if (logging)
- syslog(LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s",
- remotehost, name);
- } else
-#endif
- if ((pw = sgetpwnam("ftp")) != NULL) {
- guest = 1;
- askpasswd = 1;
- reply(331, "Guest login ok, send ident as password.");
- } else
- reply(530, "User %s unknown.", name);
- return;
- }
- if (pw = sgetpwnam(name)) {
- if ((shell = pw->pw_shell) == NULL || *shell == 0)
- shell = "/bin/sh";
-#ifdef AFS_AIX32_ENV
- if (getconfattr(SC_SYS_LOGIN, SC_SHELLS, &validshells, SEC_LIST)) {
- reply(530, MSGSTR(DENIED, "User %s access denied."), name);
- if (logging)
- syslog(LOG_NOTICE,
- MSGSTR(GETCONFATTR,
- "Getconfattr failed with error: %m"));
- pw = (struct passwd *)NULL;
- return;
- }
- while (*(cp = validshells) != NULL) {
- if (strcmp(cp, shell) == 0)
- break;
- else
- validshells += strlen(validshells) + 1;
- }
-#else
- while ((cp = getusershell()) != NULL)
- if (strcmp(cp, shell) == 0)
- break;
- endusershell();
-#endif /* AFS_AIX32_ENV */
-#ifdef AFS_AIX32_ENV
- if (*cp == NULL) {
-#else
-#ifdef AFS_OSF_ENV
- if (cp == NULL || checkuser(name)) {
-#else
- if (cp == NULL) {
-#endif
-#endif
- reply(530, "User %s access denied.", name);
- if (logging)
- syslog(LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s",
- remotehost, name);
- pw = (struct passwd *)NULL;
- return;
- }
-#ifndef AFS_OSF_ENV
- if ((fd = fopen(FTPUSERS, "r")) != NULL) {
- while (fgets(line, sizeof(line), fd) != NULL) {
- if ((cp = strchr(line, '\n')) != NULL)
- *cp = '\0';
- if (strcmp(line, name) == 0) {
- reply(530, "User %s access denied.", name);
- if (logging)
- syslog(LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s",
- remotehost, name);
- pw = (struct passwd *)NULL;
- return;
- }
- }
- }
- (void)fclose(fd);
-#endif
- }
- reply(331, "Password required for %s.", name);
- askpasswd = 1;
- /*
- * Delay before reading passwd after first failed
- * attempt to slow down passwd-guessing programs.
- */
- if (login_attempts)
- sleep((unsigned)login_attempts);
-}
-
-#ifdef AFS_OSF_ENV
-/*
- * Check if a user is in the file _PATH_FTPUSERS
- */
-checkuser(name)
- char *name;
-{
- register FILE *fd;
- register char *p;
- char line[BUFSIZ];
-
- if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) {
- while (fgets(line, sizeof(line), fd) != NULL) {
- if ((p = strchr(line, '\n')) != NULL)
- *p = '\0';
- if (line[0] == '#')
- continue;
- if (strcmp(line, name) == 0)
- return (1);
- }
- (void)fclose(fd);
- }
- return (0);
-}
-#endif
-
-
-/*
- * Terminate login as previous user, if any, resetting state;
- * used when USER command is given or login fails.
- */
-end_login()
-{
-
-#ifdef AFS_AIX32_ENV
-/* New Security Code (void) seteuid(saved_uid); */
- GET_PRIV(saved_uid);
-#else
- (void)seteuid((uid_t) 0);
-#endif
- if (logged_in)
- logwtmp(ttyline, "", "");
- pw = NULL;
- logged_in = 0;
- guest = 0;
-}
-
-pass(passwd)
- char *passwd;
-{
- char *xpasswd = 0, *salt;
- int afsauthok = 1;
- int limit;
-#ifdef AFS_OSF_ENV
- uid_t seuid;
-#endif
-#if defined(AFS_SUN53_ENV)
- struct ia_status out;
- struct passwd *pwd;
- int val;
-#endif
- if (logged_in || pw == NULL || askpasswd == 0) {
- reply(503, "Login with USER first.");
-#ifdef _CSECURITY
- NET_ACCESS_WRITE(remote_addr, "File transfer", "",
- MSGSTR(LOGINUSER, "Login with USER first."), -1);
-#endif /* _CSECURITY */
- return;
- }
- askpasswd = 0;
-
- if (!guest) { /* "ftp" is only account allowed no password */
- char *reason;
- int doafs = 0, co;
-
- if (pw == NULL)
- salt = "xx";
- else
- salt = pw->pw_passwd;
- setpag(); /* set a pag */
-#ifdef AFS_OSF_ENV
- /* SIA - sia session initialization */
- if ((co =
- sia_ses_init(&entity, sia_argc, sia_argv, hostname, pw->pw_name,
- (char *)NULL, FALSE, (char *)NULL)) != SIASUCCESS) {
- reply(530, "Initialization failure");
- return;
- }
- /* SIA - session authentication */
- if (!strcmp(pw->pw_passwd, "X")) {
- doafs = 1;
- }
-
- if (!doafs
- && (co = sia_ses_authent(NULL, passwd, entity)) != SIASUCCESS) {
- if (!doafs && pw->pw_uid) {
- if (ka_UserAuthenticate
- (pw->pw_name, /*inst */ "", /*realm */ 0,
- passwd, /*sepag */ 1, &reason)) {
- goto bad2;
- }
- goto good1;
- }
- syslog(LOG_ERR, "ses_authent failed=%d\n", co);
- bad1:
- reply(530, "Login incorrect. ");
- pw = NULL;
- if (logging)
- syslog(LOG_WARNING, "login %s from %s failed.", pw->pw_name,
- remotehost);
- if (login_attempts++ >= 5) {
- syslog(LOG_NOTICE, "repeated login failures from %s.",
- remotehost);
- sia_ses_release(&entity);
- exit(0);
- }
- sia_ses_release(&entity);
- return;
- }
- if (pw->pw_uid
- && ka_UserAuthenticate(pw->pw_name, /*inst */ "", /*realm */ 0,
- passwd, /*sepag */ 1, &reason)) {
- bad2:
- syslog(LOG_ERR, "Afs UserAuth failed\n");
- xpasswd = crypt(passwd, salt);
- afsauthok = 0;
- /* The strcmp does not catch null passwords! */
- if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) {
- goto bad1;
- }
- }
-
- good1:
- /* SIA - sia session establishment */
- if ((co = sia_ses_estab(NULL, entity)) != SIASUCCESS) {
- syslog(LOG_ERR, "ses_estab failed=%d\n", co);
- reply(530, "Login incorrect. ");
- sia_ses_release(&entity);
- return;
- }
-
- /* SIA - sia session launching */
- if ((co = sia_ses_launch(NULL, entity)) != SIASUCCESS) {
- syslog(LOG_ERR, "ses_launch failed=%d\n", co);
- reply(530, "Login incorrect. ");
- sia_ses_release(&entity);
- return;
- }
- /* SIA - get the password entry structure from entity structure */
- strncpy(pw->pw_name, entity->pwd->pw_name, sizeof(pw->pw_name));
- strncpy(pw->pw_passwd, entity->pwd->pw_passwd, sizeof(pw->pw_passwd));
- strncpy(pw->pw_gecos, entity->pwd->pw_gecos, sizeof(pw->pw_gecos));
- strncpy(pw->pw_dir, entity->pwd->pw_dir, sizeof(pw->pw_dir));
- strncpy(pw->pw_shell, entity->pwd->pw_shell, sizeof(pw->pw_shell));
- }
-#else
- if (
-#if defined(AFS_AIX32_ENV) || defined(AFS_SUN53_ENV)
- !pw->pw_uid ||
-#else
-#if defined(AFS_SUN5_ENV)
- pw->pw_uid &&
-#endif
-#endif
- ka_UserAuthenticate(pw->pw_name, /*inst */ "", /*realm */ 0,
- passwd, /*sepag */ 1, &reason)) {
-#if defined(AFS_SUN53_ENV)
- pw->pw_passwd = sgetsave(shadow_pass(pw->pw_name));
- salt = pw->pw_passwd;
-#endif
- if (passwd)
- xpasswd = crypt(passwd, salt);
- afsauthok = 0;
- /* The strcmp does not catch null passwords! */
- if (pw == NULL || *pw->pw_passwd == '\0' || !xpasswd
- || strcmp(xpasswd, pw->pw_passwd)) {
- reply(530, "Login incorrect");
- pw = NULL;
- if (login_attempts++ >= 5) {
- syslog(LOG_NOTICE, "repeated login failures from %s",
- remotehost);
- exit(0);
- }
- return;
- }
- }
- }
-
- (void)setegid((gid_t) pw->pw_gid);
- (void)initgroups(pw->pw_name, pw->pw_gid);
-
- /* open wtmp before chroot */
- (void)sprintf(ttyline, "%dftp", getpid());
- logwtmp(ttyline, pw->pw_name, remotehost);
-#endif
- login_attempts = 0; /* this time successful */
- logged_in = 1;
-
-#ifdef AFS_AIX32_ENV
- if (getuserattr(pw->pw_name, S_UFSIZE, &limit, SEC_INT) >= 0) {
- if (limit > 0)
- ulimit(2, limit);
- }
-#endif
-
- if (guest) {
-#ifdef AFS_OSF_ENV
- /*
- * SIA -ses_estab has set the euid to be that of
- * guest. Save this and then set the euid to be
- * root.
- */
- if ((seuid = geteuid()) < 0) {
- reply(550, "Can't set guest privileges.");
- goto bad;
- }
- if (seteuid((uid_t) 0) < 0) {
- reply(550, "Can't set guest privileges.");
- goto bad;
- }
-#endif
- /*
- * We MUST do a chdir() after the chroot. Otherwise
- * the old current directory will be accessible as "."
- * outside the new root!
- */
- if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
- reply(550, "Can't set guest privileges.");
-#ifdef AFS_OSF_ENV
- (void)seteuid(seuid);
-#endif
- goto bad;
- }
- } else {
-#ifdef AFS_OSF_ENV
- if (strcmp(pw->pw_dir, "/") == 0) {
-#ifdef notdef /* ingore the complains for root users like "rootl" */
- if (strcmp(pw->pw_name, "root"))
- lreply(230, "No directory! Logging in with home.");
-#endif
- } else {
-#endif
-
- if (chdir(pw->pw_dir) < 0) {
- if (chdir("/") < 0) {
- reply(530, "User %s: can't change directory to %s.",
- pw->pw_name, pw->pw_dir);
- goto bad;
- } else
- lreply(230, "No directory! Logging in with home=/");
- }
-#ifdef AFS_OSF_ENV
- }
-#endif
- }
-
-
-#ifdef AFS_AIX32_ENV
-/* New Security Code if (seteuid((uid_t)pw->pw_uid) < 0) */
- effective_uid = pw->pw_uid;
- priv.pv_priv[0] = 0;
- priv.pv_priv[1] = 0;
- setpriv(PRIV_SET | PRIV_EFFECTIVE | PRIV_BEQUEATH, &priv, sizeof(priv_t));
- if (setuidx(ID_REAL | ID_EFFECTIVE | ID_SAVED, (uid_t) pw->pw_uid) < 0) {
- reply(550, MSGSTR(NOSEETUID, "Can't set uid."));
- goto bad;
- }
-#else
-#ifndef AFS_OSF_ENV
- if (seteuid((uid_t) pw->pw_uid) < 0) {
- reply(550, "Can't set uid.");
- goto bad;
- }
-#endif
-#endif
- if (guest) {
- reply(230, "Guest login ok, access restrictions apply.");
-#ifdef SETPROCTITLE
- sprintf(proctitle, "%s: anonymous/%.*s", remotehost,
- sizeof(proctitle) - sizeof(remotehost) -
- sizeof(": anonymous/"), passwd);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
- if (logging)
- syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", remotehost,
- passwd);
- } else {
- if (afsauthok)
- reply(230, "User %s logged in.", pw->pw_name);
- else
- reply(230, "User %s logged in, no AFS authentication",
- pw->pw_name);
-#ifdef SETPROCTITLE
- sprintf(proctitle, "%s: %s", remotehost, pw->pw_name);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
- if (logging)
- syslog(LOG_INFO, "FTP LOGIN FROM %s, %s", remotehost,
- pw->pw_name);
- }
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- NET_ACCESS_WRITE(remote_addr, "File transfer", pw->pw_name, "", 0);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
-
- home = pw->pw_dir; /* home dir for globbing */
- (void)umask(defumask);
-#ifdef AFS_OSF_ENV
- sia_ses_release(&entity); /* SIA */
-#endif
- return;
- bad:
- /* Forget all about it... */
-#ifdef _CSECURITY
- NET_ACCESS_WRITE(remote_addr, "File transfer", "",
- MSGSTR(LOGINERR, "Login incorrect."), -1);
-#endif /* _CSECURITY */
- end_login();
-#ifdef AFS_OSF_ENV
- sia_ses_release(&entity); /* SIA */
-#endif
-}
-
-retrieve(cmd, name)
- char *cmd, *name;
-{
- FILE *fin, *dout;
- struct stat st;
- int (*closefunc) ();
-#ifdef _CSECURITY
- char *local, *remote;
-
- local = "";
- remote = name;
-#endif /* _CSECURITY */
- if (cmd == 0) {
- fin = fopen(name, "r"), closefunc = fclose;
- st.st_size = 0;
- } else {
- char line[BUFSIZ];
-
- (void)sprintf(line, cmd, name), name = line;
- fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
- st.st_size = -1;
- st.st_blksize = BUFSIZ;
- }
- if (fin == NULL) {
- if (errno != 0) {
- perror_reply(550, name);
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- EXPORT_DATA_WRITE(remote_addr, local, remote, sys_errlist[errno],
- errno);
- DROP_PRIV(effective_uid);
- } else {
- GET_PRIV(saved_uid);
- EXPORT_DATA_WRITE(remote_addr, local, remote,
- "Can't open remote file", -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- }
- return;
- }
- if (cmd == 0
- && (fstat(fileno(fin), &st) < 0
- || (st.st_mode & S_IFMT) != S_IFREG)) {
- reply(550, "%s: not a plain file.", name);
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- EXPORT_DATA_WRITE(remote_addr, local, remote,
- "Remote file is not plain", -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- goto done;
- }
-#ifdef AFS_OSF_ENV
- if (restart_point) {
- if (type == TYPE_A) {
- register int i, n, c;
-
- n = restart_point;
- i = 0;
- while (i++ < n) {
- if ((c = getc(fin)) == EOF) {
- perror_reply(550, name);
- goto done;
- }
- if (c == '\n')
- i++;
- }
- } else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
- perror_reply(550, name);
- goto done;
- }
- }
-#endif
- dout = dataconn(name, st.st_size, "w");
- if (dout == NULL) {
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- EXPORT_DATA_WRITE(remote_addr, local, remote,
- "Data connection not established", -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- goto done;
- }
- send_data(fin, dout, st.st_blksize);
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- EXPORT_DATA_WRITE(remote_addr, local, remote, "", 0);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- (void)fclose(dout);
- data = -1;
- pdata = -1;
- done:
- (*closefunc) (fin);
-}
-
-store(name, mode, unique)
- char *name, *mode;
- int unique;
-{
- FILE *fout, *din;
- struct stat st;
- int (*closefunc) ();
- char *gunique();
- int c;
-
-#ifdef _CSECURITY
- char *remote;
-
- remote = "";
-#endif /* _CSECURITY */
-
- if (unique && stat(name, &st) == 0 && (name = gunique(name)) == NULL)
- return;
-#ifdef AFS_OSF_ENV
- if (restart_point)
- mode = "r+w";
-#endif
- fout = fopen(name, mode);
- closefunc = fclose;
- if (fout == NULL) {
- perror_reply(553, name);
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- IMPORT_DATA_WRITE(remote_addr, name, remote, sys_errlist[errno],
- errno);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- return;
- }
-#ifdef AFS_OSF_ENV
- if (restart_point) {
- if (type == TYPE_A) {
- register int i, n, c;
-
- n = restart_point;
- i = 0;
- while (i++ < n) {
- if ((c = getc(fout)) == EOF) {
- perror_reply(550, name);
- goto done;
- }
- if (c == '\n')
- i++;
- }
- /*
- * We must do this seek to "current" position
- * because we are changing from reading to
- * writing.
- */
- if (fseek(fout, 0L, L_INCR) < 0) {
- perror_reply(550, name);
- goto done;
- }
- } else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
- perror_reply(550, name);
- goto done;
- }
- }
-#endif
- din = dataconn(name, (off_t) - 1, "r");
- if (din == NULL) {
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- IMPORT_DATA_WRITE(remote_addr, name, remote,
- MSGSTR(NODATACONN, "Can't build data connection"),
- -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- goto done;
- }
- if (receive_data(din, fout) == 0) {
- /*
- * This is AFS, so close() can return a meaningful error code
- */
- c = (*closefunc) (fout);
- if (c) {
- perror_reply(452, "Error writing file");
- (void)fclose(din);
- return;
- }
- fout = NULL;
- if (unique) {
- reply(226, "Transfer complete (unique file name:%s).", name);
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- IMPORT_DATA_WRITE(remote_addr, name, remote, sys_errlist[errno],
- errno);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- } else {
- reply(226, "Transfer complete.");
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- IMPORT_DATA_WRITE(remote_addr, name, remote,
- MSGSTR(TRANSOK, "Transfer complete."), 0);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- }
- }
- (void)fclose(din);
- data = -1;
- pdata = -1;
- done:
- if (fout)
- (*closefunc) (fout);
-}
-
-FILE *
-getdatasock(mode)
- char *mode;
-{
- int s, tries, on = 1;
- int bindretry = 0;
-
- if (data >= 0)
- return (fdopen(data, mode));
-#ifdef AFS_SUN5_ENV
- (void)seteuid(0);
-#endif
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
-#ifndef AFS_SUN5_ENV
- (void)seteuid(pw->pw_uid);
-#endif
- return (NULL);
- }
-#ifdef AFS_AIX32_ENV
-/* New Security Code (void) seteuid(saved_uid); */
- GET_PRIV(saved_uid);
-#else
-#ifndef AFS_SUN5_ENV
- (void)seteuid((uid_t) 0);
-#endif
-
-#endif
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
- goto bad;
- }
- /* anchor socket to avoid multi-homing problems */
- data_source.sin_family = AF_INET;
- data_source.sin_addr = ctrl_addr.sin_addr;
-#if defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV)
- while (bind(s, (struct sockaddr *)&data_source, sizeof(data_source)) < 0) {
- if (bindretry > 5) {
- goto bad;
- }
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV)
- if (errno == EADDRINUSE) {
- sleep(1);
- } else
- goto bad;
-#endif
- bindretry++;
- sleep(bindretry);
- }
-/* New Security Code (void) seteuid((uid_t)pw->pw_uid); */
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV)
- (void)seteuid((uid_t) pw->pw_uid);
-#else
- DROP_PRIV(effective_uid);
-#endif
-#else
- if (bind(s, (struct sockaddr *)&data_source, sizeof(data_source)) < 0) {
- goto bad;
- }
- (void)seteuid((uid_t) pw->pw_uid);
-#endif
- return (fdopen(s, mode));
- bad:
-#ifdef AFS_AIX32_ENV
-/* New Security Code (void) seteuid((uid_t)pw->pw_uid); */
- DROP_PRIV(effective_uid);
-#else
- (void)seteuid((uid_t) pw->pw_uid);
-#endif
- (void)close(s);
- return (NULL);
-}
-
-FILE *
-dataconn(name, size, mode)
- char *name;
- off_t size;
- char *mode;
-{
- char sizebuf[32];
- FILE *file;
- int retry = 0;
-#ifdef _CSECURITY
- char portbuf[8];
-#endif /* _CSECURITY */
-
- file_size = size;
- byte_count = 0;
- if (size != (off_t) - 1)
- (void)sprintf(sizebuf, " (%ld bytes)", size);
- else
- (void)strcpy(sizebuf, "");
- if (pdata >= 0) {
- struct sockaddr_in from;
- int s, fromlen = sizeof(from);
-
- s = accept(pdata, (struct sockaddr *)&from, &fromlen);
- if (s < 0) {
- reply(425, "Can't open data connection.");
- (void)close(pdata);
- pdata = -1;
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr, "", "open",
- MSGSTR(NOCONN, "Can't open data connection."),
- errno);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- return (NULL);
- }
- (void)close(pdata);
- pdata = s;
- reply(150, "Opening %s mode data connection for %s%s.",
- type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
-#ifdef _CSECURITY
- sprintf(portbuf, "%d", ntohs(from.sin_port));
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(from.sin_addr, portbuf, "open", "", 0);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- return (fdopen(pdata, mode));
- }
- if (data >= 0) {
- reply(125, "Using existing data connection for %s%s.", name, sizebuf);
- usedefault = 1;
- return (fdopen(data, mode));
- }
- if (usedefault)
- data_dest = his_addr;
- usedefault = 1;
- file = getdatasock(mode);
- if (file == NULL) {
- reply(425, "Can't create data socket (%s,%d): %s.",
- inet_ntoa(data_source.sin_addr), ntohs(data_source.sin_port),
- errno < sys_nerr ? sys_errlist[errno] : "unknown error");
-#ifdef _CSECURITY
- sprintf(portbuf, "%d", ntohs(data_source.sin_port));
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(data_source.sin_addr, portbuf, "open",
- "Can't create data socket", -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- return (NULL);
- }
- data = fileno(file);
- while (connect(data, (struct sockaddr *)&data_dest, sizeof(data_dest)) <
- 0) {
- if (errno == EADDRINUSE && retry < swaitmax) {
- sleep((unsigned)swaitint);
- retry += swaitint;
- continue;
- }
- perror_reply(425, "Can't build data connection");
- (void)fclose(file);
- data = -1;
-#ifdef _CSECURITY
- sprintf(portbuf, "%d", ntohs(data_dest.sin_port));
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(data_dest.sin_addr, portbuf, "open",
- MSGSTR(NODATACONN, "Can't build data connection"),
- errno);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- return (NULL);
- }
- reply(150, "Opening %s mode data connection for %s%s.",
- type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
-#ifdef _CSECURITY
- sprintf(portbuf, "%d", ntohs(data_dest.sin_port));
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(data_dest.sin_addr, portbuf, "open", "", 0);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- return (file);
-}
-
-/*
- * Tranfer the contents of "instr" to
- * "outstr" peer using the appropriate
- * encapsulation of the data subject
- * to Mode, Structure, and Type.
- *
- * NB: Form isn't handled.
- */
-send_data(instr, outstr, blksize)
- FILE *instr, *outstr;
- off_t blksize;
-{
- register int c, cnt;
- register char *buf;
- int netfd, filefd;
-
- transflag++;
- if (setjmp(urgcatch)) {
- transflag = 0;
- return;
- }
- switch (type) {
-
- case TYPE_A:
- while ((c = getc(instr)) != EOF) {
- byte_count++;
- if (c == '\n') {
- if (ferror(outstr))
- goto data_err;
- (void)putc('\r', outstr);
- }
- (void)putc(c, outstr);
- if (ferror(outstr))
- goto data_err;
- }
- fflush(outstr);
- transflag = 0;
- if (ferror(instr))
- goto file_err;
- if (ferror(outstr))
- goto data_err;
- reply(226, "Transfer complete.");
- return;
-
- case TYPE_I:
- case TYPE_L:
- if ((buf = malloc((u_int) blksize)) == NULL) {
- transflag = 0;
- perror_reply(451, "Local resource failure: malloc");
- return;
- }
- netfd = fileno(outstr);
- filefd = fileno(instr);
- while ((cnt = read(filefd, buf, (u_int) blksize)) > 0
- && write(netfd, buf, cnt) == cnt)
- byte_count += cnt;
- transflag = 0;
- (void)free(buf);
- if (cnt != 0) {
- if (cnt < 0)
- goto file_err;
- goto data_err;
- }
- reply(226, "Transfer complete.");
- return;
- default:
- transflag = 0;
- reply(550, "Unimplemented TYPE %d in send_data", type);
- return;
- }
-
- data_err:
- transflag = 0;
- perror_reply(426, "Data connection");
- return;
-
- file_err:
- transflag = 0;
- perror_reply(551, "Error on input file");
-}
-
-/*
- * Transfer data from peer to
- * "outstr" using the appropriate
- * encapulation of the data subject
- * to Mode, Structure, and Type.
- *
- * N.B.: Form isn't handled.
- */
-receive_data(instr, outstr)
- FILE *instr, *outstr;
-{
- register int c;
- int cnt, d;
- char buf[BUFSIZ], *bufp;
-
- transflag++;
- if (setjmp(urgcatch)) {
- transflag = 0;
- return (-1);
- }
- switch (type) {
-
- case TYPE_I:
- case TYPE_L:
- errno = d = 0;
- while ((cnt = read(fileno(instr), buf, sizeof buf)) > 0) {
-#ifdef AFS_AIX32_ENV
- byte_count += cnt;
- for (bufp = buf; cnt > 0; cnt -= d, bufp += d) {
- if ((d = write(fileno(outstr), bufp, cnt)) <= 0)
- goto file_err;
- }
-#else
- if (write(fileno(outstr), buf, cnt) != cnt)
- goto file_err;
- byte_count += cnt;
-#endif
- }
- if (cnt < 0)
- goto data_err;
- transflag = 0;
- return (0);
-
- case TYPE_E:
- reply(553, "TYPE E not implemented.");
- transflag = 0;
- return (-1);
-
- case TYPE_A:
- while ((c = getc(instr)) != EOF) {
- byte_count++;
- while (c == '\r') {
- if (ferror(outstr))
- goto data_err;
- if ((c = getc(instr)) != '\n') {
- (void)putc('\r', outstr);
- if (c == '\0' || c == EOF)
- goto contin2;
- }
- }
- (void)putc(c, outstr);
- contin2:;
- }
- fflush(outstr);
- if (ferror(instr))
- goto data_err;
- if (ferror(outstr))
- goto file_err;
- transflag = 0;
- return (0);
- default:
- reply(550, "Unimplemented TYPE %d in receive_data", type);
- transflag = 0;
- return (-1);
- }
-
- data_err:
- transflag = 0;
- perror_reply(426, "Data Connection");
- return (-1);
-
- file_err:
- transflag = 0;
- perror_reply(452, "Error writing file");
- return (-1);
-}
-
-statfilecmd(filename)
- char *filename;
-{
- char line[BUFSIZ];
- FILE *fin;
- int c;
-
- (void)sprintf(line, "/bin/ls -lgA %s", filename);
- fin = ftpd_popen(line, "r");
- lreply(211, "status of %s:", filename);
- while ((c = getc(fin)) != EOF) {
- if (c == '\n') {
- if (ferror(stdout)) {
- perror_reply(421, "control connection");
- (void)ftpd_pclose(fin);
- dologout(1);
- /* NOTREACHED */
- }
- if (ferror(fin)) {
- perror_reply(551, filename);
- (void)ftpd_pclose(fin);
- return;
- }
- (void)putc('\r', stdout);
- }
- (void)putc(c, stdout);
- }
- (void)ftpd_pclose(fin);
- reply(211, "End of Status");
-}
-
-statcmd()
-{
- struct sockaddr_in *sin;
- u_char *a, *p;
-
- lreply(211, "%s FTP server status:", hostname, version);
- printf(" %s\r\n", version);
- printf(" Connected to %s", remotehost);
- if (isdigit(remotehost[0]))
- printf(" (%s)", inet_ntoa(his_addr.sin_addr));
- printf("\r\n");
- if (logged_in) {
- if (guest)
- printf(" Logged in anonymously\r\n");
- else
- printf(" Logged in as %s\r\n", pw->pw_name);
- } else if (askpasswd)
- printf(" Waiting for password\r\n");
- else
- printf(" Waiting for user name\r\n");
- printf(" TYPE: %s", typenames[type]);
- if (type == TYPE_A || type == TYPE_E)
- printf(", FORM: %s", formnames[form]);
- if (type == TYPE_L)
-#if NBBY == 8
- printf(" %d", NBBY);
-#else
- printf(" %d", bytesize); /* need definition! */
-#endif
- printf("; STRUcture: %s; transfer MODE: %s\r\n", strunames[stru],
- modenames[mode]);
- if (data != -1)
- printf(" Data connection open\r\n");
- else if (pdata != -1) {
- printf(" in Passive mode");
- sin = &pasv_addr;
- goto printaddr;
- } else if (usedefault == 0) {
- printf(" PORT");
- sin = &data_dest;
- printaddr:
- a = (u_char *) & sin->sin_addr;
- p = (u_char *) & sin->sin_port;
-#define UC(b) (((int) b) & 0xff)
- printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]), UC(a[1]), UC(a[2]),
- UC(a[3]), UC(p[0]), UC(p[1]));
-#undef UC
- } else
- printf(" No data connection\r\n");
- reply(211, "End of status");
-}
-
-fatal(s)
- char *s;
-{
- reply(451, "Error in server: %s\n", s);
- reply(221, "Closing connection due to server error.");
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr, "ftp/tcp", "close",
- MSGSTR(CLOSECONN,
- "Closing connection due to server error."), -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- dologout(0);
- /* NOTREACHED */
-}
-
-/* VARARGS2 */
-reply(n, fmt, p0, p1, p2, p3, p4, p5)
- int n;
- long p0, p1, p2, p3, p4, p5;
- char *fmt;
-{
- printf("%d ", n);
- printf(fmt, p0, p1, p2, p3, p4, p5);
- printf("\r\n");
- (void)fflush(stdout);
- if (debug) {
- syslog(LOG_DEBUG, "<--- %d ", n);
- syslog(LOG_DEBUG, fmt, p0, p1, p2, p3, p4, p5);
- }
-}
-
-/* VARARGS2 */
-lreply(n, fmt, p0, p1, p2, p3, p4, p5)
- int n;
- long p0, p1, p2, p3, p4, p5;
- char *fmt;
-{
- printf("%d- ", n);
- printf(fmt, p0, p1, p2, p3, p4, p5);
- printf("\r\n");
- (void)fflush(stdout);
- if (debug) {
- syslog(LOG_DEBUG, "<--- %d- ", n);
- syslog(LOG_DEBUG, fmt, p0, p1, p2, p3, p4, p5);
- }
-}
-
-ack(s)
- char *s;
-{
- reply(250, "%s command successful.", s);
-}
-
-nack(s)
- char *s;
-{
- reply(502, "%s command not implemented.", s);
-}
-
-/* ARGSUSED */
-yyerror(s)
- char *s;
-{
- char *cp;
-
- if (cp = strchr(cbuf, '\n'))
- *cp = '\0';
- reply(500, "'%s': command not understood.", cbuf);
-}
-
-delete(name)
- char *name;
-{
- struct stat st;
-
- if (stat(name, &st) < 0) {
- perror_reply(550, name);
- return;
- }
- if ((st.st_mode & S_IFMT) == S_IFDIR) {
- if (rmdir(name) < 0) {
- perror_reply(550, name);
- return;
- }
- goto done;
- }
- if (unlink(name) < 0) {
- perror_reply(550, name);
- return;
- }
- done:
- ack("DELE");
-}
-
-cwd(path)
- char *path;
-{
- if (chdir(path) < 0)
- perror_reply(550, path);
- else
- ack("CWD");
-}
-
-makedir(name)
- char *name;
-{
- if (mkdir(name, 0777) < 0)
- perror_reply(550, name);
- else
- reply(257, "MKD command successful.");
-}
-
-removedir(name)
- char *name;
-{
- if (rmdir(name) < 0)
- perror_reply(550, name);
- else
- ack("RMD");
-}
-
-pwd()
-{
- char path[MAXPATHLEN + 1];
-#if 0/*ndef HAVE_GETCWD*/ /* XXX enable when autoconf happens */
- extern char *getwd();
-#define getcwd(x,y) getwd(x)
-#endif
- if (getcwd(path, MAXPATHLEN + 1) == (char *)NULL)
- reply(550, "%s.", path);
- else
- reply(257, "\"%s\" is current directory.", path);
-}
-
-char *
-renamefrom(name)
- char *name;
-{
- struct stat st;
-
- if (stat(name, &st) < 0) {
- perror_reply(550, name);
- return (NULL);
- }
- reply(350, "File exists, ready for destination name");
- return (name);
-}
-
-renamecmd(from, to)
- char *from, *to;
-{
- if (rename(from, to) < 0)
- perror_reply(550, "rename");
- else
- ack("RNTO");
-}
-
-dolog(sin)
- struct sockaddr_in *sin;
-{
- struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
- sizeof(struct in_addr), AF_INET);
- time_t t;
-
- if (hp)
- (void)strncpy(remotehost, hp->h_name, sizeof(remotehost));
- else
- (void)strncpy(remotehost, inet_ntoa(sin->sin_addr),
- sizeof(remotehost));
-#ifdef SETPROCTITLE
- sprintf(proctitle, "%s: connected", remotehost);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
-
- if (logging) {
- t = time((time_t *) 0);
- syslog(LOG_INFO, "connection from %s at %s", remotehost, ctime(&t));
- }
-}
-
-/*
- * Record logout in wtmp file
- * and exit with supplied status.
- */
-dologout(status)
- int status;
-{
- /*
- * Prevent reception of SIGURG from resulting in a resumption
- * back to the main program loop.
- */
- transflag = 0;
-
- if (logged_in) {
- (void)seteuid((uid_t) 0);
- logwtmp(ttyline, "", "");
- }
- /* beware of flushing buffers after a SIGPIPE */
- ktc_ForgetAllTokens();
- _exit(status);
-}
-
-void
-myoob()
-{
- char *cp;
-
- /* only process if transfer occurring */
- if (!transflag)
- return;
- cp = tmpline;
- if (getline(cp, 7, stdin) == NULL) {
- reply(221, "You could at least say goodbye.");
-#ifdef _CSECURITY
- GET_PRIV(saved_uid);
- CONNECTION_WRITE(remote_addr, "ftp/tcp", "close",
- MSGSTR(GOODBYE, "You could at least say goodbye."),
- -1);
- DROP_PRIV(effective_uid);
-#endif /* _CSECURITY */
- dologout(0);
- }
- upper(cp);
- if (strcmp(cp, "ABOR\r\n") == 0) {
- tmpline[0] = '\0';
- reply(426, "Transfer aborted. Data connection closed.");
- reply(226, "Abort successful");
- longjmp(urgcatch, 1);
- }
- if (strcmp(cp, "STAT\r\n") == 0) {
- if (file_size != (off_t) - 1)
- reply(213, "Status: %lu of %lu bytes transferred", byte_count,
- file_size);
- else
- reply(213, "Status: %lu bytes transferred", byte_count);
- }
-}
-
-/*
- * Note: a response of 425 is not mentioned as a possible response to
- * the PASV command in RFC959. However, it has been blessed as
- * a legitimate response by Jon Postel in a telephone conversation
- * with Rick Adams on 25 Jan 89.
- */
-passive()
-{
- int len;
- register char *p, *a;
-
- pdata = socket(AF_INET, SOCK_STREAM, 0);
- if (pdata < 0) {
- perror_reply(425, "Can't open passive connection");
- return;
- }
- pasv_addr = ctrl_addr;
- pasv_addr.sin_port = 0;
-#ifdef AFS_AIX32_ENV
-/* New Security Code (void) seteuid((uid_t)0); */
- GET_PRIV(saved_uid);
- if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) < 0) {
-/* New Security Code (void) seteuid((uid_t)pw->pw_uid); */
- DROP_PRIV(effective_uid);
- goto pasv_error;
- }
-/* New Security Code (void) seteuid((uid_t)pw->pw_uid); */
- DROP_PRIV(effective_uid);
-#else
- (void)seteuid((uid_t) 0);
- if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) < 0) {
- (void)seteuid((uid_t) pw->pw_uid);
- goto pasv_error;
- }
- (void)seteuid((uid_t) pw->pw_uid);
-#endif
- len = sizeof(pasv_addr);
- if (getsockname(pdata, (struct sockaddr *)&pasv_addr, &len) < 0)
- goto pasv_error;
- if (listen(pdata, 1) < 0)
- goto pasv_error;
- a = (char *)&pasv_addr.sin_addr;
- p = (char *)&pasv_addr.sin_port;
-
-#define UC(b) (((int) b) & 0xff)
-
- reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
- UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
- return;
-
- pasv_error:
- (void)close(pdata);
- pdata = -1;
- perror_reply(425, "Can't open passive connection");
- return;
-}
-
-/*
- * Generate unique name for file with basename "local".
- * The file named "local" is already known to exist.
- * Generates failure reply on error.
- */
-char *
-gunique(local)
- char *local;
-{
- static char new[MAXPATHLEN];
- struct stat st;
- char *cp = strrchr(local, '/');
- int count = 0;
-
- if (cp)
- *cp = '\0';
- if (stat(cp ? local : ".", &st) < 0) {
- perror_reply(553, cp ? local : ".");
- return (NULL);
- }
- if (cp)
- *cp = '/';
- (void)strcpy(new, local);
- cp = new + strlen(new);
- *cp++ = '.';
- for (count = 1; count < 100; count++) {
- (void)sprintf(cp, "%d", count);
- if (stat(new, &st) < 0)
- return (new);
- }
- reply(452, "Unique file name cannot be created.");
- return (NULL);
-}
-
-/*
- * Format and send reply containing system error number.
- */
-perror_reply(code, string)
- int code;
- char *string;
-{
- if (errno < sys_nerr)
- reply(code, "%s: %s.", string, sys_errlist[errno]);
- else
- reply(code, "%s: unknown error %d.", string, errno);
-}
-
-static char *onefile[] = {
- "",
- 0
-};
-
-send_file_list(whichfiles)
- char *whichfiles;
-{
- struct stat st;
- DIR *dirp = NULL;
- struct dirent *dir;
- FILE *dout = NULL;
- register char **dirlist, *dirname;
-#ifndef AFS_LINUX22_ENV
- char *strpbrk();
-#endif
-
-
- if (strpbrk(whichfiles, "~{[*?") != NULL) {
- extern char **glob(), *globerr;
-
- globerr = NULL;
- dirlist = glob(whichfiles);
- if (globerr != NULL) {
- reply(550, globerr);
- return;
- } else if (dirlist == NULL) {
- errno = ENOENT;
- perror_reply(550, whichfiles);
- return;
- }
- } else {
- onefile[0] = whichfiles;
- dirlist = onefile;
- }
-
- if (setjmp(urgcatch)) {
- transflag = 0;
- return;
- }
- while (dirname = *dirlist++) {
- if (stat(dirname, &st) < 0) {
- /*
- * If user typed "ls -l", etc, and the client
- * used NLST, do what the user meant.
- */
- if (dirname[0] == '-' && *dirlist == NULL && transflag == 0) {
- retrieve("/bin/ls %s", dirname);
- return;
- }
- perror_reply(550, whichfiles);
- if (dout != NULL) {
- (void)fclose(dout);
- transflag = 0;
- data = -1;
- pdata = -1;
- }
- return;
- }
-
- if ((st.st_mode & S_IFMT) == S_IFREG) {
- if (dout == NULL) {
- dout = dataconn(whichfiles, (off_t) - 1, "w");
- if (dout == NULL)
- return;
- transflag++;
- }
- fprintf(dout, "%s\n", dirname);
- byte_count += strlen(dirname) + 1;
- continue;
- } else if ((st.st_mode & S_IFMT) != S_IFDIR)
- continue;
-
- if ((dirp = opendir(dirname)) == NULL)
- continue;
-
- while ((dir = readdir(dirp)) != NULL) {
- char nbuf[MAXPATHLEN];
-
- if (dir->d_name[0] == '.' && dir->d_name[1] == 0)
- continue;
- if (dir->d_name[0] == '.' && dir->d_name[1] == '.'
- && dir->d_name[2] == 0)
- continue;
-
- sprintf(nbuf, "%s/%s", dirname, dir->d_name);
-
- /*
- * We have to do a stat to insure it's
- * not a directory or special file.
- */
- if (stat(nbuf, &st) == 0 && (st.st_mode & S_IFMT) == S_IFREG) {
- if (dout == NULL) {
- dout = dataconn(whichfiles, (off_t) - 1, "w");
- if (dout == NULL)
- return;
- transflag++;
- }
- if (nbuf[0] == '.' && nbuf[1] == '/')
- fprintf(dout, "%s\n", &nbuf[2]);
- else
- fprintf(dout, "%s\n", nbuf);
- byte_count += strlen(nbuf) + 1;
- }
- }
- (void)closedir(dirp);
- }
-
- if (dout == NULL)
- reply(550, "No files found.");
- else if (ferror(dout) != 0)
- perror_reply(550, "Data connection");
- else
- reply(226, "Transfer complete.");
-
- transflag = 0;
- if (dout != NULL)
- (void)fclose(dout);
- data = -1;
- pdata = -1;
-}
-
-#ifdef SETPROCTITLE
-/*
- * clobber argv so ps will show what we're doing.
- * (stolen from sendmail)
- * warning, since this is usually started from inetd.conf, it
- * often doesn't have much of an environment or arglist to overwrite.
- */
-
-/*VARARGS1*/
-setproctitle(fmt, a, b, c)
- char *fmt;
- long a, b, c;
-{
- register char *p, *bp, ch;
- register int i;
- char buf[BUFSIZ];
-
- (void)sprintf(buf, fmt, a, b, c);
-
- /* make ps print our process name */
- p = Argv[0];
- *p++ = '-';
-
- i = strlen(buf);
- if (i > LastArgv - p - 2) {
- i = LastArgv - p - 2;
- buf[i] = '\0';
- }
- bp = buf;
- while (ch = *bp++)
- if (ch != '\n' && ch != '\r')
- *p++ = ch;
- while (p < LastArgv)
- *p++ = ' ';
-}
-#endif /* SETPROCTITLE */
-
-#if defined(AFS_SUN53_ENV)
-char *
-shadow_pass(name)
- char *name;
-{
- struct spwd *sp;
- static char *Nothing = "";
- int oldeuid;
-
- oldeuid = geteuid();
- if (oldeuid && oldeuid != -1)
- seteuid(0);
- if ((sp = getspnam(name)) == NULL) {
- if (oldeuid && oldeuid != -1)
- seteuid(oldeuid);
- return Nothing;
- }
- if (oldeuid && oldeuid != -1)
- seteuid(oldeuid);
- return (sp->sp_pwdp);
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <afs/param.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#define SHELLS "/etc/shells"
-
-/*
- * Do not add local shells here. They should be added in /etc/shells
- */
-static char *okshells[] = { "/bin/sh", "/bin/csh", 0 };
-
-static char **shells, *strings;
-static char **curshell = NULL;
-static char **initshells();
-
-/*
- * Get a list of shells from SHELLS, if it exists.
- */
-char *
-getusershell()
-{
- char *ret;
-
- if (curshell == NULL)
- curshell = initshells();
- ret = *curshell;
- if (ret != NULL)
- curshell++;
- return (ret);
-}
-
-#ifdef AFS_AIX42_ENV
-void
-#endif
-endusershell()
-{
-
- if (shells != NULL)
- free((char *)shells);
- shells = NULL;
- if (strings != NULL)
- free(strings);
- strings = NULL;
- curshell = NULL;
-}
-
-static char **
-initshells()
-{
- register char **sp, *cp;
- register FILE *fp;
- struct stat statb;
- extern char *malloc(), *calloc();
-
- if (shells != NULL)
- free((char *)shells);
- shells = NULL;
- if (strings != NULL)
- free(strings);
- strings = NULL;
- if ((fp = fopen(SHELLS, "r")) == (FILE *) 0)
- return (okshells);
- if (fstat(fileno(fp), &statb) == -1) {
- (void)fclose(fp);
- return (okshells);
- }
- if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
- (void)fclose(fp);
- return (okshells);
- }
- shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof(char *));
- if (shells == NULL) {
- (void)fclose(fp);
- free(strings);
- strings = NULL;
- return (okshells);
- }
- sp = shells;
- cp = strings;
- while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
- while (*cp != '#' && *cp != '/' && *cp != '\0')
- cp++;
- if (*cp == '#' || *cp == '\0')
- continue;
- *sp++ = cp;
- while (!isspace(*cp) && *cp != '#' && *cp != '\0')
- cp++;
- *cp++ = '\0';
- }
- *sp = NULL;
- (void)fclose(fp);
- return (shells);
-}
-
-#ifdef AFS_AIX42_ENV
-void
-#endif
-setusershell()
-{
-
- curshell = initshells();
-}
+++ /dev/null
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * C-shell glob for random programs.
- */
-
-#include <afs/param.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-#include <stdio.h>
-#include <errno.h>
-#include <pwd.h>
-#if defined (NLS) || defined (KJI)
-#include <NLchar.h>
-#include <NLctype.h>
-#endif
-/*
-#ifdef MSG
-#include "ftpd_msg.h"
-extern nl_catd catd;
-#define MSGSTR(n,s) NLcatgets(catd,MS_FTPD,n,s)
-#else*/
-#define MSGSTR(n,s) s
-/*#endif*/
-
-#define QUOTE 0200
-#define TRIM 0177
-#define eq(a,b) (strcmp(a, b)==0)
-#define GAVSIZ (NCARGS/6)
-#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR)
-
-static char **gargv; /* Pointer to the (stack) arglist */
-static int gargc; /* Number args in gargv */
-static int gnleft;
-static short gflag;
-static int tglob();
-char **glob();
-char *globerr;
-char *home;
-struct passwd *getpwnam();
-extern int errno;
-static char *strspl(), *strend();
-char *malloc(), *strcpy(), *strcat();
-char **copyblk();
-
-static int globcnt;
-
-char *globchars = "`{[*?";
-
-static char *gpath, *gpathp, *lastgpathp;
-static int globbed;
-static char *entp;
-static char **sortbas;
-#if defined(AFS_AIX32_ENV) || defined(AFS_LINUX20_ENV)
-static ginit(char **);
-static collect(register char *);
-static acollect(register char *);
-static sort();
-static expand(char *);
-static matchdir(char *);
-static execbrc(char *, char *);
-static match(char *, char *);
-static amatch(char *, char *);
-static Gmatch(char *, char *);
-static Gcat(register char *, register char *);
-
-int any(register int, register char *);
-int blklen(register char **);
-char **blkcpy(char **, register char **);
-static char *strspl(register char *, register char *);
-char **copyblk(register char **);
-static char *strend(register char *);
-int gethdir(char *);
-
-static addpath();
-static rscan();
-
-#ifdef notdef
-static addpath(char);
-static rscan(register char **, int (*)(char));
-int letter(register char);
-int digit(register char);
-void blkfree(char **);
-#endif
-#endif
-
-char **
-glob(v)
- register char *v;
-{
- char agpath[BUFSIZ];
- char *agargv[GAVSIZ];
- char *vv[2];
-
- vv[0] = strcpy(malloc((unsigned)strlen(v) + 1), v);
- vv[1] = 0;
- gflag = 0;
- rscan(vv, tglob);
- if (gflag == 0)
- return (copyblk(vv));
-
- globerr = 0;
- gpath = agpath;
- gpathp = gpath;
- *gpathp = 0;
- lastgpathp = &gpath[sizeof agpath - 2];
- ginit(agargv);
- globcnt = 0;
- collect(v);
- if (globcnt == 0 && (gflag & 1)) {
-/* blkfree(gargv); */
- gargv = 0;
- return (0);
- } else
- return (gargv = copyblk(gargv));
-}
-
-static
-ginit(agargv)
- char **agargv;
-{
-
- agargv[0] = 0;
- gargv = agargv;
- sortbas = agargv;
- gargc = 0;
- gnleft = NCARGS - 4;
-}
-
-static
-collect(as)
- register char *as;
-{
- if (eq(as, "{") || eq(as, "{}")) {
- Gcat(as, "");
- sort();
- } else
- acollect(as);
-}
-
-static
-acollect(as)
- register char *as;
-{
- register int ogargc = gargc;
-
- gpathp = gpath;
- *gpathp = 0;
- globbed = 0;
- expand(as);
- if (gargc != ogargc)
- sort();
-}
-
-static
-sort()
-{
- register char **p1, **p2, *c;
- char **Gvp = &gargv[gargc];
-
- p1 = sortbas;
- while (p1 < Gvp - 1) {
- p2 = p1;
- while (++p2 < Gvp)
-#if defined (NLS) || defined (KJI)
- if (NLstrcmp(*p1, *p2) > 0)
-#else
- if (strcmp(*p1, *p2) > 0)
-#endif
- c = *p1, *p1 = *p2, *p2 = c;
- p1++;
- }
- sortbas = Gvp;
-}
-
-static
-expand(as)
- char *as;
-{
- register char *cs;
- register char *sgpathp, *oldcs;
- struct stat stb;
-#if defined (NLS) || defined (KJI)
- int c, c1, two_bytes;
-#endif
-
- sgpathp = gpathp;
- cs = as;
- if (*cs == '~' && gpathp == gpath) {
- addpath('~');
-#if defined (NLS) || defined (KJI)
- while (c = *++cs) {
- two_bytes = 0;
- if (NCisshift(c)) {
- two_bytes++;
- c1 = *++cs;
- _NCdec2(c, c1, c);
- cs--; /* need to pass 1st char to addpath */
- }
- if (NCisalpha(c) || NCisdigit(c) || *cs == '-') {
- addpath(*cs);
- if (two_bytes)
- addpath(*cs++);
- } else {
- break;
- }
- }
-#else
- for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
- addpath(*cs++);
-#endif
- if (!*cs || *cs == '/') {
- if (gpathp != gpath + 1) {
- *gpathp = 0;
- if (gethdir(gpath + 1))
- globerr = "Unknown user name after ~";
- (void)strcpy(gpath, gpath + 1);
- } else
- (void)strcpy(gpath, home);
- gpathp = strend(gpath);
- }
- }
- while (!any(*cs, globchars)) {
- if (*cs == 0) {
- if (!globbed)
- Gcat(gpath, "");
- else if (stat(gpath, &stb) >= 0) {
- Gcat(gpath, "");
- globcnt++;
- }
- goto endit;
- }
-#if defined (NLS) || defined (KJI)
- /* need extra call to addpath for two byte NLS char */
- if (NCisshift(*cs))
- addpath(*cs++);
-#endif
- addpath(*cs++);
- }
- oldcs = cs;
- while (cs > as && *cs != '/')
- cs--, gpathp--;
- if (*cs == '/')
- cs++, gpathp++;
- *gpathp = 0;
- if (*oldcs == '{') {
- (void)execbrc(cs, (NULL));
- return;
- }
- matchdir(cs);
- endit:
- gpathp = sgpathp;
- *gpathp = 0;
-}
-
-#ifndef AFS_LINUX20_ENV
-#define dirfd(D) (D)->dd_fd
-#endif
-
-static
-matchdir(pattern)
- char *pattern;
-{
- struct stat stb;
- register struct dirent *dp;
- DIR *dirp;
-
- /*
- * This fixes the problem of using the local
- * path on the remote machine. (PTM #35291).
- */
- if (strcmp(gpath, "") == 0)
- dirp = opendir(".");
- else
- dirp = opendir(gpath);
- if (dirp == NULL) {
- if (globbed)
- return;
- goto patherr2;
- }
- if (fstat(dirfd(dirp), &stb) < 0)
- goto patherr1;
- if (!isdir(stb)) {
- errno = ENOTDIR;
- goto patherr1;
- }
- while ((dp = readdir(dirp)) != NULL) {
- if (dp->d_ino == 0)
- continue;
- if (match(dp->d_name, pattern)) {
- Gcat(gpath, dp->d_name);
- globcnt++;
- }
- }
- closedir(dirp);
- return;
-
- patherr1:
- closedir(dirp);
- patherr2:
- globerr = "Bad directory components";
-}
-
-static
-execbrc(p, s)
- char *p, *s;
-{
- char restbuf[BUFSIZ + 2];
- register char *pe, *pm, *pl;
- int brclev = 0;
- char *lm, savec, *sgpathp;
-#if defined (NLS) || defined (KJI)
- int tc;
-#endif
-
- for (lm = restbuf; *p != '{'; *lm++ = *p++) {
-#if defined (NLS) || defined (KJI)
- if (NCisshift(*p)) {
- *lm++ = *p++;
- if (_NCdec2(*lm, *p, *lm) == 1) {
- lm--;
- p--;
- }
- }
-#endif
- continue;
- }
- for (pe = ++p; *pe; pe++)
- switch (*pe) {
-
- case '{':
- brclev++;
- continue;
-
- case '}':
- if (brclev == 0)
- goto pend;
- brclev--;
- continue;
-
- case '[':
- for (pe++; *pe && *pe != ']'; pe++) {
-#if defined (NLS) || defined (KJI)
- if (NCisshift(*pe)) {
- tc = *p++;
- if (_NCdec2(tc, *pe, tc) == 1)
- pe--;
- }
-#endif
- continue;
- }
- continue;
-#if defined (NLS) || defined (KJI)
- default:
- if (NCisshift(*pe)) {
- tc = *pe++;
- if (_NCdec2(tc, *pe, tc) == 1)
- pe--;
- }
- continue;
-#endif
-
- }
- pend:
- brclev = 0;
- for (pl = pm = p; pm <= pe; pm++)
-#if defined (NLS) || defined (KJI)
- switch (*pm) {
-#else
- switch (*pm & (QUOTE | TRIM)) {
-#endif
- case '{':
- brclev++;
- continue;
-
- case '}':
- if (brclev) {
- brclev--;
- continue;
- }
- goto doit;
-
-#if defined (NLS) || defined (KJI)
- case ',':
-#else
- case ',' | QUOTE:
- case ',':
-#endif
- if (brclev)
- continue;
- doit:
- savec = *pm;
- *pm = 0;
- (void)strcpy(lm, pl);
- (void)strcat(restbuf, pe + 1);
- *pm = savec;
- if (s == 0) {
- sgpathp = gpathp;
- expand(restbuf);
- gpathp = sgpathp;
- *gpathp = 0;
- } else if (amatch(s, restbuf))
- return (1);
- sort();
- pl = pm + 1;
- if (brclev)
- return (0);
- continue;
-
- case '[':
- for (pm++; *pm && *pm != ']'; pm++) {
-#if defined (NLS) || defined (KJI)
- if (NCisshift(*pm)) {
- tc = *pm++;
- if (_NCdec2(tc, *pm, tc) == 1)
- pm--;
- }
-#endif
- continue;
- }
- if (!*pm)
- pm--;
- continue;
-#if defined (NLS) || defined (KJI)
- default:
- if (NCisshift(*pm)) {
- tc = *pm++;
- if (_NCdec2(tc, *pm, tc) == 1)
- pm--;
- }
- continue;
-#endif
- }
- if (brclev)
- goto doit;
- return (0);
-}
-
-static
-match(s, p)
- char *s, *p;
-{
- register int c;
- register char *sentp;
- char sglobbed = globbed;
-
- if (*s == '.' && *p != '.')
- return (0);
- sentp = entp;
- entp = s;
- c = amatch(s, p);
- entp = sentp;
- globbed = sglobbed;
- return (c);
-}
-
-static
-amatch(s, p)
- register char *s, *p;
-{
- register int scc;
- int ok, lc;
- char *sgpathp;
- struct stat stb;
- int c, cc;
-#if defined (NLS) || defined (KJI)
- register int cc1, scc1;
- static int s_is2 = 0;
-#endif
-
- globbed = 1;
- for (;;) {
-#if defined (NLS) || defined (KJI)
- s_is2 = 0;
- scc = *s++;
- if (NCisshift(scc)) {
- scc1 = *s++;
- if (_NCdec2(scc, scc1, scc) == 1)
- s--;
- else
- s_is2 = 1;
- }
-#else
- scc = *s++ & TRIM;
-#endif
- switch (c = *p++) {
-
- case '{':
-#if defined (NLS) || defined (KJI)
- if (s_is2)
- return (execbrc(p - 1, s - 2));
- else
-#endif
- return (execbrc(p - 1, s - 1));
-
- case '[':
- ok = 0;
- lc = 077777;
- while (cc = *p++) {
-#if defined (NLS) || defined (KJI)
- if (NCisshift(cc))
- if (_NCdec2(cc, *p, cc) == 2)
- p++;
-#endif
- if (cc == ']') {
- if (ok)
- break;
- return (0);
- }
-#if defined (NLS) || defined (KJI)
- if (cc == '[')
- if (p[1] == ':') {
- if (!strncmp(p, "[:alpha:]", 9)) {
- ok |= (isascii(scc) && isalpha(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:upper:]", 9)) {
- ok |= (isascii(scc) && isupper(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:lower:]", 9)) {
- ok |= (isascii(scc) && islower(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:digit:]", 9)) {
- ok |= (isascii(scc) && isdigit(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:alnum:]", 9)) {
- ok |= (isascii(scc) && isalnum(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:print:]", 9)) {
- ok |= (isascii(scc) && isprint(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:punct:]", 9)) {
- ok |= (isascii(scc) && ispunct(scc));
- p += 8;
- break;
- }
-#ifdef KJI
- if (!strncmp(p, "[:jalpha:]", 10)) {
- ok |= isjalpha(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jdigit:]", 10)) {
- ok |= isjdigit(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jpunct:]", 10)) {
- ok |= isjpunct(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jparen:]", 10)) {
- ok |= isjparen(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jkanji:]", 10)) {
- ok |= isjkanji(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jhira:]", 9)) {
- ok |= isjhira(scc);
- p += 8;
- break;
- }
- if (!strncmp(p, "[:jkata:]", 9)) {
- ok |= isjkata(scc);
- p += 8;
- break;
- }
-#endif /*KJI*/
- }
- if ((cc == '-') && (lc > 0)) {
- int cu1, lcu, scu1, tco;
-
- cc1 = *p++;
- if (NCisshift(cc1))
- if (_NCdec2(cc1, *p, cc1) == 1)
- p--;
- cu1 = NCcoluniq(cc1);
- if (((tco = NCcollate(cc1)) < 0)
- && (tco = _NCxcolu(tco, &p, 0, &cu1)));
-
- lcu = NCcoluniq(lc);
- if ((tco = NCcollate(lc)) < 0) {
- char tb[3], *tbp = tb;
-
- tb[0] = tb[1] = tb[2] = '\0';
- _NCe2(lc, tb[0], tb[1]);
- tco = _NCxcolu(tco, &tbp, 0, &lcu);
- }
- scu1 = NCcoluniq(scc);
- if (((tco = NCcollate(scc)) < 0)
- && (tco = _NCxcolu(tco, &s, 0, &scu1)));
-
- /* if we have nonzero collate vals */
- if (lcu && cu1 && scu1)
- ok += (lcu <= scu1 && scu1 <= cu1);
- else
- ok += (lc == scc || scc == cu1);
-#else
- if (cc == '-') {
- if (lc <= scc && scc <= *p++)
- ok++;
-#endif /* KJI || NLS */
- } else if (scc == (lc = cc))
- ok++;
- }
- if (cc == 0)
- if (ok)
- p--;
- else
- return 0;
- continue;
-
- case '*':
- if (!*p)
- return (1);
- if (*p == '/') {
- p++;
- goto slash;
- }
-#if defined (NLS) || defined (KJI)
- if (s_is2)
- s--;
-#endif
- s--;
- do {
- if (amatch(s, p))
- return (1);
- } while (*s++);
- return (0);
-
- case 0:
- return (scc == 0);
-
- default:
-#if defined (NLS) || defined (KJI)
- if (NCisshift(c))
- if (_NCdec2(c, *p, c) == 2)
- p++;
-#endif
- if (c != scc)
- return (0);
- continue;
-
- case '?':
- if (scc == 0)
- return (0);
- continue;
-
- case '/':
- if (scc)
- return (0);
- slash:
- s = entp;
- sgpathp = gpathp;
- while (*s)
- addpath(*s++);
- addpath('/');
- if (stat(gpath, &stb) == 0 && isdir(stb))
- if (*p == 0) {
- Gcat(gpath, "");
- globcnt++;
- } else
- expand(p);
- gpathp = sgpathp;
- *gpathp = 0;
- return (0);
- }
- }
-}
-
-static
-Gmatch(s, p)
- register char *s, *p;
-{
- register int scc;
- int ok, lc;
- int c, cc;
-#if defined (NLS) || defined (KJI)
- register int scc1, cc1;
- int s_is2;
-#endif
-
- for (;;) {
-#if defined (NLS) || defined (KJI)
- s_is2 = 0;
- scc = *s++;
- if (NCisshift(scc)) {
- scc1 = *s++;
- if (_NCdec2(scc, scc1, scc) == 1)
- s--;
- else
- s_is2 = 1;
- }
-#else
- scc = *s++ & TRIM;
-#endif
- switch (c = *p++) {
-
- case '[':
- ok = 0;
- lc = 077777;
- while (cc = *p++) {
-#if defined (NLS) || defined (KJI)
- if (NCisshift(cc))
- if (_NCdec2(cc, *p, cc) == 2)
- p++;
-#endif
- if (cc == ']') {
- if (ok)
- break;
- return (0);
- }
-#if defined (NLS) || defined (KJI)
- if (cc == '[')
- if (p[1] == ':') {
- if (!strncmp(p, "[:alpha:]", 9)) {
- ok |= (isascii(scc) && isalpha(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:upper:]", 9)) {
- ok |= (isascii(scc) && isupper(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:lower:]", 9)) {
- ok |= (isascii(scc) && islower(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:digit:]", 9)) {
- ok |= (isascii(scc) && isdigit(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:alnum:]", 9)) {
- ok |= (isascii(scc) && isalnum(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:print:]", 9)) {
- ok |= (isascii(scc) && isprint(scc));
- p += 8;
- break;
- }
- if (!strncmp(p, "[:punct:]", 9)) {
- ok |= (isascii(scc) && ispunct(scc));
- p += 8;
- break;
- }
-#ifdef KJI
- if (!strncmp(p, "[:jalpha:]", 10)) {
- ok |= isjalpha(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jdigit:]", 10)) {
- ok |= isjdigit(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jpunct:]", 10)) {
- ok |= isjpunct(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jparen:]", 10)) {
- ok |= isjparen(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jkanji:]", 10)) {
- ok |= isjkanji(scc);
- p += 9;
- break;
- }
- if (!strncmp(p, "[:jhira:]", 9)) {
- ok |= isjhira(scc);
- p += 8;
- break;
- }
- if (!strncmp(p, "[:jkata:]", 9)) {
- ok |= isjkata(scc);
- p += 8;
- break;
- }
-#endif /* KJI */
- }
- if ((cc == '-') && (lc > 0)) {
- int cu1, scu1, lcu, tco;
-
- cc1 = *p++;
- if (NCisshift(cc1))
- if (_NCdec2(cc1, *p, cc1) == 1)
- p--;
- cu1 = NCcoluniq(cc1);
- if (((tco = NCcollate(cc1)) < 0)
- && (tco = _NCxcolu(tco, &p, 0, &cu1)));
-
- lcu = NCcoluniq(lc);
- if ((tco = NCcollate(lc)) < 0) {
- char tb[3], *tbp = tb;
-
- tb[0] = tb[1] = tb[2] = '\0';
- _NCe2(lc, tb[0], tb[1]);
- tco = _NCxcolu(tco, &tbp, 0, &lcu);
- }
- scu1 = NCcoluniq(scc);
- if (((tco = NCcollate(scc)) < 0)
- && (tco = _NCxcolu(tco, &s, 0, &scu1)));
-
- /* if we have nonzero collate vals */
- if (lcu && cu1 && scu1)
- ok += (lcu <= scu1 && scu1 <= cu1);
- else
- ok += (lc == scc || scc == cu1);
-#else
- if (cc == '-') {
- if (lc <= scc && scc <= *p++)
- ok++;
-#endif /* KJI || NLS */
- } else if (scc == (lc = cc))
- ok++;
- }
- if (cc == 0)
- if (ok)
- p--;
- else
- return 0;
- continue;
-
- case '*':
- if (!*p)
- return (1);
-#if defined (NLS) || defined (KJI)
- if (s_is2)
- s--;
-#endif
- for (s--; *s; s++)
- if (Gmatch(s, p))
- return (1);
- return (0);
-
- case 0:
- return (scc == 0);
-
- default:
-#if defined (NLS) || defined (KJI)
- if (NCisshift(c))
- if (_NCdec2(c, *p, c) == 2)
- p++;
- if (c != scc)
-#else
- if ((c & TRIM) != scc)
-#endif
- return (0);
- continue;
-
- case '?':
- if (scc == 0)
- return (0);
- continue;
-
- }
- }
-}
-
-static
-Gcat(s1, s2)
- register char *s1, *s2;
-{
- register int len = strlen(s1) + strlen(s2) + 1;
-
- if (len >= gnleft || gargc >= GAVSIZ - 1)
- globerr = "Arguments too long";
- else {
- gargc++;
- gnleft -= len;
- gargv[gargc] = 0;
- gargv[gargc - 1] = strspl(s1, s2);
- }
-}
-
-static
-addpath(c)
- char c;
-{
-
- if (gpathp >= lastgpathp)
- globerr = "Pathname too long";
- else {
- *gpathp++ = c;
- *gpathp = 0;
- }
-}
-
-static
-rscan(t, f)
- register char **t;
- int (*f) ();
-{
- register char *p, c;
-
- while (p = *t++) {
- if (f == tglob)
- if (*p == '~')
- gflag |= 2;
- else if (eq(p, "{") || eq(p, "{}"))
- continue;
- while (c = *p++)
- (*f) (c);
- }
-}
-
-/*
-static
-scan(t, f)
- register char **t;
- int (*f)();
-{
- register char *p, c;
-
- while (p = *t++)
- while (c = *p)
- *p++ = (*f)(c);
-} */
-
-static
-tglob(c)
- register char c;
-{
-
- if (any(c, globchars))
- gflag |= c == '{' ? 2 : 1;
- return (c);
-}
-
-/*
-static
-trim(c)
- char c;
-{
-
- return (c & TRIM);
-} */
-
-
-letter(c)
- register char c;
-{
-
- return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
-}
-
-digit(c)
- register char c;
-{
-
- return (c >= '0' && c <= '9');
-}
-
-any(c, s)
- register int c;
- register char *s;
-{
-
- while (*s)
- if (*s++ == c)
- return (1);
- return (0);
-}
-
-blklen(av)
- register char **av;
-{
- register int i = 0;
-
- while (*av++)
- i++;
- return (i);
-}
-
-char **
-blkcpy(oav, bv)
- char **oav;
- register char **bv;
-{
- register char **av = oav;
-
- while (*av++ = *bv++)
- continue;
- return (oav);
-}
-
-blkfree(av0)
- char **av0;
-{
- register char **av = av0;
-
- while (*av)
- free(*av++);
-}
-
-static
-char *
-strspl(cp, dp)
- register char *cp, *dp;
-{
- register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));
-
- if (ep == NULL)
- fatal("Out of memory");
- (void)strcpy(ep, cp);
- (void)strcat(ep, dp);
- return (ep);
-}
-
-char **
-copyblk(v)
- register char **v;
-{
- register char **nv =
- (char **)malloc((unsigned)((blklen(v) + 1) * sizeof(char **)));
- if (nv == NULL)
- fatal("Out of memory");
-
- return (blkcpy(nv, v));
-}
-
-static
-char *
-strend(cp)
- register char *cp;
-{
-
- while (*cp)
- cp++;
- return (cp);
-}
-
-/*
- * Extract a home directory from the password file
- * The argument points to a buffer where the name of the
- * user whose home directory is sought is currently.
- * We write the home directory of the user back there.
- */
-gethdir(home)
- char *home;
-{
- register struct passwd *pp = getpwnam(home);
-
- if (!pp || home + strlen(pp->pw_dir) >= lastgpathp)
- return (1);
- (void)strcpy(home, pp->pw_dir);
- return (0);
-}
+++ /dev/null
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#include <afs/param.h>
-#include <sys/types.h>
-#include <sys/file.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <utmp.h>
-#include <time.h>
-#include <string.h>
-
-#define WTMPFILE "/usr/adm/wtmp"
-#define WTMPFILEALT "/var/adm/wtmp"
-
-static int fd = 0;
-
-#ifdef AFS_LINUX20_ENV
-/* Need to conform to declaration in utmp.h */
-void
-logwtmp(const char *line, const char *name, const char *host)
-#else
-logwtmp(line, name, host)
- char *line, *name, *host;
-#endif
-{
- struct utmp ut;
- struct stat buf;
-
- if (!fd && (fd = open(WTMPFILE, O_WRONLY | O_APPEND, 0)) < 0) {
- if ((fd = open(WTMPFILEALT, O_WRONLY | O_APPEND, 0)) < 0)
- return;
- }
-
- memset((char *)&ut, 0, sizeof(ut));
- if (!fstat(fd, &buf)) {
- (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
- (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
-#if !defined(AFS_SUN5_ENV)
- (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
-#endif /* !defined(AFS_SUN5_ENV) */
-#ifdef AFS_AIX32_ENV
- (void)strncpy(ut.ut_id, line, sizeof(ut.ut_id));
- ut.ut_exit.e_termination = 0;
- ut.ut_exit.e_exit = 0;
-#endif
-#if !defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
- ut.ut_type = ((name && strlen(name)) ? USER_PROCESS : DEAD_PROCESS);
- ut.ut_pid = getpid();
-#endif
- (void)time(&ut.ut_time);
- if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
- sizeof(struct utmp))
- (void)ftruncate(fd, buf.st_size);
- }
-}
+++ /dev/null
-#!/bin/sh -
-#
-# Copyright (c) 1983 The Regents of the University of California.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are permitted
-# provided that the above copyright notice and this paragraph are
-# duplicated in all such forms and that any documentation,
-# advertising materials, and other materials related to such
-# distribution and use acknowledge that the software was developed
-# by the University of California, Berkeley. The name of the
-# University may not be used to endorse or promote products derived
-# from this software without specific prior written permission.
-# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-#
-# @(#)newvers.sh 5.3 (Berkeley) 10/31/88
-#
-if [ ! -r version ]; then echo 0 > version; fi
-touch version
-awk ' { version = $1 + 1; }\
-END { printf "char version[] = \"Version 4.%d ", version > "vers.c";\
- printf "%d\n", version > "version"; }' < version
-echo `date`'";' >> vers.c
+++ /dev/null
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software written by Ken Arnold and
- * published in UNIX Review, Vol. 6, No. 8.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#include <afs/param.h>
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <stdio.h>
-
-#ifndef AFS_AIX32_ENV
-#ifndef FD_SETSIZE /* XXX */
-typedef u_short uid_t;
-#endif
-#endif
-
-/*
- * Special version of popen which avoids call to shell. This insures noone
- * may create a pipe to a hidden program as a side effect of a list or dir
- * command.
- */
-static uid_t *pids;
-static int fds;
-
-FILE *
-ftpd_popen(program, type)
- char *program, *type;
-{
- register char *cp;
- FILE *iop;
- int argc, gargc, pdes[2], pid;
- char **pop, *argv[100], *gargv[1000], *vv[2];
- extern char **glob(), **copyblk(), *strtok();
-
- if (*type != 'r' && *type != 'w' || type[1])
- return (NULL);
-
- if (!pids) {
- if ((fds = getdtablesize()) <= 0)
- return (NULL);
- if (!(pids = (uid_t *) malloc((u_int) (fds * sizeof(uid_t)))))
- return (NULL);
- memset(pids, 0, fds * sizeof(uid_t));
- }
- if (pipe(pdes) < 0)
- return (NULL);
-
- /* break up string into pieces */
- for (argc = 0, cp = program;; cp = NULL)
- if (!(argv[argc++] = strtok(cp, " \t\n")))
- break;
-
- /* glob each piece */
- gargv[0] = argv[0];
- for (gargc = argc = 1; argv[argc]; argc++) {
- if (!(pop = glob(argv[argc]))) { /* globbing failed */
- vv[0] = argv[argc];
- vv[1] = NULL;
- pop = copyblk(vv);
- }
- argv[argc] = (char *)pop; /* save to free later */
- while (*pop && gargc < 1000)
- gargv[gargc++] = *pop++;
- }
- gargv[gargc] = NULL;
-
- iop = NULL;
- switch (pid = vfork()) {
- case -1: /* error */
- (void)close(pdes[0]);
- (void)close(pdes[1]);
- goto free;
- /* NOTREACHED */
- case 0: /* child */
- if (*type == 'r') {
- if (pdes[1] != 1) {
- dup2(pdes[1], 1);
- (void)close(pdes[1]);
- }
- (void)close(pdes[0]);
- } else {
- if (pdes[0] != 0) {
- dup2(pdes[0], 0);
- (void)close(pdes[0]);
- }
- (void)close(pdes[1]);
- }
- execv(gargv[0], gargv);
- _exit(1);
- }
- /* parent; assume fdopen can't fail... */
- if (*type == 'r') {
- iop = fdopen(pdes[0], type);
- (void)close(pdes[1]);
- } else {
- iop = fdopen(pdes[1], type);
- (void)close(pdes[0]);
- }
- pids[fileno(iop)] = pid;
-
- free:for (argc = 1; argv[argc] != NULL; argc++)
- blkfree((char **)argv[argc]);
- return (iop);
-}
-
-ftpd_pclose(iop)
- FILE *iop;
-{
- register int fdes;
- sigset_t oset;
- sigset_t sigBlock;
- int someSignals[100];
- int pid, stat_loc;
- u_int waitpid();
-
- /*
- * pclose returns -1 if stream is not associated with a
- * `popened' command, or, if already `pclosed'.
- */
- if (pids[fdes = fileno(iop)] == 0)
- return (-1);
- (void)fclose(iop);
- memset((char *)someSignals, 0, sizeof(someSignals));
- someSignals[0] =
- (1 << (SIGINT - 1)) + (1 << (SIGQUIT - 1)) + (1 << (SIGHUP - 1));
- sigBlock = *((sigset_t *) someSignals);
- sigprocmask(SIG_BLOCK, &sigBlock, &oset);
- while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1);
- sigprocmask(SIG_SETMASK, &oset, (sigset_t *) 0);
- pids[fdes] = 0;
- return (stat_loc);
-}
+++ /dev/null
-/*
- * LICENSED MATERIALS - PROPERTY OF IBM
- */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)telnet.h 5.1 (Berkeley) 5/30/85
- */
-
-/*
- * Definitions for the TELNET protocol.
- */
-#define IAC 255 /* interpret as command: */
-#define DONT 254 /* you are not to use option */
-#define DO 253 /* please, you use option */
-#define WONT 252 /* I won't use option */
-#define WILL 251 /* I will use option */
-#define SB 250 /* interpret as subnegotiation */
-#define GA 249 /* you may reverse the line */
-#define EL 248 /* erase the current line */
-#define EC 247 /* erase the current character */
-#define AYT 246 /* are you there */
-#define AO 245 /* abort output--but let prog finish */
-#define IP 244 /* interrupt process--permanently */
-#define BREAK 243 /* break */
-#define DM 242 /* data mark--for connect. cleaning */
-#define NOP 241 /* nop */
-#define SE 240 /* end sub negotiation */
-#define EOR 239 /* end of record (transparent mode) */
-
-#define SYNCH 242 /* for telfunc calls */
-
-#ifdef TELCMDS
-char *telcmds[] = {
- "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
- "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
-};
-#endif
-
-/* telnet options */
-#define TELOPT_BINARY 0 /* 8-bit data path */
-#define TELOPT_ECHO 1 /* echo */
-#define TELOPT_RCP 2 /* prepare to reconnect */
-#define TELOPT_SGA 3 /* suppress go ahead */
-#define TELOPT_NAMS 4 /* approximate message size */
-#define TELOPT_STATUS 5 /* give status */
-#define TELOPT_TM 6 /* timing mark */
-#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
-#define TELOPT_NAOL 8 /* negotiate about output line width */
-#define TELOPT_NAOP 9 /* negotiate about output page size */
-#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
-#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
-#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
-#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
-#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
-#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
-#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
-#define TELOPT_XASCII 17 /* extended ascic character set */
-#define TELOPT_LOGOUT 18 /* force logout */
-#define TELOPT_BM 19 /* byte macro */
-#define TELOPT_DET 20 /* data entry terminal */
-#define TELOPT_SUPDUP 21 /* supdup protocol */
-#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
-#define TELOPT_SNDLOC 23 /* send location */
-#define TELOPT_TTYPE 24 /* terminal type */
-#define TELOPT_EOR 25 /* end or record */
-#define TELOPT_EXOPL 255 /* extended-options-list */
-
-#ifdef TELOPTS
-#define NTELOPTS (1+TELOPT_EOR)
-char *telopts[NTELOPTS] = {
- "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
- "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
- "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
- "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
- "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
- "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
-};
-#endif
-
-/* sub-option qualifiers */
-#define TELQUAL_IS 0 /* option is... */
-#define TELQUAL_SEND 1 /* send option */
+++ /dev/null
-char version[] = "Version 4.162 Tue Nov 1 10:50:37 PST 1988";
+++ /dev/null
-srcdir=@srcdir@
-include @TOP_OBJDIR@/src/config/Makefile.config
-
-AFSLIBS = ${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libubik.a\
- ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/librx.a \
- ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/librxkad.a\
- ${TOP_LIBDIR}/libdes.a ${TOP_LIBDIR}/libcmd.a \
- ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a
-LIBS = ${AFSLIBS} ${LIBRES} ${XLIBS}
-OBJS = inetd.o setenv.o getenv.o
-
-include ../config/Makefile.version
-
-noversion: install
-
-# ta-rauth.o is used by rlogin, rsh, rcp, rlogind
-all : inetd ta-rauth.o
-
-inetd: ${OBJS}
- set -x; \
- case "${SYS_NAME}" in \
- alpha_osf1 | alpha_osf20 | alpha_osf30 | alpha_dux?? ) \
- ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} -lutil ;; \
- *) \
- ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} ;; \
- esac
-
-inetd.o: inetd.c AFS_component_version_number.c
-ta-rauth.o: ta-rauth.c
-
-clean:
- $(RM) -f inetd *.o *.BAK *~ core AFS_component_version_number.c
-
-install: ${DESTDIR}${sbindir}/inetd
-
-dest: ${DEST}/etc/inetd
- set -x; \
- case "${SYS_NAME}" in \
- sun4* ) \
- ${INSTALL} -m 644 -f inetd.conf.solaris ${DEST}/etc/inetd.conf ;; \
- sgi_* ) \
- ${INSTALL} -m 644 -f inetd.conf.sgi ${DEST}/etc/inetd.conf ;; \
- alpha_dux?? ) \
- ${INSTALL} -m 644 -f inetd.conf.dux40 ${DEST}/etc/inetd.conf ;; \
- * ) \
- ${INSTALL} -m 644 inetd.conf ${DEST}/etc/inetd.conf ;; \
- esac
-
-${DESTDIR}${sbindir}/inetd: inetd
- ${INSTALL} $? $@
-
-${DEST}/etc/inetd: inetd
- ${INSTALL} $? $@
+++ /dev/null
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <stdio.h>
-
-/*
- * _findenv --
- * Returns pointer to value associated with name, if any, else NULL.
- * Sets offset to be the offset of the name/value combination in the
- * environmental array, for use by setenv(3) and unsetenv(3).
- * Explicitly removes '=' in argument name.
- *
- * This routine *should* be a static; don't use it.
- */
-char *
-_findenv(name, offset)
- register char *name;
- int *offset;
-{
- extern char **environ;
- register int len;
- register char **P, *C;
-
- for (C = name, len = 0; *C && *C != '='; ++C, ++len);
- for (P = environ; *P; ++P)
- if (!strncmp(*P, name, len))
- if (*(C = *P + len) == '=') {
- *offset = P - environ;
- return (++C);
- }
- return (NULL);
-}
+++ /dev/null
-.\" Copyright (c) 1985 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)inetd.8 6.5 (Berkeley) 9/19/88
-.\"
-.TH INETD 8 "September 19, 1988"
-.UC 6
-.SH NAME
-inetd \- internet ``super\-server''
-.SH SYNOPSIS
-.B /etc/inetd
-[
-.B \-d
-] [ configuration file ]
-.SH DESCRIPTION
-.I Inetd
-should be run at boot time by
-.IR /etc/rc.local .
-It then listens for connections on certain
-internet sockets. When a connection is found on one
-of its sockets, it decides what service the socket
-corresponds to, and invokes a program to service the request.
-After the program is
-finished, it continues to listen on the socket (except in some cases which
-will be described below). Essentially,
-.I inetd
-allows running one daemon to invoke several others,
-reducing load on the system.
-.PP
-Upon execution,
-.I inetd
-reads its configuration information from a configuration
-file which, by default, is
-.IR /etc/inetd.conf .
-There must be an entry for each field of the configuration
-file, with entries for each field separated by a tab or
-a space. Comments are denoted by a ``#'' at the beginning
-of a line. There must be an entry for each field. The
-fields of the configuration file are as follows:
-.br
- service name
-.br
- socket type
-.br
- protocol
-.br
- wait/nowait
-.br
- user
-.br
- server program
-.br
- server program arguments
-.PP
-The
-.I service name
-entry is the name of a valid service in
-the file
-.IR /etc/services/ .
-For ``internal'' services (discussed below), the service
-name
-.I must
-be the official name of the service (that is, the first entry in
-.IR /etc/services ).
-.PP
-The
-.I socket type
-should be one of ``stream'', ``dgram'', ``raw'', ``rdm'', or ``seqpacket'',
-depending on whether the socket is a stream, datagram, raw,
-reliably delivered message, or sequenced packet socket.
-.PP
-The
-.I protocol
-must be a valid protocol as given in
-.IR /etc/protocols .
-Examples might be ``tcp'' or ``udp''.
-.PP
-The
-.I wait/nowait
-entry is applicable to datagram sockets only (other sockets should
-have a ``nowait'' entry in this space). If a datagram server connects
-to its peer, freeing the socket so
-.I inetd
-can received further messages on the socket, it is said to be
-a ``multi-threaded'' server, and should use the ``nowait''
-entry. For datagram servers which process all incoming datagrams
-on a socket and eventually time out, the server is said to be
-``single-threaded'' and should use a ``wait'' entry. ``Comsat'' (``biff'')
-and ``talk'' are both examples of the latter type of
-datagram server.
-.I Tftpd
-is an exception; it is a datagram server that establishes pseudo-connections.
-It must be listed as ``wait'' in order to avoid a race;
-the server reads the first packet, creates a new socket,
-and then forks and exits to allow
-.I inetd
-to check for new service requests to spawn new servers.
-.PP
-The
-.I user
-entry should contain the user name of the user as whom the server
-should run. This allows for servers to be given less permission
-than root.
-The
-.I server program
-entry should contain the pathname of the program which is to be
-executed by
-.I inetd
-when a request is found on its socket. If
-.I inetd
-provides this service internally, this entry should
-be ``internal''.
-.PP
-The arguments to the server program should be just as they
-normally are, starting with argv[0], which is the name of
-the program. If the service is provided internally, the
-word ``internal'' should take the place of this entry.
-.PP
-.I Inetd
-provides several ``trivial'' services internally by use of
-routines within itself. These services are ``echo'',
-``discard'', ``chargen'' (character generator), ``daytime''
-(human readable time), and ``time'' (machine readable time,
-in the form of the number of seconds since midnight, January
-1, 1900). All of these services are tcp based. For
-details of these services, consult the appropriate RFC
-from the Network Information Center.
-.PP
-.I Inetd
-rereads its configuration file when it receives a hangup signal, SIGHUP.
-Services may be added, deleted or modified when the configuration file
-is reread.
-.SH "SEE ALSO"
-comsat(8), fingerd(8), ftpd(8), rexecd(8), rlogind(8), rshd(8),
-telnetd(8), tftpd(8)
+++ /dev/null
-/* inetd.c */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Inetd - Internet super-server
- *
- * This program invokes all internet services as needed.
- * connection-oriented services are invoked each time a
- * connection is made, by creating a process. This process
- * is passed the connection as file descriptor 0 and is
- * expected to do a getpeername to find out the source host
- * and port.
- *
- * Datagram oriented services are invoked when a datagram
- * arrives; a process is created and passed a pending message
- * on file descriptor 0. Datagram servers may either connect
- * to their peer, freeing up the original socket for inetd
- * to receive further messages on, or ``take over the socket'',
- * processing all arriving datagrams and, eventually, timing
- * out. The first type of server is said to be ``multi-threaded'';
- * the second type of server ``single-threaded''.
- *
- * Inetd uses a configuration file which is read at startup
- * and, possibly, at some later time in response to a hangup signal.
- * The configuration file is ``free format'' with fields given in the
- * order shown below. Continuation lines for an entry must being with
- * a space or tab. All fields must be present in each entry.
- *
- * service name must be in /etc/services
- * socket type stream/dgram/raw/rdm/seqpacket
- * protocol must be in /etc/protocols
- * wait/nowait single-threaded/multi-threaded
- * user user to run daemon as
- * server program full path name
- * server program arguments maximum of MAXARGS (5)
- *
- * Comment lines are indicated by a `#' in column 1.
- */
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#ifdef AFS_SUN5_ENV
-#define BSD_COMP
-#endif
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#include <afs/afsutil.h>
-#include <errno.h>
-#include <signal.h>
-#include <netdb.h>
-#ifdef AIX
-#include <sys/syslog.h>
-#else
-#include <syslog.h>
-#endif /* AIX */
-#include <pwd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-#define TOOMANY 40 /* don't start more than TOOMANY */
-#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */
-#define RETRYTIME (60*10) /* retry after bind or server fail */
-
-void config(), reapchild(), retry();
-
-int debug = 0;
-int nsock, maxsock;
-fd_set allsock;
-int options;
-int timingout;
-struct servent *sp;
-
-struct servtab {
- char *se_service; /* name of service */
- int se_socktype; /* type of socket to use */
- char *se_proto; /* protocol used */
- short se_wait; /* single threaded server */
- short se_checked; /* looked at during merge */
- char *se_user; /* user name to run as */
- struct biltin *se_bi; /* if built-in, description */
- char *se_server; /* server program */
-#define MAXARGV 5
- char *se_argv[MAXARGV + 1]; /* program arguments */
- int se_fd; /* open descriptor */
- struct sockaddr_in se_ctrladdr; /* bound address */
- int se_count; /* number started since se_time */
- struct timeval se_time; /* start of se_count */
- struct servtab *se_next;
-} *servtab;
-
-int echo_stream(), discard_stream(), machtime_stream();
-int daytime_stream(), chargen_stream();
-int echo_dg(), discard_dg(), machtime_dg(), daytime_dg(), chargen_dg();
-int auth_stream(), auth_dg();
-
-struct biltin {
- char *bi_service; /* internally provided service name */
- int bi_socktype; /* type of socket supported */
- short bi_fork; /* 1 if should fork before call */
- short bi_wait; /* 1 if should wait for child */
- int (*bi_fn) (); /* function which performs it */
-} biltins[] = {
- /* Echo received data */
- "echo", SOCK_STREAM, 1, 0, echo_stream, "echo", SOCK_DGRAM, 0, 0, echo_dg,
- /* Internet /dev/null */
- "discard", SOCK_STREAM, 1, 0, discard_stream, "discard", SOCK_DGRAM,
- 0, 0, discard_dg,
- /* Return 32 bit time since 1970 */
- "time", SOCK_STREAM, 0, 0, machtime_stream, "time", SOCK_DGRAM, 0, 0,
- machtime_dg,
- /* Return human-readable time */
- "daytime", SOCK_STREAM, 0, 0, daytime_stream, "daytime", SOCK_DGRAM,
- 0, 0, daytime_dg,
- /* Familiar character generator */
- "chargen", SOCK_STREAM, 1, 0, chargen_stream, "chargen", SOCK_DGRAM,
- 0, 0, chargen_dg,
- /* Remote authentication services */
-"ta-rauth", SOCK_STREAM, 1, 0, auth_stream, "ta-rauth", SOCK_DGRAM, 0,
- 0, auth_dg, 0};
-
-#define NUMINT (sizeof(intab) / sizeof(struct inent))
-char *CONFIG = "/etc/inetd.conf";
-char **Argv;
-char *LastArg;
-int backlog = 10; /* listen() queue length */
-
-#include "AFS_component_version_number.c"
-
-long allZeroes[100];
-sigset_t sigNone;
-sigset_t sigBlock;
-
-int afs_didsetpag = 0;
-main(argc, argv, envp)
- int argc;
- char *argv[], *envp[];
-{
- extern char *optarg;
- extern int optind;
- register struct servtab *sep;
- register struct passwd *pwd;
- struct passwd *getpwnam();
- register int tmpint;
- struct sigaction sa;
- int ch, pid, dofork;
- char buf[50];
-#if defined(AFS_HPUX_ENV)
- int consoleFid;
- pid_t newSessionID;
-#endif /* defined(AFS_HPUX_ENV) */
-
- memset((char *)allZeroes, '\0', sizeof(allZeroes));
- memset((char *)allZeroes, 0, sizeof(allZeroes));
-
- sigNone = *((sigset_t *) allZeroes);
- allZeroes[0] =
- (1 << (SIGCHLD - 1)) + (1 << (SIGHUP - 1)) + (1 << (SIGALRM - 1));
- sigBlock = *((sigset_t *) allZeroes);
-
- setpag(); /* disassociate with PAG of person starting inetd */
-
- Argv = argv;
- if (envp == 0 || *envp == 0)
- envp = argv;
- while (*envp)
- envp++;
- LastArg = envp[-1] + strlen(envp[-1]);
-
- while ((ch = getopt(argc, argv, "dl:")) != EOF)
- switch (ch) {
- case 'd':
- debug = 1;
- options |= SO_DEBUG;
- break;
- case 'l':
- /* undocumented option to set listen() queue length */
- backlog = atoi(optarg);
- break;
- case '?':
- default:
- fprintf(stderr, "usage: inetd [-d]");
- exit(1);
- }
- argc -= optind;
- argv += optind;
-
- if (argc > 0)
- CONFIG = argv[0];
- if (debug == 0) {
-#if defined(AFS_OSF_ENV) && !defined(AFS_OSF32_ENV)
- daemon(0, 0);
-#else
- if (fork()) {
- exit(0);
- }
-#ifdef AFS_HPUX_ENV
- for (tmpint = 0; tmpint < getnumfds(); tmpint++)
-#else
- for (tmpint = 0; tmpint < 10; tmpint++)
-#endif
- (void)close(tmpint);
- (void)open("/", O_RDONLY);
- (void)dup2(0, 1);
- (void)dup2(0, 2);
-#ifndef AFS_HPUX_ENV
- tmpint = open("/dev/tty", O_RDWR);
- if (tmpint > 0) {
- ioctl(tmpint, TIOCNOTTY, NULL);
- close(tmpint);
- }
-#else
-#ifdef notdef
- /*
- * the way to get rid of the controlling terminal in hp-ux, if we
- * are not a process group leader
- */
- newSessionID = setsid();
- if (newSessionID == -1) {
- /*
- * we are already a process group leader, & extensive experimentation
- * indicates that (contrary to the documentation, once again), there
- * doesn't seem to be any way to get rid of our control tty, other
- * than the following ugliness:
- */
- if (fork())
- exit(0);
- }
-#endif
-#endif
-#ifdef AFS_HPUX_ENV
- (void)setpgrp();
-#else
- (void)setpgrp(0, 0);
-#endif
-
-#if !defined(AIX)
- (void)signal(SIGTSTP, SIG_IGN);
- (void)signal(SIGTTIN, SIG_IGN);
- (void)signal(SIGTTOU, SIG_IGN);
-#endif /* !defined(AIX) */
-#endif /* AFS_OSF_ENV */
- }
-
- openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
-
- memset((char *)&sa, '\0', sizeof(sa));
- sa.sa_mask = sigBlock;
- sa.sa_handler = retry;
- sigaction(SIGALRM, &sa, NULL);
- config();
- sa.sa_handler = config;
- sigaction(SIGHUP, &sa, NULL);
- sa.sa_handler = reapchild;
- sigaction(SIGCHLD, &sa, NULL);
- {
- /* space for daemons to overwrite environment for ps */
-#define DUMMYSIZE 100
- char dummy[DUMMYSIZE];
-
- (void)memset(dummy, 'x', sizeof(DUMMYSIZE) - 1);
- dummy[DUMMYSIZE - 1] = '\0';
- (void)setenv("inetd_dummy", dummy, 1);
- }
-
- for (;;) {
- int n, ctrl;
- fd_set readable;
-
- if (nsock == 0) {
- (void)sigprocmask(SIG_BLOCK, &sigBlock, (sigset_t *) 0);
- while (nsock == 0)
- sigpause(0L);
- (void)sigprocmask(SIG_SETMASK, &sigNone, (sigset_t *) 0);
- }
- readable = allsock;
- if ((n =
- select(maxsock + 1, &readable, (fd_set *) 0, (fd_set *) 0,
- NULL)) <= 0) {
- if (n < 0 && errno != EINTR)
- syslog(LOG_WARNING, "select: %m\n");
- sleep(1);
- continue;
- }
- for (sep = servtab; n && sep; sep = sep->se_next)
- if ((sep->se_fd != -1) && FD_ISSET(sep->se_fd, &readable)) {
- n--;
- if (debug)
- fprintf(stderr, "someone wants %s\n", sep->se_service);
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
- ctrl = accept(sep->se_fd, NULL, (int *)0);
- if (debug)
- fprintf(stderr, "accept, ctrl %d\n", ctrl);
- if (ctrl < 0) {
- if (errno == EINTR)
- continue;
- syslog(LOG_WARNING, "accept: %m");
- continue;
- }
- } else
- ctrl = sep->se_fd;
- (void)sigprocmask(SIG_BLOCK, &sigBlock, (sigset_t *) 0);
- pid = 0;
- dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
- if (dofork) {
- if (debug)
- fprintf(stderr, "forking\n");
- if (sep->se_socktype == SOCK_DGRAM) {
- if (sep->se_count++ == 0)
- (void)gettimeofday(&sep->se_time, NULL);
- else if (sep->se_count >= TOOMANY) {
- struct timeval now;
-
- (void)gettimeofday(&now, NULL);
- if (now.tv_sec - sep->se_time.tv_sec > CNT_INTVL) {
- sep->se_time = now;
- sep->se_count = 1;
- } else {
- syslog(LOG_ERR,
- "%s/%s server failing (looping), service terminated %d\n",
- sep->se_service, sep->se_proto,
- sep->se_socktype);
- FD_CLR(sep->se_fd, &allsock);
- (void)close(sep->se_fd);
- sep->se_fd = -1;
- sep->se_count = 0;
- nsock--;
- sigprocmask(SIG_SETMASK, &sigNone,
- (sigset_t *) 0);
- if (!timingout) {
- timingout = 1;
- alarm(RETRYTIME);
- }
- continue;
- }
- }
- }
- pid = fork();
- }
- if (pid < 0) {
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
- close(ctrl);
- sigprocmask(SIG_SETMASK, &sigNone, (sigset_t *) 0);
- sleep(1);
- continue;
- }
- if (pid && sep->se_wait) {
- sep->se_wait = pid;
- FD_CLR(sep->se_fd, &allsock);
- nsock--;
- }
- sigprocmask(SIG_SETMASK, &sigNone, (sigset_t *) 0);
- if (pid == 0) {
- if (debug) {
-#ifdef AFS_OSF_ENV
- setsid();
-#else
- if (dofork && (tmpint = open("/dev/tty", O_RDWR)) > 0) {
-#ifndef AFS_HPUX_ENV
- ioctl(tmpint, TIOCNOTTY, 0);
-#endif
- close(tmpint);
- }
- (void)setpgrp(0, 0);
-#if !defined(AIX)
- (void)signal(SIGTSTP, SIG_IGN);
- (void)signal(SIGTTIN, SIG_IGN);
- (void)signal(SIGTTOU, SIG_IGN);
-#endif /* !defined(AIX) */
-#endif
- }
- if (dofork) {
-#ifdef AFS_HPUX_ENV
- /* make child session leader */
- setsid();
- resetsignals();
- sigsetmask(0L);
- for (tmpint = getnumfds(); --tmpint > 2;)
-#else
- for (tmpint = getdtablesize(); --tmpint > 2;)
-#endif
- if (tmpint != ctrl)
- close(tmpint);
- }
- afs_didsetpag = 0;
- if (sep->se_bi)
- (*sep->se_bi->bi_fn) (ctrl, sep);
- else {
-#ifdef AFS_HPUX_ENV
- int pgid = -getpid();
-#else
-#ifndef AFS_OSF_ENV
- (void)setpgrp(0, 0);
-#endif
-#endif
- dup2(ctrl, 0);
- close(ctrl);
- dup2(0, 1);
- dup2(0, 2);
-#ifdef AFS_HPUX_ENV
- /* make child socket process group leader */
- ioctl(0, SIOCSPGRP, (char *)&pgid);
-#endif
- if ((pwd = getpwnam(sep->se_user)) == NULL) {
- fprintf(stderr, "getpwnam failed\n");
- syslog(LOG_ERR, "getpwnam: %s: No such user",
- sep->se_user);
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof(buf), 0);
- _exit(1);
- }
- if (pwd->pw_uid) {
-#ifdef AFS_HPUX_ENV
- (void)initgroups((uid_t) pwd->pw_name,
- (gid_t) pwd->pw_gid);
- (void)setgid((gid_t) pwd->pw_gid);
-#else
- (void)setgid((gid_t) pwd->pw_gid);
- initgroups(pwd->pw_name, pwd->pw_gid);
-#endif
- (void)setuid((uid_t) pwd->pw_uid);
- }
- if (!afs_didsetpag
- && (!strcmp(sep->se_service, "login")
- || !strcmp(sep->se_service, "shell"))) {
- setpag(); /* to disassociate it from current group... */
- }
-#ifdef AFS_HPUX_ENV
-#ifdef notdef
- if (sep->se_argv[0] != NULL) {
- if (!strcmp(sep->se_argv[0], "%A")) {
- char addrbuf[32];
- sprintf(addrbuf, "%s.%d",
- inet_ntoa(his_addr.sin_addr.s_addr),
- ntohs(his_addr.sin_port));
- execl(sep->se_server,
- strrchr(sep->se_server, '/') + 1,
- sep->se_socktype ==
- SOCK_DGRAM ? (char *)0 : addrbuf, NULL);
- } else
- execv(sep->se_server, sep->se_argv);
- } else
-#endif
-#endif
- execv(sep->se_server, sep->se_argv);
- if (debug)
- fprintf(stderr, "%d execl %s\n", getpid(),
- sep->se_server);
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof(buf), 0);
- syslog(LOG_ERR, "execv %s: %m", sep->se_server);
- _exit(1);
- }
- }
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
- close(ctrl);
- }
- }
-}
-
-void
-reapchild()
-{
- int status;
- int pid;
- register struct servtab *sep;
-
- for (;;) {
- pid = wait3(&status, WNOHANG, NULL);
- if (pid <= 0)
- break;
- if (debug)
- fprintf(stderr, "%d <reaped (status %d)\n", pid, status);
- for (sep = servtab; sep; sep = sep->se_next)
- if (sep->se_wait == pid) {
- if (status)
- syslog(LOG_WARNING, "%s: exit status 0x%x",
- sep->se_server, status);
- if (debug)
- fprintf(stderr, "restored %s, fd %d\n", sep->se_service,
- sep->se_fd);
- FD_SET(sep->se_fd, &allsock);
- nsock++;
- sep->se_wait = 1;
- }
- }
-}
-
-void
-config()
-{
- register struct servtab *sep, *cp, **sepp;
- struct servtab *getconfigent(), *enter();
- sigset_t oset;
-
- if (!setconfig()) {
- syslog(LOG_ERR, "%s: %m", CONFIG);
- return;
- }
- for (sep = servtab; sep; sep = sep->se_next)
- sep->se_checked = 0;
- while (cp = getconfigent()) {
-#if 0
- /* fix a bug on rt */
- if (cp->se_service == 0 || *cp->se_service == '\0')
- break;
-#endif /* 0 */
- for (sep = servtab; sep; sep = sep->se_next)
- if (strcmp(sep->se_service, cp->se_service) == 0
- && strcmp(sep->se_proto, cp->se_proto) == 0)
- break;
- if (sep != 0) {
- int i;
-
- sigprocmask(SIG_BLOCK, &sigBlock, &oset);
- if (cp->se_bi == 0)
- sep->se_wait = cp->se_wait;
-#define SWAP(a, b) { char *c = a; a = b; b = c; }
- if (cp->se_user)
- SWAP(sep->se_user, cp->se_user);
- if (cp->se_server)
- SWAP(sep->se_server, cp->se_server);
- for (i = 0; i < MAXARGV; i++)
- SWAP(sep->se_argv[i], cp->se_argv[i]);
- sigprocmask(SIG_SETMASK, &oset, (sigset_t *) 0);
- freeconfig(cp);
- if (debug)
- print_service("REDO", sep);
- } else {
- sep = enter(cp);
- if (debug)
- print_service("ADD ", sep);
- }
- sep->se_checked = 1;
- sp = getservbyname(sep->se_service, sep->se_proto);
- if (sp == 0) {
- syslog(LOG_ERR, "%s/%s: unknown service", sep->se_service,
- sep->se_proto);
- continue;
- }
- if (sp->s_port != sep->se_ctrladdr.sin_port) {
- sep->se_ctrladdr.sin_port = sp->s_port;
- if (sep->se_fd != -1)
- (void)close(sep->se_fd);
- sep->se_fd = -1;
- }
- if (sep->se_fd == -1)
- setup(sep);
- }
- endconfig();
- /*
- * Purge anything not looked at above.
- */
- sigprocmask(SIG_BLOCK, &sigBlock, &oset);
- sepp = &servtab;
- while (sep = *sepp) {
- if (sep->se_checked) {
- sepp = &sep->se_next;
- continue;
- }
- *sepp = sep->se_next;
- if (sep->se_fd != -1) {
- FD_CLR(sep->se_fd, &allsock);
- nsock--;
- (void)close(sep->se_fd);
- }
- if (debug)
- print_service("FREE", sep);
- freeconfig(sep);
- free((char *)sep);
- }
- sigprocmask(SIG_SETMASK, &oset, (sigset_t *) 0);
-}
-
-void
-retry()
-{
- register struct servtab *sep;
-
- timingout = 0;
- for (sep = servtab; sep; sep = sep->se_next)
- if (sep->se_fd == -1)
- setup(sep);
-}
-
-setup(sep)
- register struct servtab *sep;
-{
- int on = 1;
-
- if ((sep->se_fd = socket(AF_INET, sep->se_socktype, 0)) < 0) {
- syslog(LOG_ERR, "%s/%s: socket: %m", sep->se_service, sep->se_proto);
- return;
- }
-#define turnon(fd, opt) \
-setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
- if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG)
- && turnon(sep->se_fd, SO_DEBUG) < 0)
- syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
- if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
- syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
-#undef turnon
- if (bind
- (sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr,
- sizeof(sep->se_ctrladdr)) < 0) {
- syslog(LOG_ERR, "%s/%s: bind: %m", sep->se_service, sep->se_proto);
- (void)close(sep->se_fd);
- sep->se_fd = -1;
- if (!timingout) {
- timingout = 1;
- alarm(RETRYTIME);
- }
- return;
- }
- if (sep->se_socktype == SOCK_STREAM)
- listen(sep->se_fd, backlog);
- FD_SET(sep->se_fd, &allsock);
- nsock++;
- if (sep->se_fd > maxsock)
- maxsock = sep->se_fd;
-}
-
-struct servtab *
-enter(cp)
- struct servtab *cp;
-{
- register struct servtab *sep;
- sigset_t oset;
-
- sep = (struct servtab *)malloc(sizeof(*sep));
- if (sep == NULL) {
- syslog(LOG_ERR, "Out of memory.");
- exit(-1);
- }
- *sep = *cp;
- sep->se_fd = -1;
- sigprocmask(SIG_BLOCK, &sigBlock, &oset);
- sep->se_next = servtab;
- servtab = sep;
- sigprocmask(SIG_SETMASK, &oset, (sigset_t *) 0);
- return (sep);
-}
-
-FILE *fconfig = NULL;
-struct servtab serv;
-char line[256];
-char *skip(), *nextline();
-
-setconfig()
-{
-
- if (fconfig != NULL) {
- fseek(fconfig, 0L, L_SET);
- return (1);
- }
- fconfig = fopen(CONFIG, "r");
- return (fconfig != NULL);
-}
-
-endconfig()
-{
- if (fconfig) {
- (void)fclose(fconfig);
- fconfig = NULL;
- }
-}
-
-struct servtab *
-getconfigent()
-{
- register struct servtab *sep = &serv;
- int argc;
- char *cp, *arg, *copyofstr();
-
- more:
- /* modified to skip blank lines... */
- while ((cp = nextline(fconfig)) && (*cp == '#' || (strlen(cp) < 2)));
- if (cp == NULL)
- return (NULL);
- sep->se_service = copyofstr(skip(&cp));
- arg = skip(&cp);
- if (strcmp(arg, "stream") == 0)
- sep->se_socktype = SOCK_STREAM;
- else if (strcmp(arg, "dgram") == 0)
- sep->se_socktype = SOCK_DGRAM;
- else if (strcmp(arg, "rdm") == 0)
- sep->se_socktype = SOCK_RDM;
- else if (strcmp(arg, "seqpacket") == 0)
- sep->se_socktype = SOCK_SEQPACKET;
- else if (strcmp(arg, "raw") == 0)
- sep->se_socktype = SOCK_RAW;
- else
- sep->se_socktype = -1;
- sep->se_proto = copyofstr(skip(&cp));
- arg = skip(&cp);
- sep->se_wait = strcmp(arg, "wait") == 0;
- sep->se_user = copyofstr(skip(&cp));
- sep->se_server = copyofstr(skip(&cp));
- if (strcmp(sep->se_server, "internal") == 0) {
- register struct biltin *bi;
-
- for (bi = biltins; bi->bi_service; bi++)
- if (bi->bi_socktype == sep->se_socktype
- && strcmp(bi->bi_service, sep->se_service) == 0)
- break;
- if (bi->bi_service == 0) {
- syslog(LOG_ERR, "internal service %s unknown\n", sep->se_service);
- goto more;
- }
- sep->se_bi = bi;
- sep->se_wait = bi->bi_wait;
- } else
- sep->se_bi = NULL;
- argc = 0;
- for (arg = skip(&cp); cp; arg = skip(&cp))
- if (argc < MAXARGV)
- sep->se_argv[argc++] = copyofstr(arg);
- while (argc <= MAXARGV)
- sep->se_argv[argc++] = NULL;
- return (sep);
-}
-
-freeconfig(cp)
- register struct servtab *cp;
-{
- int i;
-
- if (cp->se_service)
- free(cp->se_service);
- if (cp->se_proto)
- free(cp->se_proto);
- if (cp->se_user)
- free(cp->se_user);
- if (cp->se_server)
- free(cp->se_server);
- for (i = 0; i < MAXARGV; i++)
- if (cp->se_argv[i])
- free(cp->se_argv[i]);
-}
-
-char *
-skip(cpp)
- char **cpp;
-{
- register char *cp = *cpp;
- char *start;
-
- again:
- while (*cp == ' ' || *cp == '\t')
- cp++;
- if (*cp == '\0') {
- char c;
-
- c = getc(fconfig);
- (void)ungetc(c, fconfig);
- if (c == ' ' || c == '\t')
- if (cp = nextline(fconfig))
- goto again;
- *cpp = NULL;
- return (NULL);
- }
- start = cp;
- while (*cp && *cp != ' ' && *cp != '\t')
- cp++;
- if (*cp != '\0')
- *cp++ = '\0';
- *cpp = cp;
- return (start);
-}
-
-char *
-nextline(fd)
- FILE *fd;
-{
- char *cp;
-
- if (fgets(line, sizeof(line), fd) == NULL)
- return (NULL);
- cp = strchr(line, '\n');
- if (cp)
- *cp = '\0';
- return (line);
-}
-
-char *
-copyofstr(cp)
- const char *cp;
-{
- char *new;
-
- if (cp == NULL)
- cp = "";
- new = malloc((unsigned)(strlen(cp) + 1));
- if (new == NULL) {
- syslog(LOG_ERR, "Out of memory.");
- exit(-1);
- }
- (void)strcpy(new, cp);
- return (new);
-}
-
-setproctitle(a, s)
- char *a;
- int s;
-{
- int size;
- register char *cp;
- struct sockaddr_in sin;
- char buf[80];
-
- cp = Argv[0];
- size = sizeof(sin);
- if (getpeername(s, (struct sockaddr *)&sin, &size) == 0)
- (void)sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr));
- else
- (void)sprintf(buf, "-%s", a);
- strncpy(cp, buf, LastArg - cp);
- cp += strlen(cp);
- while (cp < LastArg)
- *cp++ = ' ';
-}
-
-/*
- * Internet services provided internally by inetd:
- */
-
-/* ARGSUSED */
-echo_stream(s, sep) /* Echo service -- echo data back */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZ];
- int i;
-
- setproctitle(sep->se_service, s);
- while ((i = read(s, buffer, sizeof(buffer))) > 0
- && write(s, buffer, i) > 0);
- exit(0);
-}
-
-/* ARGSUSED */
-echo_dg(s, sep) /* Echo service -- echo data back */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZ];
- int i, size;
- struct sockaddr sa;
-
- size = sizeof(sa);
- if ((i = recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size)) < 0)
- return;
- (void)sendto(s, buffer, i, 0, &sa, sizeof(sa));
-}
-
-/* ARGSUSED */
-discard_stream(s, sep) /* Discard service -- ignore data */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZ];
-
- setproctitle(sep->se_service, s);
- while (1) {
- while (read(s, buffer, sizeof(buffer)) > 0);
- if (errno != EINTR)
- break;
- }
- exit(0);
-}
-
-/* ARGSUSED */
-discard_dg(s, sep) /* Discard service -- ignore data */
- int s;
- struct servtab *sep;
-{
- char buffer[BUFSIZ];
-
- (void)read(s, buffer, sizeof(buffer));
-}
-
-#define LINESIZ 72
-char ring[128];
-char *endring;
-
-initring()
-{
- register int i;
-
- endring = ring;
-
- for (i = 0; i <= 128; ++i)
- if (isprint(i))
- *endring++ = i;
-}
-
-/* ARGSUSED */
-chargen_stream(s, sep) /* Character generator */
- int s;
- struct servtab *sep;
-{
- register char *rs;
- int len;
- char text[LINESIZ + 2];
-
- setproctitle(sep->se_service, s);
-
- if (!endring) {
- initring();
- rs = ring;
- }
-
- text[LINESIZ] = '\r';
- text[LINESIZ + 1] = '\n';
- for (rs = ring;;) {
- if ((len = endring - rs) >= LINESIZ)
- memcpy(text, rs, LINESIZ);
- else {
- memcpy(text, rs, len);
- memcpy(text + len, ring, LINESIZ - len);
- }
- if (++rs == endring)
- rs = ring;
- if (write(s, text, sizeof(text)) != sizeof(text))
- break;
- }
- exit(0);
-}
-
-/* ARGSUSED */
-chargen_dg(s, sep) /* Character generator */
- int s;
- struct servtab *sep;
-{
- struct sockaddr sa;
- static char *rs;
- int len, size;
- char text[LINESIZ + 2];
-
- if (endring == 0) {
- initring();
- rs = ring;
- }
-
- size = sizeof(sa);
- if (recvfrom(s, text, sizeof(text), 0, &sa, &size) < 0)
- return;
-
- if ((len = endring - rs) >= LINESIZ)
- memcpy(text, rs, LINESIZ);
- else {
- memcpy(text, rs, len);
- memcpy(text + len, ring, LINESIZ - len);
- }
- if (++rs == endring)
- rs = ring;
- text[LINESIZ] = '\r';
- text[LINESIZ + 1] = '\n';
- (void)sendto(s, text, sizeof(text), 0, &sa, sizeof(sa));
-}
-
-/*
- * Return a machine readable date and time, in the form of the
- * number of seconds since midnight, Jan 1, 1900. Since gettimeofday
- * returns the number of seconds since midnight, Jan 1, 1970,
- * we must add 2208988800 seconds to this figure to make up for
- * some seventy years Bell Labs was asleep.
- */
-
-afs_int32
-machtime()
-{
- struct timeval tv;
-
- if (gettimeofday(&tv, NULL) < 0) {
- fprintf(stderr, "Unable to get time of day\n");
- return (0L);
- }
- return (htonl((afs_int32) tv.tv_sec + 2208988800U));
-}
-
-/* ARGSUSED */
-machtime_stream(s, sep)
- int s;
- struct servtab *sep;
-{
- afs_int32 result;
-
- result = machtime();
- (void)write(s, (char *)&result, sizeof(result));
-}
-
-/* ARGSUSED */
-machtime_dg(s, sep)
- int s;
- struct servtab *sep;
-{
- afs_int32 result;
- struct sockaddr sa;
- int size;
-
- size = sizeof(sa);
- if (recvfrom(s, (char *)&result, sizeof(result), 0, &sa, &size) < 0)
- return;
- result = machtime();
- (void)sendto(s, (char *)&result, sizeof(result), 0, &sa, sizeof(sa));
-}
-
-/* ARGSUSED */
-daytime_stream(s, sep) /* Return human-readable time of day */
- int s;
- struct servtab *sep;
-{
- char buffer[256];
- time_t clock;
-
- clock = time((time_t *) 0);
-
- (void)sprintf(buffer, "%.24s\r\n", ctime(&clock));
- (void)write(s, buffer, strlen(buffer));
-}
-
-/* ARGSUSED */
-daytime_dg(s, sep) /* Return human-readable time of day */
- int s;
- struct servtab *sep;
-{
- char buffer[256];
- time_t clock;
- struct sockaddr sa;
- int size;
-
- clock = time((time_t *) 0);
-
- size = sizeof(sa);
- if (recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size) < 0)
- return;
- (void)sprintf(buffer, "%.24s\r\n", ctime(&clock));
- (void)sendto(s, buffer, strlen(buffer), 0, &sa, sizeof(sa));
-}
-
-/*
- * print_service:
- * Dump relevant information to stderr
- */
-print_service(action, sep)
- char *action;
- struct servtab *sep;
-{
- fprintf(stderr,
- "%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",
- action, sep->se_service, sep->se_proto, sep->se_wait,
- sep->se_user, (int)sep->se_bi, sep->se_server);
-}
-
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-/*
- * This program is a front-end for the various remote access programs
- * (e.g. rsh, rcp, rlogin, ftp) to allow for weak remote authentication.
- * It will be used by a call to a well-known restricted tcp port; if
- * there is a service on that port, we will attempt authentication.
- *
- * Note, this only affects the Kerberos portion of the authentication;
- * the program still requires its existing authentication (although it
- * seems reasonable to change this in the future.)
- *
- * The advantage to this scheme (rather than modifying each program to
- * incorporate this authentication scheme) is it allows us to modify
- * the authentication mechanism without requiring additonal code
- * changes to the other programs.
- *
- * Current format of authentication packet:
- *
- * (1) User;
- * (2) Service;
- * (3) Token length (null terminated);
- * (4) Token (not null terminated).
- *
- * The code to add/delete to the AFS ticket cache is taken from the
- * authentication library.
- */
-
-/*
- * routine to do the actual authentication. At this time, it is
- * very simple -- the remote end passes a token length and a token.
- *
- * This routine returns the name of the requested service.
- */
-
-#define gettime(tl) do { struct timezone tzp; struct timeval tv; \
- gettimeofday(&tv,&tzp); tl = tv.tv_sec; } while(0)
-#define RAUTH_TOKENLIFE (60 * 60 * 2) /* 2 hours */
-
-#define NOPAG 0xffffffff
-int
-get_pag_from_groups(g0, g1)
- afs_uint32 g0, g1;
-{
- afs_uint32 h, l, result;
-
- g0 -= 0x3f00;
- g1 -= 0x3f00;
- if (g0 < 0xc000 && g1 < 0xc000) {
- l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
- h = (g0 >> 14);
- h = (g1 >> 14) + h + h + h;
- result = ((h << 28) | l);
- /* Additional testing */
- if (((result >> 24) & 0xff) == 'A')
- return result;
- else
- return NOPAG;
- }
- return NOPAG;
-}
-
-auth_stream(s, sepent)
- int s;
- struct servtab *sepent;
-{
- char service[100], remoteName[64];
- struct sockaddr_in from;
- int fromlen;
- int code;
- struct afsconf_dir *tdir;
- struct ktc_principal tserver, tclient;
- struct ktc_token token;
- register struct servtab *sep;
-
- /*
- * First, obtain information on remote end of connection.
- */
- if (debug)
- fprintf(stderr, "auth_stream: entered\n");
-#ifndef AFS_SUN5_ENV
- if (getpeername(s, &from, &fromlen) < 0) {
- syslog(LOG_ERR, "getpeername failed");
- if (debug)
- fprintf(stderr, "auth_stream: getpeername failed\n");
- exit(1);
- }
-#endif
- if (intoken(s, &token, service, remoteName) != 0) {
- syslog(LOG_ERR, "invalid remote authentication");
- if (debug)
- fprintf(stderr, "auth_stream: invalid remote authentication\n");
- exit(1);
- }
- /* lookup the name of the local cell */
-
- if (debug)
- fprintf(stderr, "auth_stream: look up local cell name\n");
-
- tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
- if (!tdir) {
- syslog(LOG_NOTICE, "Can't open dir %s\n", AFSDIR_CLIENT_ETC_DIRPATH);
- if (debug)
- fprintf(stderr, "Can't open dir %s\n", AFSDIR_CLIENT_ETC_DIRPATH);
- exit(1);
- }
- /* done with configuration stuff now */
- afsconf_Close(tdir);
- /* set ticket in local cell */
- strcpy(tserver.cell, remoteName);
- strcpy(tserver.name, "afs");
- tclient = tserver;
- /* now, set the token */
-
- if (debug) {
- fprintf(stderr,
- "token information: service is %s\ntoken length is %d\n",
- service, token.ticketLen);
- fprintf(stderr, "token is %s\n", token.ticket);
- fprintf(stderr, "cell name is %s\n", remoteName);
- }
- setpag();
- afs_didsetpag = 1;
- code = ktc_SetToken(&tserver, &token, &tclient, 0);
- if (code) {
- write(s, "0", 1); /* say "no" to other side */
- printf("Login incorrect.(%d)", code);
- syslog(LOG_ERR, "Invalid token from %s", inet_ntoa(from.sin_addr));
- exit(1);
- }
- write(s, "1", 1); /* say "yes" to other side */
-
- if (debug)
- fprintf(stderr, "Finished authentication code\n");
- for (sep = servtab; sep; sep = sep->se_next)
- if (strcmp(sep->se_service, service) == 0) {
- int dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
- int tmpint;
-
- if (dofork) {
- for (tmpint = getdtablesize(); --tmpint > 2;)
- if (tmpint != s)
- close(tmpint);
- }
- if (sep->se_bi) {
- (*sep->se_bi->bi_fn) (s, sep);
- } else {
- register struct passwd *pwd;
- struct passwd *getpwnam();
- char buf[BUFSIZ];
-
- if ((pwd = getpwnam(sep->se_user)) == NULL) {
- syslog(LOG_ERR, "getpwnam: %s: No such user",
- sep->se_user);
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof(buf), 0);
- abort();
- _exit(1);
- }
- if (pwd->pw_uid) {
- (void)setgid((gid_t) pwd->pw_gid);
- initgroups(pwd->pw_name, pwd->pw_gid);
- (void)setuid((uid_t) pwd->pw_uid);
- }
- dup2(s, 0);
- close(s);
- dup2(0, 1);
- if (debug)
- fprintf(stderr, "going to exec program %s(errno = %d)\n",
- sep->se_server, errno);
- errno = 0;
- debug = 0;
- dup2(0, 2);
-
- if (!afs_didsetpag && (!strcmp(sep->se_service, "login")
- || !strcmp(sep->se_service, "shell"))) {
- setpag(); /* to disassociate it from current group... */
- }
- execv(sep->se_server, sep->se_argv);
- abort();
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof(buf), 0);
- syslog(LOG_ERR, "execv %s: %m", sep->se_server);
- _exit(1);
- }
- }
- fprintf(stderr, "service not available\n");
- syslog(LOG_ERR, "auth_stream: invalid service requested %s\n", service);
- exit(0);
-}
-
-
-auth_dg()
-{
- syslog(LOG_NOTICE,
- "datagram remote authentication requested, not supported");
-}
-
-/*
- * intoken:
- *
- * This routine accepts a token on the specified file handle;
- * The input format for a token is:
- *
- * Field # Contents description
- * (0) Service Name char[]
- * (1) Version # unsigned integer (< 2^32)
- * (2) cellName char[]
- * (3) startTime unsigned afs_int32 (< 2^32)
- * (4) endTime unsigned afs_int32 (< 2^32)
- * (5) sessionKey char[8]
- * (6) kvno short (< 2^16)
- * (7) ticketLen unsigned integer (< 2^32)
- * (8) ticket char[MAXKTCTICKETLEN]
- *
- * Each field is comma separated; the last is variable length. The
- * converted token is placed into the token structure pointed to by
- * the variable "token".
- */
-
-intoken(s, token, svc, cell)
- int s;
- struct ktc_token *token;
- char *svc, *cell;
-{
- char buf[1024], *bp;
- int count;
- unsigned index, version;
-
- if (debug)
- fprintf(stderr, "intoken: entered\n");
-
- if ((count = recv(s, buf, sizeof buf, 0)) == -1) {
- if (debug) {
- fprintf(stderr, "error on fd %d\n", s);
- perror("intoken recv");
- }
- return (-1);
- }
-
- /* (0) Service Name */
- for (index = 0; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr, "overran buffer while searching for svc name\n");
- return (-1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr,
- "Didn't stop on a comma, searching for svc name\n");
- return (-1);
- }
-
- buf[index] = '\0';
-
- strcpy(svc, buf);
-
- /* (1) Version # */
-
- bp = buf + index + 1;
-
- for (; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr, "overran buffer while searching for version #\n");
- return (-1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr,
- "Didn't stop on a comma, searching for version #\n");
- return (-1);
- }
-
- buf[index] = '\0';
-
- sscanf(bp, "%u", &version);
-
- if (version > 2) {
- if (debug)
- fprintf(stderr, "Incompatible (newer) version encountered: %d\n",
- version);
- return (-1);
- }
-
- if (version > 1) {
- /* we didn't include cell name in prior versions */
- bp = buf + index + 1;
-
- for (index = 0; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr, "overran buffer while searching for cell\n");
- return (-1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr,
- "Didn't stop on a comma, searching for cell\n");
- return (-1);
- }
- buf[index] = '\0';
- strcpy(cell, bp);
- }
-
- /* (2) startTime */
-
- bp = buf + index + 1;
-
- for (; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr,
- "overran buffer while searching for startTime #\n");
- exit(1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr,
- "Didn't stop on a comma, searching for startTime #\n");
- return (-1);
- }
-
- buf[index] = '\0';
-
- sscanf(bp, "%u", &token->startTime);
-
- /* (3) endTime */
-
- bp = buf + index + 1;
-
- for (; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr, "overran buffer while searching for endTime #\n");
- return (-1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr,
- "Didn't stop on a comma, searching for endTime #\n");
- return (-1);
- }
-
- buf[index] = '\0';
-
- sscanf(bp, "%u", &token->endTime);
-
- /* (4) sessionKey */
-
- bp = buf + index + 1;
- memcpy(&token->sessionKey, bp, 8);
-
- /* (5) kvno */
-
- bp += 8;
- for (index += 9; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr, "overran buffer while searching for kvno\n");
- return (-1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr, "Didn't stop on a comma, searching for kvno\n");
- return (-1);
- }
-
- buf[index] = '\0';
-
- /* kvno is actually a short, so insist that it scan a short */
-
- sscanf(bp, "%hu", &token->kvno);
-
- /* (6) ticketLen */
-
- bp = buf + index + 1;
-
- for (; index < count && buf[index] != ','; index++);
-
- if (index == count) {
- if (debug)
- fprintf(stderr, "overran buffer while searching for ticketLen\n");
- return (-1);
- }
-
- if (buf[index] != ',') {
- if (debug)
- fprintf(stderr,
- "Didn't stop on a comma, searching for ticketLen\n");
- return (-1);
- }
-
- buf[index] = '\0';
-
- sscanf(bp, "%u", &token->ticketLen);
-
- /* (7) ticketLen */
-
- bp = buf + index + 1;
-
- if (index + token->ticketLen > count) {
- if (debug)
- fprintf(stderr, "overran buffer while copying ticket\n");
- return (-1);
- }
-
- memcpy(token->ticket, bp, token->ticketLen);
-
- return 0;
-}
-
-#ifdef AFS_HPUX_ENV
-resetsignals()
-{
- struct sigaction act, oact;
- int sign;
-
- memset(&act, '\0', sizeof(act));
- act.sa_handler = SIG_DFL;
- for (sign = 1; sign < NSIG; sign++)
- sigaction(sign, &act, &oact);
-}
-#endif
+++ /dev/null
-#
-# AFS version of Internet server configuration database
-#
-ta-rauth stream tcp nowait root internal ta-rauth
-shell stream tcp nowait root /usr/sbin/rshd rshd
-login stream tcp nowait root /usr/sbin/rlogind.afs rlogind.afs
+++ /dev/null
-#
-# AFS version of Internet server configuration database
-#
-# The "shell" line should be commented out in the vendor inetd.conf.
-#
-ta-rauth stream tcp nowait root internal ta-rauth
-shell stream tcp nowait root /usr/sbin/rshd rshd
+++ /dev/null
-#
-# AFS version of Internet server configuration database
-#
-shell stream tcp nowait root /usr/etc/rshd rshd
-login stream tcp nowait root /usr/etc/rlogind.afs rlogind.afs
-ta-rauth stream tcp nowait root internal ta-rauth
+++ /dev/null
-#
-# AFS version of Internet server configuration database
-#
-ta-rauth stream tcp nowait root internal ta-rauth
-shell stream tcp nowait root /usr/sbin/in.rshd in.rshd
-login stream tcp nowait root /usr/sbin/in.rlogind in.rlogind
+++ /dev/null
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/types.h>
-#include <stdio.h>
-
-extern char *malloc(), *realloc(), *_findenv();
-/*
- * setenv --
- * Set the value of the environmental variable "name" to be
- * "value". If rewrite is set, replace any current value.
- */
-setenv(name, value, rewrite)
- register char *name, *value;
- int rewrite;
-{
- extern char **environ;
- static int alloced; /* if allocated space before */
- register char *C;
- int l_value, offset;
-
- if (*value == '=') /* no `=' in value */
- ++value;
- l_value = strlen(value);
- if ((C = _findenv(name, &offset))) { /* find if already exists */
- if (!rewrite)
- return (0);
- if (strlen(C) >= l_value) { /* old larger; copy over */
- while (*C++ = *value++);
- return (0);
- }
- } else { /* create new slot */
- register int cnt;
- register char **P;
-
- for (P = environ, cnt = 0; *P; ++P, ++cnt);
- if (alloced) { /* just increase size */
- environ =
- (char **)realloc((char *)environ,
- (u_int) (sizeof(char *) * (cnt + 2)));
- if (!environ)
- return (-1);
- } else { /* get new space */
- alloced = 1; /* copy old entries into it */
- P = (char **)malloc((u_int) (sizeof(char *) * (cnt + 2)));
- if (!P)
- return (-1);
- memcpy(P, environ, cnt * sizeof(char *));
- environ = P;
- }
- environ[cnt + 1] = NULL;
- offset = cnt;
- }
- for (C = name; *C && *C != '='; ++C); /* no `=' in name */
- if (!(environ[offset] = /* name + `=' + value */
- malloc((u_int) ((int)(C - name) + l_value + 2))))
- return (-1);
- for (C = environ[offset]; (*C = *name++) && *C != '='; ++C);
- for (*C++ = '='; *C++ = *value++;);
- return (0);
-}
-
-/*
- * unsetenv(name) --
- * Delete environmental variable "name".
- */
-void
-unsetenv(name)
- char *name;
-{
- extern char **environ;
- register char **P;
- int offset;
-
- while (_findenv(name, &offset)) /* if set multiple times */
- for (P = &environ[offset];; ++P)
- if (!(*P = *(P + 1)))
- break;
-}
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-/*
- * This code is used for application programs who want to transfer a
- * token from the local system to the remote system.
- */
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-#include <strings.h>
-#if defined(AIX)
-#include <sys/syslog.h>
-#else /* defined(AIX) */
-#include <syslog.h>
-#endif /* defined(AIX) */
-#include <errno.h>
-#include <pwd.h>
-#include <afs/afsutil.h>
-
-
-#ifndef RAUTH_PORT
-#define RAUTH_PORT (601)
-#endif
-
- /* ta_rauth provides a single entry point into the remote */
- /* authentication scheme. This allows us to simply pass the service */
- /* name; this routine will in turn obtain whatever remote */
- /* authentication information necessary and will negotiate with the */
- /* remote connection. There are three possible return codes: */
- /* (0) There is no remote authentication system; continue without */
- /* any authentication. */
- /* (1) Remote authentication was negotiated successfully */
- /* (-1) Remote authentication failed (but did exist) */
- /* (-2) The call could not complete due to internal failure */
- /* (-3) The remote connection failed */
- /* Note that raddr is in *network* byte order! */
-
-int ta_debug = 0;
-
-int
-ta_rauth(s, svc_name, raddr)
- int s;
- char *svc_name;
- struct in_addr raddr;
-{
- char localName[64];
- int code;
- struct afsconf_dir *tdir;
- struct ktc_principal tserver;
- struct ktc_token token;
- struct sockaddr_in name;
-
- /* extract the token */
-
- tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
- if (!tdir) {
- if (ta_debug) {
- syslog(LOG_ERR, "ta_rauth: afsconf_Open failed\n");
- }
- return (-2);
- }
- code = afsconf_GetLocalCell(tdir, localName, sizeof(localName));
- if (code) {
- if (ta_debug) {
- syslog(LOG_ERR, "ta_rauth: afsconf_GetLocalCell failed\n");
- }
- return (-2);
- }
- afsconf_Close(tdir);
-
- strcpy(tserver.cell, localName);
- strcpy(tserver.name, "afs");
-
- code = ktc_GetToken(&tserver, &token, sizeof(token), NULL);
- if (code) {
- syslog(LOG_WARNING, "ta_rauth: no tokens available");
- return 0; /* try port without authentication */
- }
-
- name.sin_family = AF_INET;
- name.sin_port = htons(RAUTH_PORT);
- name.sin_addr = raddr;
- if (connect(s, (struct sockaddr *)&name, sizeof(name)) == -1) {
- extern int errno;
-
- if (ta_debug) {
- syslog(LOG_ERR,
- "ta_rauth(%s): connect call to (%d:%d) failed=%d\n",
- svc_name, raddr.s_addr, htons(RAUTH_PORT), errno);
- perror("socket");
- }
- switch (errno) {
-#ifdef AFS_AIX_ENV
- /* On conn failure aix doesn't return any error! */
- case 0:
-#endif
- case ECONNREFUSED:
- return 0;
- case ETIMEDOUT:
- case ENETUNREACH:
- return -3;
- default:
- return -2;
- }
- }
-
- if (outtoken(s, &token, svc_name, localName) == 0) {
- char result;
-
- if (read(s, &result, 1) != 1) {
- syslog(LOG_ERR, "Invalid return from remote authenticator\n");
- exit(1);
- }
- if (result == '0') /* remote authentication denied */
- return -1;
- else /* remote authentication allowed */
- return 1;
- }
-
- return (-2);
-}
-
-/*
- * outtoken:
- *
- * This routine writes a token on the specified file handle;
- * The output format for a token is:
- *
- * Field # Contents description
- * (0) Service requested char[]
- * (1) Version # unsigned integer (< 2^32)
- * (2) startTime unsigned afs_int32 (< 2^32)
- * (3) endTime unsigned afs_int32 (< 2^32)
- * (4) sessionKey char[8]
- * (5) kvno short (< 2^16)
- * (6) ticketLen unsigned integer (< 2^32)
- * (7) ticket char[MAXKTCTICKETLEN]
- *
- * All fields are comma separated except (4) and (5) because (4) is fixed
- * length; since field (7) is variable length, it is presumed to
- * begin after the ',' and to be ticketLen afs_int32.
- */
-outtoken(s, token, svc, localName)
- int s;
- struct ktc_token *token;
- char *svc, *localName;
-{
- char buf[1024], *bp;
- int count;
-
- /* (0) - (3) */
- sprintf(buf, "%s,%d,%s,%ld,%ld,", svc, 2, localName, token->startTime,
- token->endTime);
-
- /* (4) sessionKey */
- bp = buf + strlen(buf);
- memcpy(bp, &token->sessionKey, 8);
- bp += 8;
-
- /* (5) - (6) */
- sprintf(bp, "%u,%u,", token->kvno, token->ticketLen);
-
- /* (7) ticket */
- bp += strlen(bp);
- memcpy(bp, token->ticket, token->ticketLen);
- bp += token->ticketLen;
-
- if ((count = write(s, buf, (int)(bp - buf))) == -1) {
- perror("outtoken write");
- exit(1);
- }
- if (ta_debug) {
- fprintf(stderr, "sent buffer %s\n", buf);
- }
- return 0;
-}
+++ /dev/null
-AFS_component_version_number.c
-Makefile
+++ /dev/null
-# Copyright 2000, International Business Machines Corporation and others.
-# All Rights Reserved.
-#
-# This software has been released under the terms of the IBM Public
-# License. For details, see the LICENSE file in the top-level source
-# directory or online at http://www.openafs.org/dl/license10.html
-
-srcdir=@srcdir@
-include @TOP_OBJDIR@/src/config/Makefile.config
-
-
-INCPATH=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR}
-BINDIR=/usr/local/etc
-LINKDIR=/etc
-LIBS=${TOP_LIBDIR}/util.a
-
-VERS=3.4
-
-#CC=gcc -g -W -Wall
-#afs#CC=cc -g -W
-
-#afs#INSTALL= install -c
-
-#
-# FEATURES include:
-# DEBUG - include DEBUG code
-# BROADCAST_NTP - experimental support for broadcast NTP
-# XADJTIME2 - experimental support for second-order clock adjustment
-# system call.
-# SETTICKADJ - attempt to modify kernel's `tickadj' variable at run time.
-# REFCLOCK - define if you have a reference clock attached to your
-# machine. (untested by UMD)
-# PSTI - define along with REFCLOCK if you have a PSTI clock attached
-# that you'd like to use a a reference clock.
-# XTAL=0 - for line freq clock, or
-# XTAL=1 for crystal controlled clock (default)
-# LOG_NTP=foo - to change the syslog facility. You could specify
-# something like -DLOG_NTP=LOG_LOCAL3 to log into the
-# LOG_LOCAL3 syslog facility
-# NOSWAP - allow use of plock() to prevent swapping
-#
-
-#FEATURES= -DBROADCAST_NTP -DSETTICKADJ -DDEBUG
-#FEATURES= -DSETTICKADJ -DDEBUG -DREFCLOCK -DPSTI
-#afs#FEATURES= -DSETTICKADJ -DDEBUG -DREFCLOCK
-#afs# # SETTICKADJ is set in ntpd.c on SUNs.
-FEATURES= -DDEBUG -DREFCLOCK
-
-# for afs
-DEFINES= -DGENERIC_UNS_BUG -DSUN_FLT_BUG
-
-# for 4.3 BSD
-#afs#DEFINES=
-
-# for Sun
-#DEFINES= -DSUN_FLT_BUG
-
-# for Ultrix 2.0/2.2
-# don't forget to fix the broken definition of inet_addr in netdb.h
-# it should be declared as a u_long not a in_addr (the doc is wrong also)
-# VAX_COMPILER_FLT_BUG is defined for pcc which doesn't know how to
-# convert an unsigned long into a float/double
-#DEFINES= -DVAX_COMPILER_FLT_BUG -DNOSWAP
-
-#
-# for a NeXT system, define these pre-processor symbols.
-#DEFINES=-DSUN_FLT_BUG -DGENERIC_UNS_BUG
-
-CFLAGS= -O ${DEFINES} ${FEATURES} ${INCPATH} ${XCFLAGS}
-LDFLAGS= ${XLDFLAGS}
-#
-# Header files
-#
-HDRS= ntp.h patchlevel.h
-
-# Source files
-#
-NTPDSRC= ntpd.c ntpsubs.c ntp_proto.c ntp_sock.c ntp_adjust.c read_local.c \
- read_psti.c
-SRCS= ntp.c ntpdc.c test.c ${NTPDSRC}
-
-# Object files
-#
-NTPDOBJ= ntpd.o ntpsubs.o ntp_proto.o ntp_sock.o ntp_adjust.o read_local.o \
- read_psti.o
-OBJS= ntp.o ntpdc.o test.o ${NTPDOBJ}
-
-
-DIST= README Makefile man ${SRCS} ${HDRS} ntp.conf test.c extract.pl stat.pl
-PROGS= ntp ntpd ntpdc ntest
-
-include ../config/Makefile.version
-
-ntp.o: AFS_component_version_number.c
-ntpd.o: AFS_component_version_number.c
-ntpdc.o: AFS_component_version_number.c
-read_psti.o: AFS_component_version_number.c
-
-#all: ${PROGS} runntp
-# -@./ntest
-
-ntp: ntp.o ntpsubs.o
- ${CC} ${LDFLAGS} -o ntp ntp.o ntpsubs.o ${LIBS} ${XLIBS} ${XLIBELFA}
-
-ntpd: ${NTPDOBJ}
- case ${SYS_NAME} in \
- sgi_*) \
- ${CC} ${LDFLAGS} -o ntpd ${NTPDOBJ} ${LIBS} -lelf ;; \
- *) \
- ${CC} ${LDFLAGS} -o ntpd ${NTPDOBJ} ${LIBS} ${XLIBS} ${XLIBELFA} ;; \
- esac
-
-
-ntpdc: ntpdc.o
- ${CC} ${LDFLAGS} -o ntpdc ntpdc.o ${LIBS} ${XLIBS} ${XLIBELFA}
-
-ntest: test.o ntpsubs.o
- ${CC} ${LDFLAGS} -o ntest test.o ntpsubs.o ${LIBS} ${XLIBS} ${XLIBELFA}
- ./ntest
-
-sock_test: ntp_sock.c AFS_component_version_number.o
- ${CC} ${LDFLAGS} -DTEST -o sock_test ntp_sock.c ${LIBS} ${XLIBS} ${XLIBELFA}
-
-${OBJS}: ntp.h # Makefile
-ntpd.o: patchlevel.h
-
-# for afs
-
-all: AFS_component_version_number.c ntest ntpd ntp ntpdc runntp
-
-AFSLIBS=${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a
-
-runntp.o: runntp.c ${TOP_INCDIR}/afs/cellconfig.h AFS_component_version_number.c
- ${CC} ${CFLAGS} -I${TOP_INCDIR} -c runntp.c ${AFSLIBS} ${XLIBS}
-
-runntp: runntp.o ${AFSLIBS}
- ${CC} ${LDFLAGS} -o runntp runntp.o ${AFSLIBS} ${XLIBS}
-
-install: ${DESTDIR}${afssrvlibexecdir}/ntpd ${DESTDIR}${afssrvsbindir}/ntpdc ${DESTDIR}${sbindir}/ntp ${DESTDIR}${sbindir}/ntpdc ${DESTDIR}${afssrvlibexecdir}/runntp
-
-#
-# If you don't want a symlink to the daemon, comment out the next line
-# make ${MFLAGS} DESTDIR=${DESTDIR} install-link
-
-install-man:
- cd man; $(MAKE) ${MFLAGS} DESTDIR=${DESTDIR} install
-
-install-link:
- $(RM) -f ${BINDIR}/${LINKDIR}/ntpd
- ln -s ${BINDIR}/ntpd ${DESTDIR}/${LINKDIR}/ntpd
-
-print:
- enscript -2r -p - Makefile ${HDRS} ${SRCS} | qpr -q lps40
-
-clean:
- @rm -f *.o *~ core ${PROGS} ntp.tar ntest sock_test AFS_component_version_number.c
-
-dist: ntp.tar.Z
- mv ntp.tar.Z /usr/ftp/pub/ntp.${VERS}/ntp.tar.Z
-
-test-dist: ntp.tar.Z
- mv ntp.tar.Z /usr/ftp/pub/ntp.${VERS}/ntp-test.tar.Z
-
-ntp.tar.Z: ${DIST}
- $(RM) -f ntp.tar ntp.tar.Z
- tar cf ntp.tar ${DIST}
- compress ntp.tar
-
-
-depend:
- mkdep $(CFLAGS) $(SRCS)
-
-${DEST}/root.server/usr/afs/bin/ntpd: ntpd
- ${INSTALL} $? $@
-
-${DESTDIR}${afssrvlibexecdir}/ntpd: ntpd
- ${INSTALL} $? $@
-
-
-${DEST}/root.server/usr/afs/bin/ntpdc: ntpdc
- ${INSTALL} $? $@
-
-${DESTDIR}${afssrvsbindir}/ntpdc: ntpdc
- ${INSTALL} $? $@
-
-
-${DEST}/etc/ntp: ntp
- ${INSTALL} $? $@
-
-${DESTDIR}${sbindir}/ntp: ntp
- ${INSTALL} $? $@
-
-
-${DEST}/etc/ntpdc: ntpdc
- ${INSTALL} $? $@
-
-${DESTDIR}${sbindir}/ntpdc: ntpdc
- ${INSTALL} $? $@
-
-
-${DEST}/root.server/usr/afs/bin/runntp: runntp
- ${INSTALL} $? $@
-
-${DESTDIR}${afssrvlibexecdir}/runntp: runntp
- ${INSTALL} $? $@
-
-
-dest: ${DEST}/root.server/usr/afs/bin/ntpd ${DEST}/root.server/usr/afs/bin/ntpdc ${DEST}/etc/ntp ${DEST}/etc/ntpdc ${DEST}/root.server/usr/afs/bin/runntp
-
-# DO NOT DELETE THIS LINE -- mkdep uses it.
-# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
-# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+++ /dev/null
-Copyright 2000, International Business Machines Corporation and others.
-All Rights Reserved.
-
-This software has been released under the terms of the IBM Public
-License. For details, see the LICENSE file in the top-level source
-directory or online at http://www.openafs.org/dl/license10.html
-
-README for UNIX NTP release $Date$ $Revision$
-
-
-
-NTP (Network Time Protocol) Daemons
-
- There are three programs in the NTP distribution:
- ntp - simple query program used for single
- sample queries
-
- ntpd - A daemon that sets up peers and responds
- to queries. Ntpd does the clock trimming.
-
- ntpdc - program to query an ntpd. It was useful in
- checking the filters and cleaning the windows
-
-Installation:
-
- 1) Add an entry to /etc/services to define the ntp port.
-
- ntp 123/udp # network time protocol (exp)
-
- 2) Make a /etc/ntp.conf with the clocks you want to track.
- Please refer to the RFC's in the man directory, the man
- pages, and the clock.txt file to assist you in selecting
- clocks to peer with. The supplied ntp.conf is only a
- sample, and is not suitable for use.
-
-
- 3) Change the Makefile definitions to suit your environment.
- 4) make
- 5) make install
- 6) adb or remake kernel and change "tickadj"
- Recommended values for tickadj on various machines:
-
- VAX: 5
- Sun3: 10
- Sun4: 5
- NeXT: 7
-
- This step is optional; new algorithms will allow you to
- get by (with reduced accuracy) with the system supplied
- value of tickadj. For better preformence, you should
- change the value of tickadj. This can be done by making
- a new kernel or by compiling ntpd with SETTICKADJ defined,
- and having ntpd set it to the value you specify. This is
- clearly ugly.
-
- 7) Fire up ntpd in /etc/rc.local
-
-History:
-5/17/89
- Yet another preprocessor define for broken unsigned long to double
- conversions. Define GENERIC_UNS_BUG, and the unsigned long is shifted
- right one bit and cast to an int before conversion to a double. This
- seems to work much better.
-
- Preliminary support for NeXT systems. Be sure to define both
- GENERIC_UNS_BUG and SUN_FLT_BUG. The default value of tickadj in the
- kernel is too large so you'll have to adjust it by using the
- -t option and compiling with SETTICKADJ. I don't think you can use
- gdb on the running /dev/mem image. NOTE: don't even think of trying
- to run this on the 0.8 release of the system software. You will
- utterly and absolutely hang you system. Current testing is being
- done on the 0.9 release. So far, there seems to be some weirdness in
- the kernel which is attempting to sync to the clock to the internal
- clock chip every so ofter. So while it compiles and runs, it really
- doesn't work very well on the NeXT machine.
-
- Integration of the reference clock code
- has been done. To configure a reference clock, check the
- ntpd manual page.
-
-5/3/89
- The changes to the ntp_proto.c module for clockhopper suppression have
- been tweaked once more, ever so slightly to conform with the 21 April
- 1989 draft of the NTP spec. We won't switch peers if the current
- peer makes it into the final selection list, unless the first peer on
- the selection list is of a higher stratum than the current peer.
-
- The ntpd.c/hourly() function now saves the value of the drift
- compensation register to a file (/etc/ntp.drift by default). In fact,
- the last 5 hourly samples are written to the file, as well as how
- many hours the ntpd process has been running. Ntpd will also attempt
- to intialize the value of the drift compensation register from this
- file when it is started up. The hourly stats: log message has been
- augmented to log additional information.
-
-4/8/89
- Changes to the ntp_proto.c module to supress peer switching when the
- dispersion between the newly selected peer and the currently selected
- peer is "small." A new configuration option, NOSWAP, has been added
- for use on Ultrix systems which can lock the ntpd process in memory;
- very desirable for diskless workstations. peer.reach is now not
- cleared in the clear() procedure. The stat.pl perl script can now
- handle syslog records which span a month boundary correctly. We're
- getting real close to a "blessed" version now.
-
-3/29/89
- A few fixes, clean up of unused #defines in ntp.h. The receive()
- procedure is now table driven per the 26 March 1989 draft of the
- spec. If no terrible errors or bugs are found, this version
- will probably be packaged as a "blessed" working version before
- the next stage of major hacking.
-
-3/22/89
- A bunch of minor fixes here an there. The RCS header is being
- updated so that patches that are generated will apply; apparently
- the new version of RCS puts the Locked: status in the Header
-
- Minor fiddles to ntpd/ntpdc to eliminate some byte-sex dependencies.
- Changs to ntp_proto.c to fix an mis-interpretation in the packet
- procedure.
-
- The ntp program now uses connected UDP sockets to pick up ICMP
- generated errors.
-
- ntpdc will now select a value of tickadj if you don't specify one.
-
-3/17/89
- Another sort-of-working ntpd. There might still be something weird
- with the logical clock code; seems to be a little weird. Would
- really like your comments on this version.
-
- Note that the a version that supports the Precision Time WWV clock
- can be had via anonymous FTP from BITSY.MIT.EDU. The version there
- might lag the University of Maryland version.
-
-3/12/89
- A snapshot of a more-or-less working ntpd. There's been a few more
- bug fixes and changes due to the NTP spec being revised. A few more
- changes have been made to the latest NTP spec (11 March 1989 version)
- which have not yet been applied.
-
- A few problems areas: I currently observe some peer flapping between
- two clock which are both of very good quality (UMD1.UMD.EDU and
- TRUECHIMER.CSO.UIUC.EDU). Not quite sure why this is happening yet
- or if it is really a problem.
-
- There are quite a few "Dropping peer <foo>" messages in the syslog.
- Most of these are due to lower statum "transient" clocks peering with
- the local daemon. Need to find a way to supress the messages in
- the transmit procedure when we've got no intention of keeping a
- peer structure around for them.
-
- There are changes in the works to improve the reliability of the
- ntpdc program. The ntpd hooks are there now, and some work remains
- in the ntpdc program.
-
-
-3/7/89
- *** THIS IS A TEST RELEASE ***
-
- This version contain most of the new algorithms from the 6 March 1989
- draft of the NTP specification. It still operates, however, as
- Version 1, and does not support the authentication feature.
-
- The stratum 1 WWV clock code from Doug Kingston has not been tested or
- changed for this release. I would really like someone to change the
- interface to have the clock appear as just another peer.
-
- Quite a bit if clean-up and cosmetic changes were made in almost all
- of the modules. Note that the ntest program which tests certain
- arithmetic operations on you machine is automatically run by the
- Makefile. If it fail *for any reason*, stop right there and find
- out why. Until ntest works correctly, don't even bother with the
- rest of the code. Note that at least Ultrix has problems, and there
- is a define option in the makefile to accomodate the broken Ultrix
- pcc compiler. Recent version of GNU CC are known to work correctly
- on a VAX platform, and is in fact used for development. It is not
- necessary to use the GNU C compiler on you machine, however.
-
- The logical clock code in ntp_adjust.c has been changed to be more
- self-contained and independent from NTP proper. It has the tickadj
- round-off residual accumulating code, and attempts to implemenet the
- newest version of the NTP logical clock code. A large change here is
- that once an clock update has been passed to the logical clock, it will
- ignore further updated for 1<<CLOCK_UPDATE seconds. Note that the
- units for tick_adj have changed in this version. Eventually, a
- normalized version of this value will be written to a file for use
- on subsequent invocations.
-
- There has been no work in the area of supporting broadcast NTP. A
- bunch of bug fixes have been made to the ntp_proto.c module, including
- a significant one in the code which selects the clock; the dispersion
- computed before was incorrect and resulted in poor clock choices. This
- is probably the cause of having long "strings" of peers rather then
- all syncing to one clock.
-
- The ntpd will now actually delete peer entries when the hosts "go
- away." This will hopefully save some memory. The peer list is now
- doublely linked, so deletions can happen very efficiently.
-
- There is still a weirdness in there when interoperating with very old
- broken versions of ntpd. It manifests itself with peers being expunged
- and them coming back.
-
- Please beat on this version and let me know what bugs you find. I
- want to make another release, this one "blessed" until the Version 2
- one is ready.
-
-
-1/12/89
- *** THIS IS A TEST RELEASE ***
- There have been a bunch of bug fixes, and an attemtp to unify the
- the debug output and logging. There is still a problem with the
- verbose version of ntpdc; the offset values are clearly bogus.
-
- Danger: don't attempt to run ntpd on a NeXT machine. It provokes
- a bug in the OS which hangs the machine quite absolutely.
-
- There is some support for a statrum 1 clock in some code provided by
- Doug Kingston (dpk@morgan.com). I'm not really sure that its the
- ``right'' way to do it; I'd rather have the clock appear just like
- another peer, and have it selected as a reference, just like you'd
- select any other clock. In fact, by doing it that way with some other
- support, you could even have a seperate process take care of reading
- the clock, and talking to the main process with some UNIX domain
- sockets... Hmm..
-
-12/8/88
- *** THIS IS A TEST RELEASE ***
- Really. We have tested this code on a VAX platform, but not much of
- anything else. I would like to hear back about any bugs, but you
- should not treat this as a 'release' version.
-
- Very large number of changes and updates. Files have been reorganized
- with ntpd.c containing intialization and other very UNIX specific code,
- while the new file ntp_proto.c contains the bulk of the NTP code.
- This version of the UNIX NTP daemon was re-written and updated to
- conform with the revised NTP specification.
-
- For all of the mucking about with tickadj, you can now define
- SETTICKADJ in the Makefile, and specify the value of tickadj in
- /etc/ntp.conf. The ntpd will attempt to update `tickadj' using
- /dev/kmem. Yow!
-
- If possible, ntpd will attempt to discover the value of your kernel's
- `hz' variable, and set the value of `precison' automagically. If
- `precision' is specified in /etc/ntp.conf, it will override any
- automatic selection.
-
- Only hosts which are configured or mentioned in /etc/ntp.conf on a
- `peer', `server' or `passive' statement are elligable to be
- synchronized to. This solves the "ganging-up" problem, but is sorta
- ugly.
-
- The `peer' statement in /etc/ntp.conf works just as before; it sends
- packets with MODE=SYMMETRIC-ACTIVE to the remote host. The remote host
- might synchronize to you if appropriate. If reachability is lost,
- polling will continue.
-
- The new `server' statement in /etc/ntp.conf causes packets of MODE=
- CLIENT to be sent to the specified host. The remote host will *not*
- synchronize to you under any circumstances. If reachability is lost,
- polling will continue.
-
- The new `passive' statement in /etc/ntp.conf causes packets of
- MODE=SYMMETRIC-PASSIVE to be sent to the remote host *when the local
- host is polled*. If reachability is lost, then polling will cease
- until the remote host begins to the local host again.
-
- Note conditional compilation define in the makefile for
- VAX_COMPILER_FLT_BUG for old 4.2 and Ultrix 2.0/2.2/3.0 pcc compilers.
- There is a bug in the code generated to convert an unsigned long to a
- double. Previously, this code was always present, but it is now
- #ifdef'd. The 4.3BSD-tahoe and GNU CC (1.30 and 1.31 at least) are
- known to work correctly. If you don't know if your compiler
- performs this conversion correctly, try making and running the
- `ntest' program, and see if test3 passes or not.
-
- The format of the data sent between ntpd and the ntpdc programs has
- changed yet again. It is likely to change again before the final
- release of this version.
-
-7/30/88
- Added and updated manual entries contributed by Glenn Trewitt.
- (trewitt@miasma.stanford.edu)
-7/27/88
- Reorder peer list so configuted hosts are always first. This
- REALLY helps the faleticker code.
-
- Changed ntpdc to have a larger RECV socket buffer. This fixes
- the "only see 20 peers" problem. This is a side affect of using
- UDP for the status return.
-
-6/20/88
- Support for hosts with multiple interfaces. Minor updates to
- the ntpdc program; note that the format of the messages between
- the ntpd and ntpdc programs is different in this version than the
- last. You should update both ntpd and ntpdc at the same time.
-
- New file ``ntp_sock.c''. Tested with Ultrix 2.4 field test, and
- 4.3 BSD tahoe release. Debug level can be adjusted by sending
- SIGUSR1 to increase and SIGUSR2 to zero the debug level.
-
-5/17/88
- Changed peer structure alloactor to stop allocating a perm
- structure for non-peer relationships. This make the ntpdc
- output a lot more understandable.
- Installed faletick code.
- Installed work around to bug in Ultrix C compiler.
- The compiler has troubles converting unsigned longs to floats.
- This caused a lot of off by 2 second problems.
-3/31/88
- The world is ALL different now. The NTP protocols have had
- some major structural work. This is the first rev that
- attempts to meet NTP version 1 compliance. There are a couple
- of loose ends (faltickers code and clock slew rate) that
- are not finished, but should be RSN. This release is to
- bridge the compatability with the old clock system.
-
- CHANGES:
- ntpsubs.c had a MAJOR bug in the tstamp routine. Accuracy
- should be much better now.
-
- The ntp.conf file is much simpler. List your precision
- and peers, the rest is automagic.
-
- The ntp/udp service mapping is now consitent. No more hard
- coded 123s.
-
- The math routines are more robust. They now handle signed
- conversion of longs and shorts.
-
- The control structure of ntpd is radically different. A peer
- relation is NOT setup for clocks at a higher stratum. This
- reduces table clutter, but you lose the history of those
- requesters.
-
-2/20/88
- Removed the median filter and replaced it with a minimum
- filter. Experimentation by Dave Mills suggests this is
- a better way to track network clocks. Changed status field based
- on updated RFC.
-
-12/29/87
- Only believe samples were the round trip delay is positive.
- I recommend HIGHLY that you change tickadj in /sys/conf/param.c
- to equal 1 instead of 40. This reduces the granularity of
- clock slewing from 4ms/sec to .1ms/sec. This should suffice
- if your clock is less that 4.3 minutes per month. If this is
- the case get a new clock, increase the value, or live with
- periodic clock jumps due to setimeofday(). The basic problem is
- that adjtime() slews only with "tickadj" granularity. That's
- argueably broken, but needs kernel mods to fix it.
-
-12/17/87
- Added some of the changes from Greg Fowler and Ken Stone
- of HP labs. This adds "hpux" compatability. Ken and Greg
- also tighten up the "bestclock" determination so you
- don't end up tracking yourself. (thanks again)
-
- The Precision field in now correct, precision is the power
- of 2 indication of internal clock tics. (ex. 60-HZ = -6)
- This is a constant for the machine and should be set in the
- ntp.conf file.
-
-12/1/87
- Massive cleanup in the daemon code. There was a BIG problem
- with "bestclock" peer calculation. A clock of a lower type would
- be tracked if the delay to that clock was lower than the delay
- to the higher precision clock. The peers listed in the ntp.conf
- files are marked as PERM. This causes a ntp gram to go to these
- guys regardless of any recv activity. This eliminates the problem
- of a peer being down and not talking ot him when he comes back
- up because the activity indicator went to zero. Using PERM
- entries creates a fixed overhead, use it with caution.
- There is the beginning of a second order filter that can be used
- to adjust the kernel tick rate. More on that when it's done.
- The data structures have changed for queries. Querying old
- clocks will cause problems. Note - the NTP protocol has NOT
- changed, only the query hack. The SET_THRESHOLD has been changed
- to be more reasonable with the max slew rate of 4.3BSD. This
- will be relaxed when the second order stuff is working.
-
-5/29/87
-
- All of the internal math is now done with doubles. This removes
-a lot of the hair and cost. On vaxen the double yields 54(5) bits of
-accuracy. The NTP timestamps are 64 bits. Converting to doubles
-will cause the loss of some bits on ost machines. This is not bad
-since most machines don't have clocks that could track even the lower
-16 bits of the NTP timestamps.
-
- NTP makes three choices on changing the local clock.
- 1) If the local clock apperars to be off by more than
- WAYTOOBIG (1000.0) seconds, it refuses to do anything
- but fill up you log.
- 2) If the local clock is off less than WAYTOOBIG but more
- than SET_THRESHOLD (2.0) a settimeofday will be done.
- 3) If the clock is off less than SET_THRESHOLD an adjustime
- is done.
-
- Ntpd clears out the samples after every clock adjustment.
- This helped to prevent the filter from overshouting based on old
- data.
-===========================================================================
-Still cooking on the stove are:
-
- modify adjtime - it won't allow small adjustments.
- I may punt and put in a new adjtime that handles
- the second order stuff.
-
- making it handle broadcasted time like timed
-
- man pages
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <strings.h>
-#include <sysexits.h>
-
-#ifdef vax
-#define PRECISION -7 /* HZ == 100 */
-#endif
-#ifdef sun
-#define PRECISION -6 /* HZ == 50 */
-#endif
-#ifdef romp
-#define PRECISION -6 /* HZ == 64 */
-#endif
-#ifdef multimax
-#define PRECISION -3 /* HZ == 10 */
-#endif
-
-struct server {
- char *s_name;
- char *s_addr;
-};
-
-/*
- * primary servers
- */
-
-static struct server dcn5 = { "dcn5.udel.edu", "128.4.0.5" };
-static struct server wwvb = { "wwvb.isi.edu", "128.9.2.129" };
-static struct server sdsc = { "sdsc-fuzz.nsf.net", "192.12.207.1" };
-static struct server umd1 = { "umd1.umd.edu", "128.8.10.1" };
-
-/*
- * secondary servers
- */
-
-static struct server papaya = { "papaya.srv.cs.cmu.edu", "128.2.222.199" };
-static struct server guava = { "guava.srv.cs.cmu.edu", "128.2.250.187" };
-static struct server cluster1 =
- { "cluster1.fs.andrew.cmu.edu", "128.2.249.123" };
-
-static char *name;
-
-static char *headers1[] = {
- "",
- " DO NOT EDIT THIS FILE MANUALLY. It is maintained by mkntpconf.",
- "",
- " Local clock parameters",
- "",
- " Precision of the local clock to the nearest power of 2",
- " ex.",
- " 60-HZ = 2**-6",
- " 100-HZ = 2**-7",
- " 1000-HZ = 2**-10",
- 0
-};
-
-static char *headers2[] = {
- "",
- " Peers",
- "",
- 0
-};
-
-extern char *mktemp();
-void peerline();
-
-
-main(ac, av)
- int ac;
- char **av;
-{
- register char *p, **v;
- register FILE *f, *g;
- char hostname[MAXHOSTNAMELEN + 1];
- char tempfn[MAXPATHLEN + 1], config[MAXPATHLEN + 1];
- char line[BUFSIZ];
- struct server serv;
-
- name = (ac > 0) ? (ac--, *av++) : (ac = 0, "mkntpconf");
- (void)strcpy(tempfn, name);
- if ((p = strrchr(tempfn, '/')) == 0)
- p = tempfn;
- else
- p += 1;
- *p = 0;
- (void)strcpy(config, tempfn);
- (void)strcat(config, "ntp.conf");
- (void)strcat(tempfn, "ntp.XXXXXX");
- (void)mktemp(tempfn);
- if (gethostname(hostname, MAXHOSTNAMELEN) == -1) {
- perror("gethostname");
- exit(EX_OSERR);
- }
- hostname[MAXHOSTNAMELEN] = 0;
- for (p = hostname; *p; p++)
- if (isupper(*p))
- *p = tolower(*p);
- if ((f = fopen(tempfn, "w")) == NULL) {
- perror(tempfn);
- exit(EX_OSERR);
- }
-
- for (v = headers1; *v; v++)
- fprintf(f, "#%s\n", *v);
- fprintf(f, "precision %d\n", PRECISION);
- for (v = headers2; *v; v++)
- fprintf(f, "#%s\n", *v);
- if (strcmp(hostname, papaya.s_name) == 0
- || strcmp(hostname, guava.s_name) == 0) {
- if (strcmp(hostname, papaya.s_name) == 0) {
- peerline(dcn5, f);
- peerline(wwvb, f);
- } else {
- peerline(sdsc, f);
- peerline(umd1, f);
- }
- peerline(papaya, f);
- peerline(guava, f);
- peerline(cluster1, f);
- } else {
- if ((p = strchr(hostname, '.')) != 0
- && strcmp(p + 1, "srv.cs.cmu.edu") == 0) {
- peerline(papaya, f);
- peerline(guava, f);
- }
- serv.s_name = line;
- serv.s_addr = 0;
- if ((g = fopen("/etc/attributes", "r")) != NULL) {
- while (fgets(line, sizeof(line), g) != NULL) {
- if ((p = strchr(line, ':')) != 0)
- *p = 0;
- if (strcmp(line, papaya.s_name) == 0
- || strcmp(line, guava.s_name) == 0)
- continue;
- if ((p = strchr(line, '.')) == 0
- || strcmp(p + 1, "srv.cs.cmu.edu") != 0)
- continue;
- peerline(serv, f);
- }
- (void)fclose(g);
- }
- }
-
- (void)fclose(f);
- if (rename(tempfn, config) == -1) {
- perror("rename");
- exit(EX_OSERR);
- }
- if (chmod(config, 0644) == -1) {
- perror("chmod");
- exit(EX_OSERR);
- }
- exit(EX_OK);
-}
-
-
-void
-peerline(s, f)
- struct server s;
- register FILE *f;
-{
- register struct hostent *hp;
-
- fprintf(f, "peer ");
- if ((hp = gethostbyname(s.s_name)) != 0 && hp->h_addrtype == AF_INET)
- fprintf(f, "%-15.15s # %s", inet_ntoa(*(struct in_addr *)hp->h_addr),
- s.s_name);
- else if (s.s_addr)
- fprintf(f, "%-15.15s # %s", s.s_addr, s.s_name);
- else
- fprintf(f, "%s", s.s_name);
- (void)fputc('\n', f);
-}
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-/*
- * This program expects a list of host names. It will send off a
- * network time protocol packet and print out the replies on the
- * terminal.
- *
- * Example:
- *
- * % ntp umd1.umd.edu
- * Packet from: [128.8.10.1]
- * Leap 0, version 1, mode Server, poll 6, precision -10 stratum 1 (WWVB)
- * Synch Distance is 0000.1999 0.099991
- * Synch Dispersion is 0000.0000 0.000000
- * Reference Timestamp is a7bea6c3.88b40000 Tue Mar 7 14:06:43 1989
- * Originate Timestamp is a7bea6d7.d7e6e652 Tue Mar 7 14:07:03 1989
- * Receive Timestamp is a7bea6d7.cf1a0000 Tue Mar 7 14:07:03 1989
- * Transmit Timestamp is a7bea6d8.0ccc0000 Tue Mar 7 14:07:04 1989
- * Input Timestamp is a7bea6d8.1a77e5ea Tue Mar 7 14:07:04 1989
- * umd1: delay:0.019028 offset:-0.043890
- * Tue Mar 7 14:07:04 1989
- *
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <stdio.h>
-#ifdef AFS_AIX32_ENV
-#include <signal.h>
-#endif
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <strings.h>
-
-#ifdef AFS_AIX32_ENV
-#include <sys/select.h>
-#endif
-
-#include <errno.h>
-#include "ntp.h"
-
-char *modename[8] = {
- "Unspecified",
- "Symmetric Active",
- "Symmetric Passive",
- "Client",
- "Server",
- "Broadcast",
- "Reserved-1",
- "Reserved-2"
-};
-
-#define RETRY_COUNT 2 /* number of times we want to retry */
-#define TIME_OUT 10 /* time to wait for reply, in secs */
-
-
-struct sockaddr_in sin = { AF_INET };
-struct sockaddr_in dst = { AF_INET };
-struct servent *sp;
-extern double ul_fixed_to_double(), s_fixed_to_double();
-extern int errno;
-int set, verbose, force;
-int debug;
-extern int optind;
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char *argv[];
-{
- struct hostent *hp;
- struct in_addr clock_host;
- struct l_fixedpt in_timestamp;
- static struct ntpdata ntp_data;
- struct ntpdata *pkt = &ntp_data;
- struct timeval tp, timeout;
- int host, n, retry, s;
- fd_set readfds;
- int dstlen = sizeof(dst);
- double t1, t2, t3, t4, offset, delay;
- char ref_clock[5];
- time_t net_time;
-
-#ifdef AFS_AIX32_ENV
- /*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
- * in the core dump. Unfortunately, by default, only a partial core is
- * generated which, in many cases, isn't too useful.
- */
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGSEGV, &nsa, NULL);
-#endif
- ref_clock[4] = '\0';
- timeout.tv_sec = TIME_OUT;
- timeout.tv_usec = 0;
- retry = RETRY_COUNT;
-
- sp = getservbyname("ntp", "udp");
- if (sp == NULL) {
- fprintf(stderr, "udp/ntp: service unknown; using default %d\n",
- NTP_PORT);
- dst.sin_port = htons(NTP_PORT);
- } else
- dst.sin_port = sp->s_port;
-
- dst.sin_family = AF_INET;
- while ((n = getopt(argc, argv, "vsf")) != EOF) {
- switch (n) {
- case 'v':
- verbose = 1;
- break;
- case 's':
- set = 1;
- break;
- case 'f':
- force = 1;
- break;
- }
- }
- for (host = optind; host < argc; ++host) {
- afs_int32 HostAddr;
-
- if (argv[host] == NULL)
- continue;
-
- hp = NULL;
- HostAddr = inet_addr(argv[host]);
- dst.sin_addr.s_addr = (afs_uint32) HostAddr;
- if (HostAddr == -1) {
- hp = gethostbyname(argv[host]);
- if (hp == NULL) {
- fprintf(stderr, "\nNo such host: %s\n", argv[host]);
- continue;
- }
- memcpy((char *)&dst.sin_addr, hp->h_addr, hp->h_length);
- }
-
- memset((char *)pkt, 0, sizeof(ntp_data));
-
- pkt->status = NTPVERSION_1 | NO_WARNING | MODE_CLIENT;
- pkt->stratum = UNSPECIFIED;
- pkt->ppoll = 0;
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("ntp socket");
- exit(1);
- }
-
- FD_ZERO(&readfds);
- FD_SET(s, &readfds); /* since it's always modified on ret */
-
- if (connect(s, (struct sockaddr *)&dst, dstlen)) {
- perror("connect");
- exit(1);
- }
-
- /*
- * Needed to fill in the time stamp fields
- */
- (void)gettimeofday(&tp, NULL);
- tstamp(&pkt->xmt, &tp);
-
- if (send(s, (char *)pkt, sizeof(ntp_data), 0) < 0) {
- perror("send");
- exit(1);
- }
-
- /*
- * Wait for the reply by watching the file descriptor
- */
- if ((n =
- select(FD_SETSIZE, (fd_set *) & readfds, (fd_set *) 0,
- (fd_set *) 0, &timeout)) < 0) {
- perror("ntp select");
- exit(1);
- }
-
- if (n == 0) {
- fprintf(stderr, "*Timeout*\n");
- if (--retry)
- --host;
- else {
- fprintf(stderr, "Host %s is not responding\n", argv[host]);
- retry = RETRY_COUNT;
- }
- continue;
- }
- if ((recvfrom
- (s, (char *)pkt, sizeof(ntp_data), 0, (struct sockaddr *)&sin,
- &dstlen)) < 0) {
- perror("recvfrom");
- exit(1);
- }
- (void)gettimeofday(&tp, NULL);
- tstamp(&in_timestamp, &tp);
-
- close(s);
- if (verbose) {
- printf("Packet from: [%s]\n", inet_ntoa(sin.sin_addr));
- printf
- ("Leap %d, version %d, mode %s, poll %d, precision %d stratum %d",
- (pkt->status & LEAPMASK) >> 6,
- (pkt->status & VERSIONMASK) >> 3,
- modename[pkt->status & MODEMASK], pkt->ppoll, pkt->precision,
- pkt->stratum);
- switch (pkt->stratum) {
- case 0:
- case 1:
- (void)strncpy(ref_clock, (char *)&pkt->refid, 4);
- ref_clock[4] = '\0';
- printf(" (%s)\n", ref_clock);
- break;
- default:
- clock_host.s_addr = (afs_uint32) pkt->refid;
- printf(" [%s]\n", inet_ntoa(clock_host));
- break;
- }
- printf("Synch Distance is %04X.%04x %f\n",
- ntohs(pkt->distance.int_part),
- ntohs(pkt->distance.fraction),
- s_fixed_to_double(&pkt->distance));
-
- printf("Synch Dispersion is %04X.%04x %f\n",
- ntohs(pkt->dispersion.int_part),
- ntohs(pkt->dispersion.fraction),
- s_fixed_to_double(&pkt->dispersion));
-
- net_time = ntohl(pkt->reftime.int_part) - JAN_1970;
- printf("Reference Timestamp is %08lx.%08lx %s",
- ntohl(pkt->reftime.int_part), ntohl(pkt->reftime.fraction),
- ctime(&net_time));
-
- net_time = ntohl(pkt->org.int_part) - JAN_1970;
- printf("Originate Timestamp is %08lx.%08lx %s",
- ntohl(pkt->org.int_part), ntohl(pkt->org.fraction),
- ctime(&net_time));
-
- net_time = ntohl(pkt->rec.int_part) - JAN_1970;
- printf("Receive Timestamp is %08lx.%08lx %s",
- ntohl(pkt->rec.int_part), ntohl(pkt->rec.fraction),
- ctime(&net_time));
-
- net_time = ntohl(pkt->xmt.int_part) - JAN_1970;
- printf("Transmit Timestamp is %08lx.%08lx %s",
- ntohl(pkt->xmt.int_part), ntohl(pkt->xmt.fraction),
- ctime(&net_time));
- }
- t1 = ul_fixed_to_double(&pkt->org);
- t2 = ul_fixed_to_double(&pkt->rec);
- t3 = ul_fixed_to_double(&pkt->xmt);
- t4 = ul_fixed_to_double(&in_timestamp);
-
- net_time = ntohl(in_timestamp.int_part) - JAN_1970;
- if (verbose)
- printf("Input Timestamp is %08lx.%08lx %s",
- ntohl(in_timestamp.int_part), ntohl(in_timestamp.fraction),
- ctime(&net_time));
-
- delay = (t4 - t1) - (t3 - t2);
- offset = (t2 - t1) + (t3 - t4);
- offset = offset / 2.0;
- printf("%.20s: delay:%f offset:%f ", hp ? hp->h_name : argv[host],
- delay, offset);
- net_time = ntohl(pkt->xmt.int_part) - JAN_1970 + delay;
- fputs(ctime(&net_time), stdout);
- (void)fflush(stdout);
-
- if (!set)
- continue;
-
- if ((offset < 0 ? -offset : offset) > WAYTOOBIG && !force) {
- fprintf(stderr,
- "Offset too large - use -f option to force clock set.\n");
- continue;
- }
-
- if (pkt->status & LEAPMASK == ALARM) {
- fprintf(stderr, "Can't set time from %s - unsynchronized\n",
- argv[host]);
- continue;
- }
-
- /* set the clock */
- gettimeofday(&tp, NULL);
- offset += tp.tv_sec;
- offset += tp.tv_usec / 1000000.0;
- tp.tv_sec = offset;
- tp.tv_usec = (offset - tp.tv_sec) * 1000000.0;
-
- if (settimeofday(&tp, NULL)) {
- perror("Can't set time (settimeofday)");
- } else
- set = 0;
- } /* end of for each host */
- exit(0);
-} /* end of main */
+++ /dev/null
-# Copyright 2000, International Business Machines Corporation and others.
-# All Rights Reserved.
-#
-# This software has been released under the terms of the IBM Public
-# License. For details, see the LICENSE file in the top-level source
-# directory or online at http://www.openafs.org/dl/license10.html
-
-# Local clock parameters
-#
-# Stratum MUST only be defined if you are a primary clock
-# If so, include the 4 char clock type
-#stratum 1 WWVB
-#
-# Precision of the local clock to the nearest power of 2
-# ex.
-# 60-HZ = 2**-6
-# 100-HZ = 2**-7
-# 1000-HZ = 2**-10
-precision -6
-#
-# Peers Type Name
-#
-# This is the peer list for cluster1.fs.andrew.cmu.edu, system control
-# machine for the Andrew cell
-#
-#peer cluster1.fs.andrew.cmu.edu
-peer 192.5.146.42 #fuzzgate.psc.edu
-peer GUAVA.SRV.CS.CMU.EDU #128.2.250.187
-peer PAPAYA.SRV.CS.CMU.EDU #128.2.222.199
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#ifndef FD_SET
-#define NFDBITS 32
-#define FD_SETSIZE 32
-#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p)))
-#endif
-
-#ifndef NBBY
-#define NBBY 8 /* number of bits per byte */
-#endif
-
-#define MAXNETIF 10
-
-struct intf {
- int fd;
- char *name;
- struct sockaddr_in sin;
- struct sockaddr_in bcast;
- struct sockaddr_in mask;
- int uses;
- int if_flags;
-};
-extern struct intf addrs[];
-extern int nintf;
-
-/*
- * Definitions for the masses
- */
-#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */
-
-/*
- * Daemon specific (ntpd.c)
- */
-#define SHIFT_MASK 0xff /* number of intervals to wait */
-
-#ifndef WAYTOOBIG
-#define WAYTOOBIG 1000.0 /* Too many seconds to correct, something is
- * really wrong */
-#endif
-
-#ifndef XTAL
-#define XTAL 1 /* crystal controlled clock by default */
-#endif
-
-#ifndef NTPINITFILE
-#define NTPINITFILE "/etc/ntp.conf"
-#endif
-#ifndef NTPDRIFTCOMP
-#define NTPDRIFTCOMP "/etc/ntp.drift"
-#endif
-
-struct list {
- struct ntp_peer *head;
- struct ntp_peer *tail;
- int members;
-};
-
-#define STRMCMP(a, cond, b) \
- (((a) == UNSPECIFIED ? NTP_INFIN+1 : a) cond \
- ((b) == UNSPECIFIED ? NTP_INFIN+1 : (b)))
-
-
-/*
- * Definitions outlined in the NTP spec
- */
-#define NTP_VERSION 1
-#define NTP_PORT 123 /* for ref only (see /etc/services) */
-#define NTP_INFIN 15
-#define NTP_MAXAGE 86400
-#define NTP_MAXSKW 0.01 /* seconds */
-#define NTP_MINDIST 0.02 /* seconds */
-#ifdef REFCLOCK
-#define NTP_REFMAXSKW 0.001 /* seconds (for REFCLOCKs) */
-#define NTP_REFMINDIST 0.001 /* seconds (for REFCLOCKs) */
-#endif
-#define NTP_MINPOLL 6 /* (64) seconds between messages */
-#define NTP_MAXPOLL 10 /* (1024) secs to poll */
-#define NTP_WINDOW 8 /* size of shift register */
-#define NTP_MAXWGT 8 /* maximum allowable dispersion */
-#define NTP_MAXLIST 5 /* max size of selection list */
-#define NTP_MAXSTRA 2 /* max number of strata in selection list */
-#define X_NTP_CANDIDATES 64 /* number of peers to consider when doing
- * clock selection */
-#define NTP_SELECT 0.75 /* weight used to compute dispersion */
-
-#define PEER_MAXDISP 64.0 /* Maximum dispersion */
-#define PEER_THRESHOLD 0.5 /* dispersion threshold */
-#define PEER_FILTER 0.5 /* filter weight */
-
-#if XTAL == 0
-#define PEER_SHIFT 4
-#define NTP_WINDOW_SHIFT_MASK 0x0f
-#else
-#define PEER_SHIFT 8
-#define NTP_WINDOW_SHIFT_MASK 0xff
-#endif
-
-
-/*
- * 5.1 Uniform Phase Adjustments
- * Clock parameters
- */
-#define CLOCK_UPDATE 8 /* update interval (1<<CLOCK_UPDATE secs) */
-#if XTAL
-#define CLOCK_ADJ 2 /* adjustment interval (1<<CLOCK_ADJ secs) */
-
-#if defined (hpux) /* must use settimeofday instead of adjtime */
-#define CLOCK_PHASE 5 /* send bigger chunks */
-#define CLOCK_MAX 0.128 /* maximum aperture (milliseconds) */
-
-#else
-
-#if defined (AFS_SUN_ENV) /* these guys have such terrible clocks... */
-#define CLOCK_PHASE 8 /* phase shift */
-#define CLOCK_MAX 0.512 /* maximum aperture (milliseconds) */
-
-#else
-
-#if defined (AFS_AIX32_ENV) /* there is a bug in adjtime */
-#define CLOCK_PHASE 8 /* phase shift */
-#define CLOCK_MAX 0.512 /* maximum aperture (milliseconds) */
-
-#else
-
-#define CLOCK_PHASE 8 /* phase shift */
-#define CLOCK_MAX 0.128 /* maximum aperture (milliseconds) */
-#endif
-#endif
-#endif
-
-#else /*!XTAL */
-#define CLOCK_ADJ 0
-#define CLOCK_PHASE 6 /* phase shift */
-#define CLOCK_MAX 0.512 /* maximum aperture (milliseconds) */
-#endif
-#define CLOCK_FREQ 10 /* frequency shift */
-#define CLOCK_TRACK 8
-#define CLOCK_COMP 4
-#define CLOCK_FACTOR 18
-\f
-/*
- * Structure definitions for NTP fixed point values
- *
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Integer Part |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Fraction Part |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Integer Part | Fraction Part |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-struct l_fixedpt {
- afs_uint32 int_part;
- afs_uint32 fraction;
-};
-
-struct s_fixedpt {
- u_short int_part;
- u_short fraction;
-};
-
-/* sign extension problem */
-#if defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV)
-#define s_char(v) char v
-#else
-#if defined(AFS_HPUX_ENV) || defined(AFS_AIX_ENV)
-#define s_char(v) signed char v
-#else
-#define s_char(v) int v:8
-#endif
-#endif
-
-/* ================= Table 3.3. Packet Variables ================= */
-/*
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |LI | VN | Mode| Stratum | Poll | Precision |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Synchronizing Distance |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Synchronizing Dispersion |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Reference Clock Identifier |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * | Reference Timestamp (64 bits) |
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * | Originate Timestamp (64 bits) |
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * | Receive Timestamp (64 bits) |
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * | Transmit Timestamp (64 bits) |
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-struct ntpdata {
- u_char status; /* status of local clock and leap info */
- u_char stratum; /* Stratum level */
- u_char ppoll; /* poll value */
- s_char(precision); /* -6..-31 */
-
- struct s_fixedpt distance;
- struct s_fixedpt dispersion;
- afs_uint32 refid;
- struct l_fixedpt reftime;
- struct l_fixedpt org;
- struct l_fixedpt rec;
- struct l_fixedpt xmt;
-};
-/*
- * Leap Second Codes (high order two bits)
- */
-#define NO_WARNING 0x00 /* no warning */
-#define PLUS_SEC 0x40 /* add a second (61 seconds) */
-#define MINUS_SEC 0x80 /* minus a second (59 seconds) */
-#define ALARM 0xc0 /* alarm condition (clock unsynchronized) */
-
-#ifdef MODEMASK
-#undef MODEMASK
-#endif
-
-/*
- * Clock Status Bits that Encode Version
- */
-#define NTPVERSION_1 0x08
-#define VERSIONMASK 0x38
-#define LEAPMASK 0xc0
-#define MODEMASK 0x07
-
-/*
- * Code values
- */
-#define MODE_UNSPEC 0 /* unspecified */
-#define MODE_SYM_ACT 1 /* symmetric active */
-#define MODE_SYM_PAS 2 /* symmetric passive */
-#define MODE_CLIENT 3 /* client */
-#define MODE_SERVER 4 /* server */
-#define MODE_BROADCAST 5 /* broadcast */
-#define MODE_RES1 6 /* reserved */
-#define MODE_RES2 7 /* reserved */
-
-/*
- * Stratum Definitions
- */
-#define UNSPECIFIED 0
-#define PRIM_REF 1 /* radio clock */
-#define INFO_QUERY 62 /* **** THIS implementation dependent **** */
-#define INFO_REPLY 63 /* **** THIS implementation dependent **** */
-
-
-/* ================= table 3.2 Peer Variables ================= */
-struct ntp_peer {
- struct ntp_peer *next, *prev;
- struct sockaddr_in src; /* both peer.srcadr and
- * peer.srcport */
- int flags; /* local flags */
-#define PEER_FL_CONFIG 1
-#define PEER_FL_AUTHENABLE 2
-#define PEER_FL_SANE 0x0100 /* sane peer */
-#define PEER_FL_CANDIDATE 0x0200 /* candidate peer */
-#define PEER_FL_SYNC 0x1000 /* peer can bet sync'd to */
-#define PEER_FL_BCAST 0x2000 /* broadcast peer */
-#define PEER_FL_REFCLOCK 0x4000 /* peer is a local reference clock */
-#define PEER_FL_SELECTED 0x8000 /* actually used by query routine */
-
- int sock; /* index into sockets to derive
- * peer.dstadr and peer.dstport */
- u_char leap; /* receive */
- u_char hmode; /* receive */
- u_char stratum; /* receive */
- u_char ppoll; /* receive */
- u_char hpoll; /* poll update */
- short precision; /* receive */
- struct s_fixedpt distance; /* receive */
- struct s_fixedpt dispersion; /* receive */
- afs_uint32 refid; /* receive */
- struct l_fixedpt reftime; /* receive */
- struct l_fixedpt org; /* receive, clear */
- struct l_fixedpt rec; /* receive, clear */
- struct l_fixedpt xmt; /* transmit, clear */
- afs_uint32 reach; /* receive, transmit, clear */
- afs_uint32 valid; /* packet, transmit, clear */
- afs_uint32 timer; /* receive, transmit, poll update */
- afs_int32 stopwatch; /* <<local>> for timing */
- /*
- * first order offsets
- */
- struct filter {
- short samples; /* <<local>> */
- double offset[PEER_SHIFT];
- double delay[PEER_SHIFT];
- } filter; /* filter, clear */
-
- double estdelay; /* filter */
- double estoffset; /* filter */
- double estdisp; /* filter */
-
- afs_uint32 pkt_sent; /* <<local>> */
- afs_uint32 pkt_rcvd; /* <<local>> */
- afs_uint32 pkt_dropped; /* <<local>> */
-};
-
-/* ================= table 3.1: System Variables ================= */
-
-struct sysdata { /* procedure */
- u_char leap; /* clock update */
- u_char stratum; /* clock update */
- short precision; /* system */
- struct s_fixedpt distance; /* clock update */
- struct s_fixedpt dispersion; /* clock update */
- afs_uint32 refid; /* clock update */
- struct l_fixedpt reftime; /* clock update */
- int hold; /* clock update */
- struct ntp_peer *peer; /* selection */
- int maxpeers; /* <<local>> */
- u_char filler; /* put here for %&*%$$ SUNs */
-};
-\f
-#define NTPDC_VERSION 2
-
-/*
- * These structures are used to pass information to the ntpdc (control)
- * program. They are unique to this implementation and not part of the
- * NTP specification.
- */
-struct clockinfo {
- afs_uint32 net_address;
- afs_uint32 my_address;
- u_short port;
- u_short flags;
- afs_uint32 pkt_sent;
- afs_uint32 pkt_rcvd;
- afs_uint32 pkt_dropped;
- afs_uint32 timer;
- u_char leap;
- u_char stratum;
- u_char ppoll;
- s_char(precision);
-
- u_char hpoll;
- u_char filler1;
- u_short reach;
-
- afs_int32 estdisp; /* scaled by 1000 */
- afs_int32 estdelay; /* in milliseconds */
- afs_int32 estoffset; /* in milliseconds */
- afs_uint32 refid;
- struct l_fixedpt reftime;
- struct info_filter {
- short index;
- short filler;
- afs_int32 offset[PEER_SHIFT]; /* in milliseconds */
- afs_int32 delay[PEER_SHIFT]; /* in milliseconds */
- } info_filter;
-};
-
-struct ntpinfo {
- u_char version;
- u_char type; /* request type (stratum in ntp packets) */
- u_char count; /* number of entries in this packet */
- u_char seq; /* sequence number of this packet */
-
- u_char npkts; /* total number of packets */
- u_char peers;
- u_char fill3;
- u_char fill4;
-};
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <strings.h>
-#include <errno.h>
-#if defined(AIX)
-#include <sys/syslog.h>
-#else
-#include <syslog.h>
-#endif /* defined(AIX) */
-
-#include "ntp.h"
-
-#ifdef DEBUG
-extern int debug;
-#endif
-
-extern int doset;
-extern int debuglevel;
-extern int kern_tickadj;
-extern char *ntoa();
-extern struct sysdata sys;
-
-double drift_comp = 0.0, compliance, clock_adjust;
-afs_int32 update_timer = 0;
-
-int adj_precision;
-double adj_residual;
-int firstpass = 1;
-
-#define MICROSECONDS 1000000
-
-#define abs(x) ((x) < 0 ? -(x) : (x))
-
-void
-init_logical_clock()
-{
- if (kern_tickadj)
- adj_precision = kern_tickadj;
- else
- adj_precision = 1;
- /*
- * If you have the "fix" for adjtime() installed in you kernel, you'll
- * have to make sure that adj_precision is set to 1 here.
- */
-}
-
-
-/*
- * 5.0 Logical clock procedure
- *
- * Only paramter is an offset to vary the clock by, in seconds. We'll either
- * arrange for the clock to slew to accomodate the adjustment, or just preform
- * a step adjustment if the offset is too large.
- *
- * The update which is to be performed is left in the external
- * clock_adjust.
- *
- * Returns non-zero if clock was reset rather than slewed.
- *
- * Many thanks for Dennis Ferguson <dennis@gw.ccie.utoronto.ca> for his
- * corrections to my code.
- */
-
-int
-adj_logical(offset)
- double offset;
-{
- struct timeval tv1, tv2;
-#ifdef XADJTIME2
- struct timeval delta, olddelta;
-#endif
-
- /*
- * Now adjust the logical clock
- */
- if (!doset)
- return 0;
-
- adj_residual = 0.0;
- if (offset > CLOCK_MAX || offset < -CLOCK_MAX) {
- double steptime = offset;
-
- (void)gettimeofday(&tv2, NULL);
- steptime += tv2.tv_sec;
- steptime += tv2.tv_usec / 1000000.0;
- tv1.tv_sec = steptime;
- tv1.tv_usec = (steptime - tv1.tv_sec) * 1000000;
-#ifdef DEBUG
- if (debug > 2) {
- steptime =
- (tv1.tv_sec + tv1.tv_usec / 1000000.0) - (tv2.tv_sec +
- tv2.tv_usec /
- 1000000.0);
- printf("adj_logical: %f %f\n", offset, steptime);
- }
-#endif
- if (settimeofday(&tv1, NULL) < 0) {
- syslog(LOG_ERR, "Can't set time: %m");
- return (-1);
- }
- firstpass = 1;
- update_timer = 0;
- clock_adjust = 0.0;
- return (1); /* indicate that step adjustment was done */
- } else {
- double ai;
-
- /*
- * If this is our very first adjustment, don't touch
- * the drift compensation (this is f in the spec
- * equations), else update using the *old* value
- * of the compliance.
- */
- clock_adjust = offset;
- if (firstpass)
- firstpass = 0;
- else if (update_timer > 0) {
- ai = abs(compliance);
- ai = (double)(1 << CLOCK_COMP) - (double)(1 << CLOCK_FACTOR) * ai;
- if (ai < 1.0) /* max(... , 1.0) */
- ai = 1.0;
- drift_comp += offset / (ai * (double)update_timer);
- }
-
- /*
- * Set the timer to zero. adj_host_clock() increments it
- * so we can tell the period between updates.
- */
- update_timer = 0;
-
- /*
- * Now update the compliance. The compliance is h in the
- * equations.
- */
- compliance += (offset - compliance) / (double)(1 << CLOCK_TRACK);
-
-#ifdef XADJTIME2
- delta.tv_sec = offset;
- delta.tv_usec = (offset - delta.tv_sec) * 1000;
- (void)adjtime2(&delta, &olddelta);
-#endif
- return (0);
- }
-}
-
-#ifndef XADJTIME2
-extern int adjtime();
-
-/*
- * This is that routine that performs the periodic clock adjustment.
- * The procedure is best described in the the NTP document. In a
- * nutshell, we prefer to do lots of small evenly spaced adjustments.
- * The alternative, one large adjustment, creates two much of a
- * clock disruption and as a result oscillation.
- *
- * This function is called every 2**CLOCK_ADJ seconds.
- *
- */
-
-/*
- * global for debugging?
- */
-double adjustment;
-
-void
-adj_host_clock()
-{
-
- struct timeval delta, olddelta;
-
- if (!doset)
- return;
-
- /*
- * Add update period into timer so we know how long it
- * took between the last update and the next one.
- */
- update_timer += 1 << CLOCK_ADJ;
- /*
- * Should check to see if update_timer > 1 day here?
- */
-
- /*
- * Compute phase part of adjustment here and update clock_adjust.
- * Note that the equations used here are implicit in the last
- * two equations in the spec (in particular, look at the equation
- * for g and figure out how to find the k==1 term given the k==0 term.)
- */
- adjustment = clock_adjust / (double)(1 << CLOCK_PHASE);
- clock_adjust -= adjustment;
-
- /*
- * Now add in the frequency component. Be careful to note that
- * the ni occurs in the last equation since those equations take
- * you from 64 second update to 64 second update (ei is the total
- * adjustment done over 64 seconds) and we're only deal in the
- * little 4 second adjustment interval here.
- */
- adjustment += drift_comp / (double)(1 << CLOCK_FREQ);
-
- /*
- * Add in old adjustment residual
- */
- adjustment += adj_residual;
-
- /*
- * Simplify. Adjustment shouldn't be bigger than 2 ms. Hope
- * writer of spec was truth telling.
- */
-#ifdef DEBUG
- delta.tv_sec = adjustment;
- if (debug && delta.tv_sec)
- abort();
-#else
- delta.tv_sec = 0;
-#endif
-#if defined(AFS_AIX32_ENV)
- /* aix 3.1 ajdtime has unsigned bug. */
- if (adjustment < 0.0)
- adj_precision = 5000;
- else if (adjustment < 1000000.0)
- adj_precision = 1000;
- else
- adj_precision = 5000;
-#endif
- delta.tv_usec = ((afs_int32) (adjustment * 1000000.0) / adj_precision)
- * adj_precision;
-
- adj_residual = adjustment - (double)delta.tv_usec / 1000000.0;
-
- if (delta.tv_usec == 0)
- return;
-
- if (adjtime(&delta, &olddelta) < 0)
- syslog(LOG_ERR, "Can't adjust time: %m");
-
-#ifdef DEBUG
- if (debug > 2)
- printf("adj: %ld us %f %f\n", delta.tv_usec, drift_comp,
- clock_adjust);
-#endif
-}
-#endif
-
-#if defined(AFS_HPUX_ENV) && !defined(AFS_HPUX102_ENV)
-/*
- * adjtime for HPUX. Basically a poor man's version of the BSD adjtime call.
- * It accumulates adjustments until such time as there are enough to use the
- * stime primitive. This code is ugly. It also does no range checking,
- * since the assumption is that the adjustments will be (fairly) small.
- *
- * The basic mechanism is simple: we only have a coarse granularity (1
- * second) so we accumulate changes until they exceed 1 second. When
- * that is the case, an adjustment is made which will always be less
- * than 1 second. If it is a negative adjustment, we won't allow it
- * to timewarp more frequently than once every ten seconds.
- *
- */
-static struct timeval cum = { 0, 0 }; /* use to accumulate unadjusted time */
-
-ZeroAIXcum()
-{
- if (debug > 6)
- printf("Zeroing aix_adjtime accumulation: %d %d\n", cum.tv_sec,
- cum.tv_usec);
- memset(&cum, 0, sizeof(cum));
-}
-
-int
-adjtime(newdelta, olddelta)
- struct timeval *newdelta;
- struct timeval *olddelta;
-{
- static struct timeval lastbackadj; /* last time adjusted backwards */
- struct timeval now, new;
-
-#if 0
- { /* punt accumulated change if sign of correction changes */
- int dNeg = ((newdelta->tv_sec < 0 || newdelta->tv_usec < 0) ? 1 : 0);
- int cNeg = ((cum.tv_sec < 0 || cum.tv_usec < 0) ? 1 : 0);
- if (dNeg != cNeg)
- ZeroAIXcum();
- }
-#endif /* 0 */
-
- *olddelta = cum;
- cum.tv_usec += newdelta->tv_usec;
- cum.tv_sec += newdelta->tv_sec + cum.tv_usec / MICROSECONDS;
- cum.tv_usec =
- (cum.tv_usec <
- 0) ? -((-cum.tv_usec) % MICROSECONDS) : cum.tv_usec % MICROSECONDS;
-
- gettimeofday(&now, NULL);
- new = now;
- new.tv_sec += cum.tv_sec;
- new.tv_usec += cum.tv_usec;
- if (new.tv_usec >= MICROSECONDS)
- new.tv_sec++, new.tv_usec -= MICROSECONDS;
- else if (new.tv_usec < 0)
- new.tv_sec--, new.tv_usec += MICROSECONDS;
- if (debug > 6) {
- printf("cum is %d %d, new is %d %d, now is %d %d\n", cum.tv_sec,
- cum.tv_usec, new.tv_sec, new.tv_usec, now.tv_sec, now.tv_usec);
- }
-
- if (cum.tv_sec || abs(cum.tv_usec) > 2000) {
- /* wait till accumulated update is at least 2msec since this call
- * seems to add some jitter. */
- settimeofday(&new, NULL);
- if (debug > 4) /* do set before doing I/O */
- printf("hp_adjtime: pushing clock by %d usec w/ settimeofday \n",
- cum.tv_sec * 1000000 + cum.tv_usec);
- cum.tv_sec = 0;
- cum.tv_usec = 0;
- }
- return 0;
-}
-#endif /* defined(AFS_HPUX_ENV) */
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-/*
- * This module actually implements the the bulk of the NTP protocol processing.
- * It contains a minimum of machine and operating system dependencies (or at
- * least that's the idea). Setup of UDP sockets, timers, etc is done in the
- * ntpd.c module, while arithmetic conversion routines are in ntpsubs.c
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#ifdef AFS_SUN5_ENV
-#include <sys/sysmacros.h>
-#endif
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <strings.h>
-#include <errno.h>
-#if defined(AIX)
-#include <sys/syslog.h>
-#else
-#include <syslog.h>
-#endif /* defined(AIX) */
-
-#include "ntp.h"
-
-int peer_switches, peer_sw_inhibited;
-
-struct ntp_peer dummy_peer;
-extern double WayTooBig;
-extern afs_uint32 clock_watchdog;
-#ifdef DEBUG
-extern int debug;
-extern void dump_pkt();
-#endif
-extern int trusting, logstats;
-extern struct sysdata sys;
-extern struct list peer_list;
-extern struct ntp_peer *check_peer();
-extern struct servent *servp;
-extern char *malloc(), *ntoa();
-extern double drift_comp, compliance; /* logical clock variables */
-extern double s_fixed_to_double(), ul_fixed_to_double();
-extern void make_new_peer(), double_to_s_fixed(), demobilize();
-#ifndef AFS_SUN58_ENV
-extern void tstamp();
-#endif
-
-
-#ifdef REFCLOCK
-void refclock_input();
-#endif
-
-void process_packet(), clock_update(), clear(), clock_filter(), receive(),
-select_clock(), poll_update();
-
-/* 3.4. Event Processing */
-
-/* 3.4.1. Transmit Procedure */
-void
-transmit(peer)
- struct ntp_peer *peer;
-{
- struct timeval txtv;
- static struct ntpdata ntpframe;
- struct ntpdata *pkt = &ntpframe;
- int i;
-
- pkt->status = sys.leap | NTPVERSION_1 | peer->hmode;
- pkt->stratum = sys.stratum;
- pkt->ppoll = peer->hpoll;
- pkt->precision = sys.precision;
- pkt->distance = sys.distance;
- pkt->dispersion = sys.dispersion;
- pkt->refid = sys.refid;
- pkt->reftime = sys.reftime;
- pkt->org = peer->org;
- pkt->rec = peer->rec;
- (void)gettimeofday(&txtv, NULL);
-#if 0
- if (peer->flags & PEER_FL_AUTHENABLE) {
- /* add encryption time into the timestamp */
- tstamp(&pkt->xmt, &txtv);
- /* call encrypt() procedure */
- pkt->keyid = ? ? ?;
- pkt->mac = ? ? ?;
- } else {
- pkt->mac[0] = pkt->mac[1] = 0;
- pkt->keyid = 0; /* XXX */
- tstamp(&pkt->xmt, &txtv);
- }
-#else
- tstamp(&pkt->xmt, &txtv);
-#endif
-
- peer->xmt = pkt->xmt;
-
- if ((peer->flags & (PEER_FL_BCAST | PEER_FL_REFCLOCK)) == 0) {
- /* select correct socket to send reply on */
- if (sendto
- (addrs[(peer->sock < 0 ? 0 : peer->sock)].fd, (char *)pkt,
- sizeof(ntpframe), 0, (struct sockaddr *)&peer->src,
- sizeof(peer->src)) < 0) {
- syslog(LOG_ERR, "sendto: %s %m", ntoa(peer->src.sin_addr));
- return;
- }
-#ifdef REFCLOCK
- } else if (peer->flags & PEER_FL_REFCLOCK) {
- /* Special version of code below, adjusted for refclocks */
-
-
- peer->pkt_sent++;
- i = peer->reach; /* save a copy */
-
- peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK;
-
- if (i && peer->reach == 0) {
- syslog(LOG_INFO, "Lost reachability with %.4s",
- (char *)&peer->refid);
-#ifdef DEBUG
- if (debug)
- printf("Lost reachability with %.4s\n", (char *)&peer->refid);
-#endif
- }
-
- if (peer->reach == 0)
- clear(peer);
-
- if (peer->valid < 2)
- peer->valid++;
- else {
- clock_filter(peer, 0.0, 0.0); /* call with invalid values */
- select_clock(); /* and try to reselect clock */
- }
-
- peer->timer = 1 << NTP_MINPOLL; /* poll refclocks frequently */
-
- refclock_input(peer, pkt);
- return;
-#endif /* REFCLOCK */
- } else {
-#ifdef BROADCAST_NTP
- if (sendto
- (addrs[peer->sock].fd, (char *)pkt, sizeof(ntpframe), 0,
- &peer->src, sizeof(peer->src)) < 0) {
- syslog(LOG_ERR, "bcast sendto: %s %m", ntoa(peer->src.sin_addr));
- return;
- }
-#else
- return;
-#endif
- }
-
-#ifdef DEBUG
- if (debug > 5) {
- printf("\nSent ");
- dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL);
- }
-#endif
- peer->pkt_sent++;
- i = peer->reach; /* save a copy */
-
- peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK;
-
- if ((peer->reach == 0) && ((peer->flags & PEER_FL_CONFIG) == 0)
- && (peer != &dummy_peer)) {
- demobilize(&peer_list, peer);
- return;
- }
-
- if (i && peer->reach == 0) {
- syslog(LOG_INFO, "Lost reachability with %s",
- ntoa(peer->src.sin_addr));
-#ifdef DEBUG
- if (debug)
- printf("Lost reachability with %s", ntoa(peer->src.sin_addr));
-#endif
- }
-
- if (peer->reach == 0) {
- clear(peer);
- peer->sock = -1; /* since he fell off the end of the
- * earth, don't depend on local address
- * any longer */
- }
-
- if (peer->valid < 2)
- peer->valid++;
- else {
- clock_filter(peer, 0.0, 0.0); /* call with invalid values */
- select_clock(); /* and try to reselect clock */
- if (sys.peer != NULL)
- poll_update(sys.peer, NTP_MINPOLL);
- }
-
- peer->timer =
- 1 <<
- (MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)), NTP_MINPOLL));
-
- if (peer->estdisp > PEER_THRESHOLD)
- poll_update(peer, peer->hpoll - 1);
- else
- poll_update(peer, peer->hpoll + 1);
-}
-\f
-#ifdef REFCLOCK
-void
-refclock_input(peer, pkt)
- struct ntpdata *pkt;
- struct ntp_peer *peer;
-{
- struct timeval *tvp;
- struct timeval *otvp;
-
- if (read_clock(peer->sock, &tvp, &otvp))
- return;
-
- tstamp(&pkt->rec, tvp);
- pkt->xmt = pkt->rec;
- pkt->reftime = pkt->rec;
- tstamp(&pkt->org, otvp);
- peer->xmt = pkt->org;
- pkt->refid = peer->refid;
- pkt->status &= ~ALARM;
- pkt->stratum = peer->stratum;
- pkt->ppoll = 0xff;
- pkt->precision = peer->precision;
- double_to_s_fixed(&pkt->distance, 0.0);
- double_to_s_fixed(&pkt->dispersion, 0.0);
-#ifdef DEBUG
- if (debug > 5) {
- printf("\nFaking packet ");
- dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL);
- }
-#endif
- receive((struct sockaddr_in *)peer, pkt, otvp, -1);
- return;
-}
-#endif /* REFCLOCK */
-\f
-/* 3.4.2. Receive Procedure */
-void
-receive(dst, pkt, tvp, sock)
- struct sockaddr_in *dst;
- struct ntpdata *pkt;
- struct timeval *tvp;
- int sock;
-{
- struct ntp_peer *peer;
- int peer_mode;
-
-#define ACT_ERROR 1
-#define ACT_RECV 2
-#define ACT_XMIT 3
-#define ACT_PKT 4
-
- static char actions[5][5] = {
-
- /* Sym Act Sym Pas Client Server Broadcast |Host / */
- /* -------- -------- -------- --------- --------- | / Peer */
- /* ------------ */
- {ACT_PKT, ACT_PKT, ACT_RECV, ACT_XMIT, ACT_XMIT}, /* Sym Act */
- {ACT_PKT, ACT_ERROR, ACT_RECV, ACT_ERROR, ACT_ERROR}, /* Sym Pas */
- {ACT_XMIT, ACT_XMIT, ACT_ERROR, ACT_XMIT, ACT_XMIT}, /* Client */
- {ACT_PKT, ACT_ERROR, ACT_RECV, ACT_ERROR, ACT_ERROR}, /* Server */
- {ACT_PKT, ACT_ERROR, ACT_RECV, ACT_ERROR, ACT_ERROR}
- }; /* Broadcast */
-
- /* if we're only going to support NTP Version 2 then this stuff
- * isn't necessary, right? */
-
- if ((peer_mode = pkt->status & MODEMASK) == 0 && dst) {
- /* packet from an older NTP implementation. Synthesize the
- * correct mode. The mapping goes like this:
- *
- * pkt source port pkt dst port Mode
- * --------------- ------------ ----
- * NTP Port NTP Port symmetric active
- * NTP Port not NTP Port server
- * not NTP Port NTP Port client
- * not NTP Port not NTP Port <not possible>
- *
- * Now, since we only are processing packets with the
- * destination being NTP Port, it reduces to the two cases:
- *
- * pkt source port pkt dst port Mode
- * --------------- ------------ ----
- * NTP Port NTP Port symmetric active
- * not NTP Port NTP Port client */
-
- if (dst->sin_port == servp->s_port)
- peer_mode = MODE_SYM_ACT;
- else
- peer_mode = MODE_CLIENT;
- }
-
- if (peer_mode == MODE_CLIENT) {
- /*
- * Special case: Use the dummy peer item that we keep around
- * just for this type of thing
- */
- peer = &dummy_peer;
- make_new_peer(peer);
- peer->src = *dst;
- peer->sock = sock;
- peer->hmode = MODE_SYM_PAS;
- peer->reach = 0;
- clear(peer);
-#ifdef REFCLOCK
- } else if (sock == -1) {
- /* we're begin called by refclock_input(), get peer ptr */
- peer = (struct ntp_peer *)dst;
-#endif
- } else
- peer = check_peer(dst, sock);
-
- if (peer == NULL) {
- peer = (struct ntp_peer *)malloc(sizeof(struct ntp_peer));
- if (peer == NULL) {
- syslog(LOG_ERR, "peer malloc: %m");
- return;
- }
- make_new_peer(peer);
- peer->src = *dst;
- peer->sock = sock; /* remember which socket we heard
- * this from */
- peer->hmode = MODE_SYM_PAS;
- peer->reach = 0;
- clear(peer);
- /*
- * If we decide to consider any random NTP peer that might
- * come as a peer we might sync to, then set the PEER_FL_SYNC
- * flag in the peer structure.
- *
- * Alternatively, we could change the hmode to MODE_SERVER,
- * but then the peer state wouldn't be persistant.
- */
- if (trusting)
- peer->flags |= PEER_FL_SYNC;
-
- enqueue(&peer_list, peer);
- }
-
- /*
- * "pre-configured" peers are initially assigned a socket index of
- * -1, which means we don't know which interface we'll use to talk
- * to them. Once the first reply comes back, we'll update the
- * peer structure
- */
- if (peer->sock == -1)
- peer->sock = sock;
-
-#ifdef BROADCAST_NTP
- /*
- * Input frame matched a funny broadcast peer; these peers only
- * exist to periodically generate broadcasts. If an input packet
- * matched, it means that it looked like it *came* from the broadcast
- * address. This is clearly bogus.
- */
- if (peer->flags & PEER_FL_BCAST) {
-#ifdef DEBUG
- if (debug > 1)
- printf("receive: input frame for broadcast peer?\n");
-#endif
- return;
- }
-#endif /* BROADCAST_NTP */
-
-#if 0
- if ((peer->flags & PEER_FL_AUTHENABLE) && pkt->mac) {
- /* verify computed crypto-checksum */
- }
-#endif
-
- if (peer_mode < MODE_SYM_ACT || peer_mode > MODE_BROADCAST) {
- syslog(LOG_DEBUG, "Bogus peer_mode %d from %s", peer_mode,
- ntoa(dst->sin_addr));
-#ifdef DEBUG
- if (debug > 3)
- abort();
-#endif
- return;
- }
-
- if (peer->hmode < MODE_SYM_ACT || peer->hmode > MODE_BROADCAST) {
- syslog(LOG_ERR, "Bogus hmode %d for peer %s", peer->hmode,
- ntoa(peer->src.sin_addr));
- abort();
- }
-
- switch (actions[peer_mode - 1][peer->hmode - 1]) {
- case ACT_RECV:
- if (!(((peer->flags & PEER_FL_CONFIG) == 0)
- && STRMCMP(pkt->stratum, >, sys.stratum))) {
- peer->reach |= 1;
- process_packet(dst, pkt, tvp, peer);
- break;
- }
- /* Note fall-through */
- case ACT_ERROR:
- if (((peer->flags & PEER_FL_CONFIG) == 0) && (peer != &dummy_peer))
- demobilize(&peer_list, peer);
- break;
-
- case ACT_PKT:
- if (!(((peer->flags & PEER_FL_CONFIG) == 0)
- && STRMCMP(pkt->stratum, >, sys.stratum))) {
- peer->reach |= 1;
- process_packet(dst, pkt, tvp, peer);
- break;
- }
- /* Note fall-through */
- case ACT_XMIT:
- process_packet(dst, pkt, tvp, peer);
- poll_update(peer, peer->ppoll);
- transmit(peer);
- break;
-
- default:
- abort();
- }
-}
-
-#undef ACT_ERROR
-#undef ACT_RECV
-#undef ACT_XMIT
-#undef ACT_PKT
-\f
-
-/* 3.4.3 Packet procedure */
-void
-process_packet(dst, pkt, tvp, peer)
- struct sockaddr_in *dst;
- struct ntpdata *pkt;
- struct timeval *tvp;
- struct ntp_peer *peer;
-{
- double t1, t2, t3, t4, offset, delay;
- short duplicate, bogus;
-
- duplicate = (pkt->xmt.int_part == peer->org.int_part)
- && (pkt->xmt.fraction == peer->org.fraction);
-
- bogus = ((pkt->org.int_part != peer->xmt.int_part)
- || (pkt->org.fraction != peer->xmt.fraction))
- || (peer->xmt.int_part == 0);
-
- peer->pkt_rcvd++;
- peer->leap = pkt->status & LEAPMASK;
- peer->stratum = pkt->stratum;
- peer->ppoll = pkt->ppoll;
- peer->precision = pkt->precision;
- peer->distance = pkt->distance;
- peer->dispersion = pkt->dispersion;
- peer->refid = pkt->refid;
- peer->reftime = pkt->reftime;
- peer->org = pkt->xmt;
- tstamp(&peer->rec, tvp);
-#ifdef DEBUG
- if (debug > 3)
- printf("Input Timestamp is %08lx.%08lx %f\n",
- ntohl(peer->rec.int_part), ntohl(peer->rec.fraction),
- ul_fixed_to_double(&peer->rec));
-#endif
- poll_update(peer, peer->hpoll);
-
- /*
- * may want to do something special here for Broadcast Mode peers to
- * allow these through
- */
- if (bogus || duplicate
- || (pkt->org.int_part == 0 && pkt->org.fraction == 0)
- || (pkt->rec.int_part == 0 && pkt->rec.fraction == 0)) {
- peer->pkt_dropped++;
-#ifdef DEBUG
- if (debug > 3)
- printf("process_packet: dropped duplicate or bogus\n");
-#endif
- return;
- }
-
- /*
- * Now compute local adjusts
- */
- t1 = ul_fixed_to_double(&pkt->org);
- t2 = ul_fixed_to_double(&pkt->rec);
- t3 = ul_fixed_to_double(&pkt->xmt);
- t4 = ul_fixed_to_double(&peer->rec);
-#ifdef DEBUG
- if ((t1 > t4) || (t2 > t3))
- printf("process_packet: out of order timestamps %f %f %f %f\n", t1,
- t2, t3, t4);
- if (debug > 3) {
- double sys_p, peer_p;
-
- sys_p = 1.0 / (afs_uint32) (1L << -sys.precision);
- if ((sys_p < 0.000001) || (sys_p > 0.1))
- printf("process_packet: bogus sys precision %f\n", sys_p);
-
- if (peer->precision < 0
- && -peer->precision < sizeof(afs_int32) * NBBY) {
- peer_p = 1.0 / (afs_uint32) (1L << -peer->precision);
- if ((peer_p < 0.000001) || (peer_p > 0.1))
- printf("process_packet: bogus peer precision %f\n", peer_p);
- } else
- peer_p = 0;
- if ((t4 - t1) + sys_p < (t3 - t2) - peer_p)
- printf("process_packet: non-concentric interval %f %f %f %f\n",
- t1, t2, t3, t4);
- }
-#endif
-
- /*
- * although the delay computation looks different than the one in the
- * specification, it is correct. Think about it.
- */
- delay = (t2 - t1) - (t3 - t4);
- offset = ((t2 - t1) + (t3 - t4)) / 2.0;
-
- delay += 1.0 / (afs_uint32) (1L << -sys.precision)
-#ifndef REFCLOCK
- + NTP_MAXSKW;
-#else
- + (peer->flags & PEER_FL_REFCLOCK ? NTP_REFMAXSKW : NTP_MAXSKW);
-#endif
- if (peer->precision < 0 && -peer->precision < sizeof(afs_int32) * NBBY)
- delay += 1.0 / (afs_uint32) (1L << -peer->precision);
-
- if (delay < 0.0) {
- peer->pkt_dropped++;
-#ifdef DEBUG
- if (debug > 3)
- printf
- ("process_packet: negative delay %f, timestamps: %f %f %f %f\n",
- delay, t1, t2, t3, t4);
-#endif
- return;
- }
-#ifndef REFCLOCK
- delay = MAX(delay, NTP_MINDIST);
-#else
- delay =
- MAX(delay,
- (peer->flags & PEER_FL_REFCLOCK) ? NTP_REFMINDIST : NTP_MINDIST);
-#endif
-
- peer->valid = 0;
- clock_filter(peer, delay, offset); /* invoke clock filter procedure */
-#ifdef DEBUG
- if (debug) {
- printf("host: %s : %f : %f : %f : %f : %f : %o\n",
- dst ? ntoa(dst->sin_addr) : "refclock", delay, offset,
- peer->estdelay, peer->estoffset, peer->estdisp, peer->reach);
- }
-#endif
- clock_update(peer); /* call clock update procedure */
-}
-
-/* 3.4.4 Primary clock procedure */
-/*
- * We don't have a primary clock.
- *
- * TODO:
- *
- * ``When a primary clock is connected to the host, it is convient to
- * incorporate its information into the database as if the clock was
- * represented as an ordinary peer. The clock can be polled once a
- * minute or so and the returned timecheck used to produce a new update
- * for the logical clock.''
- */
-\f
-
-/* 3.4.5 Clock update procedure */
-
-void
-clock_update(peer)
- struct ntp_peer *peer;
-{
- double temp;
- extern int adj_logical();
-
- select_clock();
- if (sys.peer != NULL)
- poll_update(sys.peer, NTP_MINPOLL);
-
- /*
- * Did we just sync to this peer?
- */
- if ((peer == sys.peer) && (sys.hold == 0)) {
- char buf[200];
-
- /*
- * Update the local system variables
- */
- sys.leap = peer->leap;
-#ifndef REFCLOCK
- sys.stratum = peer->stratum + 1;
- sys.refid = peer->src.sin_addr.s_addr;
-#else
- if (peer->flags & PEER_FL_REFCLOCK) {
- /* once we re-map the stratums so that stratum 0 is
- * better than stratum 1, some of this foolishness
- * can go away */
- sys.stratum = peer->stratum;
- sys.refid = peer->refid;
- } else {
- sys.stratum = peer->stratum + 1;
- sys.refid = peer->src.sin_addr.s_addr;
- }
-#endif
-
- temp = s_fixed_to_double(&peer->distance) + peer->estdelay;
- double_to_s_fixed(&sys.distance, temp);
-
- temp = s_fixed_to_double(&peer->dispersion) + peer->estdisp;
- double_to_s_fixed(&sys.dispersion, temp);
-
- sys.reftime = peer->rec;
-
-#ifdef DEBUG
- if (debug > 3)
- printf("clock_update: synced to peer, adj clock\n");
-#endif
-
- /*
- * Sanity check: is computed offset insane?
- */
- if (peer->estoffset > WayTooBig || peer->estoffset < -WayTooBig) {
- syslog(LOG_ERR, "Clock is too far off %f sec. [%s]",
- peer->estoffset, ntoa(peer->src.sin_addr));
-#ifdef DEBUG
- if (debug)
- printf("Clock is too far off %f sec. [%s] (max %f)\n",
- peer->estoffset, ntoa(peer->src.sin_addr), WayTooBig);
-#endif /*DEBUG*/
- return;
- }
-
- clock_watchdog = 0; /* reset watchdog timer */
- if (adj_logical(peer->estoffset) > 0) {
- register struct ntp_peer *p = peer_list.head;
- /* did you know syslog only took 4 parameters? */
- sprintf(buf, "adjust: STEP %s st %d off %f drft %f cmpl %f",
- inet_ntoa(peer->src.sin_addr), peer->stratum,
- peer->estoffset, drift_comp, compliance);
- syslog(LOG_INFO, buf);
-#ifdef DEBUG
- if (debug)
- printf("Clockset from %s stratum %d offset %f\n",
- inet_ntoa(peer->src.sin_addr), peer->stratum,
- peer->estoffset);
-
-#endif
- while (p) {
- clear(p);
- p = p->next;
- }
- sys.hold = PEER_SHIFT * (1 << NTP_MINPOLL);
-#ifdef DEBUG
- if (debug > 3)
- printf("clock_updates: STEP ADJ\n");
-#endif
- } else {
- if (logstats
-#ifdef DEBUG
- || (debug > 1)
-#endif
- ) {
- sprintf(buf, "adjust: SLEW %s st %d off %f drft %f cmpl %f",
- inet_ntoa(peer->src.sin_addr), peer->stratum,
- peer->estoffset, drift_comp, compliance);
- if (logstats)
- syslog(LOG_INFO, buf);
-#ifdef DEBUG
- if (debug > 1)
- printf("%s\n", buf);
-#endif
- }
- }
- }
-}
-
-/* 3.4.6 Initialization procedure */
-
-void
-initialize()
-{
- sys.leap = ALARM; /* indicate unsynchronized */
- sys.stratum = 0;
- sys.precision = 0; /* may be specified in the config file;
- * if not, gets set in init_kern_vars() */
-#if 0 /* under construction */
- sys.keyid = 0;
- sys.keys = ? ?;
-#endif
- sys.distance.int_part = sys.distance.fraction = 0;
- sys.dispersion.int_part = sys.dispersion.fraction = 0;
- sys.refid = 0;
- sys.reftime.int_part = sys.reftime.fraction = 0;
- sys.hold = 0;
- sys.peer = NULL;
-}
-
-/* 3.4.7 Clear Procedure */
-void
-clear(peer)
- register struct ntp_peer *peer;
-{
- register int i;
-
-#ifdef DEBUG
- if (debug > 3)
- printf("clear: emptied filter for %s\n", ntoa(peer->src.sin_addr));
-#endif
- peer->hpoll = NTP_MINPOLL;
- peer->estdisp = PEER_MAXDISP;
- for (i = 0; i < NTP_WINDOW; i++)
- peer->filter.offset[i] = 0.0;
- peer->filter.samples = 0; /* Implementation specific */
- peer->valid = 0;
- peer->org.int_part = peer->org.fraction = 0;
- peer->rec.int_part = peer->rec.fraction = 0;
- peer->xmt.int_part = peer->xmt.fraction = 0;
- poll_update(peer, NTP_MINPOLL);
- select_clock();
- if (sys.peer != NULL)
- poll_update(sys.peer, NTP_MINPOLL);
-}
-
-
-/* 3.4.8 Poll Update Procedure */
-void
-poll_update(peer, new_hpoll)
- register struct ntp_peer *peer;
- int new_hpoll;
-{
- int interval;
-
- peer->hpoll = MAX(NTP_MINPOLL, MIN(NTP_MAXPOLL, new_hpoll));
-
-#if XTAL /* if crystal controlled clock */
- if (peer == sys.peer)
-#endif
- peer->hpoll = NTP_MINPOLL;
-
- interval =
- 1 <<
- (MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)), NTP_MINPOLL));
-
-#ifdef REFCLOCK
- if (peer->flags & PEER_FL_REFCLOCK)
- interval = 1 << NTP_MINPOLL;
-#endif
- if (interval == peer->timer)
- return;
-
- /* only randomize when poll interval changes */
- if (interval < peer->timer)
- peer->timer = interval;
-
- /*
- * "Rand uses a multiplicative congruential random number gen-
- * erator with period 2**32 to return successive pseudo-random
- * numbers in the range from 0 to (2**31)-1"
- */
- interval =
- (double)interval *((double)rand() /
- (double)((afs_uint32) (1L << 31) - 1));
-
-#ifdef DEBUG
- if (debug > 3)
- printf("poll_update: timer %d, poll=%d\n", peer->timer, interval);
-#endif
-}
-\f
-
-/* 3.4.9 Authentication Procedures */
-#if 0
-encrypt()
-{
-}
-
-decrypt()
-{
-}
-#endif
-\f
-/* 4.1 Clock Filter Procedure */
-/*
- * The previous incarnation of this code made the assumption that
- * the value of PEER_FILTER was a power of two and used shifting.
- * This version has been generalized, so that experimenting with
- * different PEER_FILTER values should be much easier.
- */
-
-void
-clock_filter(peer, new_delay, new_offset)
- register struct ntp_peer *peer;
- double new_delay, new_offset;
-{
- double offset[PEER_SHIFT], delay[PEER_SHIFT];
- register double temp, d, w;
- register int i, j, samples;
-
- if (peer->filter.samples < PEER_SHIFT)
- peer->filter.samples++;
- /*
- * Too bad C doesn't have a barrel shifter...
- */
- for (i = PEER_SHIFT - 1; i; i--) {
- peer->filter.offset[i] = peer->filter.offset[i - 1];
- peer->filter.delay[i] = peer->filter.delay[i - 1];
- }
- peer->filter.offset[0] = new_offset;
- peer->filter.delay[0] = new_delay;
-
- samples = 0;
- /*
- * Now sort the valid (non-zero delay) samples into a temporary
- * list by delay.
- *
- * First, build the temp list...
- */
- for (i = 0; i < peer->filter.samples; i++) {
- if (peer->filter.delay[i] != 0.0) {
- offset[samples] = peer->filter.offset[i];
- delay[samples++] = peer->filter.delay[i];
- }
- }
- /* ..and now sort it. */
- if (samples) {
- for (i = 0; i < samples - 1; i++) {
- for (j = i + 1; j < samples; j++) {
- if (delay[i] > delay[j]) {
- temp = delay[i];
- delay[i] = delay[j];
- delay[j] = temp;
- temp = offset[i];
- offset[i] = offset[j];
- offset[j] = temp;
- }
- }
- }
- /* samples are now sorted by delay */
-
- peer->estdelay = delay[0];
- peer->estoffset = offset[0];
- }
-
- temp = 0.0;
- w = 1.0;
-
- for (i = 0; i < PEER_SHIFT; i++) {
- if (i >= samples)
- d = PEER_MAXDISP;
- else {
- if ((d = offset[i] - offset[0]) < 0)
- d = -d;
- if (d > PEER_MAXDISP)
- d = PEER_MAXDISP;
- }
- temp += d * w;
- /* compute PEER_FILTER**i as we go along */
- w *= PEER_FILTER;
- }
- peer->estdisp = temp;
-#ifdef DEBUG
- if (debug > 3)
- printf("clock_filter: estdelay %f, estoffset %f, estdisp %f\n",
- peer->estdelay, peer->estoffset, peer->estdisp);
-#endif
-}
-
-/* 4.2 Clock Select Procedure */
-void
-select_clock()
-{
- struct ntp_peer *ptmp, *peer = peer_list.head;
- struct sel_lst {
- struct ntp_peer *peer;
- double distance;
- double precision;
- } sel_lst[X_NTP_CANDIDATES];
- int i, j, stratums, candidates;
- int sanity_check();
- double falsetick(), dtmp;
-
- candidates = 0;
- stratums = 0;
-
- while (peer != NULL && candidates < X_NTP_CANDIDATES) {
- /*
- * Check if this is a candidate for "sys.peer"
- */
- peer->flags &= ~(PEER_FL_SANE | PEER_FL_CANDIDATE);
- if (sanity_check(peer)) {
- sel_lst[candidates].peer = peer;
- sel_lst[candidates].distance =
- peer->estdisp + s_fixed_to_double(&peer->dispersion);
- peer->flags |= PEER_FL_SANE;
- candidates++;
- }
- peer = peer->next;
- }
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: step1 %d candidates\n", candidates);
-#endif
- /*
- * If no candidates passed the sanity check, then give up.
- */
- if (!candidates) {
- if (sys.peer != NULL) {
- syslog(LOG_INFO, "Lost NTP peer %s",
- inet_ntoa(sys.peer->src.sin_addr));
-#ifdef DEBUG
- if (debug)
- printf("Lost NTP peer %s\n",
- inet_ntoa(sys.peer->src.sin_addr));
-#endif
- }
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: no candidates\n");
-#endif
- sys.peer = NULL;
- /*
- * leave sys.stratum and sys.refid intact after losing
- * reachability to all clocks. After 24 hours, we'll
- * set the alarm condition if we didn't get any clock
- * updates.
- */
- return;
- }
-
- /*
- * Sort the list. We assume that sanity_check() above trashed any
- * peers which were stratum 0, so we can safely compare stratums
- * below. Sort the list by stratum. Where stratums are equal, the
- * peer with the lowest (peer.estdisp + peer.dispersion) is preferred.
- */
- for (i = 0; i < candidates - 1; i++) {
- for (j = i + 1; j < candidates; j++) {
- if ((sel_lst[i].peer->stratum > sel_lst[j].peer->stratum)
- || ((sel_lst[i].peer->stratum == sel_lst[j].peer->stratum)
- && (sel_lst[i].distance > sel_lst[j].distance))) {
- ptmp = sel_lst[i].peer;
- dtmp = sel_lst[i].distance;
- sel_lst[i].peer = sel_lst[j].peer;
- sel_lst[i].distance = sel_lst[j].distance;
- sel_lst[j].peer = ptmp;
- sel_lst[j].distance = dtmp;
- }
- }
- }
-
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: step2 %d candidates\n", candidates);
-#endif
-
- /* truncate the list at NTP_MAXLIST peers */
- if (candidates > NTP_MAXLIST)
- candidates = NTP_MAXLIST;
-
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: step3 %d candidates\n", candidates);
-#endif
-
- /* truncate list where number of different strata exceeds NTP_MAXSTRA */
- for (stratums = 0, i = 1; i < candidates; i++) {
- if (sel_lst[i - 1].peer->stratum != sel_lst[i].peer->stratum) {
- if (++stratums > NTP_MAXSTRA) {
-#ifdef DEBUG
- if (debug > 2)
- printf("select_clock: truncated to %d peers\n", i);
-#endif
- candidates = i;
-
- break;
- }
- }
- }
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: step4 %d candidates\n", candidates);
-#endif
- /*
- * Kick out falsetickers
- */
- /* now, re-sort the list by peer.stratum and peer.estdelay */
- for (i = 0; i < candidates - 1; i++) {
- for (j = i + 1; j < candidates; j++) {
- if ((sel_lst[i].peer->stratum > sel_lst[j].peer->stratum)
- || ((sel_lst[i].peer->stratum == sel_lst[j].peer->stratum)
- && (sel_lst[i].peer->estdelay >
- sel_lst[j].peer->estdelay))) {
- ptmp = sel_lst[i].peer;
- sel_lst[i].peer = sel_lst[j].peer;
- sel_lst[j].peer = ptmp;
- }
- }
- }
- while (candidates > 1) {
- double maxdispersion = 0.0, dispersion, weight;
- double min_precision_thres = 10e20, precision_thres;
- short worst = 0; /* shut up GNU CC about unused var */
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: step5 %d candidates\n", candidates);
-#endif
- for (i = 0; i < candidates; i++) {
- /* compute dispersion of candidate `i' relative to the
- * rest of the candidates */
- dispersion = 0.0;
- weight = 1.0;
- sel_lst[i].peer->flags |= PEER_FL_CANDIDATE;
- for (j = 0; j < candidates; j++) {
- dtmp =
- sel_lst[j].peer->estoffset - sel_lst[i].peer->estoffset;
- if (dtmp < 0)
- dtmp = -dtmp;
- dispersion += dtmp * weight;
- weight *= NTP_SELECT;
- }
- /* since we just happen to have this double floating
- * around.. */
- sel_lst[i].distance = dispersion;
-
- precision_thres = NTP_MAXSKW + 1.0 / (1 << -sys.precision);
- if (sel_lst[i].peer->precision < 0
- && -sel_lst[i].peer->precision < sizeof(afs_int32) * NBBY)
- precision_thres += 1.0 / (1 << -sel_lst[i].peer->precision);
-
- sel_lst[i].precision = precision_thres;
-
- if (dispersion >= maxdispersion) {
- maxdispersion = dispersion;
- worst = i;
- }
- if (precision_thres < min_precision_thres) {
- min_precision_thres = precision_thres;
- }
-#ifdef DEBUG
- if (debug > 4) {
- printf(" peer %s => disp %f prec_th %f\n",
- ntoa(sel_lst[i].peer->src.sin_addr), dispersion,
- precision_thres);
- }
-#endif
- }
- /*
- * Now check to see if the max dispersion is greater than
- * the min dispersion limit. If so, crank again, otherwise
- * bail out.
- */
- if (!(maxdispersion > min_precision_thres)) {
-#ifdef DEBUG
- if (debug > 4)
- printf(" %d left valid\n", candidates);
-#endif
- break;
- }
-#ifdef DEBUG
- if (debug > 4)
- printf(" peer %s => TOSS\n",
- ntoa(sel_lst[worst].peer->src.sin_addr));
-#endif
- /*
- * now, we need to trash the peer with the worst dispersion
- * and interate until there is only one candidate peer left.
- */
- if (worst != candidates - 1) {
- sel_lst[worst].peer->flags &= ~PEER_FL_CANDIDATE;
- for (i = worst, j = worst + 1; j < candidates;)
- sel_lst[i++].peer = sel_lst[j++].peer;
- }
- candidates--;
- /* one more time.. */
- }
-#ifdef DEBUG
- if (debug > 3)
- printf("select_clock: step6 %d candidates\n", candidates);
-#endif
-
- /*
- * Check to see if current peer is on the list of candidate peers. If
- * don't change sys.peer. Note that if the first selected clock is
- * at a lower stratum, don't even bother; we're going to want to
- * switch to it.
- */
- if (sys.peer != NULL && (sys.peer->stratum <= sel_lst[0].peer->stratum)) {
- for (i = 0; i < candidates; i++) {
- if (sys.peer == sel_lst[i].peer) {
- /*
- * The clock we're currently synchronized to
- * is among the candidate peers. Don't switch.
- */
- if (i != 0) {
- /*
- * Count instances where the best
- * candidate is different from the
- * current clock, thus inhibiting
- * clockhopping.
- */
- peer_sw_inhibited++;
- }
- return;
- }
- }
- }
-
- /*
- * The currently selected peer (if any) isn't on the candidate list.
- * Grab the first one and let it be.
- */
-
- if (sys.peer != sel_lst[0].peer) {
- if (sys.peer != NULL)
- syslog(LOG_INFO,
- "clock: select peer %s stratum %d was %s stratum %d",
- ntoa(sel_lst[0].peer->src.sin_addr),
- sel_lst[0].peer->stratum, ntoa(sys.peer->src.sin_addr),
- sys.peer->stratum);
- else
- syslog(LOG_INFO, "clock: select peer %s stratum %d was UNSYNCED",
- ntoa(sel_lst[0].peer->src.sin_addr),
- sel_lst[0].peer->stratum);
-
-#ifdef DEBUG
- if (debug > 2)
- printf("clock: select peer %s stratum %d of %d cand\n",
- ntoa(sel_lst[0].peer->src.sin_addr),
- sel_lst[0].peer->stratum, candidates);
-#endif
- sys.peer = sel_lst[0].peer;
- peer_switches++;
- }
-}
-
-int
-sanity_check(peer)
- struct ntp_peer *peer;
-{
-#ifdef DEBUG
- if (debug > 7)
- printf("Checking peer %s stratum %d\n", inet_ntoa(peer->src.sin_addr),
- peer->stratum);
-#endif
- /* Sanity check 0. ?? */
- if (!(peer->flags & PEER_FL_SYNC))
- return (0);
-
- /* Sanity check 1. */
- if (peer->stratum <= 0 || peer->stratum >= NTP_INFIN)
- return (0);
-
- /* Sanity check 2.
- * if peer.stratum is greater than one (synchronized via NTP),
- * peer.refid must not match peer.dstadr */
-
- if (peer->stratum > 1) {
- register int i;
- for (i = 1; i < nintf; i++)
- if (addrs[i].sin.sin_addr.s_addr == peer->refid)
- return (0);
- }
-
- /* Sanity check 3.
- * Both peer.estdelay and
- * peer.estdisp to be less than NTP_MAXWGT, which insures that the
- * filter register at least half full, yet avoids using data from
- * very noisy associations or broken implementations. */
- if (peer->estdisp > (float)NTP_MAXWGT
- || peer->estdelay > (float)NTP_MAXWGT)
- return (0);
-
- /* Sanity check 4.
- * The peer clock must be synchronized... and the interval since
- * the peer clock was last updated satisfy
- *
- * peer.org - peer.reftime < NTP.MAXAGE
- */
- if (peer->leap == ALARM || (ul_fixed_to_double(&peer->org)
- - ul_fixed_to_double(&peer->reftime)) >=
- NTP_MAXAGE)
- return (0);
-
-#ifdef DEBUG
- if (debug > 7)
- printf("That one is certainly qualified %s\n",
- inet_ntoa(peer->src.sin_addr));
-#endif
- return (1);
-}
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/types.h>
-#include <sys/param.h>
-#ifdef AFS_SUN5_ENV
-#define BSD_COMP
-#endif
-#include <sys/ioctl.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <errno.h>
-#include <syslog.h>
-#include <stdio.h>
-#include "ntp.h"
-
-#define MAX_INTF 10
-struct intf addrs[MAX_INTF];
-int nintf;
-
-#ifdef TEST
-extern int errno;
-
-#include "AFS_component_version_number.c"
-
-main()
-{
- int i, cc, val;
- char foo[10];
-
- syslog(LOG_ERR, "ifconfig test");
- create_sockets(htons(43242));
- for (i = 0; i < nintf; i++) {
- printf("%d: %s fd %d addr %s mask %x ", i, addrs[i].name,
- addrs[i].fd, inet_ntoa(addrs[i].sin.sin_addr.s_addr),
- ntohl(addrs[i].mask.sin_addr.s_addr));
- cc = sizeof(val);
- if (getsockopt
- (addrs[0].fd, SOL_SOCKET, SO_BROADCAST, (char *)&val, &cc)) {
- perror("getsockopt");
- exit(1);
- }
- printf("BCAST opt %d", val);
- cc = sizeof(val);
- if (getsockopt(addrs[0].fd, SOL_SOCKET, SO_RCVBUF, (char *)&val, &cc)) {
- perror("getsockopt");
- exit(1);
- }
- printf("sockbuf size = %d ", val);
- putchar('\n');
- }
-
- for (i = 0; i < nintf; i++) {
- fprintf(stderr, "Read fd %d.. ", addrs[i].fd);
- cc = read(addrs[i].fd, foo, 10);
- fprintf(stderr, " returns %d ", cc);
- perror("read errno");
- }
-}
-#endif
-
-#ifndef SIOCGIFCONF
-/*
- * If we can't determine the interface configuration, just listen with one
- * socket at the INADDR_ANY address.
- */
-create_sockets(port)
- unsigned int port;
-{
- addrs[0].sin.sin_family = AF_INET;
- addrs[0].sin.sin_port = 0;
- addrs[0].sin.sin_addr.s_addr = INADDR_ANY;
- addrs[0].sin.sin_mask.s_addr = htonl(~0);
- addrs[0].name = "wildcard";
-
- if ((addrs[0].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "socket() failed: %m");
-#ifdef TEST
- perror("socket() failed");
-#endif
- exit(1);
- /*NOTREACHED*/}
-
- if (fcntl(addrs[i].fd, F_SETFL, FNDELAY) < 0) {
- syslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
-#ifdef TEST
- perror("fcntl(FNDELAY) fails");
-#endif
- exit(1);
- /*NOTREACHED*/}
- addrs[0].sin.sin_family = AF_INET;
- addrs[0].sin.sin_port = port;
- addrs[0].if_flags = 0;
- if (bind
- (addrs[0].fd, (struct sockaddr *)&addrs[0].sin,
- sizeof(addrs[0].sin)) < 0) {
- syslog(LOG_ERR, "bind() fails: %m");
-#ifdef TEST
- perror("bind fails\n");
-#endif
- exit(1);
- }
- nintf = 1;
- return nintf;
-}
-#else
-/*
- * Grab interface configuration, and create a socket for each interface
- * address.
- */
-create_sockets(port)
- unsigned int port;
-{
- char buf[1024];
- struct ifconf ifc;
- struct ifreq ifreq, *ifr;
- int on = 1, off = 0;
- int n, i, vs;
- extern char *malloc();
-
- /*
- * create pseudo-interface with wildcard address
- */
- addrs[nintf].sin.sin_family = AF_INET;
- addrs[nintf].sin.sin_port = 0;
- addrs[nintf].sin.sin_addr.s_addr = INADDR_ANY;
- addrs[nintf].name = "wild";
- addrs[nintf].mask.sin_addr.s_addr = htonl(~0);
-
- nintf = 1;
-
- if ((vs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "vs=socket(AF_INET, SOCK_DGRAM) %m");
-#ifdef TEST
- perror("vs=socket(AF_INET, SOCK_DGRAM)");
-#endif
- exit(1);
- }
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
- if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {
- syslog(LOG_ERR, "get interface configuration: %m");
-#ifdef TEST
- perror("ioctl(SIOCGIFCONF) fails");
-#endif
- exit(1);
- }
- n = ifc.ifc_len / sizeof(struct ifreq);
-
- for (ifr = ifc.ifc_req; n > 0; n--, ifr++) {
- if (ifr->ifr_addr.sa_family != AF_INET)
- continue;
- ifreq = *ifr;
- if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "get interface flags: %m");
-#ifdef TEST
- perror("SIOCGIFFFLAGS fails");
-#endif
- continue;
- }
- if ((ifreq.ifr_flags & IFF_UP) == 0)
- continue;
- addrs[nintf].if_flags = ifreq.ifr_flags;
-
- if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "get interface addr: %m");
-#ifdef TEST
- perror("SIOCGIFADDR fails");
-#endif
- continue;
- }
- if ((addrs[nintf].name = malloc(strlen(ifreq.ifr_name) + 1))
- == NULL) {
- syslog(LOG_ERR, "malloc failed");
- exit(1);
- }
- strcpy(addrs[nintf].name, ifreq.ifr_name);
- addrs[nintf].sin = *(struct sockaddr_in *)&ifreq.ifr_addr;
-
-#ifdef SIOCGIFBRDADDR
- if (addrs[nintf].if_flags & IFF_BROADCAST) {
- if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "SIOCGIFBRDADDR fails");
-#ifdef TEST
- perror("SIOCGIFBRDADDR fails");
-#endif
- exit(1);
- }
-#ifdef ifr_broadaddr
- addrs[nintf].bcast = *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
-#else
- addrs[nintf].bcast = *(struct sockaddr_in *)&ifreq.ifr_addr;
-#endif
- }
-#endif /* SIOCGIFBRDADDR */
-#ifdef SIOCGIFNETMASK
- if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "SIOCGIFNETMASK fails");
-#ifdef TEST
- perror("SIOCGIFNETMASK fails");
-#endif
- exit(1);
- }
- addrs[nintf].mask = *(struct sockaddr_in *)&ifreq.ifr_addr;
-#endif /* SIOCGIFNETMASK */
-
- /*
- * look for an already existing source interface address. If
- * the machine has multiple point to point interfaces, then
- * the local address may appear more than once.
- */
- for (i = 0; i < nintf; i++)
- if (addrs[i].sin.sin_addr.s_addr ==
- addrs[nintf].sin.sin_addr.s_addr) {
-#ifdef TEST
- printf("dup interface address %s on %s\n",
- inet_ntoa(addrs[nintf].sin.sin_addr.s_addr),
- ifreq.ifr_name);
-#endif
- goto next;
- }
- nintf++;
- next:;
- }
- close(vs);
-
- for (i = 0; i < nintf; i++) {
- /* create a datagram (UDP) socket */
- if ((addrs[i].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "socket() failed: %m");
-#ifdef TEST
- perror("socket(AF_INET, SOCK_DGRAM) fails");
-#endif
- exit(1);
- /*NOTREACHED*/}
-
- /* set SO_REUSEADDR since we will be binding the same port
- * number on each interface */
- if (setsockopt
- (addrs[i].fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
- sizeof(on))) {
-#ifdef TEST
- perror("setsockopt SO_REUSEADDR on");
-#endif
- syslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m");
- }
-
- /*
- * set non-blocking I/O on the descriptor
- */
- if (fcntl(addrs[i].fd, F_SETFL, FNDELAY) < 0) {
- syslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
-#ifdef TEST
- perror("fcntl(F_SETFL, FNDELAY) fails");
-#endif
- exit(1);
- /*NOTREACHED*/}
-
- /*
- * finally, bind the local address address.
- */
- addrs[i].sin.sin_family = AF_INET;
- addrs[i].sin.sin_port = port;
- if (bind
- (addrs[i].fd, (struct sockaddr *)&addrs[i].sin,
- sizeof(addrs[i].sin)) < 0) {
- syslog(LOG_ERR, "bind() fails: %m");
-#ifdef TEST
- perror("bind fails");
-#endif
- exit(1);
- }
-
- /*
- * Turn off the SO_REUSEADDR socket option. It apparently
- * causes heartburn on systems with multicast IP installed.
- * On normal systems it only gets looked at when the address
- * is being bound anyway..
- */
- if (setsockopt
- (addrs[i].fd, SOL_SOCKET, SO_REUSEADDR, (char *)&off,
- sizeof(off))) {
- syslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
-#ifdef TEST
- perror("setsockopt SO_REUSEADDR off");
-#endif
- }
-#ifdef SO_BROADCAST
- /* if this interface can support broadcast, set SO_BROADCAST */
- if (addrs[i].if_flags & IFF_BROADCAST) {
- if (setsockopt
- (addrs[i].fd, SOL_SOCKET, SO_BROADCAST, (char *)&on,
- sizeof(on))) {
- syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
-#ifdef TEST
- perror("setsockopt(SO_BROADCAST) on");
-#endif
- }
- }
-#endif /* SO_BROADCAST */
- }
- return nintf;
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#if defined(AFS_SGI_ENV)
-#define NOSWAP 1
-#endif
-#include <stdio.h>
-#ifdef AFS_AIX32_ENV
-#include <signal.h>
-#endif
-#ifdef AFS_SUN5_ENV
-#include <signal.h>
-#endif
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#ifdef AFS_SUN5_ENV
-#define BSD_COMP
-#endif
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <sys/file.h>
-#ifdef NOSWAP
-#include <sys/lock.h>
-#endif
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <strings.h>
-#include <errno.h>
-#include <syslog.h>
-#ifndef LOG_NTP
-#define LOG_NTP LOG_DAEMON
-#endif
-#ifdef AFS_SUN5_ENV
-#include <libelf.h>
-#endif
-#include <nlist.h>
-
-#ifdef AFS_AIX32_ENV
-#include <sys/select.h>
-#include <sys/signal.h>
-#endif
-
-#ifdef AFS_HPUX_ENV
-#include <signal.h>
-#endif
-
-#include "ntp.h"
-#include "patchlevel.h"
-
-#define TRUE 1
-#define FALSE 0
-
-struct sockaddr_in dst_sock = { AF_INET };
-
-struct servent *servp;
-struct list peer_list;
-
-struct itimerval it;
-struct itimerval *itp = ⁢
-struct timeval tv;
-char *prog_name;
-
-char *conf = NTPINITFILE;
-char *driftcomp_file = NTPDRIFTCOMP;
-static int drift_fd = -1;
-
-#ifdef DEBUG
-int debug = 0;
-#endif
-
-int tickadj = 0;
-int dotickadj = 0;
-int dosynctodr = 0;
-
-#ifdef NOSWAP
-int noswap = 0;
-#endif
-
-int doset = 1;
-int ticked;
-int selfds;
-int trusting = 1;
-int logstats;
-
-double WayTooBig = WAYTOOBIG;
-afs_uint32 clock_watchdog;
-
-struct ntpdata ntpframe;
-struct sysdata sys;
-
-extern int errno;
-extern char *malloc(), *ntoa();
-extern double s_fixed_to_double(), ul_fixed_to_double();
-
-void finish(), timeout(), tock(), make_new_peer(), init_ntp(), initialize(),
-hourly();
-extern void transmit(), process_packet(), clock_update(), clear(),
-clock_filter(), select_clock();
-
-extern void init_logical_clock();
-
-#if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
-#define SETTICKADJ
-#endif
-
-#if !defined(AFS_SUN5_ENV)
-#define INIT_KERN_VARS
-#endif
-
-#if defined(INIT_KERN_VARS)
-void init_kern_vars();
-#endif /* INIT_KERN_VARS */
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char *argv[];
-{
- struct sockaddr_in *dst = &dst_sock;
- struct ntpdata *pkt = &ntpframe;
- fd_set readfds, tmpmask;
- int dstlen = sizeof(struct sockaddr_in);
- int cc;
- int dontFork = 0;
- register int i;
- extern char *optarg;
- extern int atoi();
-
-#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
- void incdebug(), decdebug();
-#endif
-
-#ifdef AFS_AIX32_ENV
- /*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
- * in the core dump. Unfortunately, by default, only a partial core is
- * generated which, in many cases, isn't too useful.
- */
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGSEGV, &nsa, NULL);
-#endif
- initialize(); /* call NTP protocol initialization first,
- * then allow others to override default
- * values */
- prog_name = argv[0];
- while ((cc = getopt(argc, argv, "a:c:dD:lstrnf")) != EOF) {
- switch (cc) {
- case 'a':
- if (strcmp(optarg, "any") == 0)
- WayTooBig = 10e15;
- else
- WayTooBig = atof(optarg);
- break;
-
- case 'd':
-#ifdef DEBUG
- debug++;
-#else
- fprintf(stderr, "%s: not compiled with DEBUG\n", prog_name);
-#endif
- break;
-
- case 'D':
-#ifdef DEBUG
- debug = atoi(optarg);
-#else
- fprintf(stderr, "%s: not compiled with DEBUG\n", prog_name);
-#endif
- break;
-
- case 's':
- doset = 0;
- break;
-
- case 't':
-#ifdef SETTICKADJ
- dotickadj++;
-#else
- fprintf(stderr, "%s: not compiled to set tickadj\n", prog_name);
-#endif
- break;
-
- case 'r':
-#ifdef SETTICKADJ
- dosynctodr++;
-#else
- fprintf(stderr, "%s: not compiled to set kernel variables\n",
- prog_name);
-#endif
- break;
-
- case 'n':
-#ifdef NOSWAP
- noswap = 1;
-#else
- fprintf(stderr, "%s: not compiled for noswap\n", prog_name);
-#endif
- break;
-
- case 'l':
- logstats = 1;
- break;
-
- case 'c':
- conf = optarg;
- break;
-
- case 'f':
- dontFork = 1;
- break;
-
- default:
- fprintf(stderr, "ntpd: -%c: unknown option\n", cc);
- break;
- }
- }
-
-#ifdef DEBUG
- if (!debug && !dontFork)
-#else
- if (!dontFork)
-#endif
- {
- if (fork())
- exit(0);
-
- {
- int s;
- for (s = getdtablesize(); s >= 0; s--)
- (void)close(s);
- (void)open("/", 0);
- (void)dup2(0, 1);
- (void)dup2(0, 2);
- (void)setpgrp(0, getpid());
- s = open("/dev/tty", 2);
- if (s >= 0) {
-#ifndef AFS_HPUX_ENV
- (void)ioctl(s, (afs_uint32) TIOCNOTTY, NULL);
-#endif
- (void)close(s);
- }
- }
- }
-
- openlog("ntpd", LOG_PID | LOG_NDELAY, LOG_NTP);
-#ifdef DEBUG
- if (debug)
- setlogmask(LOG_UPTO(LOG_DEBUG));
- else
-#endif /* DEBUG */
- setlogmask(LOG_UPTO(LOG_INFO));
-
- syslog(LOG_NOTICE, "%s version $Revision$", prog_name);
- syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
-
-#ifdef DEBUG
- if (debug)
- printf("%s version $Revision$ patchlevel %d\n", prog_name,
- PATCHLEVEL);
-#endif
-#if defined(AFS_AIX_ENV)
- (void)nice(-10);
-#else
-#if defined(AFS_HPUX_ENV)
- (void)rtprio(0, 90);
-#else
- (void)setpriority(PRIO_PROCESS, 0, -10);
-#endif
-#endif
-
-#ifdef NOSWAP
- if (noswap)
- if (plock(PROCLOCK) != 0) {
- syslog(LOG_ERR, "plock() failed: %m");
-#ifdef DEBUG
- if (debug)
- perror("plock() failed");
-#endif
- }
-#endif
-
- servp = getservbyname("ntp", "udp");
- if (servp == NULL) {
- syslog(LOG_CRIT, "udp/ntp: service unknown, using default %d",
- NTP_PORT);
- (void)create_sockets(htons(NTP_PORT));
- } else
- (void)create_sockets(servp->s_port);
-
-
- peer_list.head = peer_list.tail = NULL;
- peer_list.members = 0;
-
- init_ntp(conf);
-#if defined(INIT_KERN_VARS)
- init_kern_vars();
-#endif /* INIT_KERN_VARS */
- init_logical_clock();
-
- /*
- * Attempt to open for writing the file for storing the drift comp
- * register. File must already exist for snapshots to be taken.
- */
- if ((i = open(driftcomp_file, O_WRONLY | O_CREAT, 0644)) >= 0) {
- drift_fd = i;
- }
- (void)gettimeofday(&tv, NULL);
- srand(tv.tv_sec);
-
- FD_ZERO(&tmpmask);
- for (i = 0; i < nintf; i++) {
- FD_SET(addrs[i].fd, &tmpmask);
-#ifdef DEBUG
- if (debug > 2) {
- if (addrs[i].if_flags & IFF_BROADCAST)
- printf("Addr %d: %s fd %d %s broadcast %s\n", i,
- addrs[i].name, addrs[i].fd,
- ntoa(addrs[i].sin.sin_addr),
- ntoa(addrs[i].bcast.sin_addr));
- else
- printf("Addr %d: %s fd %d %s\n", i, addrs[i].name,
- addrs[i].fd, ntoa(addrs[i].sin.sin_addr));
- }
-#endif
- }
-
- (void)signal(SIGINT, finish);
- (void)signal(SIGTERM, finish);
- (void)signal(SIGALRM, tock);
-#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
- (void)signal(SIGUSR1, incdebug);
- (void)signal(SIGUSR2, decdebug);
-#endif
- itp->it_interval.tv_sec = (1 << CLOCK_ADJ);
- itp->it_interval.tv_usec = 0;
- itp->it_value.tv_sec = 1;
- itp->it_value.tv_usec = 0;
-
- /*
- * Find highest fd in use. This might save a few microseconds in
- * the select system call.
- */
- for (selfds = FD_SETSIZE - 1; selfds; selfds--)
- if (FD_ISSET(selfds, &tmpmask))
- break;
-#ifdef DEBUG
- if (debug > 2)
- printf("Highest fd in use is %d\n", selfds);
- if (!selfds)
- abort();
-#endif
- selfds++;
-
- (void)setitimer(ITIMER_REAL, itp, NULL);
-
- for (;;) { /* go into a finite but hopefully very long
- * loop */
- int nfds;
-
- readfds = tmpmask;
- nfds = select(selfds, &readfds, (fd_set *) 0, (fd_set *) 0, NULL);
- (void)gettimeofday(&tv, NULL);
-
- for (i = 0; i < nintf && nfds; i++) {
- if (!FD_ISSET(addrs[i].fd, &readfds))
- continue;
- addrs[i].uses++;
- dstlen = sizeof(struct sockaddr_in);
- if ((cc =
- recvfrom(addrs[i].fd, (char *)pkt, sizeof(ntpframe), 0,
- (struct sockaddr *)dst, &dstlen)) < 0) {
-
- if (errno != EWOULDBLOCK) {
- syslog(LOG_ERR, "recvfrom: %m");
-#ifdef DEBUG
- if (debug > 2)
- perror("recvfrom");
-#endif
- }
- continue;
- }
-
- /* hpux seems to generate these zero's randomly */
- if (cc == 0)
- continue;
-
- if (cc < sizeof(*pkt)) {
-#ifdef DEBUG
- if (debug)
- printf
- ("Runt packet from %s, got %d bytes, should be %d\n",
- ntoa(dst->sin_addr), cc, sizeof(*pkt));
-#endif
- continue;
- } else if (cc > sizeof(*pkt)) {
-#ifdef DEBUG
- if (debug)
- printf
- ("too many chars returned by recvfrom. Host %s, got %d bytes, should be %d\n",
- ntoa(dst->sin_addr), cc, sizeof(*pkt));
-#endif
- continue;
- }
-
- if (pkt->stratum == INFO_QUERY || pkt->stratum == INFO_REPLY) {
- query_mode(dst, pkt, i);
- continue;
- }
-#ifdef DEBUG
- if (debug > 3) {
- printf("\nInput ");
- dump_pkt(dst, pkt, NULL);
- }
-#endif
- if ((pkt->status & VERSIONMASK) != NTPVERSION_1)
- continue;
-
- receive(dst, pkt, &tv, i);
- }
- if (ticked) {
- ticked = 0;
- timeout();
- }
- } /* end of forever loop */
-}
-
-struct ntp_peer *
-check_peer(dst, sock)
- struct sockaddr_in *dst;
- int sock;
-{
- register struct ntp_peer *peer = peer_list.head;
-
- while (peer != NULL) {
- if ((peer->src.sin_addr.s_addr == dst->sin_addr.s_addr)
- && (peer->src.sin_port == dst->sin_port) && ((peer->sock == sock)
- || (peer->sock ==
- -1)))
- return peer;
- peer = peer->next;
- }
- return ((struct ntp_peer *)NULL);
-}
-
-#ifdef DEBUG
-dump_pkt(dst, pkt, peer)
- struct sockaddr_in *dst;
- struct ntpdata *pkt;
- struct ntp_peer *peer;
-{
- struct in_addr clock_host;
-
- printf("Packet: [%s](%d)\n", inet_ntoa(dst->sin_addr),
- (int)htons(dst->sin_port));
- printf("Leap %d, version %d, mode %d, poll %d, precision %d stratum %d",
- (pkt->status & LEAPMASK) >> 6, (pkt->status & VERSIONMASK) >> 3,
- pkt->status & MODEMASK, pkt->ppoll, pkt->precision, pkt->stratum);
- switch (pkt->stratum) {
- case 0:
- case 1:
- printf(" (%.4s)\n", (char *)&pkt->refid);
- break;
- default:
- clock_host.s_addr = (afs_uint32) pkt->refid;
- printf(" [%s]\n", inet_ntoa(clock_host));
- break;
- }
- printf("Synch Dist is %04X.%04X Synch Dispersion is %04X.%04X\n",
- ntohs((u_short) pkt->distance.int_part),
- ntohs((u_short) pkt->distance.fraction),
- ntohs((u_short) pkt->dispersion.int_part),
- ntohs((u_short) pkt->dispersion.fraction));
- printf("Reference Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->reftime.int_part), ntohl(pkt->reftime.fraction),
- ul_fixed_to_double(&pkt->reftime));
- printf("Originate Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->org.int_part), ntohl(pkt->org.fraction),
- ul_fixed_to_double(&pkt->org));
- printf("Receive Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->rec.int_part), ntohl(pkt->rec.fraction),
- ul_fixed_to_double(&pkt->rec));
- printf("Transmit Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->xmt.int_part), ntohl(pkt->xmt.fraction),
- ul_fixed_to_double(&pkt->xmt));
- if (peer != NULL)
- printf("Input Timestamp is %08lx.%08lx %f\n",
- ntohl(peer->rec.int_part), ntohl(peer->rec.fraction),
- ul_fixed_to_double(&peer->rec));
- putchar('\n');
-}
-#endif
-
-void
-make_new_peer(peer)
- struct ntp_peer *peer;
-{
- int i;
-
- /*
- * initialize peer data fields
- */
- peer->src.sin_family = AF_INET;
- peer->src.sin_port = 0;
- peer->src.sin_addr.s_addr = 0;
- peer->hmode = MODE_SYM_PAS; /* default: symmetric passive mode */
- peer->flags = 0;
- peer->timer = 1 << NTP_MINPOLL;
- peer->stopwatch = 0;
- peer->hpoll = NTP_MINPOLL;
- double_to_s_fixed(&peer->dispersion, PEER_MAXDISP);
- peer->reach = 0;
- peer->estoffset = 0.0;
- peer->estdelay = 0.0;
- peer->org.int_part = peer->org.fraction = 0;
- peer->rec.int_part = peer->rec.fraction = 0;
- peer->filter.samples = 0;
- for (i = 0; i < NTP_WINDOW; i++) {
- peer->filter.offset[i] = 0.0;
- peer->filter.delay[i] = 0.0;
- }
- peer->pkt_sent = 0;
- peer->pkt_rcvd = 0;
- peer->pkt_dropped = 0;
-}
-
-/*
- * This procedure is called to delete a peer from our list of peers.
- */
-void
-demobilize(l, peer)
- struct list *l;
- struct ntp_peer *peer;
-{
- extern struct ntp_peer dummy_peer;
-
- if (peer == &dummy_peer)
-#ifdef DEBUG
- abort();
-#else
- return;
-#endif
-
-#ifdef DEBUG
- if ((peer->next == NULL && peer->prev == NULL) || l->tail == NULL
- || l->head == NULL)
- abort();
-#endif
-
- /* delete only peer in list? */
- if (l->head == l->tail) {
-#ifdef DEBUG
- if (l->head != peer)
- abort();
-#endif
- l->head = l->tail = NULL;
- goto dropit;
- }
-
- /* delete first peer? */
- if (l->head == peer) {
- l->head = peer->next;
- l->head->prev = NULL;
- goto dropit;
- }
-
- /* delete last peer? */
- if (l->tail == peer) {
- l->tail = peer->prev;
- l->tail->next = NULL;
- goto dropit;
- }
-
- /* drop peer in middle */
- peer->prev->next = peer->next;
- peer->next->prev = peer->prev;
-
- dropit:
-#ifdef DEBUG
- /* just some sanity checking */
- if ((l->members <= 0) || (l->members && l->tail == NULL)
- || (l->members == 0 && l->tail != NULL)) {
- syslog(LOG_ERR, "List hosed (demobilize)");
- abort();
- }
- peer->next = peer->prev = NULL;
-#endif
- free((char *)peer);
- l->members--;
-
- return;
-}
-
-enqueue(l, peer)
- register struct list *l;
- struct ntp_peer *peer;
-{
- l->members++;
- if (l->tail == NULL) {
- /* insertion into empty list */
- l->tail = l->head = peer;
- peer->next = peer->prev = NULL;
- return;
- }
-
- /* insert at end of list */
- l->tail->next = peer;
- peer->next = NULL;
- peer->prev = l->tail;
- l->tail = peer;
-}
-\f
-/* XXX */
-/*
- * Trivial signal handler.
- */
-void
-tock(x)
-{
- ticked = 1;
-
- /* re-enable self (we're not BSD any more) */
- (void)signal(SIGALRM, tock);
-}
-
-void
-timeout()
-{
- static int periodic = 0;
- register struct ntp_peer *peer = peer_list.head, *next;
-#ifndef XADJTIME2
- extern void adj_host_clock();
-
- adj_host_clock();
-#endif
- /*
- * Count down sys.hold if necessary.
- */
- if (sys.hold) {
- if (sys.hold <= (1 << CLOCK_ADJ))
- sys.hold = 0;
- else
- sys.hold -= (1 << CLOCK_ADJ);
- }
- /*
- * If interval has expired blast off an NTP to that host.
- */
- while (peer != NULL) {
-#ifdef DEBUG
- if (peer->next == NULL && peer != peer_list.tail) {
- printf("Broken peer list\n");
- syslog(LOG_ERR, "Broken peer list");
- abort();
- }
-#endif
- next = peer->next;
- if (peer->reach != 0 || peer->hmode != MODE_SERVER) {
- peer->stopwatch += (1 << CLOCK_ADJ);
- if (peer->timer <= peer->stopwatch) {
- transmit(peer);
- peer->stopwatch = 0;
- }
- }
- peer = next;
- }
-
- periodic += (1 << CLOCK_ADJ);
- if (periodic >= 60 * 60) {
- periodic = 0;
- hourly();
- }
-
- clock_watchdog += (1 << CLOCK_ADJ);
- if (clock_watchdog >= NTP_MAXAGE) {
- /* woof, woof - barking dogs bite! */
- sys.leap = ALARM;
- if (clock_watchdog < NTP_MAXAGE + (1 << CLOCK_ADJ)) {
- syslog(LOG_ERR, "logical clock adjust timeout (%d seconds)",
- NTP_MAXAGE);
-#ifdef DEBUG
- if (debug)
- printf("logical clock adjust timeout (%d seconds)\n",
- NTP_MAXAGE);
-#endif
- }
- }
-#ifdef DEBUG
- if (debug)
- (void)fflush(stdout);
-#endif
-}
-\f
-
-/*
- * init_ntp() reads NTP daemon configuration information from disk file.
- */
-void
-init_ntp(config)
- char *config;
-{
- struct sockaddr_in sin;
- char ref_clock[5];
- char name[81];
- FILE *fp;
- int error = FALSE, c;
- struct ntp_peer *peer;
- int precision;
- int stratum;
- int i;
- int debuglevel;
- int stagger = 0;
- double j;
- extern double drift_comp;
-
- memset((char *)&sin, 0, sizeof(sin));
- fp = fopen(config, "r");
- if (fp == NULL) {
- fprintf(stderr, "Problem opening NTP initialization file %s\n",
- config);
- syslog(LOG_ERR, "Problem opening NTP initialization file %s", config);
- exit(1);
- }
-
- while (fscanf(fp, "%s", name) != EOF) { /* read first word of line
- * and compare to key words */
- if (strcmp(name, "maxpeers") == 0) {
- if (fscanf(fp, "%d", &sys.maxpeers) != 1)
- error = TRUE;
- } else if (strcmp(name, "trusting") == 0) {
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
- else {
- if (*name == 'Y' || *name == 'y') {
- trusting = 1;
- } else if (*name == 'N' || *name == 'n') {
- trusting = 0;
- } else
- trusting = atoi(name);
- }
- } else if (strcmp(name, "logclock") == 0) {
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
- else {
- if (*name == 'Y' || *name == 'y') {
- logstats = 1;
- } else if (*name == 'N' || *name == 'n') {
- logstats = 0;
- } else
- logstats = atoi(name);
- }
- } else if (strcmp(name, "driftfile") == 0) {
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
- else {
- if (driftcomp_file = malloc(strlen(name) + 1))
- strcpy(driftcomp_file, name);
- }
- } else if (strcmp(name, "waytoobig") == 0
- || strcmp(name, "setthreshold") == 0) {
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
- else {
- if (strcmp(name, "any") == 0)
- WayTooBig = 10e15;
- else
- WayTooBig = atof(name);
- }
- } else if (strncmp(name, "debuglevel", 5) == 0) {
- if (fscanf(fp, "%d", &debuglevel) != 1)
- error = TRUE;
-#ifdef DEBUG
- else
- debug += debuglevel;
-#endif
- } else if (strcmp(name, "stratum") == 0) {
- fprintf(stderr, "Obsolete command 'stratum'\n");
- error = TRUE;
- } else if (strcmp(name, "precision") == 0) {
- if (fscanf(fp, "%d", &precision) != 1)
- error = TRUE;
- else
- sys.precision = (char)precision;
-#ifdef SETTICKADJ
- } else if (strcmp(name, "tickadj") == 0) {
- if (fscanf(fp, "%d", &i) != 1)
- error = TRUE;
- else
- tickadj = i;
- } else if (strcmp(name, "settickadj") == 0) {
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
- else {
- if (*name == 'Y' || *name == 'y') {
- dotickadj = 1;
- } else if (*name == 'N' || *name == 'n') {
- dotickadj = 0;
- } else
- dotickadj = atoi(name);
- }
- } else if (strcmp(name, "setdosynctodr") == 0) {
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
- else {
- if (*name == 'Y' || *name == 'y') {
- dosynctodr = 1;
- } else if (*name == 'N' || *name == 'n') {
- dosynctodr = 0;
- } else
- dosynctodr = atoi(name);
- }
-#endif
-#ifdef NOSWAP
- } else if (strcmp(name, "noswap") == 0) {
- noswap = 1;
-#endif
-#ifdef BROADCAST_NTP
- } else if (strcmp(name, "broadcast") == 0) {
- if (fscanf(fp, "%s", name) != 1) {
- error = TRUE;
- goto skipit;
- }
- for (i = 0; i < nintf; i++)
- if (strcmp(addrs[i].name, name) == 0)
- break;
- if (i == nintf) {
- syslog(LOG_ERR, "config file: %s not a known interface");
- error = TRUE;
- goto skipit;
- }
- if ((addrs[i].if_flags & IFF_BROADCAST) == 0) {
- syslog(LOG_ERR, "config file: %s doesn't support broadcast",
- name);
- error = TRUE;
- goto skipit;
- }
- if (peer = check_peer(&addrs[i].bcast, -1)) {
- syslog(LOG_ERR, "config file: duplicate broadcast for %s",
- name);
- error = TRUE;
- goto skipit;
- }
- peer = (struct ntp_peer *)malloc(sizeof(struct ntp_peer));
- if (peer == NULL) {
- error = TRUE;
- syslog(LOG_ERR, "No memory");
- goto skipit;
- }
- make_new_peer(peer);
- peer->flags = PEER_FL_BCAST;
- peer->hmode = MODE_BROADCAST;
- peer->src = addrs[i].bcast;
- peer->sock = i;
-#endif /* BROADCAST_NTP */
- } else if ((strcmp(name, "peer") == 0)
- || (strcmp(name, "passive") == 0)
- || (strcmp(name, "server") == 0)) {
- int mode = 0;
-
- if (strcmp(name, "peer") == 0) {
- mode = MODE_SYM_ACT;
- } else if (strcmp(name, "server") == 0) {
- mode = MODE_CLIENT;
- } else if (strcmp(name, "passive") == 0) {
- mode = MODE_SYM_PAS;
- } else {
- printf("can't happen\n");
- abort();
- }
- if (fscanf(fp, "%s", name) != 1)
- error = TRUE;
-#ifdef REFCLOCK
- else if (name[0] == '/') {
- int stratum, precision;
- char clk_type[20];
-
- if (fscanf(fp, "%4s", ref_clock) != 1) {
- error = TRUE;
- syslog(LOG_ERR, "reference id missing");
- goto skipit;
- }
- if (fscanf(fp, "%4d", &stratum) != 1) {
- error = TRUE;
- syslog(LOG_ERR, "reference stratum missing");
- goto skipit;
- }
- if (fscanf(fp, "%4d", &precision) != 1) {
- error = TRUE;
- syslog(LOG_ERR, "reference precision missing");
- goto skipit;
- }
- if (fscanf(fp, "%19s", clk_type) != 1) {
- error = TRUE;
- syslog(LOG_ERR, "reference type missing");
- goto skipit;
- }
-
- if ((i = init_clock(name, clk_type)) < 0) {
- /* If we could not initialize clock line */
-#ifdef DEBUG
- if (debug)
- printf
- ("Could not init reference source %s (type %s)\n",
- name, clk_type);
- else
-#endif /* DEBUG */
- syslog(LOG_ERR,
- "Could not init reference source %s (type %s)",
- name, clk_type);
- error = TRUE;
- goto skipit;
- }
- peer = (struct ntp_peer *)
- malloc(sizeof(struct ntp_peer));
- if (peer == NULL) {
- close(i);
- error = TRUE;
- goto skipit;
- }
- make_new_peer(peer);
- ref_clock[4] = 0;
- (void)strncpy((char *)&peer->refid, ref_clock, 4);
- peer->flags = PEER_FL_CONFIG | PEER_FL_REFCLOCK;
- peer->hmode = MODE_SYM_ACT;
- peer->stopwatch = stagger;
- stagger += (1 << CLOCK_ADJ);
- peer->flags |= PEER_FL_SYNC;
- peer->sock = i;
- peer->stratum = stratum;
- peer->precision = precision;
- clear(peer);
- enqueue(&peer_list, peer);
-#ifdef DEBUG
- if (debug > 1)
- printf
- ("Peer %s mode %d refid %.4s stratum %d precision %d\n",
- name, peer->hmode, (char *)&peer->refid, stratum,
- precision);
-#endif
- transmit(peer); /* head start for REFCLOCK */
- }
-#endif /* REFCLOCK */
- else if (GetHostName(name, &sin) == 0)
- syslog(LOG_ERR, "%s: unknown host", name);
- else {
- for (i = 0; i < nintf; i++)
- if (addrs[i].sin.sin_addr.s_addr == sin.sin_addr.s_addr)
- goto skipit;
-
- if (servp)
- sin.sin_port = servp->s_port;
- else
- sin.sin_port = htons(NTP_PORT);
-
- peer = check_peer(&sin, -1);
- if (peer == NULL) {
- peer = (struct ntp_peer *)
- malloc(sizeof(struct ntp_peer));
- if (peer == NULL)
- error = TRUE;
- else {
- make_new_peer(peer);
- peer->flags = PEER_FL_CONFIG;
- switch (mode) {
- case MODE_SYM_ACT: /* "peer" */
- peer->hmode = MODE_SYM_ACT;
- peer->stopwatch = stagger;
- stagger += (1 << CLOCK_ADJ);
- peer->flags |= PEER_FL_SYNC;
- break;
- case MODE_CLIENT: /* "server" */
- peer->hmode = MODE_CLIENT;
- peer->stopwatch = stagger;
- stagger += (1 << CLOCK_ADJ);
- peer->flags |= PEER_FL_SYNC;
- break;
- case MODE_SYM_PAS: /* "passive" */
- peer->hmode = MODE_SYM_PAS;
- peer->flags |= PEER_FL_SYNC;
- break;
- default:
- printf("can't happen\n");
- abort();
- }
- peer->src = sin;
- peer->sock = -1;
- clear(peer);
- enqueue(&peer_list, peer);
-#ifdef DEBUG
- if (debug > 1)
- printf("Peer %s/%d af %d mode %d\n",
- inet_ntoa(peer->src.sin_addr),
- ntohs(peer->src.sin_port),
- peer->src.sin_family, peer->hmode);
-#endif
- }
- } else {
- syslog(LOG_WARNING, "Duplicate peer %s in in config file",
- inet_ntoa(sin.sin_addr));
-#ifdef DEBUG
- if (debug)
- printf("Duplicate peer %s in in config file\n",
- inet_ntoa(sin.sin_addr));
-#endif
- }
- }
- skipit:;
- } else if (*name != '#') {
- syslog(LOG_ERR, "config file: %s not recognized", name);
-#ifdef DEBUG
- if (debug)
- printf("unrecognized option in config file: %s\n", name);
-#endif
- }
- do
- c = fgetc(fp);
- while (c != '\n' && c != EOF); /* next line */
- } /* end while */
- if (error) {
- fprintf(stderr, "init_ntp: %s: initialization error\n", config);
- syslog(LOG_ERR, "init_ntp: %s: initialization error", config);
-
- exit(1);
- }
- /*
- * Read saved drift compensation register value.
- */
-#if defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV)
-#define BOGUS_DRIFT_COMPENSATION 10.0
-#else
-#define BOGUS_DRIFT_COMPENSATION 1.0
-#endif
- if ((fp = fopen(driftcomp_file, "r")) != NULL) {
- if (fscanf(fp, "%lf", &j) == 1 && j > -BOGUS_DRIFT_COMPENSATION
- && j < BOGUS_DRIFT_COMPENSATION) {
- drift_comp = j;
- syslog(LOG_INFO, "Drift compensation value initialized to %f", j);
- } else {
- fprintf(stderr, "init_ntp: bad drift compensation value\n");
- syslog(LOG_ERR, "init_ntp: bad drift compensation value\n");
- }
- fclose(fp);
- }
-}
-\f
-int kern_tickadj, kern_hz, kern_tick, kern_dosynctodr;
-
-#ifdef SETTICKADJ
-int
-SetKernel(kmem, nl, newValue)
- int kmem;
- struct nlist *nl;
-{
- static char *memory = "/dev/kmem";
- if (lseek(kmem, (long)nl->n_value, L_SET) == -1) {
- syslog(LOG_ERR, "%s: lseek fails: %m", memory);
- perror("setting kernel variable");
- return errno;
- }
- if (write(kmem, &newValue, sizeof(int)) != sizeof(int)) {
- syslog(LOG_ERR, "%s: kernel variable assignment fails: %m", memory);
- printf("SetKernel variable %s fails\n", nl->n_name);
- perror("setting kernel variable");
- return errno;
- }
- syslog(LOG_INFO, "System %s SET to %d", nl->n_name, newValue);
- printf("System %s SET to %d\n", nl->n_name, newValue);
-}
-#endif
-
-#if defined(INIT_KERN_VARS)
-void
-init_kern_vars()
-{
- int kmem;
- static char *memory = "/dev/kmem";
- static struct nlist nl[] = {
-#ifndef NeXT
- {"_tickadj"},
- {"_hz"},
- {"_tick"},
-#ifdef AFS_SUN_ENV
- {"_dosynctodr"},
-#endif
- {""},
-#else
- {{"_tickadj"}},
- {{"_hz"}},
- {{"_tick"}},
- {{""}},
-#endif
- };
- static int *kern_vars[] =
- { &kern_tickadj, &kern_hz, &kern_tick, &kern_dosynctodr };
- int i;
- kmem = open(memory, O_RDONLY);
- if (kmem < 0) {
- syslog(LOG_ERR, "Can't open %s for reading: %m", memory);
-#ifdef DEBUG
- if (debug)
- perror(memory);
-#endif
- return;
- }
-
- nlist("/vmunix", nl);
-
- for (i = 0; i < (sizeof(kern_vars) / sizeof(kern_vars[0])); i++) {
- long where;
-
- if ((where = nl[i].n_value) == 0) {
- syslog(LOG_ERR, "Unknown kernal var %s",
-#ifdef NeXT
- nl[i].n_un.n_name
-#else
- nl[i].n_name
-#endif
- );
- continue;
- }
- if (lseek(kmem, where, L_SET) == -1) {
- syslog(LOG_ERR, "lseek for %s fails: %m",
-#ifdef NeXT
- nl[i].n_un.n_name
-#else
- nl[i].n_name
-#endif
- );
- continue;
- }
- if (read(kmem, kern_vars[i], sizeof(int)) != sizeof(int)) {
- syslog(LOG_ERR, "read for %s fails: %m",
-#ifdef NeXT
- nl[i].n_un.n_name
-#else
- nl[i].n_name
-#endif
- );
-
- *kern_vars[i] = 0;
- }
- }
-
- /*
- * If desired value of tickadj is not specified in the configuration
- * file, compute a "reasonable" value here, based on the assumption
- * that we don't have to slew more than 2ms every 4 seconds.
- *
- * TODO: the 500 needs to be parameterized.
- */
- if (tickadj == 0 && kern_hz)
- tickadj = 500 / kern_hz;
-
-#ifdef DEBUG
- if (debug) {
- printf("kernel vars: tickadj = %d, hz = %d, tick = %d\n",
- kern_tickadj, kern_hz, kern_tick);
-#ifdef AFS_SUN_ENV
- if (kern_dosynctodr)
- printf("dosynctodr is on\n");
-#endif
- printf("desired tickadj = %d, dotickadj = %d\n", tickadj, dotickadj);
- }
-#endif
- close(kmem);
-
-#ifdef SETTICKADJ
- {
- int set_tickadj, set_dosynctodr;
- int code;
- set_tickadj = (dotickadj && tickadj && (tickadj != kern_tickadj)
- /* do some plausibility checks on the value... */
- && (kern_tickadj > 0) && (kern_tickadj < 20000));
- set_dosynctodr = (dosynctodr && (kern_dosynctodr == 1));
- if (set_tickadj || set_dosynctodr) {
- if ((kmem = open(memory, O_RDWR)) >= 0) {
- if (set_tickadj) {
- code = SetKernel(kmem, &nl[0], tickadj);
- if (code == 0)
- kern_tickadj = tickadj;
- }
- if (set_dosynctodr) {
- code = SetKernel(kmem, &nl[3], 0);
- if (code == 0)
- kern_dosynctodr = 0;
- }
- close(kmem);
- } else {
- syslog(LOG_ERR, "Can't open %s: %m", memory);
- printf("Can't open %s\n", memory);
- }
- }
- }
-#endif /* SETTICKADJ */
-
- /*
- * If we have successfully discovered `hz' from the kernel, then we
- * can set sys.precision, if it has not already been specified. If
- * no value of `hz' is available, then use default (-6)
- */
- if (sys.precision == 0) {
- char msg[128];
- int interval = 0;
- sys.precision = MeasurePrecision(&interval);
- if (sys.precision) {
- sprintf(msg,
- "sys.precision set to %d from measured minimum clock interval of %d usec",
- sys.precision, interval);
- } else {
- if (kern_hz <= 64)
- sys.precision = -6;
- else if (kern_hz <= 128)
- sys.precision = -7;
- else if (kern_hz <= 256)
- sys.precision = -8;
- else if (kern_hz <= 512)
- sys.precision = -9;
- else if (kern_hz <= 1024)
- sys.precision = -10;
- else
- sys.precision = -11;
- sprintf(msg, "sys.precision set to %d from sys clock of %d HZ",
- sys.precision, kern_hz);
- }
- syslog(LOG_INFO, msg);
- printf("%s\n", msg);
- }
-}
-#endif /* INIT_KERN_VARS */
-
-
-/*
- * Given host or net name or internet address in dot notation assign the
- * internet address in byte format. source is ../routed/startup.c with minor
- * changes to detect syntax errors.
- *
- * We now try to interpret the name as in address before we go off and bother
- * the domain name servers.
- *
- * Unfortunately the library routine inet_addr() does not detect mal formed
- * addresses that have characters or byte values > 255.
- */
-
-GetHostName(name, sin)
- char *name;
- struct sockaddr_in *sin;
-{
- afs_int32 HostAddr;
- struct hostent *hp;
-
- if ((HostAddr = inet_addr(name)) != -1) {
- sin->sin_addr.s_addr = (afs_uint32) HostAddr;
- sin->sin_family = AF_INET;
- return (1);
- }
-
- if (hp = gethostbyname(name)) {
- if (hp->h_addrtype != AF_INET)
- return (0);
- memcpy((char *)&sin->sin_addr, (char *)hp->h_addr, hp->h_length);
- sin->sin_family = hp->h_addrtype;
- return (1);
- }
- return (0);
-}
-
-#define PKTBUF_SIZE 536
-
-/* number of clocks per packet */
-#define N_NTP_PKTS \
- ((PKTBUF_SIZE - sizeof(struct ntpinfo))/(sizeof(struct clockinfo)))
-
-query_mode(dst, ntp, sock)
- struct sockaddr_in *dst;
- struct ntpdata *ntp;
- int sock; /* which socket packet arrived on */
-{
- char packet[PKTBUF_SIZE];
- register struct ntpinfo *nip = (struct ntpinfo *)packet;
- register struct ntp_peer *peer = peer_list.head;
- struct clockinfo *cip;
- int seq = 0;
- int i;
-
- if (ntp->stratum != INFO_QUERY)
- return;
- nip->version = NTPDC_VERSION;
- nip->type = INFO_REPLY;
- nip->seq = 0;
- nip->npkts = peer_list.members / N_NTP_PKTS;
- if (peer_list.members % N_NTP_PKTS)
- nip->npkts++;
- nip->peers = peer_list.members;
- nip->count = 0;
- cip = (struct clockinfo *)&nip[1];
-
- while (peer != NULL) {
- cip->net_address = peer->src.sin_addr.s_addr;
- if ((peer->sock < 0) || (peer->sock >= nintf))
- cip->my_address = htonl(0);
- else
- cip->my_address = addrs[peer->sock].sin.sin_addr.s_addr;
- cip->port = peer->src.sin_port; /* already in network order */
- cip->flags = htons(peer->flags);
- if (sys.peer == peer)
- cip->flags |= htons(PEER_FL_SELECTED);
- cip->pkt_sent = htonl(peer->pkt_sent);
- cip->pkt_rcvd = htonl(peer->pkt_rcvd);
- cip->pkt_dropped = htonl(peer->pkt_dropped);
- cip->timer = htonl(peer->timer);
- cip->leap = peer->leap;
- cip->stratum = peer->stratum;
- cip->ppoll = peer->ppoll;
- cip->precision = peer->precision;
- cip->hpoll = peer->hpoll;
- cip->reach = htons(peer->reach & NTP_WINDOW_SHIFT_MASK);
- cip->estdisp = htonl((afs_int32) (peer->estdisp * 1000.0));
- cip->estdelay = htonl((afs_int32) (peer->estdelay * 1000.0));
- cip->estoffset = htonl((afs_int32) (peer->estoffset * 1000.0));
- cip->refid = peer->refid;
- cip->reftime.int_part = htonl(peer->reftime.int_part);
- cip->reftime.fraction = htonl(peer->reftime.fraction);
-
- cip->info_filter.index = htons(peer->filter.samples);
- for (i = 0; i < PEER_SHIFT; i++) {
- cip->info_filter.offset[i] =
- htonl((afs_int32) (peer->filter.offset[i] * 1000.0));
- cip->info_filter.delay[i] =
- htonl((afs_int32) (peer->filter.delay[i] * 1000.0));
- }
- cip++;
- if (nip->count++ >= N_NTP_PKTS - 1) {
- nip->seq = seq++;
- if ((sendto
- (addrs[sock].fd, (char *)packet, sizeof(packet), 0,
- (struct sockaddr *)dst, sizeof(struct sockaddr_in))) < 0) {
- syslog(LOG_ERR, "sendto: %s %m", inet_ntoa(dst->sin_addr));
- }
- nip->type = INFO_REPLY;
- nip->count = 0;
- cip = (struct clockinfo *)&nip[1];
- }
- peer = peer->next;
- }
- if (nip->count) {
- nip->seq = seq;
- if ((sendto
- (addrs[sock].fd, (char *)packet, sizeof(packet), 0,
- (struct sockaddr *)dst, sizeof(struct sockaddr_in))) < 0) {
- syslog(LOG_ERR, "sendto: %s %m", ntoa(dst->sin_addr));
- }
- }
-}
-
-/* every hour, dump some useful information to the log */
-void
-hourly()
-{
- char buf[200];
- register int p = 0;
- static double drifts[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
- static int drift_count = 0;
- extern double drift_comp, compliance;
- extern int peer_switches, peer_sw_inhibited;
-
- (void)sprintf(buf, "stats: dc %f comp %f peersw %d inh %d", drift_comp,
- compliance, peer_switches, peer_sw_inhibited);
-
- if (sys.peer == NULL) {
- strcat(buf, " UNSYNC");
-#ifdef REFCLOCK
- } else if (sys.peer->flags & PEER_FL_REFCLOCK) {
- p = strlen(buf);
- (void)sprintf(buf + p, " off %f SYNC %.4s %d", sys.peer->estoffset,
- (char *)&sys.peer->refid, sys.peer->stratum);
-#endif
- } else {
- p = strlen(buf);
- (void)sprintf(buf + p, " off %f SYNC %s %d", sys.peer->estoffset,
- ntoa(sys.peer->src.sin_addr), sys.peer->stratum);
- }
- syslog(LOG_INFO, buf);
-#ifdef DEBUG
- if (debug)
- puts(buf);
-#endif
- /*
- * If the drift compensation snapshot file is open, then write
- * the current value to it. Since there's only one block in the
- * file, and no one else is reading it, we'll just keep the file
- * open and write to it.
- */
- if (drift_fd >= 0) {
- drifts[drift_count % 5] = drift_comp;
- /* works out to be 70 bytes */
- (void)sprintf(buf,
- "%+12.10f %+12.10f %+12.10f %+12.10f %+12.10f %4d\n",
- drifts[drift_count % 5], drifts[(drift_count + 4) % 5],
- drifts[(drift_count + 3) % 5],
- drifts[(drift_count + 2) % 5],
- drifts[(drift_count + 1) % 5], drift_count + 1);
-
- (void)lseek(drift_fd, 0L, L_SET);
- if (write(drift_fd, buf, strlen(buf)) < 0) {
- syslog(LOG_ERR, "Error writing drift comp file: %m");
- }
- drift_count++;
- }
-}
-\f
-#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
-void
-incdebug(x)
-{
- /* re-enable self (we're not BSD any more) */
- (void)signal(SIGUSR1, incdebug);
-
- if (debug == 255)
- return;
- debug++;
- printf("DEBUG LEVEL %d\n", debug);
-#ifdef LOG_DAEMON
- (void)setlogmask(LOG_UPTO(LOG_DEBUG));
-#endif
- syslog(LOG_DEBUG, "DEBUG LEVEL %d", debug);
-}
-
-void
-decdebug(x)
-{
- /* re-enable self (we're not BSD any more) */
- (void)signal(SIGUSR2, decdebug);
-
- if (debug == 0)
- return;
- debug--;
- printf("DEBUG LEVEL %d\n", debug);
- syslog(LOG_DEBUG, "DEBUG LEVEL %d", debug);
-#ifdef LOG_DAEMON
- if (debug == 0)
- (void)setlogmask(LOG_UPTO(LOG_INFO));
-#endif
-}
-#endif
-
-void
-finish(sig)
- int sig;
-{
- syslog(LOG_NOTICE, "terminated: (sig %d)", sig);
-#ifdef DEBUG
- if (debug)
- printf("ntpd terminated (sig %d)\n", sig);
-#endif
- exit(1);
-}
-\f
-#ifdef REFCLOCK
-struct refclock {
- int fd;
- int (*reader) ();
- struct refclock *next;
-} *refclocks = NULL;
-
-int init_clock_local(), read_clock_local();
-#ifdef PSTI
-int init_clock_psti(), read_clock_psti();
-#endif /* PSTI */
-
-init_clock(name, type)
- char *name, *type;
-{
- struct refclock *r;
- int (*reader) ();
- int cfd;
-
- if (strcmp(type, "local") == 0) {
- reader = read_clock_local;
- cfd = init_clock_local(name);
- }
-#ifdef PSTI
- else if (strcmp(type, "psti") == 0) {
- reader = read_clock_psti;
- cfd = init_clock_psti(name);
- }
-#endif /* PSTI */
- else {
-#ifdef DEBUG
- if (debug)
- printf("Unknown reference type\n");
- else
-#endif
- syslog(LOG_ERR, "Unknown reference clock type (%s)\n", type);
- return (-1);
- }
- if (cfd >= 0) {
- r = (struct refclock *)malloc(sizeof(struct refclock));
- r->fd = cfd;
- r->reader = reader;
- r->next = refclocks;
- refclocks = r;
- }
- return (cfd);
-}
-
-read_clock(cfd, tvpp, otvpp)
- int cfd;
- struct timeval **tvpp, **otvpp;
-{
- struct refclock *r;
-
- for (r = refclocks; r; r = r->next)
- if (r->fd == cfd)
- return ((r->reader) (cfd, tvpp, otvpp));
- return (1); /* Can't happen */
-}
-#endif
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <signal.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <netinet/udp.h>
-#include <errno.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <strings.h>
-#include <arpa/inet.h>
-
-#ifdef AFS_AIX32_ENV
-#include <sys/select.h>
-#endif
-
-#include "ntp.h"
-
-#define WTIME 10 /* Time to wait for all responses */
-#define STIME 500000 /* usec to wait for another response */
-#define MAXPACKETSIZE 1500
-
-extern int errno;
-int debug;
-int s;
-int timedout;
-void timeout();
-int nflag, vflag;
-
-struct sockaddr_in sin = { AF_INET };
-
-char packet[MAXPACKETSIZE];
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-char LocalHostName[MAXHOSTNAMELEN + 1]; /* our hostname */
-char *LocalDomain; /* our local domain name */
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char *argv[];
-{
- char *p;
- int on = 48 * 1024;
-
-#ifdef AFS_AIX32_ENV
- /*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
- * in the core dump. Unfortunately, by default, only a partial core is
- * generated which, in many cases, isn't too useful.
- */
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGSEGV, &nsa, NULL);
-#endif
- (void)gethostname(LocalHostName, sizeof LocalHostName);
- if (p = strchr(LocalHostName, '.')) {
- *p++ = '\0';
- LocalDomain = p;
- } else
- LocalDomain = "";
-
- if (argc < 2) {
- usage:
- printf("usage: %s [ -v ][ -n ] hosts...\n", argv[0]);
- exit(1);
- }
-
- argv++, argc--;
- if (*argv[0] == '-') {
- switch (argv[0][1]) {
- case 'n':
- nflag++;
- break;
- case 'v':
- vflag++;
- break;
- default:
- goto usage;
- }
- argc--, argv++;
- }
- if (argc > 1)
- printf("--- %s ---\n", *argv);
-
- while (argc > 0) {
- /*
- * Get a new socket each time - this will cause us to ignore
- * packets from the previously queried host.
- */
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- perror("socket");
- exit(2);
- }
-#ifdef SO_RCVBUF
- if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) < 0) {
- fprintf(stderr, "setsockopt SO_RCVBUF\n");
- }
-#endif
- if (query(*argv))
- answer(*argv);
- close(s);
- argv++;
- if (argc-- > 1)
- printf("--- %s ---\n", *argv);
- }
-
-}
-
-answer(host)
- char *host;
-{
- register struct ntpinfo *msg = (struct ntpinfo *)packet;
- register struct clockinfo *n;
- struct sockaddr_in from;
- int fromlen = sizeof(from);
- int count, cc;
- fd_set bits;
- struct timeval shorttime;
- int first = 1;
- afs_int32 replies = 0;
-
- /*
- * Listen for returning packets; may be more than one packet per
- * host.
- */
- FD_ZERO(&bits);
- FD_SET(s, &bits);
- shorttime.tv_sec = 0;
- shorttime.tv_usec = STIME;
- (void)signal(SIGALRM, timeout);
- (void)alarm(WTIME);
- timedout = 0;
- while ((first || replies)
- && (!timedout
- || select(FD_SETSIZE, &bits, (fd_set *) 0, (fd_set *) 0,
- &shorttime) > 0)) {
- if ((cc =
- recvfrom(s, packet, sizeof(packet), 0, (struct sockaddr *)&from,
- &fromlen)) <= 0) {
- if (cc == 0 || errno == EINTR)
- continue;
- fflush(stdout);
- perror(host);
- (void)close(s);
- return;
- }
- FD_SET(s, &bits);
-
- if (msg->type != INFO_REPLY)
- return;
-
- if (msg->version != NTPDC_VERSION) {
- printf("ntpd(%d) - ntpdc(%d) version mismatch\n", msg->version,
- NTPDC_VERSION);
- alarm(0);
- return;
- }
-
- if (first) {
- first = 0;
- replies = (1L << msg->npkts) - 1;
- if (!vflag) {
- printf
- (" (rem) Address (lcl) Strat Poll Reach Delay Offset Disp\n");
- printf
- ("==========================================================================\n");
- }
- }
- replies &= ~(1L << msg->seq);
- n = (struct clockinfo *)&msg[1];
- for (count = msg->count; count > 0; count--) {
- if (vflag)
- print_verbose(n);
- else
- print_terse(n);
- n++;
- }
- }
- alarm(0);
- if (replies)
- printf("Timed out waiting for replies\n");
-}
-
-int
-query(host)
- char *host;
-{
- struct sockaddr_in watcher;
- register struct ntpdata *msg = (struct ntpdata *)packet;
- struct hostent *hp;
- static struct servent *sp = NULL;
- afs_int32 HostAddr;
-
- memset((char *)&watcher, 0, sizeof(watcher));
- watcher.sin_family = AF_INET;
- HostAddr = inet_addr(host);
- watcher.sin_addr.s_addr = (afs_uint32) HostAddr;
- if (HostAddr == -1) {
- hp = gethostbyname(host);
- if (hp == 0) {
- fprintf(stderr, "%s: unknown\n", host);
- return 0;
- }
- memcpy((char *)&watcher.sin_addr, hp->h_addr, hp->h_length);
- }
- sp = getservbyname("ntp", "udp");
- if (sp == 0) {
- fprintf(stderr, "udp/ntp: service unknown, using default %d\n",
- NTP_PORT);
- watcher.sin_port = htons(NTP_PORT);
- } else
- watcher.sin_port = sp->s_port;
- msg->status = NTPVERSION_1;
- msg->stratum = INFO_QUERY;
- if (connect(s, (struct sockaddr *)&watcher, sizeof(watcher))) {
- perror("connect");
- return 0;
- }
- if (send(s, packet, sizeof(struct ntpdata), 0) < 0) {
- perror("send");
- return 0;
- }
- return 1;
-}
-
-void
-timeout()
-{
- timedout = 1;
-}
-
-print_terse(n)
- struct clockinfo *n;
-{
- int i;
- double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp, del, off;
- char c;
- char *cvthname();
- int flags;
-
- sin.sin_addr.s_addr = n->net_address;
- for (i = 0; i < PEER_SHIFT; i++) {
- delay[i] =
- (double)((afs_int32) (ntohl(n->info_filter.delay[i]) / 1000.0));
- offset[i] =
- (double)((afs_int32) (ntohl(n->info_filter.offset[i]) / 1000.0));
- }
- dsp = (afs_int32) ntohl(n->estdisp); /* leave in milliseconds */
- del = (afs_int32) ntohl(n->estdelay); /* leave in milliseconds */
- off = (afs_int32) ntohl(n->estoffset); /* leave in milliseconds */
- c = ' ';
- flags = ntohs(n->flags);
- if (flags & PEER_FL_CONFIG)
- c = '-'; /* mark pre-configured */
- if (flags & PEER_FL_SANE)
- c = '.'; /* passed sanity check */
- if (flags & PEER_FL_CANDIDATE)
- c = '+'; /* made candidate list */
- if (flags & PEER_FL_SELECTED)
- c = '*'; /* mark peer selection */
- sin.sin_addr.s_addr = n->net_address;
- printf("%c%-15.15s ", c, cvthname(&sin));
- sin.sin_addr.s_addr = n->my_address;
- printf("%-16.16s %2d %4d %03o %8.1f %8.1f %8.1f\n",
- sin.sin_addr.s_addr ? inet_ntoa(sin.sin_addr) : "wildcard",
- n->stratum, (int)ntohl((afs_uint32) n->timer),
- ntohs(n->reach) & SHIFT_MASK, del, off, dsp);
-}
-
-print_verbose(n)
- struct clockinfo *n;
-{
- int i;
- struct in_addr clock_host;
- double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp, del, off;
- char *cvthname();
-
- sin.sin_addr.s_addr = n->net_address;
- for (i = 0; i < PEER_SHIFT; i++) {
- delay[i] = (double)(afs_int32) ntohl(n->info_filter.delay[i]);
- offset[i] = (double)(afs_int32) ntohl(n->info_filter.offset[i]);
- }
- dsp = (double)((afs_int32) ntohl(n->estdisp)); /* in milliseconds */
- del = (double)((afs_int32) ntohl(n->estdelay)); /* in milliseconds */
- off = (double)((afs_int32) ntohl(n->estoffset)); /* in milliseconds */
- printf("Neighbor address %s port:%d", inet_ntoa(sin.sin_addr),
- (int)ntohs(n->port));
- sin.sin_addr.s_addr = n->my_address;
- printf(" local address %s\n", inet_ntoa(sin.sin_addr));
- printf("Reach: 0%o stratum: %d, precision: %d\n",
- ntohs(n->reach) & SHIFT_MASK, n->stratum, n->precision);
- printf("dispersion: %f, flags: %x, leap: %x\n", dsp, ntohs(n->flags),
- n->leap);
- if (n->stratum == 1 || n->stratum == 0) {
- printf("Reference clock ID: %.4s", (char *)&n->refid);
- } else {
- clock_host.s_addr = (afs_uint32) n->refid;
- printf("Reference clock ID: [%s]", inet_ntoa(clock_host));
- }
- printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part),
- ntohl(n->reftime.fraction));
-
- printf
- ("hpoll: %d, ppoll: %d, timer: %d, sent: %d received: %d dropped: %d\n",
- n->hpoll, n->ppoll, (int)ntohl((afs_uint32) n->timer),
- (int)ntohl(n->pkt_sent), (int)ntohl(n->pkt_rcvd),
- (int)ntohl(n->pkt_dropped));
- printf("Delay(ms) ");
- for (i = 0; i < PEER_SHIFT; i++)
- printf("%7.2f ", delay[i]);
- printf("\n");
- printf("Offset(ms) ");
- for (i = 0; i < PEER_SHIFT; i++)
- printf("%7.2f ", offset[i]);
- printf("\n");
- printf("\n\tdelay: %f offset: %f dsp %f\n", del, off, dsp);
- printf("\n");
-}
-
-/*
- * Return a printable representation of a host address.
- */
-char *
-cvthname(f)
- struct sockaddr_in *f;
-{
- struct hostent *hp;
- register char *p;
- extern char *inet_ntoa();
-
- if (f->sin_family != AF_INET) {
- printf("Malformed from address\n");
- return ("???");
- }
- if (!nflag)
- hp = gethostbyaddr((char *)&f->sin_addr, sizeof(struct in_addr),
- f->sin_family);
- else
- return (inet_ntoa(f->sin_addr));
-
- if (hp == 0)
- return (inet_ntoa(f->sin_addr));
-
- if ((p = strchr(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
- *p = '\0';
- return (hp->h_name);
-}
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#if defined(AIX)
-#include <sys/syslog.h>
-#else
-#include <syslog.h>
-#endif
-#include "ntp.h"
-
-extern int errno;
-
-#define TRUE 1
-#define FALSE 0
-
-/*
- * The nice thing here is that the quantity is NEVER signed.
- */
-double
-ul_fixed_to_double(t)
- struct l_fixedpt *t;
-{
- double a, b;
-#ifdef GENERIC_UNS_BUG
- register int i;
-
- i = ntohl(t->fraction);
- a = (afs_int32) ((i >> 1) & 0x7fffffff);
- a *= 2.0;
- if (i & 1)
- a += 1.0;
- a = a / (4.294967296e9); /* shift dec point over by 32 bits */
- i = ntohl(t->int_part);
- b = (afs_int32) ((i >> 1) & 0x7fffffff);
- b *= 2.0;
- if (i & 1)
- b += 1.0;
-#else /* GENERIC_UNS_BUG */
- a = (afs_uint32) ntohl(t->fraction);
-#ifdef VAX_COMPILER_FLT_BUG
- if (a < 0.0)
- a += 4.294967296e9;
-#endif
- a = a / (4.294967296e9); /* shift dec point over by 32 bits */
- b = (afs_uint32) ntohl(t->int_part);
-#ifdef VAX_COMPILER_FLT_BUG
- if (b < 0.0)
- b += 4.294967296e9;
-#endif
-#endif /* GENERIC_UNS_BUG */
- return (a + b);
-}
-
-/*
- * Here we have to worry about the high order bit being signed
- */
-
-#if 0
-double
-l_fixed_to_double(t)
- struct l_fixedpt *t;
-{
- double a, b;
-
- if (ntohl(t->int_part) & 0x80000000) {
- a = ntohl(~t->fraction);
-#ifdef VAX_COMPILER_FLT_BUG
- if (a < 0.0)
- a += 4.294967296e9;
-#endif
- a = a / (4.294967296e9);
- b = ntohl(~t->int_part);
-#ifdef VAX_COMPILER_FLT_BUG
- if (b < 0.0)
- b += 4.294967296e9;
-#endif
- a += b;
- a = -a;
- } else {
- a = ntohl(t->fraction);
-#ifdef VAX_COMPILER_FLT_BUG
- if (a < 0.0)
- a += 4.294967296e9;
-#endif
- a = a / (4.294967296e9);
- b = ntohl(t->int_part);
-#ifdef VAX_COMPILER_FLT_BUG
- if (b < 0.0)
- b += 4.294967296e9;
-#endif
- a += b;
- }
- return (a);
-}
-#endif
-
-/*
- * Here we have to worry about the high order bit being signed
- */
-double
-s_fixed_to_double(t)
- struct s_fixedpt *t;
-{
- double a;
-
- if (ntohs(t->int_part) & 0x8000) {
- a = ntohs(~t->fraction & 0xFFFF);
- a = a / 65536.0; /* shift dec point over by 16 bits */
- a += ntohs(~t->int_part & 0xFFFF);
- a = -a;
- } else {
- a = ntohs(t->fraction);
- a = a / 65536.0; /* shift dec point over by 16 bits */
- a += ntohs(t->int_part);
- }
- return (a);
-}
-
-void
-double_to_l_fixed(t, value)
- struct l_fixedpt *t;
- double value;
-{
- double temp;
-
- if (value >= (double)0.0) {
- t->int_part = value;
- temp = value - t->int_part;
- temp *= 4.294967296e9;
- t->fraction = temp;
- t->int_part = htonl(t->int_part);
- t->fraction = htonl(t->fraction);
- } else {
- value = -value;
- t->int_part = value;
- temp = value - t->int_part;
- temp *= 4.294967296e9;
- t->fraction = temp;
- t->int_part = htonl(~t->int_part);
- t->fraction = htonl(~t->fraction);
- }
-}
-
-void
-double_to_s_fixed(t, value)
- struct s_fixedpt *t;
- double value;
-{
- double temp;
-
- if (value >= (double)0.0) {
- t->int_part = value;
- temp = value - t->int_part;
- temp *= 65536.0;
- t->fraction = temp;
- t->int_part = htons(t->int_part);
- t->fraction = htons(t->fraction);
- } else {
- value = -value;
- t->int_part = value;
- temp = value - t->int_part;
- temp *= 65536.0;
- t->fraction = temp;
- t->int_part = htons(~t->int_part);
- t->fraction = htons(~t->fraction);
- }
-}
-
-/*
- in the sun, trying to assign a float between 2^31 and 2^32
- results in the value 2^31. Neither 4.2bsd nor VMS have this
- problem. Reported it to Bob O'Brien of SMI
-*/
-#ifndef AFS_SUN58_ENV
-#ifdef SUN_FLT_BUG
-tstamp(stampp, tvp)
- struct l_fixedpt *stampp;
- struct timeval *tvp;
-{
- int tt;
- double dd;
-
- stampp->int_part = ntohl(JAN_1970 + tvp->tv_sec);
- dd = (float)tvp->tv_usec / 1000000.0;
- tt = dd * 2147483648.0;
- stampp->fraction = ntohl((tt << 1));
-}
-#else
-tstamp(stampp, tvp)
- struct l_fixedpt *stampp;
- struct timeval *tvp;
-{
- stampp->int_part = ntohl((afs_uint32) (JAN_1970 + tvp->tv_sec));
- stampp->fraction =
- ntohl((afs_uint32) ((float)tvp->tv_usec * 4294.967295));
-}
-#endif
-#endif /* AFS_SUN58_ENV */
-
-/*
- * ntoa is similar to inet_ntoa, but cycles through a set of 8 buffers
- * so it can be invoked several times in a function parameter list.
- */
-
-char *
-ntoa(in_addr)
- struct in_addr in_addr;
-{
- static int i = 0;
- static char bufs[8][20];
- unsigned char *p = (unsigned char *)&in_addr.s_addr;
-
- i = (i + 1) % (sizeof bufs / sizeof bufs[0]);
- sprintf(bufs[i], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- return bufs[i];
-}
-
-/* calculate effective precision, but repeated calls to gettimeofday */
-
-int
-MeasurePrecision(intervalP)
- int *intervalP;
-{
-#if defined(AFS_SUN5_ENV)
-#define MAXTIMEDIFFS 100
-#else
-#define MAXTIMEDIFFS 10
-#endif
-
- int diff[MAXTIMEDIFFS];
- int nDiff;
- int interval;
- int i;
- int q;
- struct timeval tv0;
-
- gettimeofday(&tv0, 0);
- nDiff = 0;
- while (nDiff < MAXTIMEDIFFS) {
- struct timeval tv, ntv;
- int counting = 2; /* a counting kernel */
- gettimeofday(&tv, 0);
- do {
- gettimeofday(&ntv, 0);
-
- /*
- * Bail if we are taking too long -- 30 seconds is arbitrary,
- * but better than the previous approach, which was to bail
- * after an arbitrary count of calls to gettimeofday(). This
- * caused problems because the machines kept getting faster
- * and the count kept getting exceeded.
- */
- if (ntv.tv_sec - tv0.tv_sec > 30)
- return 0;
-
- interval =
- (ntv.tv_sec - tv.tv_sec) * 1000000 + ntv.tv_usec - tv.tv_usec;
- if (interval <= counting)
- counting = interval + 2;
- } while (interval <= counting); /* RT & sun4/280 kernels count */
- if (interval < 0)
- return 0; /* shouldn't happen but who knows... */
- if (interval > 0)
- diff[nDiff++] = interval;
- }
-
- /* find average interval */
- interval = 0;
- for (i = 0; i < MAXTIMEDIFFS; i++)
- interval += diff[i];
- interval = (interval + (MAXTIMEDIFFS / 2)) / MAXTIMEDIFFS; /* round */
- if (interval == 0)
- return 0; /* some problem... */
- if (intervalP)
- *intervalP = interval;
-
- /* calculate binary exponent of interval in seconds */
- q = 1000000;
- i = 0;
- while (q > interval) {
- q >>= 1;
- i--;
- }
- return i;
-}
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#define PATCHLEVEL 13
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#ifdef REFCLOCK
-/*
- * A dummy clock reading routine that reads the current system time.
- * from the local host. Its possible that this could be actually used
- * if the system was in fact a very accurate time keeper (a true real-time
- * system with good crystal clock or better).
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-init_clock_local(file)
- char *file;
-{
- return getdtablesize(); /* invalid if we ever use it */
-}
-
-read_clock_local(cfd, tvp, mtvp)
- int cfd;
- struct timeval **tvp, **mtvp;
-{
- static struct timeval realtime, mytime;
-
- gettimeofday(&realtime, 0);
- mytime = realtime;
- *tvp = &realtime;
- *mtvp = &mytime;
- return (0);
-}
-#endif
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#if defined(REFCLOCK) && defined(PSTI)
-#define ERR_RATE 60 /* Repeat errors once an hour */
-
-/*
- * read_psti.c
- * January 1988 -- orignal
- * January 1989 -- QU version
- *
- * This module facilitates reading a Precision Time Standard, Inc.
- * WWV radio clock. We assume that clock is configured for 9600 baud,
- * no parity. Output is accepted in either 24 or 12 hour format.
- * Time is requested and processed in GMT.
- *
- * This version is designed to make use of the QU command due to
- * additional information it provides (like date and flags).
- * Select is used to prevent hanging in a read when there are
- * no characters to read. The line is run in cooked mode to
- * reduce overhead.
- *
- * This requires a PSTI ROM revision later 4.01.000 or later.
- *
- * Routines defined:
- * init_clock_psti(): Open the tty associated with the clock and
- * set its tty mode bits. Returns fd on success
- * and -1 on failure.
- * read_clock_psti(): Reads the clock and returns either 0 on success
- * or non-zero on error. On success, pointers are
- * provided to the reference and local time.
- */
-#include <stdio.h>
-#include <syslog.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#if defined(AFS_SUN_ENV)
-#include <termio.h>
-#endif
-
-#ifdef DEBUG
-extern int debug;
-#endif /* DEBUG */
-
-static int nerrors = 0;
-static char clockdata[32];
-#define MIN_READ 13 /* for Rev 4.01.001 */
-
-static double reltime();
-
-#ifdef STANDALONE
-
-#ifndef CLOCKDEV
-#define CLOCKDEV "/dev/radioclock"
-#endif
-
-#define DEBUG 1
-int debug = 1;
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- struct timeval *tvp, *otvp;
-
- debug = argc;
- if (openclock(CLOCKDEV))
- do {
- (void)readclock(&tvp, &otvp);
- sleep(1);
- } while (debug > 1);
- exit(0);
-}
-#endif /* STANDALONE */
-
-
-init_clock_psti(timesource)
- char *timesource;
-{
- int cfd;
-#ifdef TCSETA
- struct termio tty;
-#else
- struct sgttyb tty;
-#endif
-
- if ((cfd = open(timesource, 2)) < 0) {
-#ifdef DEBUG
- if (debug)
- perror(timesource);
- else
-#endif /* DEBUG */
- syslog(LOG_ERR, "can't open %s: %m", timesource);
- return (-1);
- }
-
- if (ioctl(cfd, TIOCEXCL, 0) < 0) {
-#ifdef DEBUG
- if (debug)
- perror("TIOCEXCL on radioclock failed");
- else
-#endif /* DEBUG */
- syslog(LOG_ERR, "TIOCEXCL on %s failed: %m", timesource);
- return (-1);
- }
-#ifdef TCSETA
- if (ioctl(cfd, TCGETA, &tty) < 0) {
-#ifdef DEBUG
- if (debug)
- perror("ioctl on radioclock failed");
- else
-#endif /* DEBUG */
- syslog(LOG_ERR, "ioctl on %s failed: %m", timesource);
- return (-1);
- }
- tty.c_cflag = (B9600 << 16) | B9600 | CS8 | CLOCAL | CREAD;
- tty.c_iflag = ICRNL;
- tty.c_oflag = 0;
- tty.c_lflag = 0;
- memset((char *)tty.c_cc, 0, sizeof tty.c_cc);
- tty.c_cc[VMIN] = MIN_READ;
- tty.c_cc[VTIME] = 0;
- if (ioctl(cfd, TCSETA, &tty) < 0) {
-#else /* TCSETA Use older Berkeley style IOCTL's */
- memset((char *)&tty, 0, sizeof tty);
- tty.sg_ispeed = tty.sg_ospeed = B9600;
- tty.sg_flags = ANYP | CRMOD;
- tty.sg_erase = tty.sg_kill = '\0';
- if (ioctl(cfd, TIOCSETP, &tty) < 0) {
-#endif /* TCSETA */
-#ifdef DEBUG
- if (debug)
- perror("ioctl on radioclock failed");
- else
-#endif /* DEBUG */
- syslog(LOG_ERR, "ioctl on %s failed: %m", timesource);
- return (-1);
- }
- if (write(cfd, "xxxxxxsn\r", 9) != 9) {
-#ifdef DEBUG
- if (debug)
- perror("init write to radioclock failed");
- else
-#endif /* DEBUG */
- syslog(LOG_ERR, "init write to %s failed: %m", timesource);
- return (-1);
- }
- return (cfd); /* Succeeded in opening the clock */
-}
-
-/*
- * read_clock_psti() -- Read the PSTI Radio Clock.
- */
-read_clock_psti(cfd, tvpp, otvpp)
- int cfd;
- struct timeval **tvpp, **otvpp;
-{
- static struct timeval radiotime;
- static struct timeval mytime;
- struct timeval timeout;
- struct tm *mtm;
- struct tm radio_tm, *rtm = &radio_tm;
- register int i;
- register int millis;
- register double diff;
- int stat1, stat2;
- fd_set readfds;
- char message[256];
-#ifndef TCSETA
- register char *cp;
- int need;
-#endif /* TCSETA */
-
- FD_ZERO(&readfds);
- FD_SET(cfd, &readfds);
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
-
- (void)ioctl(cfd, TIOCFLUSH, 0); /* scrap the I/O queues */
-
- /* BEGIN TIME CRITICAL CODE SECTION!!!!!! */
- /* EVERY CYCLE FROM THIS POINT OUT ADDS TO THE INACCURACY OF
- * THE READ CLOCK VALUE!!!!! */
- if (write(cfd, "\003qu0000", 7) != 7) {
-#ifdef DEBUG
- if (debug)
- printf("radioclock write failed\n");
- else
-#endif /* DEBUG */
- if ((nerrors++ % ERR_RATE) == 0)
- syslog(LOG_ERR, "write to radioclock failed: %m");
- return (1);
- }
- if (select(cfd + 1, &readfds, 0, 0, &timeout) != 1) {
-#ifdef DEBUG
- if (debug)
- printf("radioclock poll timed out\n");
- else
-#endif /* DEBUG */
- if ((nerrors++ % ERR_RATE) == 0)
- syslog(LOG_ERR, "poll of radioclock failed: %m");
- return (1);
- }
- if ((i = read(cfd, clockdata, sizeof clockdata)) < MIN_READ) {
-#ifdef DEBUG
- if (debug)
- printf("radioclock read error (%d)\n", i);
- else
-#endif /* DEBUG */
- if ((nerrors++ % ERR_RATE) == 0)
- syslog(LOG_ERR, "radioclock read error (%d!=13): %m", i);
- return (1);
- }
-
- (void)gettimeofday(&mytime, NULL);
- /* END OF TIME CRITICAL CODE SECTION!!!! */
-
- if (clockdata[i - 1] != '\n') {
-#ifdef DEBUG
- if (debug)
- printf("radioclock format error1 (%.12s)(0x%x)\n", clockdata,
- clockdata[12]);
- else
-#endif /* DEBUG */
- if ((nerrors++ % ERR_RATE) == 0)
- syslog(LOG_ERR, "radioclock format error1 (%.12s)(0x%x)",
- clockdata, clockdata[12]);
- return (1);
- }
- for (i = 0; i < 12; i++) {
- if (clockdata[i] < '0' || clockdata[i] > 'o') {
-#ifdef DEBUG
- if (debug)
- printf("radioclock format error2\n");
- else
-#endif /* DEBUG */
- if ((nerrors++ % ERR_RATE) == 0)
- syslog(LOG_ERR, "radioclock format error2\n");
- return (1);
- }
- }
- stat1 = clockdata[0] - '0';
- stat2 = clockdata[1] - '0';
- millis = ((clockdata[2] - '0') * 64) + (clockdata[3] - '0');
- rtm->tm_sec = (clockdata[4] - '0');
- rtm->tm_min = (clockdata[5] - '0');
- rtm->tm_hour = (clockdata[6] - '0');
- rtm->tm_yday = ((clockdata[7] - '0') * 64) + (clockdata[8] - '0') - 1;
- rtm->tm_year = 86 + (clockdata[9] - '0');
- /* byte 10 and 11 reserved */
-
- /*
- * Correct "hours" based on whether or not AM/PM mode is enabled.
- * If clock is in 24 hour (military) mode then no correction is
- * needed.
- */
- if (stat2 & 0x10) { /* Map AM/PM time to Military */
- if (stat2 & 0x8) {
- if (rtm->tm_hour != 12)
- rtm->tm_hour += 12;
- } else {
- if (rtm->tm_hour == 12)
- rtm->tm_hour = 0;
- }
- }
-
- if (stat1 != 0x4 && (nerrors++ % ERR_RATE) == 0) {
-#ifdef DEBUG
- if (debug)
- printf("radioclock fault #%d 0x%x:%s%s%s%s%s%s\n", nerrors, stat1,
- stat1 & 0x20 ? " Out of Spec," : "",
- stat1 & 0x10 ? " Hardware Fault," : "",
- stat1 & 0x8 ? " Signal Fault," : "",
- stat1 & 0x4 ? " Time Avail," : "",
- stat1 & 0x2 ? " Year Mismatch," : "",
- stat1 & 0x1 ? " Clock Reset," : "");
- else {
-#endif /* DEBUG */
- sprintf(message, "radioclock fault #%d 0x%x:%s%s%s%s%s%s\n",
- nerrors, stat1, stat1 & 0x20 ? " Out of Spec," : "",
- stat1 & 0x10 ? " Hardware Fault," : "",
- stat1 & 0x8 ? " Signal Fault," : "",
- stat1 & 0x4 ? " Time Avail," : "",
- stat1 & 0x2 ? " Year Mismatch," : "",
- stat1 & 0x1 ? " Clock Reset," : "");
- syslog(LOG_ERR, message);
- }
- }
- if (stat1 & 0x38) /* Out of Spec, Hardware Fault, Signal Fault */
- return (1);
- if ((millis > 999 || rtm->tm_sec > 60 || rtm->tm_min > 60
- || rtm->tm_hour > 23 || rtm->tm_yday > 365)
- && (nerrors++ % ERR_RATE) == 0) {
-#ifdef DEBUG
- if (debug)
- printf("radioclock bogon #%d: %dd %dh %dm %ds %dms\n", nerrors,
- rtm->tm_yday, rtm->tm_hour, rtm->tm_min, rtm->tm_sec,
- millis);
- else
-#endif /* DEBUG */
- sprintf(message, "radioclock bogon #%d: %dd %dh %dm %ds %dms\n",
- nerrors, rtm->tm_yday, rtm->tm_hour, rtm->tm_min,
- rtm->tm_sec, millis);
- syslog(LOG_ERR, message);
- return (1);
- }
-
- mtm = gmtime(&mytime.tv_sec);
- diff = reltime(rtm, millis * 1000) - reltime(mtm, mytime.tv_usec);
-#ifdef DEBUG
- if (debug > 1) {
- char buf[256];
- strftime(buf, 256, "Clock time: %Y day %j %T", rtm);
- strcat(buf, ".%03d diff %.3f\n", millis, diff);
- printf(buf);
- }
-#endif /* DEBUG */
-
- if (diff > (90 * 24 * 60 * 60.0) && (nerrors++ % ERR_RATE) == 0) {
- char buf1[16], buf2[16];
- strftime(buf1, 16, "%Y/%j", mtm);
- strftime(buf2, 16, "%Y/%j", rtm);
-#ifdef DEBUG
- if (debug) {
- printf("offset excessive (system %s, clock %s)\n", buf1, buf2);
- } else
-#endif /* DEBUG */
- syslog(LOG_ERR, "offset excessive (system %s, clock %s)\n", buf1,
- buf2);
- return (1);
- }
-
- diff += (double)mytime.tv_sec + ((double)mytime.tv_usec / 1000000.0);
- radiotime.tv_sec = diff;
- radiotime.tv_usec = (diff - (double)radiotime.tv_sec) * 1000000;
-#ifdef DEBUG
- if (debug > 1) {
- char buf[256];
- strftime(buf, 256, "%Y day %j %T", mtm);
- printf("System time: %s.%03d\n", buf, mytime.tv_usec / 1000);
- printf("stat1 0%o, stat2 0%o: ", stat1, stat2);
- if (stat1 || stat2)
- printf("%s%s%s%s%s%s%s%s%s%s%s%s",
- stat1 & 0x20 ? " Out of Spec," : "",
- stat1 & 0x10 ? " Hardware Fault," : "",
- stat1 & 0x8 ? " Signal Fault," : "",
- stat1 & 0x4 ? " Time Avail," : "",
- stat1 & 0x2 ? " Year Mismatch," : "",
- stat1 & 0x1 ? " Clock Reset," : "",
- stat2 & 0x20 ? " DST on," : "",
- stat2 & 0x10 ? " 12hr mode," : "",
- stat2 & 0x8 ? " PM," : "", stat2 & 0x4 ? " Spare?," : "",
- stat2 & 0x2 ? " DST??? +1," : "",
- stat2 & 0x1 ? " DST??? -1," : "");
- printf("\n");
- }
-#endif /* DEBUG */
- /* If necessary, acknowledge "Clock Reset" flag bit */
- if (stat1 & 0x1) {
- if (write(cfd, "si0", 3) != 3) {
-#ifdef DEBUG
- if (debug)
- printf("radioclock reset write failed\n");
- else
-#endif /* DEBUG */
- syslog(LOG_ERR, "reset write to radioclock failed: %m");
- return (1);
- }
- }
- if (nerrors && stat1 == 0x4) {
- syslog(LOG_ERR, "radioclock OK (after %d errors)", nerrors);
- nerrors = 0;
- }
- *tvpp = &radiotime;
- *otvpp = &mytime;
- return (0);
-}
-
-static double
-reltime(tm, usec)
- register struct tm *tm;
- register int usec;
-{
- return (tm->tm_year * (366.0 * 24.0 * 60.0 * 60.0) +
- tm->tm_yday * (24.0 * 60.0 * 60.0) + tm->tm_hour * (60.0 * 60.0) +
- tm->tm_min * (60.0) + tm->tm_sec + usec / 1000000.0);
-}
-#endif
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <afs/stds.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <afs/com_err.h>
-#include <afs/cellconfig.h>
-#include <afs/afsutil.h>
-
-
-extern int errno;
-
-char *whoami;
-
-static afs_int32 lastTime = 0;
-
-static afs_int32
-GetCellInfo(cellinfoP)
- struct afsconf_cell *cellinfoP;
-{
- struct afsconf_dir *conf;
- char lcell[MAXHOSTCHARS];
- afs_int32 code;
-
- conf = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
- if (conf == 0)
- return AFSCONF_NOTFOUND;
- code = afsconf_GetLocalCell(conf, lcell, sizeof(lcell));
- if (code)
- return code;
- code = afsconf_GetCellInfo(conf, lcell, 0, cellinfoP);
- lastTime = conf->timeRead;
- afsconf_Close(conf);
- return code;
-}
-
-/* Check the date of the afsconf stuff and return 0 if its date is the
- same as the last call the GetCellInfo. */
-
-static int
-IsCellInfoNew()
-{
- struct afsconf_dir *conf;
- int new;
-
- /* not using cellinfo, so always return OK */
- if (lastTime == 0)
- return 0;
-
- conf = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
- if (conf == 0)
- return 1; /* something's wrong */
- new = conf->timeRead != lastTime;
- afsconf_Close(conf);
- return (new);
-}
-
-int pid = 0; /* process id of ntpd */
-
-void
-terminate()
-{
- if (pid)
- kill(pid, 9); /* kill off ntpd */
- exit(0);
-}
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char *argv[];
-{
- afs_int32 code;
- char *filename;
- FILE *f; /* ntp.conf output file */
- int a;
- int i;
- int local = 0; /* just use machine's local clock */
- int precision = 0; /* precision specification */
- int stratum = 12; /* stratum for local clock */
- char *logfile; /* file for ntpd output streams */
- char *ntpdPath; /* pathname of ntpd executable */
- int nHostArgs = 0; /* number of explicit hosts */
- char *explicitHosts[10]; /* hosts names from arglist */
-
-#ifdef AFS_AIX32_ENV
- /*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
- * in the core dump. Unfortunately, by default, only a partial core is
- * generated which, in many cases, isn't too useful.
- */
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGSEGV, &nsa, NULL);
-#endif
- whoami = argv[0];
- logfile = 0;
-
- /* Initialize dirpaths */
- if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
- fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
- argv[0]);
- exit(2);
- }
-
- ntpdPath = AFSDIR_SERVER_NTPD_FILEPATH;
- for (a = 1; a < argc; a++) {
- if (strcmp(argv[a], "-localclock") == 0)
- local = 1;
- else if (strcmp(argv[a], "-precision") == 0) {
- if (++a >= argc)
- goto usage;
- precision = atoi(argv[a]); /* next arg is (negative) precision */
- } else if (strcmp(argv[a], "-logfile") == 0) {
- if (++a >= argc)
- goto usage;
- logfile = argv[a]; /* next arg is pathname for stdout */
- f = fopen(logfile, "a");
- if (f == NULL) {
- com_err(whoami, errno, "Can't open %s as logfile", logfile);
- goto usage;
- }
- fclose(f);
- } else if (strcmp(argv[a], "-ntpdpath") == 0) {
- if (++a >= argc)
- goto usage;
- ntpdPath = argv[a]; /* next arg is pathname of ntpd */
- f = fopen(ntpdPath, "r");
- if (f == NULL) {
- com_err(whoami, errno, "Can't find ntp daemon at %s",
- ntpdPath);
- goto usage;
- }
- fclose(f);
- } else if (argv[a][0] != '-') { /* must be a hostname */
- if (nHostArgs >= sizeof(explicitHosts) / sizeof(explicitHosts[0])) {
- com_err(whoami, 0, "Too many hosts specified");
- goto usage;
- } else
- explicitHosts[nHostArgs++] = argv[a];
- } else {
- usage:
- fprintf(stdout,
- "Usage: %s [-localclock] [-precision <small-negative-integer>] [-logfile <filename for ntpd's stdout/stderr] [-ntpdpath <pathname of ntpd executable (/usr/afs/bin/ntpd)>] [<host>*] [-help]\n",
- whoami);
- exit(-1);
- }
- }
-
- /* setup to write to output file */
- filename = "/tmp/ntp.conf";
- f = fopen(filename, "w");
- if (f == 0) {
- com_err(whoami, errno, "can't create output file %s", filename);
- exit(4);
- }
-#if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
- /*
- * NOTE: Ntpd does not know how to set kernel variables on Solaris
- * systems, and it does not seem to be necessary on Solaris 2.6 and
- * later.
- */
-
- /* first, for SUNs set tickadj and dosynctodr */
- fprintf(f, "setdosynctodr Y\nsettickadj Y\n");
-#endif
-
- /* specify precision */
- if (precision) {
- fprintf(f, "precision %d\n", precision);
- }
-
- /* then dump the appropriate type of host list */
-
- if (local) { /* use the machines local clock */
- fprintf(f, "peer\t/dev/null\tLOCL\t%d\t%d\tlocal\n", stratum,
- precision);
- }
- if (nHostArgs) { /* use the explicitly provided list */
- for (i = 0; i < nHostArgs; i++) {
- fprintf(f, "peer\t%s\n", explicitHosts[i]);
- }
- }
- if (!(local || nHostArgs)) { /* just use CellServDB info instead */
- struct afsconf_cell cellinfo;
-
- code = GetCellInfo(&cellinfo);
- if (code) {
- com_err(whoami, 0, "can't get local cell info");
- exit(1);
- }
- for (i = 0; i < cellinfo.numServers; i++) {
- fprintf(f, "peer\t%s\t#%s\n",
- inet_ntoa(cellinfo.hostAddr[i].sin_addr),
- cellinfo.hostName[i]);
- }
- }
-
- /* all done with ntp.conf file */
- if (fclose(f) == EOF) {
- com_err(whoami, errno, "can't close output file %s", filename);
- exit(5);
- }
-
- /* handle bozo kills right */
-
- {
- struct sigaction sa;
- memset((char *)&sa, 0, sizeof(sa));
- sa.sa_handler = terminate;
- code = sigaction(SIGTERM, &sa, NULL);
- if (code) {
- com_err(whoami, errno, "can't set up handler for SIGTERM");
- exit(9);
- }
- }
-
- /* now start ntpd with proper arguments */
-
- pid = fork();
- if (pid == -1) {
- com_err(whoami, errno, "forking for ntpd process");
- exit(6);
- }
- if (pid == 0) { /* this is child */
- char *argv[5];
- char *envp[1];
- afs_int32 now = time(0);
- extern char *ctime();
- char *nowString = ctime(&now);
-
- if (logfile == 0)
- logfile = "/dev/null";
- freopen(logfile, "a", stdout);
- freopen(logfile, "a", stderr);
- nowString[strlen(nowString) - 1] = '\0'; /* punt the newline char */
- fprintf(stdout, "Starting %s at %s with output to logfile\n",
- ntpdPath, nowString);
- fflush(stdout);
-
- argv[0] = "ntpd";
- argv[1] = "-f"; /* don't fork */
- argv[2] = "-c"; /* read our conf file */
- argv[3] = filename;
- argv[4] = 0;
- envp[0] = 0;
- code = execve(ntpdPath, argv, envp);
- if (code)
- com_err(whoami, errno, "execve of %s failed", ntpdPath);
- exit(errno);
- } else { /* this is parent */
- int status;
- int waitInterval = 0;
- do {
- i = wait3(&status, WNOHANG | WUNTRACED, 0);
- if (i == -1) {
- (void)kill(pid, 9); /* try to kill off ntpd */
- com_err(whoami, errno, "wait3 ing");
- exit(7);
- } else if (i == pid) {
- printf("ntpd exited status = %x (code=%d, %ssignal=%d)\n",
- status, (status & 0xffff) >> 8,
- ((status & 0x80) ? "coredump, " : ""), status & 0x7f);
- exit(8);
- } else if (i != 0) {
- printf("strange return from wait3 %d\n", i);
- break;
- }
- sleep(waitInterval > 60 ? 60 : waitInterval++);
- } while (!IsCellInfoNew());
-
- code = kill(pid, 9); /* kill off ntpd */
- if (code)
- com_err(whoami, errno, "trying to kill ntpd process");
- else
- printf("Exiting due to change in cellinfo\n");
- }
-
- exit(0);
-}
+++ /dev/null
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- *
- * This software has been released under the terms of the IBM Public
- * License. For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#include <sys/param.h>
-#include <afsconfig.h>
-
-RCSID
- ("$Header$");
-
-#include <afs/stds.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-#include <errno.h>
-#include <syslog.h>
-
-#include "ntp.h"
-
-#define TRUE 1
-#define FALSE 0
-
-int test1(), test2(), test3(), test4(), test5(), test6();
-
-double value[8] = { 5.1, -5.1, 1.5, -1.5, 0.5, -0.5, -0.05, 0.0 };
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- if (argc > 1 && strcmp(argv[1], "-v") == 0) {
- int error;
- error = test1(1);
- error += test2(1);
- error += test3(1);
- error += test4(1);
- error += test5(1);
- error += test6(1);
- exit(error);
- } else {
- if (test2(0))
- exit(2);
- if (test3(0))
- exit(3);
- if (test4(0))
- exit(4);
- if (test5(0))
- exit(5);
- if (test6(0))
- exit(6);
- }
- exit(0);
-}
-
-
-test1()
-{
- int i;
- double l_fixed_to_double();
- struct l_fixedpt sample;
- double s_fixed_to_double();
- struct s_fixedpt s_sample;
-
- for (i = 0; i < 8; i++) {
- printf(" %4.2f ", value[i]);
- double_to_l_fixed(&sample, value[i]);
- printf(" x%#8X.%#8X ", sample.int_part, sample.fraction);
-#if 0
- printf(" %4.2f", l_fixed_to_double(&sample));
-#endif
- printf("\t");
- double_to_s_fixed(&s_sample, value[i]);
- printf(" x%#4X.%#4X ", s_sample.int_part, s_sample.fraction);
- printf(" %4.2f\n", s_fixed_to_double(&s_sample));
- }
- return 0;
-}
-
-test2(v)
- int v; /* verbose */
-{
- struct timeval tp;
- struct l_fixedpt time_lm;
-
- (void)gettimeofday(&tp, NULL);
- tstamp(&time_lm, &tp);
-
- if (v) {
- printf("tv_sec: %d tv_usec: %d \n", tp.tv_sec, tp.tv_usec);
- printf("intpart: %lu fraction: %lu \n", ntohl(time_lm.int_part),
- ntohl(time_lm.fraction));
- printf("intpart: %lX fraction: %lX \n", ntohl(time_lm.int_part),
- ntohl(time_lm.fraction));
- }
- {
- extern double ul_fixed_to_double();
- double d;
- d = ul_fixed_to_double(&time_lm);
- if (v)
- printf("ul_fixed_to_double returns %f\n", d);
- if (d < 0) {
- printf("ul_ftd returned negative number\n");
- return 1;
- }
- d = -d;
- double_to_l_fixed(&time_lm, d);
- if (v)
- printf("intpart: %lX fraction: %lX \n", ntohl(time_lm.int_part),
- ntohl(time_lm.fraction));
- d = ul_fixed_to_double(&time_lm);
- if (d < 0) {
- printf("second ul_ftd returned negative number\n");
- return 1;
- }
- if (v)
- printf("ul_fixed_to_double(double_to_l_fixed(-d)) returns %f\n",
- d);
- }
- if (v)
- printf("test2 passes\n");
- return 0;
-}
-
-test3(v)
- int v;
-{
- afs_uint32 ul = 0x80000001;
- double dbl;
-
-#ifdef GENERIC_UNS_BUG
- /*
- * Hopefully, we can avoid the unsigned issue altogether. Make sure
- * that the high-order (sign) bit is zero, and fiddle from there
- */
- dbl = (afs_int32) ((ul >> 1) & 0x7fffffff);
- dbl *= 2.0;
- if (ul & 1)
- dbl += 1.0;
-#else
- dbl = ul;
-#ifdef VAX_COMPILER_FLT_BUG
- if (dbl < 0.0)
- dbl += 4.294967296e9;
-#endif
-#endif
- if (dbl != 2147483649.0) {
- printf("test3 fails: can't convert from unsigned long to float\n");
- printf(" (%lu != %15g)\n", ul, dbl);
- printf
- ("Try defining VAX_COMPILER_FLT_BUG or GENERIC_UNS_BUG in the Makefile.\n");
- return 1;
- } else {
- if (v)
- printf("test3 passes\n");
- return 0;
- }
-}
-
-test4(v)
- int v;
-{
- double dbl = 1024.0 * 1024.0 * 1024.0; /* 2^30 */
-#ifdef SUN_FLT_BUG
- int l = 1.5 * dbl;
- afs_uint32 ul = (l << 1);
-#else
- afs_uint32 ul = 3.0 * dbl; /* between 2^31 and 2^32 */
-#endif
- if (v)
- printf("test4: 3.0*1024.0*1024.0*1024.0 = 0x%08x\n", ul);
-
- if (ul != 0xc0000000) {
- printf("test4 fails:\n");
- printf("Can't convert unsigned long to double.\n");
- printf("Try defining SUN_FLT_BUG in the Makefile\n");
- return 1;
- } else {
- if (v)
- printf("test4 passes\n");
- return 0;
- }
-}
-
-/* test5 - check for sign extension of int:8 in pkt precision variable. */
-
-test5(v)
- int v;
-{
- struct ntpdata pkt;
- struct ntp_peer peer;
- struct sysdata sys;
- double delay;
-
- memset(&peer, 0, sizeof(peer));
- memset(&sys, 0, sizeof(sys));
- pkt.precision = -6;
- peer.precision = pkt.precision;
- sys.precision = pkt.precision;
- if ((pkt.precision != -6) || (peer.precision != -6)
- || (sys.precision != -6)) {
- printf("pkt %d, peer %d, sys %d, all should be %d\n", pkt.precision,
- peer.precision, sys.precision, -6);
- return 1;
- }
- delay = 0;
- delay += 1.0 / (afs_uint32) (1L << -peer.precision)
- + ((peer.flags & PEER_FL_REFCLOCK) ? NTP_REFMAXSKW : NTP_MAXSKW);
- if (peer.precision < 0 && -peer.precision < sizeof(afs_int32) * NBBY)
- delay += 1.0 / (afs_uint32) (1L << -peer.precision);
- if (v)
- printf("delay is %f\n", delay);
-
- if ((delay - 0.041249) > .000002) {
- printf("delay calculation in error: delay was %d, should be %d\n",
- delay, 0.04125);
- return -1;
- }
- if (v)
- printf("test5 passes\n");
- return 0;
-}
-
-/* test6 - calculates the machine clock's apparent precision. */
-
-int
-test6(v)
- int v;
-{
- int interval = 0;
- int precision;
- int code;
-#if defined(AFS_SUN_ENV) || defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV)
-#define PRECISION -20
-#else
-#define PRECISION -18
-#endif
-
-
- code = 0;
- precision = MeasurePrecision(&interval);
- if ((precision >= 0) || (-precision >= sizeof(afs_int32) * NBBY)) {
- printf("Couldn't measure precision\n");
- code = 1;
- }
- if (precision < PRECISION) {
- printf
- ("Precision (%d) seems too small (best interval measured to date: 13 usec, 10/10/94). -JPM\n",
- precision);
- printf
- ("Make certain that the reported interval is accurate (possible), and then relax\n");
- printf("this check only if appropriate.\n");
- code = 2;
- }
- if (v || code) {
- printf
- ("precision is %d (%f) from measured interval of %d usec (%f)\n",
- precision, 1.0 / (afs_uint32) (1L << -precision), interval,
- interval / 1000000.0);
- if (!code)
- printf("test6 passes\n");
- }
- return code;
-}
+++ /dev/null
-#
-# Copyright (c) 1988 Regents of the University of California.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are permitted
-# provided that the above copyright notice and this paragraph are
-# duplicated in all such forms and that any documentation, advertising
-# materials, and other materials related to such redistribution and
-# use acknowledge that the software was developed by the University
-# of California, Berkeley. The name of the University may not be
-# used to endorse or promote products derived from this software
-# without specific prior written permission. THIS SOFTWARE IS PROVIDED
-# ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-# WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
-# FITNESS FOR A PARTICULAR PURPOSE.
-#
-srcdir=@srcdir@
-include @TOP_OBJDIR@/src/config/Makefile.config
-
-
-LIBC= /lib/libc.a
-SRCS= rcp.c
-OBJS= rcp.o ../rsh/rcmd.o ../rsh/herror.o ../inetd/ta-rauth.o
-
-
-CFLAGS=${COMMON_CFLAGS} ${XCFLAGS}
-AFSLIBS = ${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libubik.a \
- ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a \
- ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \
- ${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/libcom_err.a \
- ${TOP_LIBDIR}/util.a
-LIBRES =
-LIBS = ${AFSLIBS} ${LIBRES}
-MAN=
-
-include ../config/Makefile.version
-
-all: rcp
-
-rcp.o: AFS_component_version_number.c
-
-system: install
-
-rcp: ${OBJS} ${LIBS}
- set -x; \
- case "${SYS_NAME}" in \
- alpha_osf30 | alpha_osf32 | alpha_osf32c | alpha_dux?? ) \
- ${CC} -o $@ ${CFLAGS} ${OBJS} ${LIBS} ${XLIBS} -non_shared ;; \
- * ) \
- ${CC} -o $@ ${CFLAGS} ${OBJS} ${LIBS} ${XLIBS} ;; \
- esac
-
-../rsh/rcmd.o: ../rsh/rcmd.c
- (cd ../rsh ; $(MAKE) rcmd.o SRCDIR=${SRCDIR} DESTDIR=${DESTDIR})
-
-../rsh/herror.o: ../rsh/herror.c
- (cd ../rsh ; $(MAKE) herror.o SRCDIR=${SRCDIR} DESTDIR=${DESTDIR})
-
-../inetd/ta-rauth.o: ../inetd/ta-rauth.c
- (cd ../inetd ; $(MAKE) ta-rauth.o SRCDIR=${SRCDIR} DESTDIR=${DESTDIR})
-
-clean:
-clean:
- $(RM) -f ${OBJS} core rcp AFS_component_version_number.c
-
-cleandir: clean
- $(RM) -f ${MAN} tags .depend
-
-depend: ${SRCS}
- mkdep -p ${CFLAGS} ${SRCS}
-
-install: ${DESTDIR}${bindir}/rcp
-
-${DEST}/bin/rcp: rcp
- ${INSTALL} $? $@
-
-${DESTDIR}${bindir}/rcp: rcp
- ${INSTALL} $? $@
-
-
-dest: ${DEST}/bin/rcp
-
+++ /dev/null
-.\" Copyright (c) 1983 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)rcp.1 6.6 (Berkeley) 9/20/88
-.\"
-.TH RCP 1 "September 20, 1988"
-.UC 5
-.SH NAME
-rcp \- remote file copy
-.SH SYNOPSIS
-.B rcp
-[
-.B \-p
-] file1 file2
-.br
-.B rcp
-[
-.B \-p
-] [
-.B \-r
-] file ... directory
-.SH DESCRIPTION
-.I Rcp
-copies files between machines. Each
-.I file
-or
-.I directory
-argument is either a remote file name of the
-form ``rhost:path'', or a local file name (containing no `:' characters,
-or a `/' before any `:'s).
-.PP
-If the
-.B \-r
-option
-is specified and any of the source files are directories,
-.I rcp
-copies each subtree rooted at that name; in this case
-the destination must be a directory.
-.PP
-By default, the mode and owner of
-.I file2
-are preserved if it already existed; otherwise the mode of the source file
-modified by the
-.IR umask (2)
-on the destination host is used.
-The
-.B \-p
-option causes
-.I rcp
-to attempt to preserve (duplicate) in its copies the modification
-times and modes of the source files, ignoring the
-.IR umask .
-.PP
-If
-.I path
-is not a full path name, it is interpreted relative to
-your login directory on
-.IR rhost .
-A
-.I path
-on a remote host may be quoted (using \e, ", or \(aa)
-so that the metacharacters are interpreted remotely.
-.PP
-.I Rcp
-does not prompt for passwords; your current local user name
-must exist on
-.I rhost
-and allow remote command execution via
-.IR rsh (1).
-.PP
-.I Rcp
-handles third party copies, where neither source nor target files
-are on the current machine.
-Hostnames may also take the form ``rname@rhost'' to use
-.I rname
-rather than the current user name on the remote host.
-.SH SEE ALSO
-cp(1), ftp(1), rsh(1), rlogin(1)
-.SH BUGS
-Doesn't detect all cases where the target of a copy might
-be a file in cases where only a directory should be legal.
-.PP
-Is confused by any output generated by commands in a
-\&.login, \&.profile, or \&.cshrc file on the remote host.
-.PP
-The destination user and hostname may have to be specified as
-``rhost.rname'' when the destination machine is running the 4.2BSD
-version of \fIrcp\fP.
-
+++ /dev/null
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * rcp
- */
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <signal.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <netdb.h>
-#include <errno.h>
-
-#ifdef AFS_SUN5_ENV
-#include <sys/fcntl.h>
-#endif
-#include <dirent.h>
-
-#if defined(AFS_AIX_ENV)
-#define vfork() fork()
-#endif
-
-#ifdef AFS_AIX32_ENV
-#ifndef MSG
-#define MSGSTR(n,s) s
-#define SYSERR(x) sys_errlist[x]
-#define NLfprintf fprintf
-#endif /* MSG */
-
-#ifdef NLS
-#include <NLchar.h>
-#include <NLctype.h>
-#endif
-#endif /* AFS_AIX32_ENV */
-
-#ifdef AFS_OSF_ENV
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#define _PATH_CP "/bin/cp"
-#define _PATH_RSH "/usr/bin/rsh"
-#define _PATH_BSHELL "/bin/sh"
-#endif
-
-int rem;
-char *colon(), *malloc(), *strcpy();
-int errs;
-#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV)
-extern char *sys_errlist[];
-#endif
-void lostconn();
-int iamremote, targetshouldbedirectory;
-int iamrecursive;
-int pflag;
-struct passwd *pwd;
-struct passwd *getpwuid();
-int userid;
-int port;
-
-struct buffer {
- int cnt;
- char *buf;
-} *allocbuf();
-
- /*VARARGS*/ int error();
-
-#define ga() (void) write(rem, "", 1)
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- char *targ, *host, *src;
- char *suser, *tuser, *thost;
- int i, tos;
- char buf[BUFSIZ], cmd[16];
- struct servent *sp;
-
-#if defined(AFS_AIX32_ENV) && (defined(NLS) || defined(KJI))
- setlocale(LC_ALL, "");
-#endif
- sp = getservbyname("shell", "tcp");
- if (sp == NULL) {
- fprintf(stderr, "rcp: shell/tcp: unknown service\n");
- exit(1);
- }
- port = sp->s_port;
- pwd = getpwuid(userid = getuid());
- if (pwd == 0) {
- fprintf(stderr, "who are you?\n");
- exit(1);
- }
-
- for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
- (*argv)++;
- while (**argv)
- switch (*(*argv)++) {
-
- case 'r':
- iamrecursive++;
- break;
-
- case 'p': /* preserve mtimes and atimes */
- pflag++;
- break;
-
- /* The rest of these are not for users. */
- case 'd':
- targetshouldbedirectory = 1;
- break;
-
- case 'f': /* "from" */
- iamremote = 1;
- (void)response();
- (void)setuid(userid);
- source(--argc, ++argv);
- exit(errs);
-
- case 't': /* "to" */
- iamremote = 1;
- (void)setuid(userid);
- sink(--argc, ++argv);
- exit(errs);
-
- default:
- usage();
- }
- }
- if (argc < 2)
- usage();
- if (argc > 2)
- targetshouldbedirectory = 1;
- rem = -1;
- (void)sprintf(cmd, "rcp%s%s%s", iamrecursive ? " -r" : "",
- pflag ? " -p" : "", targetshouldbedirectory ? " -d" : "");
- (void)signal(SIGPIPE, lostconn);
-
- targ = colon(argv[argc - 1]);
- if (targ) { /* ... to remote */
- *targ++ = 0;
- if (*targ == 0)
- targ = ".";
- thost = strchr(argv[argc - 1], '@');
- if (thost) {
- *thost++ = 0;
- tuser = argv[argc - 1];
- if (*tuser == '\0')
- tuser = NULL;
- else if (!okname(tuser))
- exit(1);
- } else {
- thost = argv[argc - 1];
- tuser = NULL;
- }
- for (i = 0; i < argc - 1; i++) {
- char *binpath = "/usr/ucb/rsh";
- struct stat tstat;
-
- if (stat(binpath, &tstat)) {
- /*
- * Doesn't exist; try another path
- */
- binpath = "/bin/rsh";
- }
- src = colon(argv[i]);
- if (src) { /* remote to remote */
- *src++ = 0;
- if (*src == 0)
- src = ".";
- host = strchr(argv[i], '@');
- if (host) {
- *host++ = 0;
- suser = argv[i];
- if (*suser == '\0')
- suser = pwd->pw_name;
- else if (!okname(suser))
- continue;
- (void)sprintf(buf, "%s %s -l %s -n %s %s '%s%s%s:%s'",
- binpath, host, suser, cmd, src,
- tuser ? tuser : "", tuser ? "@" : "", thost,
- targ);
- } else
- (void)sprintf(buf, "%s %s -n %s %s '%s%s%s:%s'", binpath,
- argv[i], cmd, src, tuser ? tuser : "",
- tuser ? "@" : "", thost, targ);
- (void)susystem(buf);
- } else { /* local to remote */
- if (rem == -1) {
- (void)sprintf(buf, "%s -t %s", cmd, targ);
- host = thost;
- rem =
- rcmd(&host, port, pwd->pw_name,
- tuser ? tuser : pwd->pw_name, buf, 0);
- if (rem < 0)
- exit(1);
-#ifdef AFS_OSF_ENV
- tos = IPTOS_THROUGHPUT;
- if (setsockopt
- (rem, IPPROTO_IP, IP_TOS, (char *)&tos,
- sizeof(int)) < 0)
- perror("rcp: setsockopt TOS (ignored)");
-#endif
- if (response() < 0)
- exit(1);
- (void)setuid(userid);
- }
- source(1, argv + i);
- }
- }
- } else { /* ... to local */
- if (targetshouldbedirectory)
- verifydir(argv[argc - 1]);
- for (i = 0; i < argc - 1; i++) {
- src = colon(argv[i]);
- if (src == 0) { /* local to local */
-#ifdef AFS_OSF_ENV
- (void)sprintf(buf, "%s%s%s %s %s", _PATH_CP,
-#else
- (void)sprintf(buf, "/bin/cp%s%s %s %s",
-#endif
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
- argv[i], argv[argc - 1]);
- (void)susystem(buf);
- } else { /* remote to local */
- *src++ = 0;
- if (*src == 0)
- src = ".";
- host = strchr(argv[i], '@');
- if (host) {
- *host++ = 0;
- suser = argv[i];
- if (*suser == '\0')
- suser = pwd->pw_name;
- else if (!okname(suser))
- continue;
- } else {
- host = argv[i];
- suser = pwd->pw_name;
- }
- (void)sprintf(buf, "%s -f %s", cmd, src);
- rem = rcmd(&host, port, pwd->pw_name, suser, buf, 0);
- if (rem < 0)
- continue;
-#ifdef AFS_HPUX_ENV
- (void)setuid(userid);
- sink(1, argv + argc - 1);
- (void)setuid(0);
-#else
-#ifdef AFS_OSF_ENV
- tos = IPTOS_THROUGHPUT;
- if (setsockopt
- (rem, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- perror("rcp: setsockopt TOS (ignored)");
-#endif
- (void)setreuid(0, userid);
- sink(1, argv + argc - 1);
- (void)setreuid(userid, 0);
-#endif
- (void)close(rem);
- rem = -1;
- }
- }
- }
- exit(errs);
-}
-
-verifydir(cp)
- char *cp;
-{
- struct stat stb;
-
- if (stat(cp, &stb) >= 0) {
- if ((stb.st_mode & S_IFMT) == S_IFDIR)
- return;
- errno = ENOTDIR;
- }
- error("rcp: %s: %s.\n", cp, sys_errlist[errno]);
- exit(1);
-}
-
-char *
-colon(cp)
- char *cp;
-{
-
- while (*cp) {
- if (*cp == ':')
- return (cp);
- if (*cp == '/')
- return (0);
- cp++;
- }
- return (0);
-}
-
-okname(cp0)
- char *cp0;
-{
- register char *cp = cp0;
- register int c;
-
- do {
- c = *cp;
- if (c & 0200)
- goto bad;
- if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
- goto bad;
- cp++;
- } while (*cp);
- return (1);
- bad:
- fprintf(stderr, "rcp: invalid user name %s\n", cp0);
- return (0);
-}
-
-susystem(s)
- char *s;
-{
- int status, pid, w;
-#ifdef AFS_OSF_ENV
- register sig_t istat, qstat;
-#else
- register void (*istat) (), (*qstat) ();
-#endif
-
- if ((pid = vfork()) == 0) {
- (void)setuid(userid);
-#ifdef AFS_OSF_ENV
- execl(_PATH_BSHELL, "sh", "-c", s, NULL);
-#else
- execl("/bin/sh", "sh", "-c", s, NULL);
-#endif
- _exit(127);
- }
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
- while ((w = wait(&status)) != pid && w != -1);
- if (w == -1)
- status = -1;
- (void)signal(SIGINT, istat);
- (void)signal(SIGQUIT, qstat);
- return (status);
-}
-
-source(argc, argv)
- int argc;
- char **argv;
-{
- char *last, *name;
- struct stat stb;
- static struct buffer buffer;
- struct buffer *bp;
- int x, readerr, f, amt;
- off_t i;
- char buf[BUFSIZ];
-
- for (x = 0; x < argc; x++) {
- name = argv[x];
- if ((f = open(name, 0)) < 0) {
- error("rcp: %s: %s\n", name, sys_errlist[errno]);
- continue;
- }
- if (fstat(f, &stb) < 0)
- goto notreg;
- switch (stb.st_mode & S_IFMT) {
-
- case S_IFREG:
- break;
-
- case S_IFDIR:
- if (iamrecursive) {
- (void)close(f);
- rsource(name, &stb);
- continue;
- }
- /* fall into ... */
- default:
- notreg:
- (void)close(f);
- error("rcp: %s: not a plain file\n", name);
- continue;
- }
- last = strrchr(name, '/');
- if (last == 0)
- last = name;
- else
- last++;
- if (pflag) {
- /*
- * Make it compatible with possible future
- * versions expecting microseconds.
- */
- (void)sprintf(buf, "T%ld 0 %ld 0\n", stb.st_mtime, stb.st_atime);
- (void)write(rem, buf, strlen(buf));
- if (response() < 0) {
- (void)close(f);
- continue;
- }
- }
- (void)sprintf(buf, "C%04o %ld %s\n", stb.st_mode & 07777, stb.st_size,
- last);
- (void)write(rem, buf, strlen(buf));
- if (response() < 0) {
- (void)close(f);
- continue;
- }
- if ((bp = allocbuf(&buffer, f, BUFSIZ)) == 0) {
- (void)close(f);
- continue;
- }
- readerr = 0;
- for (i = 0; i < stb.st_size; i += bp->cnt) {
- amt = bp->cnt;
- if (i + amt > stb.st_size)
- amt = stb.st_size - i;
- if (readerr == 0 && read(f, bp->buf, amt) != amt)
- readerr = errno;
- (void)write(rem, bp->buf, amt);
- }
- (void)close(f);
- if (readerr == 0)
- ga();
- else
- error("rcp: %s: %s\n", name, sys_errlist[readerr]);
- (void)response();
- }
-}
-
-
-rsource(name, statp)
- char *name;
- struct stat *statp;
-{
- DIR *d = opendir(name);
- char *last;
- struct dirent *dp;
- char buf[BUFSIZ];
- char *bufv[1];
-
- if (d == 0) {
- error("rcp: %s: %s\n", name, sys_errlist[errno]);
- return;
- }
- last = strrchr(name, '/');
- if (last == 0)
- last = name;
- else
- last++;
- if (pflag) {
- (void)sprintf(buf, "T%ld 0 %ld 0\n", statp->st_mtime,
- statp->st_atime);
- (void)write(rem, buf, strlen(buf));
- if (response() < 0) {
- closedir(d);
- return;
- }
- }
- (void)sprintf(buf, "D%04o %d %s\n", statp->st_mode & 07777, 0, last);
- (void)write(rem, buf, strlen(buf));
- if (response() < 0) {
- closedir(d);
- return;
- }
- while (dp = readdir(d)) {
- if (dp->d_ino == 0)
- continue;
- if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
- continue;
- if (strlen(name) + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
- error("%s/%s: Name too long.\n", name, dp->d_name);
- continue;
- }
- (void)sprintf(buf, "%s/%s", name, dp->d_name);
- bufv[0] = buf;
- source(1, bufv);
- }
- closedir(d);
- (void)write(rem, "E\n", 2);
- (void)response();
-}
-
-response()
-{
- char resp, c, rbuf[BUFSIZ], *cp = rbuf;
-
- if (read(rem, &resp, 1) != 1)
- lostconn();
- switch (resp) {
-
- case 0: /* ok */
- return (0);
-
- default:
- *cp++ = resp;
- /* fall into... */
- case 1: /* error, followed by err msg */
- case 2: /* fatal error, "" */
- do {
- if (read(rem, &c, 1) != 1)
- lostconn();
- *cp++ = c;
- } while (cp < &rbuf[BUFSIZ] && c != '\n');
- if (iamremote == 0)
- (void)write(2, rbuf, cp - rbuf);
- errs++;
- if (resp == 1)
- return (-1);
- exit(1);
- }
- /*NOTREACHED*/}
-
-void
-lostconn()
-{
-
- if (iamremote == 0)
- fprintf(stderr, "rcp: lost connection\n");
- exit(1);
-}
-
-sink(argc, argv)
- int argc;
- char **argv;
-{
- off_t i, j;
- char *targ, *whopp, *cp;
- int of, mode, wrerr, exists, first, count, amt, size;
- struct buffer *bp;
- static struct buffer buffer;
- struct stat stb;
- int targisdir = 0;
- int mask = umask(0);
- char *myargv[1];
- char cmdbuf[BUFSIZ], nambuf[BUFSIZ];
- int setimes = 0;
- struct timeval tv[2];
-#define atime tv[0]
-#define mtime tv[1]
-#define SCREWUP(str) { whopp = str; goto screwup; }
-
- if (!pflag)
- (void)umask(mask);
- if (argc != 1) {
- error("rcp: ambiguous target\n");
- exit(1);
- }
- targ = *argv;
- if (targetshouldbedirectory)
- verifydir(targ);
- ga();
- if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)
- targisdir = 1;
- for (first = 1;; first = 0) {
- cp = cmdbuf;
- if (read(rem, cp, 1) <= 0)
- return;
- if (*cp++ == '\n')
- SCREWUP("unexpected '\\n'");
- do {
- if (read(rem, cp, 1) != 1)
- SCREWUP("lost connection");
- } while (*cp++ != '\n');
- *cp = 0;
- if (cmdbuf[0] == '\01' || cmdbuf[0] == '\02') {
- if (iamremote == 0)
- (void)write(2, cmdbuf + 1, strlen(cmdbuf + 1));
- if (cmdbuf[0] == '\02')
- exit(1);
- errs++;
- continue;
- }
- *--cp = 0;
- cp = cmdbuf;
- if (*cp == 'E') {
- ga();
- return;
- }
-#define getnum(t) (t) = 0; while (isdigit(*cp)) (t) = (t) * 10 + (*cp++ - '0');
- if (*cp == 'T') {
- setimes++;
- cp++;
- getnum(mtime.tv_sec);
- if (*cp++ != ' ')
- SCREWUP("mtime.sec not delimited");
- getnum(mtime.tv_usec);
- if (*cp++ != ' ')
- SCREWUP("mtime.usec not delimited");
- getnum(atime.tv_sec);
- if (*cp++ != ' ')
- SCREWUP("atime.sec not delimited");
- getnum(atime.tv_usec);
- if (*cp++ != '\0')
- SCREWUP("atime.usec not delimited");
- ga();
- continue;
- }
- if (*cp != 'C' && *cp != 'D') {
- /*
- * Check for the case "rcp remote:foo\* local:bar".
- * In this case, the line "No match." can be returned
- * by the shell before the rcp command on the remote is
- * executed so the ^Aerror_message convention isn't
- * followed.
- */
- if (first) {
- error("%s\n", cp);
- exit(1);
- }
- SCREWUP("expected control record");
- }
- cp++;
- mode = 0;
- for (; cp < cmdbuf + 5; cp++) {
- if (*cp < '0' || *cp > '7')
- SCREWUP("bad mode");
- mode = (mode << 3) | (*cp - '0');
- }
- if (*cp++ != ' ')
- SCREWUP("mode not delimited");
- size = 0;
- while (isdigit(*cp))
- size = size * 10 + (*cp++ - '0');
- if (*cp++ != ' ')
- SCREWUP("size not delimited");
- if (targisdir)
- (void)sprintf(nambuf, "%s%s%s", targ, *targ ? "/" : "", cp);
- else
- (void)strcpy(nambuf, targ);
- exists = stat(nambuf, &stb) == 0;
- if (cmdbuf[0] == 'D') {
- if (exists) {
- if ((stb.st_mode & S_IFMT) != S_IFDIR) {
- errno = ENOTDIR;
- goto bad;
- }
- if (pflag)
- (void)chmod(nambuf, mode);
- } else if (mkdir(nambuf, mode) < 0)
- goto bad;
- myargv[0] = nambuf;
- sink(1, myargv);
- if (setimes) {
- setimes = 0;
- if (utimes(nambuf, tv) < 0)
- error("rcp: can't set times on %s: %s\n", nambuf,
- sys_errlist[errno]);
- }
- continue;
- }
- if ((of = open(nambuf, O_WRONLY | O_CREAT, mode)) < 0) {
- bad:
- error("rcp: %s: %s\n", nambuf, sys_errlist[errno]);
- continue;
- }
- if (exists && pflag)
- (void)fchmod(of, mode);
- ga();
- if ((bp = allocbuf(&buffer, of, BUFSIZ)) == 0) {
- (void)close(of);
- continue;
- }
- cp = bp->buf;
- count = 0;
- wrerr = 0;
- for (i = 0; i < size; i += BUFSIZ) {
- amt = BUFSIZ;
- if (i + amt > size)
- amt = size - i;
- count += amt;
- do {
- j = read(rem, cp, amt);
- if (j <= 0) {
- if (j == 0)
- error("rcp: dropped connection");
- else
- error("rcp: %s\n", sys_errlist[errno]);
- exit(1);
- }
- amt -= j;
- cp += j;
- } while (amt > 0);
- if (count == bp->cnt) {
- if (wrerr == 0 && write(of, bp->buf, count) != count)
- wrerr++;
- count = 0;
- cp = bp->buf;
- }
- }
- if (count != 0 && wrerr == 0 && write(of, bp->buf, count) != count)
- wrerr++;
- if (ftruncate(of, size))
- error("rcp: can't truncate %s: %s\n", nambuf, sys_errlist[errno]);
- (void)close(of);
- (void)response();
- if (setimes) {
- setimes = 0;
- if (utimes(nambuf, tv) < 0)
- error("rcp: can't set times on %s: %s\n", nambuf,
- sys_errlist[errno]);
- }
- if (wrerr)
- error("rcp: %s: %s\n", nambuf, sys_errlist[errno]);
- else
- ga();
- }
- screwup:
- error("rcp: protocol screwup: %s\n", whopp);
- exit(1);
-}
-
-struct buffer *
-allocbuf(bp, fd, blksize)
- struct buffer *bp;
- int fd, blksize;
-{
- struct stat stb;
- int size;
-
- if (fstat(fd, &stb) < 0) {
- error("rcp: fstat: %s\n", sys_errlist[errno]);
- return (NULL);
- }
-#if defined(AIX) || defined(AFS_SUN5_ENV)
- size = blksize;
-#else
- size = roundup(stb.st_blksize, blksize);
-#endif /* defined(AIX) */
- if (size == 0)
- size = blksize;
- if (bp->cnt < size) {
- if (bp->buf != 0)
- free(bp->buf);
- bp->buf = (char *)malloc((unsigned)size);
- if (bp->buf == 0) {
- error("rcp: malloc: out of memory\n");
- return (NULL);
- }
- }
- bp->cnt = size;
- return (bp);
-}
-
-/*VARARGS1*/
-error(fmt, a1, a2, a3, a4, a5)
- char *fmt;
-#if defined(AFS_64BIT_ENV)
- char *a1, *a2, *a3, *a4, *a5;
-#else
- int a1, a2, a3, a4, a5;
-#endif
-{
- char buf[BUFSIZ], *cp = buf;
-
- errs++;
- *cp++ = 1;
- (void)sprintf(cp, fmt, a1, a2, a3, a4, a5);
- (void)write(rem, buf, strlen(buf));
- if (iamremote == 0)
- (void)write(2, buf + 1, strlen(buf + 1));
-}
-
-usage()
-{
- fputs("usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n", stderr);
- exit(1);
-}
+++ /dev/null
-#
-# Copyright (c) 1988 Regents of the University of California.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are permitted
-# provided that the above copyright notice and this paragraph are
-# duplicated in all such forms and that any documentation, advertising
-# materials, and other materials related to such redistribution and
-# use acknowledge that the software was developed by the University
-# of California, Berkeley. The name of the University may not be
-# used to endorse or promote products derived from this software
-# without specific prior written permission. THIS SOFTWARE IS PROVIDED
-# ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-# WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
-# FITNESS FOR A PARTICULAR PURPOSE.
-#
-# @(#)Makefile 5.3 (Berkeley) 9/20/88
-#
-srcdir=@srcdir@
-include @TOP_OBJDIR@/src/config/Makefile.config
-
-
-LIBC= /lib/libc.a
-SRCS= rlogind.c ../rsh/rcmd.c ../rsh/herror.c ../inetd/ta-rauth.c
-OBJS= rlogind.o ../rsh/rcmd.o ../rsh/herror.o ../inetd/ta-rauth.o
-MAN=
-AFSLIBS = ${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libprot.a \
- ${TOP_LIBDIR}/libubik.a ${TOP_LIBDIR}/libauth.a \
- ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a \
- ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librxkad.a \
- ${TOP_LIBDIR}/libdes.a ${TOP_LIBDIR}/libcmd.a \
- ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a \
- ${TOP_LIBDIR}/libaudit.a
-RES =
-LIBS = ../login/libutil.a ${RES} ${AFSLIBS}
-ALIBS= ${AFSLIBS}
-CFLAGS=-I. -I${srcdir} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
-
-include ../config/Makefile.version
-
-all: rlogind rexecd
-
-system: install
-
-rlogind: ${OBJS} ${LIBS} ../login/libutil.a
- case ${SYS_NAME} in \
- rs_aix*) \
- ${CC} -o $@ ${CFLAGS} ${OBJS} ${LIBS} ${XLIBS} -ls ;; \
- hp_ux110) \
- ${CC} -o $@ ${CFLAGS} ${OBJS} ${LIBS} ${XLIBS} -lsec ;; \
- *) ${CC} -o $@ ${CFLAGS} ${OBJS} ${LIBS} ${XLIBS} ;;\
- esac
-
-rlogind.o: rlogind.c AFS_component_version_number.c
-
-rexecd.o: rexecd.c AFS_component_version_number.c
-
-rexecd: rexecd.o ${ALIBS}
- case ${SYS_NAME} in \
- rs_aix*) \
- ${CC} -o $@ ${CFLAGS} rexecd.o ${ALIBS} ${XLIBS} -ls ;; \
- *) ${CC} -o $@ ${CFLAGS} rexecd.o ${ALIBS} ${XLIBS} ;;\
- esac
-
-
-../login/libutil.a : ../login/util_login.c ../login/util_logout.c ../login/util_logwtmp.c
- ( cd ../login ; $(MAKE) libutil.a )
-
-../rsh/rcmd.o : ../rsh/rcmd.c
- (cp AFS_component_version_number.c ../rsh/AFS_component_version_number.c ; cd ../rsh ; $(MAKE) rsh.o )
-
-../rsh/herror.o : ../rsh/herror.c
- ( cd ../rsh ; $(MAKE) herror.o )
-
-clean:
- $(RM) -f ${OBJS} core rlogind AFS_component_version_number.c
-
-cleandir: clean
- $(RM) -f ${MAN} tags .depend
-
-depend: ${SRCS}
- mkdep -p ${CFLAGS} ${SRCS}
-
-install: ${DESTDIR}${sbindir}/rlogind ${DESTDIR}${sbindir}/rexecd
-
-${DEST}/etc/rlogind: rlogind
- ${INSTALL} $? $@
-
-${DESTDIR}${sbindir}/rlogind: rlogind
- ${INSTALL} $? $@
-
-${DEST}/etc/rexecd: rexecd
- ${INSTALL} $? $@
-
-${DESTDIR}${sbindir}/rexecd: rexecd
- ${INSTALL} $? $@
-
-
-dest: ${DEST}/etc/rlogind ${DEST}/etc/rexecd
-
+++ /dev/null
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <afs/kautils.h> /* for UserAuthGeneral */
-#include <sys/types.h>
-#ifdef AFS_SUN5_ENV
-#define BSD_COMP
-#endif
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <netdb.h>
-#ifdef AFS_SUN5_ENV
-#include <shadow.h>
-#endif
-#if defined(AFS_AIX_ENV)
-#include <sys/syslog.h>
-#include <usersec.h>
-#endif
-
-extern errno;
-struct passwd *getpwnam();
-char *crypt(), *strncat();
-#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_OSF_ENV) && !defined(AFS_SUN5_ENV)
-char *sprintf();
-#endif
-/*VARARGS1*/
-int error();
-
-#include "AFS_component_version_number.c"
-
-#ifdef AFS_OSF_ENV
-#include <sia.h>
-SIAENTITY *entity = NULL;
-int oargc;
-char **oargv;
-#endif
-
-/*
- * remote execute server:
- * username\0
- * password\0
- * command\0
- * data
- */
- /*ARGSUSED*/
-main(argc, argv)
- int argc;
- char **argv;
-{
- struct sockaddr_in from;
- int fromlen;
-
- fromlen = sizeof(from);
- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- fprintf(stderr, "%s: ", argv[0]);
- perror("getpeername");
- exit(1);
- }
-#ifdef AFS_OSF_ENV
- oargc = argc;
- oargv = argv;
-#endif
- doit(0, &from);
-}
-
-char env_user[20] = "USER=";
-char env_home[64] = "HOME=";
-char env_shell[64] = "SHELL=";
-char env_logname[32] = "LOGNAME=";
-char env_password_expires[64] = "PASSWORD_EXPIRES=";
-afs_int32 password_expires = -1;
-char pwd_expires_str[10];
-/* make sure env_password_expires is always the last item in envinit array */
-#if defined(AFS_OSF_ENV) || defined(AFS_AIX_ENV)
-char time_zone[20] = "TZ=";
-char *envinit[] =
- { env_home, env_shell, "PATH=:/usr/ucb:/bin:/usr/bin:/usr/sbin", env_user,
- time_zone, env_logname, env_password_expires, 0
-};
-#else
-char *envinit[] =
- { env_home, env_shell, "PATH=:/usr/ucb:/bin:/usr/bin", env_user,
- env_logname, env_password_expires, 0
-};
-#endif
-#define PATHENV ":/usr/ucb:/bin:/usr/bin:/usr/bin/X11"
-extern char **environ;
-
-struct sockaddr_in asin = { AF_INET };
-
-doit(f, fromp)
- int f;
- struct sockaddr_in *fromp;
-{
- char cmdbuf[NCARGS + 1], *cp, *namep;
- char user[16], pass[16];
- struct passwd *pwd;
- char *password;
- char **penvlist;
- int s;
- short port;
- int pv[2], pid, cc;
- fd_set ready, readfrom;
- char buf[BUFSIZ], sig;
- int one = 1;
- int afsauthok = 1;
-#ifdef AFS_SUN5_ENV
- struct spwd *shpwd;
-#endif
-
- (void)signal(SIGINT, SIG_DFL);
- (void)signal(SIGQUIT, SIG_DFL);
- (void)signal(SIGTERM, SIG_DFL);
-#ifdef DEBUG
- {
- int t = open("/dev/tty", 2);
- if (t >= 0) {
- ioctl(t, TIOCNOTTY, NULL);
- (void)close(t);
- }
- }
-#endif
- dup2(f, 0);
- dup2(f, 1);
- dup2(f, 2);
- (void)alarm(60);
- port = 0;
- for (;;) {
- char c;
- if (read(f, &c, 1) != 1)
- exit(1);
- if (c == 0)
- break;
- port = port * 10 + c - '0';
- }
- (void)alarm(0);
- if (port != 0) {
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- exit(1);
- if (bind(s, (struct sockaddr *)&asin, sizeof(asin)) < 0)
- exit(1);
- (void)alarm(60);
- fromp->sin_port = htons((u_short) port);
- if (connect(s, (struct sockaddr *)fromp, sizeof(*fromp)) < 0)
- exit(1);
- (void)alarm(0);
- }
- getstr(user, sizeof(user), "username");
- getstr(pass, sizeof(pass), "password");
- getstr(cmdbuf, sizeof(cmdbuf), "command");
- setpwent();
- pwd = getpwnam(user);
-#ifdef AFS_SUN5_ENV
- (void)setspent(); /* Shadow password file */
- shpwd = getspnam(user);
- if (pwd == NULL || shpwd == NULL) {
-#else
- if (pwd == NULL) {
-#endif
- error("Login Incorrect..\n");
- exit(1);
- }
- endpwent();
-#ifdef AFS_SUN5_ENV
- endspent();
- password = shpwd->sp_pwdp;
-#else
- password = pwd->pw_passwd;
-#endif
- if (*password != '\0') {
- char *reason;
-
- setpag(); /* Also set a pag */
- /*
- * If it's called as "root" we don't bother with afs authentication...
- */
- if (strcmp(user, "root")) {
- /* changed from ka_UserAuthenticate *
- * to get password_expires information */
- if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, user, /* kerberos name */
- NULL, /* instance */
- NULL, /* realm */
- pass, /* password */
- 0, /* default lifetime */
- &password_expires, 0, /* spare 2 */
- &reason /* error string */
- )) {
-
- afsauthok = 0;
- }
- } else
- afsauthok = 0;
- /*
- * if (strcmp(user, "root") &&
- * strcmp(password, NO_VICE_AUTH_PWD)) {
- * rc = U_Authenticate(user, pass, &cToken, &sToken);
- * } else
- * rc = AUTH_FAILED;
- */
- namep = crypt(pass, password);
- if (strcmp(namep, password) && !afsauthok) {
- error("Password Incorrect..\n");
- exit(1);
- }
- }
- if (chdir(pwd->pw_dir) < 0) {
- error("No remote directory.\n");
- exit(1);
- }
- (void)write(2, "\0", 1);
- if (port) {
- (void)pipe(pv);
- pid = fork();
- if (pid == (int)-1) {
- error("Try again.\n");
- exit(1);
- }
- if (pid) {
- (void)close(0);
- (void)close(1);
- (void)close(2);
- (void)close(f);
- (void)close(pv[1]);
- FD_ZERO(&readfrom);
- FD_SET(s, &readfrom);
- FD_SET(pv[0], &readfrom);
- ioctl(pv[1], FIONBIO, (char *)&one);
- /* should set s nbio! */
- for (;;) {
- int maxfd;
- maxfd = -1;
- if (FD_ISSET(s, &readfrom) && maxfd < s)
- maxfd = s;
- if (FD_ISSET(pv[0], &readfrom) && maxfd < pv[0])
- maxfd = pv[0];
- if (maxfd == -1)
- break;
- ready = readfrom;
- (void)select(maxfd + 1, &ready, (fd_set *) 0, (fd_set *) 0,
- NULL);
- if (FD_ISSET(s, &ready)) {
- if (read(s, &sig, 1) <= 0)
- FD_CLR(s, &readfrom);
- else
- killpg(pid, sig);
- }
- if (FD_ISSET(pv[0], &ready)) {
- cc = read(pv[0], buf, sizeof(buf));
- if (cc <= 0) {
- shutdown(s, 1 + 1);
- FD_CLR(pv[0], &readfrom);
- } else
- (void)write(s, buf, cc);
- }
- }
- exit(0);
- }
- setpgid(0, getpid());
- (void)close(s);
- (void)close(pv[0]);
- dup2(pv[1], 2);
- }
- if (*pwd->pw_shell == '\0')
- pwd->pw_shell = "/bin/sh";
- if (f > 2)
- (void)close(f);
-
-#ifdef AFS_AIX_ENV
- /* For 7403 - try setting ulimit here */
- /*
- * Need to set user's ulimit, else system default
- */
- if (setpcred(pwd->pw_name, NULL) < 0) {
- error("Can't set user credentials.\n");
- exit(1);
- }
-#endif /* AFS_AIX_ENV */
-
- /*
- * For both setgid() and setuid() we should have checked for errors but we ignore them since
- * they may fail in afs...
- */
- (void)setgid((gid_t) pwd->pw_gid);
- initgroups(pwd->pw_name, pwd->pw_gid);
- (void)setuid((uid_t) pwd->pw_uid);
-#ifndef AFS_AIX_ENV
- environ = envinit;
- strncat(env_home, pwd->pw_dir, sizeof(env_home) - 6);
- strncat(env_shell, pwd->pw_shell, sizeof(env_shell) - 7);
- strncat(env_user, pwd->pw_name, sizeof(env_user) - 6);
- strncat(env_logname, pwd->pw_name, sizeof(env_logname) - 9);
- /* Determine if password expiration is used
- * if not, take out env_password_expires string from envinit */
- if ((password_expires >= 0) && (password_expires < 255)) {
- sprintf(env_password_expires, "%s%d", env_password_expires,
- password_expires);
- } else {
- /* taking out PASSWORD_EXPIRES env var from array */
-#if defined(AFS_OSF_ENV)
- envinit[6] = 0;
-#else
- envinit[5] = 0;
-#endif /* AFS_OSF_ENV */
- }
-#else
- penvlist = getpenv(PENV_USR);
- environ = penvlist + 1;
- addenvvar("HOME", pwd->pw_dir);
- addenvvar("SHELL", pwd->pw_shell);
- addenvvar("PATH", PATHENV);
- addenvvar("LOGNAME", pwd->pw_name);
- addenvvar("USER", pwd->pw_name);
- /* Determine if password expiration is used
- * if not, take out env_password_expires string from envinit */
- if ((password_expires >= 0) && (password_expires < 255)) {
- sprintf(pwd_expires_str, "%d", password_expires);
- addenvvar("PASSWORD_EXPIRES", pwd_expires_str);
- }
-#endif
- cp = strrchr(pwd->pw_shell, '/');
- if (cp)
- cp++;
- else
- cp = pwd->pw_shell;
- execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
- perror(pwd->pw_shell);
- exit(1);
-}
-
-#ifdef AFS_AIX_ENV
-addenvvar(tag, value)
- char *tag, *value;
-{
- char *penv;
- unsigned int len = strlen(tag) + 1; /* allow for '=' */
-
- if (!tag) {
- errno = EINVAL;
- perror("rexecd, addenvvar");
- exit(1);
- }
- if (value)
- len += strlen(value);
- penv = malloc(len + 1);
- strcpy(penv, tag);
- strcat(penv, "=");
- if (value)
- strcat(penv, value);
- if (putenv(penv) < 0) {
- perror("rexecd, putenv");
- exit(1);
- }
- return;
-}
-#endif
-
-
-/*VARARGS1*/
-error(fmt, a1, a2, a3)
- char *fmt;
- int a1, a2, a3;
-{
- char buf[BUFSIZ];
-
- buf[0] = 1;
- (void)sprintf(buf + 1, fmt, a1, a2, a3);
- (void)write(2, buf, strlen(buf));
-}
-
-getstr(buf, cnt, err)
- char *buf;
- int cnt;
- char *err;
-{
- char c;
-
- do {
- if (read(0, &c, 1) != 1)
- exit(1);
- *buf++ = c;
- if (--cnt == 0) {
- error("%s too long\n", (int)err, 0, 0);
- exit(1);
- }
- } while (c != 0);
-}
+++ /dev/null
-.\" Copyright (c) 1983 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)rlogind.8 6.8 (Berkeley) 1/6/89
-.\"
-.TH RLOGIND 8 "January 6, 1989"
-.UC 5
-.SH NAME
-rlogind \- remote login server
-.SH SYNOPSIS
-.B /etc/rlogind
-[
-.B \-ln
-]
-.SH DESCRIPTION
-.I Rlogind
-is the server for the
-.IR rlogin (1)
-program. The server provides a remote login facility
-with authentication based on privileged port numbers from trusted hosts.
-.PP
-.I Rlogind
-listens for service requests at the port indicated in
-the ``login'' service specification; see
-.IR services (5).
-When a service request is received the following protocol
-is initiated:
-.IP 1)
-The server checks the client's source port.
-If the port is not in the range 512-1023, the server
-aborts the connection.
-.IP 2)
-The server checks the client's source address
-and requests the corresponding host name (see
-.IR gethostbyaddr (3),
-.IR hosts (5)
-and
-.IR named (8)).
-If the hostname cannot be determined,
-the dot-notation representation of the host address is used.
-.PP
-Once the source port and address have been checked,
-.I rlogind
-proceeds with the authentication process described in
-.IR rshd (8C).
-It then allocates a pseudo terminal (see
-.IR pty (4)),
-and manipulates file descriptors so that the slave
-half of the pseudo terminal becomes the
-.B stdin ,
-.B stdout ,
-and
-.B stderr
-for a login process.
-The login process is an instance of the
-.IR login (1)
-program, invoked with the
-.B \-f
-option if authentication has succeeded.
-If automatic authentication fails, the user is
-prompted to log in as if on a standard terminal line. The
-.I -l
-option prevents any authentication based on the user's
-``.rhosts'' file, unless the user is logging in as the superuser.
-.PP
-The parent of the login process manipulates the master side of
-the pseudo terminal, operating as an intermediary
-between the login process and the client instance of the
-.I rlogin
-program. In normal operation, the packet protocol described
-in
-.IR pty (4)
-is invoked to provide ^S/^Q type facilities and propagate
-interrupt signals to the remote programs. The login process
-propagates the client terminal's baud rate and terminal type,
-as found in the environment variable, ``TERM''; see
-.IR environ (7).
-The screen or window size of the terminal is requested from the client,
-and window size changes from the client are propagated to the pseudo terminal.
-.PP
-Transport-level keepalive messages are enabled unless the
-.B \-n
-option is present.
-The use of keepalive messages allows sessions to be timed out
-if the client crashes or becomes unreachable.
-.SH DIAGNOSTICS
-All diagnostic messages are returned on the connection
-associated with the
-.BR stderr ,
-after which any network connections are closed.
-An error is indicated by a leading byte with a value of 1.
-.PP
-.B ``Try again.''
-.br
-A
-.I fork
-by the server failed.
-.PP
-.B ``/bin/sh: ...''
-.br
-The user's login shell could not be started.
-.SH "SEE ALSO"
-ruserok(3), rshd(8)
-.SH BUGS
-The authentication procedure used here assumes the integrity
-of each client machine and the connecting medium. This is
-insecure, but is useful in an ``open'' environment.
-.PP
-A facility to allow all data exchanges to be encrypted should be
-present.
-.PP
-A more extensible protocol should be used.
+++ /dev/null
-/*
- * Copyright (c) 1983, 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID("$Header$");
-
-#ifdef MSG
-#include "rlogind_msg.h"
-#define MF_LIBC "libc.cat"
-#define MS_LIBC 1
-#define MSGSTR(n,s) NLgetamsg(MF_RLOGIND, MS_RLOGIND, n, s)
-#else*/
-#define MSGSTR(n,s) s
-/*#endif*/
-
-
-/*
- * remote login server:
- * \0
- * remuser\0
- * locuser\0
- * terminal_type/speed\0
- * data
- *
- * Automatic login protocol is done here, using login -f upon success,
- * unless OLD_LOGIN is defined (then done in login, ala 4.2/4.3BSD).
- */
-
-#include <afs/param.h>
-#ifdef AFS_SUN5_ENV
-#define BSD_COMP
-#include <sys/ioctl.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/file.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-
-#include <netinet/in.h>
-
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#ifdef _AIX
-#include <utmp.h>
-/* POSIX TERMIOS */
-#include <termios.h>
-#include <sys/ioctl.h>
-#ifndef AFS_AIX41_ENV
-#include <sys/tty.h>
-#endif
-#include <sys/acl.h>
-#include <sys/access.h>
-#else /* _AIX */
-#include <sgtty.h>
-#endif /* _AIX */
-#include <stdio.h>
-#include <netdb.h>
-#ifdef AFS_AIX32_ENV
-#include <sys/lockf.h>
-#endif
-#include <syslog.h>
-#include <strings.h>
-
-#ifdef AFS_OSF_ENV
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/file.h>
-#include <sys/signal.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#define TTYDEFCHARS
-#include <sys/termios.h>
-#define _PATH_LOGIN "/usr/bin/login"
-#endif
-
-#if defined(AFS_HPUX_ENV)
-#include <fcntl.h>
-#include <sys/ptyio.h>
-#endif /* defined(AFS_HPUX_ENV) */
-
-#ifdef _AIX
-#define DEF_UTMP "Active tty entry not found in utmp file.\n"
-
-#define NOLOGIN "/etc/nologin"
-#define BSHELL "/bin/sh"
-
-/*#define KAUTH*/
-
-#ifdef KAUTH
-int pass_tokens;
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#endif /* KAUTH */
-
-struct utmp utmp;
-#define UT_NAMESIZE sizeof(utmp.ut_user)
-#define UTSIZ (sizeof (struct utmp))
-
-static void loginlog();
-#endif /* _AIX */
-
-#ifndef TIOCPKT_WINDOW
-#define TIOCPKT_WINDOW 0x80
-#endif
-
-char *env[2];
-#define NMAX 30
-char lusername[NMAX + 1], rusername[NMAX + 1];
-static char term[64] = "TERM=";
-#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */
-int keepalive = 1;
-int tracing = 0;
-#ifdef AFS_OSF_ENV
-int check_all = 0;
-#endif
-
-#define SUPERUSER(pwd) ((pwd)->pw_uid == 0)
-
-extern int errno;
-int reapchild();
-struct passwd *getpwnam(), *pwd;
-#ifdef AFS_HPUX_ENV
-#include <unistd.h>
-struct s_passwd *s_pwd, *getspwnam();
-struct stat s_pfile;
-#endif
-#if defined(AFS_AIX32_ENV) && (defined(NLS) || defined(KJI))
-#include <locale.h>
-#endif
-
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- extern int opterr, optind, _check_rhosts_file;
- int ch;
- int on = 1, fromlen;
- struct sockaddr_in from;
-#ifdef AFS_AIX32_ENV
- struct sigaction sa;
- void trace_handler(int);
-
-#if defined(NLS) || defined(KJI)
- setlocale(LC_ALL, "");
-#endif
-#endif
- openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH);
-
-#ifdef KAUTH
- pass_tokens = 0;
-#endif
- opterr = 0;
- while ((ch = getopt(argc, argv, "ln")) != EOF)
- switch (ch) {
-#ifdef AFS_OSF_ENV
- case 'a':
- check_all = 1;
- break;
-#endif
- case 'l':
- _check_rhosts_file = 0;
- break;
- case 'n':
- keepalive = 0;
- break;
-#ifdef AFS_AIX32_ENV
-#ifdef KAUTH
- case 'v':
- pass_tokens = 1;
- break;
-#endif /* KAUTH */
- case 's':
- tracing = 1;
- break;
-#endif
- case '?':
- default:
-#ifdef AFS_AIX32_ENV
-#ifdef KAUTH
- syslog(LOG_ERR, "usage: rlogind [-v] [-l] [-n] [-s]");
-#else /* KAUTH */
- syslog(LOG_ERR, "usage: rlogind [-l] [-n] [-s]");
-#endif /* KAUTH */
-#else
-#ifdef AFS_OSF_ENV
- syslog(LOG_ERR, "usage: rlogind [-l] [-n] [-a] [-s]");
-#else
- syslog(LOG_ERR, "usage: rlogind [-l] [-n]");
-#endif
-#endif
- break;
- }
- argc -= optind;
- argv += optind;
-
- fromlen = sizeof(from);
- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- syslog(LOG_ERR, "Couldn't get peer name of remote host: %m");
- fatalperror("Can't get peer name of host");
- }
- if (keepalive
- && setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- sizeof(on)) < 0)
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
-#ifdef AFS_AIX32_ENV
- if (tracing
- && setsockopt(0, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_WARNING, MSGSTR(SETDEBUG, "setsockopt (SO_DEBUG): %m"));
- /*MSG*/
- /* set-up signal handler routines for SRC TRACE ON/OFF support */
- memset((char *)&sa, 0, sizeof(sa));
- sa.sa_mask.losigs = sigmask(SIGUSR2);
- sa.sa_handler = trace_handler;
- sa.sa_flags = SA_RESTART;
- sigaction(SIGUSR1, &sa, NULL);
- sa.sa_mask.losigs = sigmask(SIGUSR1);
- sa.sa_handler = trace_handler;
- sa.sa_flags = SA_RESTART;
- sigaction(SIGUSR2, &sa, NULL);
-#endif
-#ifdef AFS_OSF_ENV
- on = IPTOS_LOWDELAY;
- if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
-#endif
- doit(0, &from);
-}
-
-#ifdef AFS_AIX32_ENV
-/*
- * trace_handler - SRC TRACE ON/OFF signal handler
- */
-void
-trace_handler(int sig)
-{
- int onoff;
-
- onoff = (sig == SIGUSR1) ? 1 : 0;
- if (setsockopt(0, SOL_SOCKET, SO_DEBUG, &onoff, sizeof(onoff)) < 0)
- syslog(LOG_WARNING, MSGSTR(SETDEBUG, "setsockopt (SO_DEBUG): %m"));
- /*MSG*/}
-#endif
-
-int child;
-void cleanup();
-int netf;
-#ifdef AFS_OSF_ENV
-char line[MAXPATHLEN];
-#else
-char *line;
-#endif
-#ifdef _AIX
-char tbuf[MAXPATHLEN + 2];
-struct hostent *hp;
-struct hostent hostent;
-#endif /* _AIX */
-
-extern char *inet_ntoa();
-#ifdef AFS_HPUX_ENV
-int netp;
-char master[MAXPATHLEN], slave[MAXPATHLEN], tname[MAXPATHLEN];
-#endif
-
-#if defined(TIOCSWINSZ) || defined(AFS_OSF_ENV)
-struct winsize win = { 0, 0, 0, 0 };
-#else /* ~TIOCWINSIZ */
-/*
- * Window/terminal size structure.
- * This information is stored by the kernel
- * in order to provide a consistent interface,
- * but is not used by the kernel.
- *
- * Type must be "unsigned short" so that types.h not required.
- */
-struct winsize {
- unsigned short ws_row; /* rows, in characters */
- unsigned short ws_col; /* columns, in characters */
- unsigned short ws_xpixel; /* horizontal size, pixels */
- unsigned short ws_ypixel; /* vertical size, pixels */
-};
-#endif /* ~TIOCWINSIZ */
-
-doit(f, fromp)
- int f;
- struct sockaddr_in *fromp;
-{
- int i, p, t, pid, on = 1;
-#ifdef AFS_OSF_ENV
- int master;
-#endif
-#ifdef AFS_HPUX_ENV
- int t_;
- char *tn;
-#endif
- char pline[16];
-
-#ifndef OLD_LOGIN
- int authenticated = 0, hostok = 0;
- char remotehost[2 * MAXHOSTNAMELEN + 1];
-#endif
-#ifndef _AIX
- register struct hostent *hp;
- struct hostent hostent;
-#endif
- char c, *cp;
-
-#if defined(AFS_HPUX_ENV)
- int ptyStatusFlags;
-#endif /* defined(AFS_HPUX_ENV) */
-
- alarm(60);
- read(f, &c, 1);
- if (c != 0)
- exit(1);
-
- alarm(0);
- fromp->sin_port = ntohs((u_short) fromp->sin_port);
- hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof(struct in_addr),
- fromp->sin_family);
- if (hp == 0) {
- /*
- * Only the name is used below.
- */
- hp = &hostent;
- hp->h_name = inet_ntoa(fromp->sin_addr);
-#ifndef OLD_LOGIN
- hostok++;
-#endif
- }
-#ifndef OLD_LOGIN
-#ifdef AFS_HPUX_ENV
- else if (errno != ECONNREFUSED) {
-#else
-#ifdef AFS_OSF_ENV
- else if (check_all || local_domain(hp->h_name)) {
-#else
- else if (local_domain(hp->h_name)) {
-#endif
-#endif
- /*
- * If name returned by gethostbyaddr is in our domain,
- * attempt to verify that we haven't been fooled by someone
- * in a remote net; look up the name and check that this
- * address corresponds to the name.
- */
- strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1);
- remotehost[sizeof(remotehost) - 1] = 0;
- hp = gethostbyname(remotehost);
- if (hp)
-#if defined(BSD_42)
- if (!memcmp
- (hp->h_addr, (caddr_t) & fromp->sin_addr,
- sizeof(fromp->sin_addr))) {
-#else /* BSD_42 */
- for (; hp->h_addr_list[0]; hp->h_addr_list++)
- if (!memcmp
- (hp->h_addr_list[0], (caddr_t) & fromp->sin_addr,
- sizeof(fromp->sin_addr))) {
-#endif /* BSD_42 */
- hostok++;
-#if !defined(BSD_42)
- break;
-#endif
- }
- } else
- hostok++;
-#endif
-
- if (fromp->sin_family != AF_INET || fromp->sin_port >= IPPORT_RESERVED
- || fromp->sin_port < IPPORT_RESERVED / 2) {
- syslog(LOG_NOTICE, "Connection from %s on illegal port",
- inet_ntoa(fromp->sin_addr));
- fatal(f, "Permission denied");
- }
-#ifdef IP_OPTIONS
- {
- u_char optbuf[BUFSIZ / 3], *cp;
- char lbuf[BUFSIZ], *lp;
- int optsize = sizeof(optbuf), ipproto;
- struct protoent *ip;
-
- if ((ip = getprotobyname("ip")) != NULL)
- ipproto = ip->p_proto;
- else
- ipproto = IPPROTO_IP;
- if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, &optsize) == 0
- && optsize != 0) {
- lp = lbuf;
- for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
- sprintf(lp, " %2.2x", *cp);
- syslog(LOG_NOTICE,
- "Connection received using IP options (ignored):%s", lbuf);
- if (setsockopt(0, ipproto, IP_OPTIONS, (char *)NULL, optsize) !=
- 0) {
- syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
- exit(1);
- }
- }
- }
-#endif
- write(f, "", 1);
-#ifndef OLD_LOGIN
- if (do_rlogin(hp->h_name) == 0) {
- if (hostok)
- authenticated++;
- else
- write(f, "rlogind: Host address mismatch.\r\n",
- sizeof("rlogind: Host address mismatch.\r\n") - 1);
- }
-#endif
-#ifdef KAUTH
- if (pass_tokens) {
- if (intokens(0)) {
- fprintf(stderr, "%s: invalid remote authentication\n", "login");
- exit(1);
- }
- }
-#endif /* KAUTH */
-
-#ifdef AFS_OSF_ENV
- netf = f;
-
- pid = forkpty(&master, line, NULL, &win);
- if (pid < 0) {
- if (errno == ENOENT)
- fatal(f, "Out of ptys", 0);
- else
- fatal(f, "Forkpty", 1);
- }
- if (pid == 0) {
- if (f > 2) /* f should always be 0, but... */
- (void)close(f);
- setup_term(0);
- if (authenticated) {
- execl(_PATH_LOGIN, "login", "-p", "-h", hp->h_name, "-f",
- lusername, NULL);
- } else {
- char *sp = lusername;
- while (*sp == ' ')
- sp++;
- if (!strncmp(sp, "-f", 2)) {
- syslog(LOG_ERR, "Can't use '-f' in username");
- exit(1);
- }
- execl(_PATH_LOGIN, "login", "-p", "-h", hp->h_name, lusername,
- NULL);
- }
- fatalperror(2, _PATH_LOGIN);
- /*NOTREACHED*/}
- ioctl(f, FIONBIO, &on);
- ioctl(master, FIONBIO, &on);
- ioctl(master, TIOCPKT, &on);
- signal(SIGCHLD, cleanup);
- protocol(f, master);
- signal(SIGCHLD, SIG_IGN);
- cleanup();
-#else
-#if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV) && defined(notdef)
- /*
- * Find an unused pty. A security hole exists if we
- * allow any other process to hold the slave side of the
- * pty open while we are setting up. The other process
- * could read from the slave side at the time that in.rlogind
- * is forwarding the "rlogin authentication" string from the
- * rlogin client through the pty to the login program. If the
- * other process grabs this string, the user at the rlogin
- * client program can forge an authentication string.
- * This problem would not exist if the pty subsystem
- * would fail the open of the master side when there are
- * existing open instances of the slave side.
- * Until the pty driver is changed to work this way, we use
- * a side effect of one particular ioctl to test whether
- * any process has the slave open.
- */
-
- for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {
- struct stat stb;
- int pgrp;
-
- /* make sure this "bank" of ptys exists */
- line = "/dev/ptyXX";
- line[strlen("/dev/pty")] = *cp;
- line[strlen("/dev/ptyp")] = '0';
- if (stat(line, &stb) < 0)
- break;
- for (i = 0; i < 16; i++) {
- line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
- line[strlen("/dev/")] = 'p';
-
- /*
- * Test to see if this pty is unused. The open
- * on the master side of the pty will fail if
- * any other process has it open.
- */
- if ((p = open(line, O_RDWR | O_NOCTTY)) == -1)
- continue;
-
- /*
- * Lock the slave side so that no one else can
- * open it after this.
- */
- line[strlen("/dev/")] = 't';
- if (chmod(line, 0600) == -1) {
- (void)close(p);
- continue;
- }
-
- /*
- * XXX - Use a side effect of TIOCGPGRP on ptys
- * to test whether any process is holding the
- * slave side open. May not work as we expect
- * in anything other than SunOS 4.1.
- */
- if ((ioctl(p, TIOCGPGRP, &pgrp) == -1) && (errno == EIO))
- goto gotpty;
- else {
- (void)chmod(line, 0666);
- (void)close(p);
- }
- }
- }
- fatal(f, "Out of ptys");
- /*NOTREACHED*/ gotpty:
- (void)ioctl(p, TIOCSWINSZ, &win);
- netf = f;
- line[strlen("/dev/")] = 't';
- t = open(line, O_RDWR | O_NOCTTY);
- if (t < 0)
- fatalperror(f, line);
- {
- /* These should be converted to termios ioctls. */
- struct sgttyb b;
- int zero = 0;
-
- if (gtty(t, &b) == -1)
- perror("gtty");
- b.sg_flags = RAW | ANYP;
- /* XXX - ispeed and ospeed must be non-zero */
- b.sg_ispeed = B38400;
- b.sg_ospeed = B38400;
- if (stty(t, &b) == -1)
- perror("stty");
- /*
- * Turn off PASS8 mode, since "login" no longer does so.
- */
- if (ioctl(t, TIOCLSET, &zero) == -1)
- perror("ioctl TIOCLSET");
- }
-#else
-#ifdef _AIX
- (void)setsid();
- if ((p = open("/dev/ptc", O_RDWR)) >= 0) {
- line = ttyname(p);
- } else {
- fatal(f, MSGSTR(NOPTY, "Out of ptys"));
- /*MSG*/}
-
-#else
-#ifdef AFS_HPUX_ENV
- if (getpty(&p, master, slave) != 0)
- fatal(f, "Unable to allocate pty on remote host");
- /* Global copies for use by SIGCHLD handler */
- netf = f;
- netp = p;
-
- /* Slave becomes controlling terminal for this session. */
- t_ = open(slave, O_RDWR);
- if (t_ < 0)
- fatalperror(f, slave);
- /* Remove any reference to the current control terminal */
- if (vhangup() < 0)
- fatalperror(f, "rlogind: vhangup()");
- /* reopen the slave pseudo-terminal */
- t = open(slave, O_RDWR);
- if (t < 0)
- fatalperror(f, slave);
- close(t_);
- /* Get the line name for utmp accounting. */
- tn = ttyname(t);
- if (tn != NULL)
- strcpy(tname, tn);
- else
- strcpy(tname, slave);
-#ifdef TIOCSWINSZ
- (void)ioctl(p, TIOCSWINSZ, &win);
-#endif /* TIOCSWINSZ */
-#ifndef OLD_LOGIN
- setup_term(t);
-#endif /* ~OLD_LOGIN */
-
- /* Lock the pty so that the parent can then synchronize setting up
- * the child's process group and controlling terminal with the
- * login process. The login process won't be able to read from
- * the pty until the parent unlocks it.
- */
- lockf(p, F_LOCK, 0);
-#else
- for (c = 'p'; c <= 'z'; c++) {
- struct stat stb;
- line = "/dev/ptyXX";
- line[strlen("/dev/pty")] = c;
- line[strlen("/dev/ptyp")] = '0';
- if (stat(line, &stb) < 0)
- break;
- for (i = 0; i < 16; i++) {
- line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i];
- p = open(line, O_RDWR);
- if (p > 0)
- goto gotpty;
- }
- }
- fatal(f, "Out of ptys");
- /*NOTREACHED*/ gotpty:
-#endif
-#endif /* _AIX */
-
-#ifdef AFS_SUN_ENV
-
- /* defect #2976 */
-
- strcpy(pline, line);
- pline[strlen("/dev/")] = 't';
- chmod(pline, 0620);
-
- if (close(p) < 0)
- goto L1;
- if ((p = open(line, O_RDWR)) < 0)
- fatal(f, "Bad open");
-
- L1:
-#endif
-
-#ifndef AFS_HPUX_ENV
-#ifdef AFS_AIX32_ENV
-#ifdef TIOCSWINSZ
- (void)ioctl(p, TIOCSWINSZ, &win);
-#else
-#ifdef TXSETWINSZ
- (void)ioctl(p, TXSETWINSZ, &win);
-#endif /* TXSETWINSZ */
-#endif /* TIOCSWINSZ */
-#endif
-#ifdef TIOCSWINSZ
- (void)ioctl(p, TIOCSWINSZ, &win);
-#endif
- netf = f;
-#ifndef _AIX
- line[strlen("/dev/")] = 't';
- t = open(line, O_RDWR);
- if (t < 0)
- fatalperror(f, line);
-#if !defined(ultrix)
- if (fchmod(t, 0))
- fatalperror(f, line);
- (void)signal(SIGHUP, SIG_IGN);
-#if ! defined(AFS_HPUX_ENV) && ! defined(AFS_OSF_ENV)
- vhangup();
-#endif /* !defined(AFS_HPUX_ENV) */
- (void)signal(SIGHUP, SIG_DFL);
-#endif /* ultrix */
- t = open(line, O_RDWR);
- if (t < 0)
- fatalperror(f, line);
- setup_term(t);
-#endif /* _AIX */
-#endif /* !AFS_SUN_ENV && !AFS_SUN5_ENV */
-#ifdef DEBUG
- {
- int tt = open("/dev/tty", O_RDWR);
- if (tt > 0) {
- (void)ioctl(tt, TIOCNOTTY, 0);
- (void)close(tt);
- }
- }
-#endif
-#endif /* !AFS_HPUX_ENV */
- pid = fork();
- if (pid < 0) {
- fatalperror(f, "");
- }
- if (pid == 0) {
-#if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV) && defined(notdef)
- int tt;
-
- /* The child process needs to be the session leader
- * and have the pty as its controlling tty
- */
- setpgrp(0, 0);
- tt = open(line, O_RDWR);
- if (tt < 0)
- fatalperror(f, line);
- close(f), close(p), close(t);
- if (tt != 0)
- dup2(tt, 0);
- if (tt != 1)
- dup2(tt, 1);
- if (tt != 2)
- dup2(tt, 2);
- if (tt > 2)
- close(tt);
-#ifdef notdef
- close(f), close(p);
- dup2(t, 0), dup2(t, 1), dup2(t, 2);
- close(t);
-#endif
-#else
-#ifdef _AIX
- (void)setsid();
- t = open(line, O_RDWR);
- if (t < 0)
- fatalperror(f, line);
- if (acl_fset(t, NO_ACC, NO_ACC, NO_ACC))
- fatalperror(f, line);
- (void)signal(SIGHUP, SIG_IGN);
- /* frevoke(t); */
-
- {
- struct sigaction sa;
- memset((char *)&sa, 0, sizeof(sa));
- sa.sa_handler = SIG_DFL;
- sigaction(SIGQUIT, &sa, NULL);
- sa.sa_handler = SIG_DFL;
- sigaction(SIGHUP, &sa, NULL);
- }
-
- t = open(line, O_RDWR);
- if (t < 0)
- fatalperror(f, line);
- setup_term(t);
-#endif /* _AIX */
-#ifdef AFS_OSF_ENV
- (void)setsid();
- (void)ioctl(t, TIOCSCTTY, 0);
-#endif /* AFS_OSF_ENV */
-#ifdef AFS_HPUX_ENV
- /* Wait for the parent to setup our process group and controlling tty. */
- lockf(p, F_LOCK, 0);
- lockf(p, F_ULOCK, 0);
-#endif
- close(f), close(p);
- dup2(t, 0), dup2(t, 1), dup2(t, 2);
- close(t);
-#endif /* AFS_SUN_ENV */
-#ifdef AFS_AIX32_ENV
- /*
- * Reset SIGUSR1 and SIGUSR2 to non-restartable so children
- * of rlogind do not get clobbered by the way rlogind handles
- * these signals.
- */
- {
- struct sigaction sa;
-
- memset((char *)&sa, 0, sizeof(sa));
- sa.sa_mask.losigs = sigmask(SIGUSR2);
- sa.sa_handler = trace_handler;
- sigaction(SIGUSR1, &sa, NULL);
- sa.sa_mask.losigs = sigmask(SIGUSR1);
- sa.sa_handler = trace_handler;
- sigaction(SIGUSR2, &sa, NULL);
- }
-
- (void)loginlog(lusername, line, hp->h_name);
-#endif
-#ifdef OLD_LOGIN
- execl("/bin/login", "login", "-r", hp->h_name, 0);
-#else /* OLD_LOGIN */
- if (authenticated) {
-#ifdef AFS_AIX32_ENV
- execl("/bin/login.afs", "login", /*"-v", */ "-p", "-h",
- hp->h_name, "-f", "--", lusername, 0);
-#else
- execl("/bin/login", "login", "-p", "-h", hp->h_name, "-f",
- lusername, 0);
-#endif
- } else {
- char *sp = lusername;
- while (*sp == ' ')
- sp++;
- if (!strncmp(sp, "-f", 2)) {
- syslog(LOG_ERR, "Can't use '-f' in username");
- exit(1);
- }
-#ifdef AFS_AIX32_ENV
- execl("/bin/login.afs", "login", /*"-v", */ "-p", "-h",
- hp->h_name, "--", lusername, 0);
-#else
- execl("/bin/login", "login", "-p", "-h", hp->h_name, lusername,
- 0);
-#endif
- }
-#endif /* OLD_LOGIN */
- fatalperror(2, "/bin/login");
- /*NOTREACHED*/}
-#ifdef AFS_HPUX_ENV
- /* Set the child up as a process group leader.
- * It must not be part of the parent's process group,
- * because signals issued in the child's process group
- * must not affect the parent.
- */
- setpgid(pid, pid);
-
- /* Make the pty slave the controlling terminal for the child's process group. */
- tcsetpgrp(t, pid);
- /* Close our controlling terminal. */
- close(t);
-
- /* Let the child know that it is a process group leader and has a controlling tty. */
- lockf(p, F_ULOCK, 0);
- ioctl(f, FIONBIO, &on);
- ioctl(p, FIONBIO, &on);
- ioctl(p, TIOCPKT, &on);
- signal(SIGTSTP, SIG_IGN);
- signal(SIGCHLD, cleanup);
-#ifdef AFS_HPUX102_ENV
- signal(SIGTERM, cleanup);
- signal(SIGPIPE, cleanup);
-#else
- signal(SIGTERM, cleanup,
- sigmask(SIGCLD) | sigmask(SIGTERM) | sigmask(SIGPIPE));
- signal(SIGPIPE, cleanup,
- sigmask(SIGCLD) | sigmask(SIGTERM) | sigmask(SIGPIPE));
-#endif
- setpgid(0, 0);
- protocol(f, p);
- signal(SIGCHLD, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
- cleanup();
- return;
-#endif
-#ifndef _AIX
- close(t);
-#endif
-
- ioctl(f, FIONBIO, &on);
-
-#if !defined(AFS_HPUX_ENV)
- ioctl(p, FIONBIO, &on);
-#else /* !defined(AFS_HPUX_ENV) */
- /* HPUX does not support FIONBIO on ptys, so, we do it the hard way */
- ptyStatusFlags = fcntl(p, F_GETFL, 0);
- fcntl(p, F_SETFL, ptyStatusFlags | O_NDELAY);
-#endif /* !defined(AFS_HPUX_ENV) */
-
-#if !defined(AFS_SUN5_ENV)
- ioctl(p, TIOCPKT, &on);
- signal(SIGTSTP, SIG_IGN);
-#if defined(AFS_HPUX_ENV)
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
-#endif /* defined(AFS_HPUX_ENV) */
-#endif /* !defined(AFS_SUN5_ENV) */
- signal(SIGCHLD, cleanup);
-#ifndef _AIX
-#ifdef AFS_HPUX102_ENV
- setpgrp();
-#else
- setpgrp(0, 0);
-#endif
-#endif
-#ifdef AFS_AIX32_ENV
- protocol(f, p, pid);
- (void)signal(SIGCHLD, SIG_IGN);
- cleanup(pid);
-#else
- protocol(f, p);
- signal(SIGCHLD, SIG_IGN);
- cleanup();
-#endif
-#endif /* AFS_OSF_ENV */
-}
-
-char magic[2] = { 0377, 0377 };
-char oobdata[] = { TIOCPKT_WINDOW };
-
-/*
- * Handle a "control" request (signaled by magic being present)
- * in the data stream. For now, we are only willing to handle
- * window size changes.
- */
-control(pty, cp, n)
- int pty;
- char *cp;
- int n;
-{
- struct winsize w;
-
- if (n < 4 + sizeof(w) || cp[2] != 's' || cp[3] != 's')
- return (0);
- oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
- memcpy((char *)&w, cp + 4, sizeof(w));
- w.ws_row = ntohs(w.ws_row);
- w.ws_col = ntohs(w.ws_col);
- w.ws_xpixel = ntohs(w.ws_xpixel);
- w.ws_ypixel = ntohs(w.ws_ypixel);
-#ifdef AFS_AIX32_ENV
-#ifdef TIOCSWINSZ
- (void)ioctl(pty, TIOCSWINSZ, &w);
-#else
- (void)ioctl(pty, TXSETWINSZ, &w);
-#endif
-#else
-#ifdef TIOCSWINSZ
- (void)ioctl(pty, TIOCSWINSZ, &w);
-#endif
-#endif
- return (4 + sizeof(w));
-}
-
-/*
- * rlogin "protocol" machine.
- */
-#ifdef AFS_AIX32_ENV
-protocol(f, p, pid)
- int f, p;
- pid_t pid;
-#else
-protocol(f, p)
- int f, p;
-#endif
-{
- char pibuf[1024], fibuf[1024], *pbp, *fbp;
- register pcc = 0, fcc = 0;
- int cc, nfd, pmask, fmask;
- char cntl;
-
- /*
- * Must ignore SIGTTOU, otherwise we'll stop
- * when we try and set slave pty's window shape
- * (our controlling tty is the master pty).
- */
- (void)signal(SIGTTOU, SIG_IGN);
-#ifdef AFS_OSF_ENV
- /* delay TIOCPKT_WINDOW oobdata, for backward compatibility */
- sleep(1);
-#endif
- send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */
- if (f > p)
- nfd = f + 1;
- else
- nfd = p + 1;
- fmask = 1 << f;
- pmask = 1 << p;
- for (;;) {
- int ibits, obits, ebits;
-
- ibits = 0;
- obits = 0;
- if (fcc)
- obits |= pmask;
- else
- ibits |= fmask;
- if (pcc >= 0)
- if (pcc)
- obits |= fmask;
- else
- ibits |= pmask;
- ebits = pmask;
-
- if (select(nfd, &ibits, obits ? &obits : (int *)NULL, &ebits, 0) < 0) {
- if (errno == EINTR)
- continue;
-#ifdef AFS_AIX32_ENV
- cleanup(pid);
-#endif
- fatalperror(f, "select");
- }
- if (ibits == 0 && obits == 0 && ebits == 0) {
- /* shouldn't happen... */
- sleep(5);
- continue;
- }
-#if !defined(AFS_SUN5_ENV)
-#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
- if (ebits & pmask) {
- cc = read(p, &cntl, 1);
- if (cc == 1 && pkcontrol(cntl)) {
- cntl |= oobdata[0];
- send(f, &cntl, 1, MSG_OOB);
- if (cntl & TIOCPKT_FLUSHWRITE) {
- pcc = 0;
- ibits &= ~pmask;
- }
- }
- }
-#endif /* !defined(AFS_SUN5_ENV) */
-
- if (ibits & fmask) {
- fcc = read(f, fibuf, sizeof(fibuf));
- if (fcc < 0 && errno == EWOULDBLOCK)
- fcc = 0;
- else {
- register char *cp;
- int left, n;
-
- if (fcc <= 0)
- break;
- fbp = fibuf;
-
- top:
- for (cp = fibuf; cp < fibuf + fcc - 1; cp++)
- if (cp[0] == magic[0] && cp[1] == magic[1]) {
- left = fcc - (cp - fibuf);
- n = control(p, cp, left);
- if (n) {
- left -= n;
- if (left > 0)
- memcpy(cp, cp + n, left);
- fcc -= n;
- goto top; /* n^2 */
- }
- }
- obits |= pmask; /* try write */
- }
- }
-
- if ((obits & pmask) && fcc > 0) {
- cc = write(p, fbp, fcc);
- if (cc > 0) {
- fcc -= cc;
- fbp += cc;
- }
- }
-
- if (ibits & pmask) {
- pcc = read(p, pibuf, sizeof(pibuf));
- pbp = pibuf;
- if (pcc < 0 && errno == EWOULDBLOCK)
- pcc = 0;
- else if (pcc <= 0)
- break;
- else if (pibuf[0] == 0) {
- pbp++, pcc--;
- obits |= fmask; /* try a write */
- } else {
-#if !defined(AFS_SUN5_ENV)
- if (pkcontrol(pibuf[0])) {
- pibuf[0] |= oobdata[0];
- send(f, &pibuf[0], 1, MSG_OOB);
- }
-#endif /* !defined(AFS_SUN5_ENV) */
- pcc = 0;
- }
- }
-
- if ((obits & fmask) && pcc > 0) {
- cc = write(f, pbp, pcc);
- if (cc < 0 && errno == EWOULDBLOCK) {
- /* also shouldn't happen */
- sleep(5);
- continue;
- }
- if (cc > 0) {
- pcc -= cc;
- pbp += cc;
- }
- }
- }
-}
-
-#ifdef AFS_AIX32_ENV
-void
-cleanup(pid_t pid)
-#else
-void
-cleanup()
-#endif
-{
- char *p;
-#ifdef AFS_HPUX_ENV
- char buf[BUFSIZ];
- int cc;
-
- fcntl(netp, F_SETFL, O_NDELAY);
- if ((cc = read(netp, buf, sizeof buf)) > 0) {
- write(netf, buf, cc);
- }
- {
- chmod(master, 0666);
- chown(master, 0, 0);
- chmod(slave, 0666);
- chown(slave, 0, 0);
- }
-#else
-#ifdef AFS_AIX32_ENV
- struct utmp cutmp;
- int found = 0, f, t;
- int rcode;
- off_t offset;
-
- p = line + sizeof("/dev/") - 1;
- if (logout(p))
- logwtmp(p, "", "");
-#ifdef _AIX
- (void)acl_set(line, R_ACC | W_ACC | X_ACC, R_ACC | W_ACC | X_ACC,
- R_ACC | W_ACC | X_ACC);
-#else
- (void)chmod(line, 0666);
-#endif /* _AIX */
- (void)chown(line, 0, 0);
- *p = 'p';
-#ifdef _AIX
- (void)acl_set(line, R_ACC | W_ACC | X_ACC, R_ACC | W_ACC | X_ACC,
- R_ACC | W_ACC | X_ACC);
-#else
- (void)chmod(line, 0666);
-#endif /* _AIX */
-#else
- p = line + sizeof("/dev/") - 1;
- if (logout(p))
- logwtmp(p, "", "");
- (void)chmod(line, 0666);
- (void)chown(line, 0, 0);
- *p = 'p';
- (void)chmod(line, 0666);
-#endif
- (void)chown(line, 0, 0);
-#endif
- shutdown(netf, 2);
- exit(1);
-}
-
-fatal(f, msg)
- int f;
- char *msg;
-{
- char buf[BUFSIZ];
-
- buf[0] = '\01'; /* error indicator */
- (void)sprintf(buf + 1, "rlogind: %s.\r\n", msg);
- (void)write(f, buf, strlen(buf));
-
- exit(1);
-}
-
-fatalperror(f, msg)
- int f;
- char *msg;
-{
- char buf[BUFSIZ];
- extern int sys_nerr;
- extern char *sys_errlist[];
-
- if ((unsigned)errno < sys_nerr)
- (void)sprintf(buf, "%s: %s", msg, sys_errlist[errno]);
- else
- (void)sprintf(buf, "%s: Error %d", msg, errno);
-
- fatal(f, buf);
-}
-
-#ifndef OLD_LOGIN
-do_rlogin(host)
- char *host;
-{
-
- int ru;
- getstr(rusername, sizeof(rusername), "remuser too long");
- getstr(lusername, sizeof(lusername), "locuser too long");
- getstr(term + ENVSIZE, sizeof(term) - ENVSIZE, "Terminal type too long");
-
- if (getuid())
- return (-1);
- pwd = getpwnam(lusername);
- if (pwd == NULL)
- return (-1);
-#ifdef AFS_HPUX_ENV
-#define SUPERUSER(pwd) ((pwd)->pw_uid == 0)
-#define SECUREPASS "/.secure/etc/passwd"
- /* If /.secure/etc/passwd file exists then make sure that user has
- * a valid entry in both password files.
- * Initialize s_pwd to point to pwd so check won't fail if the
- * secure password file doesn't exists.
- */
- s_pwd = (struct s_passwd *)pwd;
- if (stat(SECUREPASS, &s_pfile) == 0)
- s_pwd = getspwnam(lusername);
- if (s_pwd == NULL) {
- return (-1);
- }
-#endif
-
-#ifdef _AIX
- if (*pwd->pw_shell == '\0')
- pwd->pw_shell = BSHELL;
- /* check for disabled logins before */
- /* authenticating based on .rhosts */
- if (pwd->pw_uid)
- if (checknologin() == 0)
- return (-1);
-#endif /* _AIX */
- ru = ruserok(host, SUPERUSER(pwd), rusername, lusername);
- return (ru);
-}
-
-
-getstr(buf, cnt, errmsg)
- char *buf;
- int cnt;
- char *errmsg;
-{
- char c;
-
- do {
- if (read(0, &c, 1) != 1)
- exit(1);
- if (--cnt < 0)
- fatal(1, errmsg);
- *buf++ = c;
- } while (c != 0);
-}
-
-extern char **environ;
-
-#ifdef _AIX
-/* POSIX TERMIOS */
-speed_t
-speeds(speed)
- char *speed;
-{
- if (strcmp(speed, "38400") == 0)
- return (B38400);
- if (strcmp(speed, "19200") == 0)
- return (B19200);
- if (strcmp(speed, "9600") == 0)
- return (B9600);
- if (strcmp(speed, "4800") == 0)
- return (B4800);
- if (strcmp(speed, "2400") == 0)
- return (B2400);
- if (strcmp(speed, "1800") == 0)
- return (B1800);
- if (strcmp(speed, "1200") == 0)
- return (B1200);
- if (strcmp(speed, "600") == 0)
- return (B600);
- if (strcmp(speed, "300") == 0)
- return (B300);
- if (strcmp(speed, "200") == 0)
- return (B200);
- if (strcmp(speed, "150") == 0)
- return (B150);
- if (strcmp(speed, "134") == 0)
- return (B134);
- if (strcmp(speed, "110") == 0)
- return (B110);
- if (strcmp(speed, "75") == 0)
- return (B75);
- if (strcmp(speed, "50") == 0)
- return (B50);
- if (strcmp(speed, "0") == 0)
- return (B0);
- return (B0);
-}
-#else
-char *speeds[] = {
- "0", "50", "75", "110", "134", "150", "200", "300", "600",
- "1200", "1800", "2400", "4800", "9600", "19200", "38400",
-#ifdef AFS_HPUX_ENV
- "EXTA", "EXTB"
-#endif
-};
-
-#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
-#endif
-
-setup_term(fd)
- int fd;
-{
-#ifndef AFS_OSF_ENV
- register char *cp = strchr(term, '/'), **cpp;
-#endif
-#ifdef AFS_AIX32_ENV
-#ifdef _AIX
- /* POSIX TERMIOS */
- struct termios termios;
-#else /* _AIX */
- struct sgttyb sgttyb;
-#endif /* _AIX */
- char *speed;
-#ifdef AFS_HPUX_ENV
- struct termio tp;
-#endif
-
-#ifdef _AIX
- /* POSIX TERMIOS */
- tcgetattr(fd, &termios);
-#else /* _AIX */
-#ifdef AFS_HPUX_ENV
- ioctl(fd, TCGETA, &tp);
-#else
- (void)ioctl(fd, TIOCGETP, &sgttyb);
-#endif
-#endif /* _AIX */
- if (cp) {
- *cp++ = '\0';
- speed = cp;
- cp = strchr(speed, '/');
- if (cp)
- *cp++ = '\0';
-#ifdef _AIX
- /* POSIX TERMIOS */
- /* Setup PTY with some reasonable defaults */
- termios.c_cc[VINTR] = CINTR;
- termios.c_cc[VQUIT] = CQUIT;
- termios.c_cc[VERASE] = CERASE;
- termios.c_cc[VKILL] = CKILL;
- termios.c_cc[VEOF] = CEOF;
-#if defined (NLS) || defined (KJI)
- /* For NLS environments, we need 8 bit data stream. */
- termios.c_iflag = IXON | BRKINT | IGNPAR | ICRNL;
- termios.c_cflag = PARENB | CS8 | HUPCL | CREAD;
-#else
- termios.c_iflag = IXON | BRKINT | IGNPAR | ISTRIP | ICRNL;
- termios.c_cflag = PARENB | CS7 | HUPCL | CREAD;
-#endif /* NLS */
- termios.c_oflag = OPOST | ONLCR | TAB3;
- termios.c_lflag =
- ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOKE | ECHOCTL | IEXTEN;
- cfsetispeed(&termios, speeds(speed));
- cfsetospeed(&termios, speeds(speed));
-#else /* _AIX */
- for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
- if (strcmp(*cpp, speed) == 0) {
-#ifdef AFS_HPUX_ENV
- tp.c_cflag &= ~CBAUD;
- tp.c_cflag |= cpp - speeds;
-#else
- sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds;
-#endif
- break;
- }
-#endif /* _AIX */
- }
-#ifdef _AIX
- /* POSIX TERMIOS */
- tcsetattr(fd, TCSANOW, &termios);
-#else /* _AIX */
-#ifdef AFS_HPUX_ENV
- tp.c_iflag &= ~INPCK;
- tp.c_iflag |= ICRNL | IXON;
- tp.c_oflag |= OPOST | ONLCR | TAB3;
- tp.c_oflag &= ~ONLRET;
- tp.c_lflag |= (ECHO | ECHOE | ECHOK | ISIG | ICANON);
- tp.c_cflag &= ~PARENB;
- tp.c_cflag |= CS8;
- tp.c_cc[VMIN] = 1;
- tp.c_cc[VTIME] = 0;
- tp.c_cc[VEOF] = CEOF;
- ioctl(fd, TCSETAF, &tp);
-#else
- sgttyb.sg_flags = ECHO | CRMOD | ANYP | XTABS;
- (void)ioctl(fd, TIOCSETP, &sgttyb);
-#endif
-#endif /* _AIX */
-
-#else /* AFS_AIX32_ENV */
-
-#ifdef AFS_OSF_ENV
- register char *cp = strchr(term + ENVSIZE, '/');
- char *speed;
- struct termios tt;
-
- tcgetattr(fd, &tt);
- if (cp) {
- *cp++ = '\0';
- speed = cp;
- cp = strchr(speed, '/');
- if (cp)
- *cp++ = '\0';
- cfsetspeed(&tt, atoi(speed));
- }
-
- tt.c_iflag = TTYDEF_IFLAG;
- tt.c_oflag = TTYDEF_OFLAG;
- tt.c_lflag = TTYDEF_LFLAG;
- memcpy(tt.c_cc, ttydefchars, sizeof(tt.c_cc));
- tcsetattr(fd, TCSAFLUSH, &tt);
-#else
- struct sgttyb sgttyb;
- char *speed;
-
- (void)ioctl(fd, TIOCGETP, &sgttyb);
- if (cp) {
- *cp++ = '\0';
- speed = cp;
- cp = strchr(speed, '/');
- if (cp)
- *cp++ = '\0';
- for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
- if (strcmp(*cpp, speed) == 0) {
- sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds;
- break;
- }
- }
- sgttyb.sg_flags = ECHO | CRMOD | ANYP | XTABS;
- (void)ioctl(fd, TIOCSETP, &sgttyb);
-#endif
-#endif /* AFS_AIX32_ENV */
- env[0] = term;
- env[1] = 0;
- environ = env;
-}
-
-/*
- * Check whether host h is in our local domain,
- * as determined by the part of the name following
- * the first '.' in its name and in ours.
- * If either name is unqualified (contains no '.'),
- * assume that the host is local, as it will be
- * interpreted as such.
- */
-local_domain(h)
- char *h;
-{
- char localhost[MAXHOSTNAMELEN];
- char *p1, *p2 = strchr(h, '.');
-#ifdef AFS_OSF_ENV
- char *topdomain();
-
- localhost[0] = 0;
-#endif
-
- (void)gethostname(localhost, sizeof(localhost));
-#ifdef AFS_OSF_ENV
- p1 = topdomain(localhost);
- p2 = topdomain(h);
-#else
- p1 = strchr(localhost, '.');
-#endif
- if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))
- return (1);
- return (0);
-}
-#endif /* OLD_LOGIN */
-
-
-#ifdef AFS_OSF_ENV
-char *
-topdomain(h)
- char *h;
-{
- register char *p;
- char *maybe = NULL;
- int dots = 0;
-
- for (p = h + strlen(h); p >= h; p--) {
- if (*p == '.') {
- if (++dots == 2)
- return (p);
- maybe = p;
- }
- }
- return (maybe);
-}
-#endif
-
-
-#ifdef _AIX
-/*
- * NAME: getnonflatname()
- *
- * FUNCTION: gets the name in /etc/passwd and replaces the
- * flattened name that might have been passed in.
- *
- * EXECUTION ENVIRONMENT: static
- *
- * RETURNS: none.
- *
- */
-
-void
-getnonflatname(char *user)
-{
- struct passwd *pw; /* return from getpwent() */
- char currflat[UT_NAMESIZE + 1]; /* name we are looking for */
- char dataflat[UT_NAMESIZE + 1]; /* name from data base */
- register int siz;
- register int members = 0;
-
-#ifndef _KJI
- setpwent();
-
- while ((pw = getpwent()) != NULL) {
- /* Map NLS characters in name to ascii */
- NLflatstr(user, currflat, UT_NAMESIZE + 1);
- NLflatstr(pw->pw_name, dataflat, UT_NAMESIZE + 1);
- if (strcmp(currflat, dataflat) == 0) {
- strcpy(user, pw->pw_name);
- break;
- }
- }
- endpwent();
-#endif
-}
-
-
-checknologin()
-{
- register int fd;
-
- if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
- return (0);
- close(fd);
- } else
- return (-1);
-}
-
-
-/*
- * NAME: loginlog
- *
- * FUNCTION: log the login
- *
- * EXECUTION ENVIRONMENT: static
- *
- * record login in utmp and wtmp files
- *
- * RETURNS: void
- */
-
-static void
-loginlog(user, tty, hostname)
- char *user;
- char *tty;
- char *hostname;
-{
- char *home; /* user's home directory */
- char *dev; /* final portion of tty name [ with hft# ] */
- char hush[PATH_MAX]; /* .hushlogin file */
- int t; /* index into the utmp file */
- int found = 0; /* utmp entry was found */
- int f; /* file descriptor */
- uid_t uid; /* the user ID */
- off_t offset; /* for keeping wtmp file un-corrupted */
- struct utmp utmp; /* utmp structure being created */
- struct utmp outmp; /* utmp entry from /etc/utmp file */
- struct utmp *up; /* pointer to entry in utmp file */
-
- int rcode;
-
- /*
- * Initialize a utmp file entry to be filled in and written
- * to UTMP_FILE and WTMP_FILE.
- */
-
- memset(&utmp, 0, UTSIZ);
- up = &utmp;
-
- /*
- * The last portion of the device name is placed in the utmp
- * entry. If the last portion is all digits it is assumed to
- * be a multiplexed device, such as an hft, and the pointer
- * is backed up to find the previous portion.
- */
-
- if (dev = strrchr(tty, '/')) {
- if (!*(dev + strspn(dev, "/0123456789")))
- while (dev != tty && *--dev != '/');
-
- if (*dev == '/')
- dev++;
-
- tty = dev;
- }
-
- if (tty)
- strncpy(up->ut_line, tty, sizeof up->ut_line);
-
- /*
- * The remainder of the utmp entry is filled in. The process
- * id and tty line should already have been present, however,
- * these are set here for completeness.
- */
-
- strncpy(up->ut_user, user, sizeof up->ut_user);
- up->ut_pid = getpid();
- up->ut_type = LOGIN_PROCESS;
- up->ut_time = time((time_t *) 0);
-
- if (hostname)
- strncpy(up->ut_host, hostname, sizeof up->ut_host);
-
- /* Scan the utmp file. If an entry is found that */
- /* is the same as this tty, use this slot to create the */
- /* new entry. This slot has to be an empty slot. */
- /* Re-using the same slot used by the tty (with an */
- /* empty type) will avoid printing of empty slots on */
- /* "who -a" output. */
-
- if ((f = open(UTMP_FILE, O_RDWR)) >= 0) {
- lseek(f, (off_t) 0, SEEK_SET);
- rcode = lockf(f, F_LOCK, 0);
- t = 0;
- while (read(f, (char *)&outmp, UTSIZ) == UTSIZ) {
- if ((!strcmp(outmp.ut_line, tty)) && outmp.ut_type == EMPTY) {
- break;
- } else
- t++;
- }
- lseek(f, (off_t) (t * UTSIZ), 0);
- write(f, (char *)up, UTSIZ);
- lseek(f, (off_t) 0, SEEK_SET);
- rcode = lockf(f, F_ULOCK, 0);
- close(f);
- }
-
- /*
- * The utmp entry is appended to the wtmp file to maintain a
- * log of all login activity.
- */
- if ((f = open(WTMP_FILE, O_WRONLY | O_APPEND)) >= 0) {
- offset = lseek(f, 0L, 2);
- if (offset % UTSIZ)
- write(f, (char *)up, UTSIZ - (offset % UTSIZ));
-
- write(f, (char *)up, UTSIZ);
- close(f);
- }
-
-}
-
-#ifdef KAUTH
-#define MAXLOCALTOKENS 4
-#define HEADER_SIZE 18
-
-/*
- * intkens:
- *
- * This routine accepts a token on the specified file handle;
- * The input format for a token is:
- *
- * Field # Contents description
- * (1) Version # unsigned integer (< 2^32)
- * (2) Length unsigned integer (< 2^32)
- * (3) startTime unsigned afs_int32 (< 2^32)
- * (4) endTime unsigned afs_int32 (< 2^32)
- * (5) sessionKey char[8]
- * (6) kvno short (< 2^16)
- * (7) ticketLen unsigned integer (< 2^32)
- * (8) ticket char[MAXKTCTICKETLEN]
- * (9) AFS name char[MAXKTCNAMELEN]
- * (10) Cell Name char[MAXKTCREALMLEN]
- *
- * Each field is comma separated except (5) and (6), and (8) and (9); the
- * ticket is variable length. The * converted token is placed into the
- * token structure pointed to by the variable "token". The first and second
- * fields are padded with spaces on the right so that they can be fixed length.
- * This is required so that the length can be read in before reading in the
- * whole packet.
- */
-
-extern int errno;
-
-intokens(s)
- int s;
-{
- char buf[512 * MAXLOCALTOKENS], *bp;
- int length, readed, count;
- unsigned index, version;
- struct ktc_token token;
- struct ktc_principal tclient, tserver;
-
- if (setpag()) {
- perror("setpag");
- exit(1);
- }
-
-/*
-** Read in the first two fields.
-*/
-
- readed = 0;
- errno = 0;
- while (readed < HEADER_SIZE) {
- count = read(s, (char *)((int)buf + readed), HEADER_SIZE - readed);
- if (count <= 0) {
- perror("intokens read");
- exit(1);
- }
- readed = readed + count;
- }
-
- count = readed;
- bp = buf;
-
- /* (1) Version # */
- for (index = 0; (index + bp - buf) < count && bp[index] != ','; index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for version #\n");
- exit(1);
- }
-
- if (bp[index] != ',') {
- fprintf(stderr, "Didn't stop on a comma, searching for version #\n");
- exit(1);
- }
-
- bp[index] = '\0';
-
- sscanf(bp, "%u", &version);
-
- if (version != 2) {
- fprintf(stderr, "intokens: incompatible version encountered: %d\n",
- version);
- exit(1);
- }
-
- bp = bp + index + 1;
-
- /* (2) Length # */
- for (index = 0; (index + bp - buf) < count && bp[index] != ','; index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for length #\n");
- exit(1);
- }
-
- if (bp[index] != ',') {
- fprintf(stderr, "Didn't stop on a comma, searching for length\n");
- exit(1);
- }
-
- bp[index] = '\0';
-
- sscanf(bp, "%u", &length);
-
- bp = bp + index + 1;
-
- errno = 0;
- while (readed < length) {
- count = read(s, (char *)((int)buf + readed), length - readed);
- if (count <= 0) {
- perror("intokens read");
- exit(1);
- }
- readed = readed + count;
- }
-
- count = readed;
-
-/*
-** Terminate looping through the list of tokens when we hit a null byte.
-*/
- while (*bp) {
- /* (3) startTime */
-
- for (index = 0; (index + bp - buf) < count && bp[index] != ',';
- index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr,
- "overran buffer while searching for startTime #\n");
- exit(1);
- }
-
- if (bp[index] != ',') {
- fprintf(stderr,
- "Didn't stop on a comma, searching for startTime #\n");
- exit(1);
- }
-
- bp[index] = '\0';
-
- sscanf(bp, "%u", &token.startTime);
-
- /* (4) endTime */
-
- bp = bp + index + 1;
-
- for (index = 0; (index + bp - buf) < count && bp[index] != ',';
- index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for endTime #\n");
- exit(1);
- }
-
- if (bp[index] != ',') {
- fprintf(stderr,
- "Didn't stop on a comma, searching for endTime #\n");
- exit(1);
- }
-
- bp[index] = '\0';
-
- sscanf(bp, "%u", &token.endTime);
-
- /* (5) sessionKey */
-
- bp = bp + index + 1;
- memcpy(token.sessionKey.data, bp, 8);
-
- /* (6) kvno */
-
- bp = bp + 8;
- for (index = 0; (index + bp - buf) < count && bp[index] != ',';
- index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for kvno\n");
- exit(1);
- }
-
- if (bp[index] != ',') {
- fprintf(stderr, "Didn't stop on a comma, searching for kvno\n");
- exit(1);
- }
-
- bp[index] = '\0';
-
- token.kvno = atoi(bp);
-
- /* (7) ticketLen */
-
- bp = bp + index + 1;
-
- for (index = 0; (index + bp - buf) < count && bp[index] != ',';
- index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for ticketLen\n");
- exit(1);
- }
-
- if (bp[index] != ',') {
- fprintf(stderr,
- "Didn't stop on a comma, searching for ticketLen\n");
- exit(1);
- }
-
- bp[index] = '\0';
-
- sscanf(bp, "%u", &token.ticketLen);
-
- /* (8) ticketLen */
-
- bp = bp + index + 1;
-
- if ((index + bp - buf) + token.ticketLen > count) {
- fprintf(stderr, "overran buffer while copying ticket\n");
- exit(1);
- }
-
- memcpy(token.ticket, bp, token.ticketLen);
-
- bp = bp + token.ticketLen;
-
- /* (9) User name */
-
- for (index = 0; (index + bp - buf) < count && bp[index] != ',';
- index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for Cell Name\n");
- exit(1);
- }
-
- bp[index] = '\0';
- tclient.instance[0] = '\0';
- strncpy(tclient.name, bp, MAXKTCNAMELEN);
-
- /* (10) Cell name */
-
- bp = bp + index + 1;
-
- for (index = 0; (index + bp - buf) < count && bp[index] != ',';
- index++);
-
- if ((index + bp - buf) == count) {
- fprintf(stderr, "overran buffer while searching for end\n");
- exit(1);
- }
-
- bp[index] = '\0';
- strncpy(tclient.cell, bp, MAXKTCREALMLEN);
- bp = bp + index + 1;
-
- strcpy(tserver.name, "afs");
- tserver.instance[0] = '\0';
- strncpy(tserver.cell, tclient.cell, MAXKTCREALMLEN);
-
- if (ktc_SetToken(&tserver, &token, &tclient, 0)) {
- fprintf(stderr, "intokens: ktc_SetToken failed for %s\n",
- tclient.cell);
- }
- }
- return (0);
-}
-#endif /* KAUTH */
-#endif /* _AIX */
-
-#ifdef AFS_HPUX_ENV
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <stdio.h>
-
-# define MAX_PTY_LEN MAXPATHLEN+1
-# define CLONE_DRV "/dev/ptym/clone"
-
-/*
-** Ugh! The following is gross, but there is no other simple way
-** to tell if a file is a master pty without looking at its major
-** device number. Lets put it in ifdefs so it will fail to compile
-** on other architectures without modification.
-*/
-#ifdef __hp9000s300
-#define PTY_MASTER_MAJOR_NUMBER 16
-#endif
-#ifdef __hp9000s800
-#define PTY_MASTER_MAJOR_NUMBER 16
-#endif
-
-struct stat stb;
-struct stat m_stbuf; /* stat buffer for master pty */
-struct stat s_stbuf; /* stat buffer for slave pty */
-
-/*
-** ptymdirs -- directories to search for master ptys
-** ptysdirs -- directories to search for slave ptys
-** ptymloc -- full path to pty master
-** ptysloc -- full path to pty slave
-*/
-char *ptymdirs[] = { "/dev/ptym/", "/dev/", (char *)0 };
-char *ptysdirs[] = { "/dev/pty/", "/dev/", (char *)0 };
-char ptymloc[MAX_PTY_LEN];
-char ptysloc[MAX_PTY_LEN];
-
-/*
-** oltrs -- legal first char of pty name (letter) (old style)
-** onums -- legal second char of pty name (number) for namespace 1
-** (old style)
-** ltrs -- legal first char of pty name (letter) (new style)
-** nums -- legal second and third char of pty name (number) (new style)
-** nums -- legal second, third and fourth char of pty name for names
-** space 3.
-*/
-char oltrs[] = "onmlkjihgfecbazyxwvutsrqp";
-char onums[] = "0123456789abcdef";
-char ltrs[] = "pqrstuvwxyzabcefghijklmno";
-char nums[] = "0123456789";
-
-/*
-** getpty() -- get a pty pair
-**
-** Input -- none
-** Output -- zero if pty pair gotten; non-zero if not
-** [value parameter mfd]
-** mfd Master FD for the pty pair
-** [optional value parameters -- only set if != NULL]
-** mname Master pty file name
-** sname Slave pty file name
-**
-** NOTE: This routine does not open the slave pty. Therefore, if you
-** want to quickly find the slave pty to open, it is recommended that
-** you *not* pass sname as NULL.
-*/
-
-/*
-** Modified 3/28/89 by Peter Notess to search the new, expanded naming
-** convention. The search is intended to proceed efficiently for both
-** large and small configurations, assuming that the ptys are created
-** in a pre-specified order. This routine will do a last-ditch,
-** brute-force search of all files in the pty directories if the more
-** efficient search fails. This is intended to make the search robust
-** in the case where the pty configuration is a non-standard one,
-** although it might take longer to find a pty in this case. The
-** assumed order of creation is:
-** /dev/ptym/pty[p-z][0-f]
-** /dev/ptym/pty[a-ce-o][0-f]
-** /dev/ptym/pty[p-z][0-9][0-9]
-** /dev/ptym/pty[a-ce-o][0-9][0-9]
-** with /dev/ptym/pty[p-r][0-f] linked into /dev. The search will
-** proceed in an order that leaves the ptys which also appear in /dev
-** searched last so that they remain available for other applications
-** as long as possible.
-*/
-
-/*
- * Modified by Glen A. Foster, September 23, 1986 to get around a problem
- * with 4.2BSD job control in the HP-UX (a.k.a. system V) kernel. Before
- * this fix, getpty() used to find a master pty to use, then open the cor-
- * responding slave side, just to see if it was there (kind of a sanity
- * check), then close the slave side, fork(), and let the child re-open
- * the slave side in order to get the proper controlling terminal. This
- * was an excellent solution EXCEPT for the case when another process was
- * already associated with the same slave side before we (telnetd) were
- * exec()ed. In that case, the controlling tty stuff gets all messed up,
- * and the solution is to NOT open the slave side in the parent (before the
- * fork()), but to let the child be the first to open it after its setpgrp()
- * call. This works in all cases. This stuff is black magic, really!
- *
- * This is necessary due to HP's implementation of 4.2BSD job control.
- */
-
-/*
- * Modified by Byron Deadwiler, March 9, 1992 to add access to the clone
- * driver to get ptys faster. Also added code to access ptys using
- * a new namespace (naming convention) that increases the number of
- * pty's that can be configured on a system.
- *
- * Name-Space It is a union of three name-spaces, the earlier two
- * being supported for compatibility. The name comprises
- * a generic name (/dev/pty/tty) followed by an alphabet
- * followed by one to three numerals. The alphabet is one
- * of the 25 in alpha[], which has 'p' thro' 'o' excluding
- * 'd'. The numeral is either hex or decimal.
- * ------------------------------------
- * | minor | name | Remarks |
- * |----------------------------------|
- * | 0| ttyp0| Modulo 16 hex |
- * | :| :| representation. |
- * | 15| ttypf| |
- * | 16| ttyq0| |
- * | :| :| |
- * | 175| ttyzf| |
- * | 176| ttya0| |
- * | :| :| |
- * | 223| ttycf| |
- * | 224| ttye0| |
- * | :| :| |
- * | 399| ttyof| Total 400 |
- * |----------------------------------|
- * | 400| ttyp00| Modulo hundred |
- * | :| :| decimal repr. |
- * | 499| ttyp99| |
- * | 500| ttyq00| |
- * | :| :| |
- * | 1499| ttyz99| |
- * | 1500| ttya00| |
- * | :| :| |
- * | 1799| ttyc99| |
- * | 1800| ttye00| |
- * | :| :| |
- * | 2899| ttyo99| Total 2500 |
- * |----------------------------------|
- * | 2900|ttyp000| Modulo thousand |
- * | :| :| decimal repr. |
- * | 3899|ttyp999| |
- * | 4900|ttyq000| |
- * | :| :| |
- * | 12899|ttyz999| |
- * | 13900|ttya000| |
- * | :| :| |
- * | 16899|ttyc999| |
- * | 16900|ttye000| |
- * | :| :| |
- * | 27899|ttyo999| Total 25000 |
- * | 27900| | invalid |
- * ------------------------------------
- */
-
-/*
-** NOTE: this routine should be put into a library somewhere, since
-** both rlogin and telnet need it! also, other programs might want to
-** call it some day to get a pty pair ...
-*/
-getpty(mfd, mname, sname)
- int *mfd;
- char *mname, *sname;
-{
- int loc, ltr, num, num2;
- register int mlen, slen;
- char *s, *s_path;
-
- if ((*mfd = open(CLONE_DRV, O_RDWR)) != -1) {
- s_path = ptsname(*mfd);
- strcpy(sname, s_path);
- (void)chmod(sname, 0622);
- /* get master path name */
- s = strrchr(sname, '/') + 2; /* Must succeed since slave_pty */
- /* begins with /dev/ */
- sprintf(mname, "%s%s%s", ptymdirs[0], "p", s);
- return 0;
- }
-
-
- for (loc = 0; ptymdirs[loc] != NULL; loc++) {
- if (stat(ptymdirs[loc], &stb)) /* no directory ... */
- continue; /* so try next one */
-
- /* first, try the 3rd name space ptyp000-ptyo999 */
- /* generate the master pty path */
- if (namesp3(mfd, mname, sname, loc) == 0) {
- return 0;
- }
-
- /* second, try the 2nd name space ptyp00-ptyo99 */
- /* generate the master pty path */
- (void)strcpy(ptymloc, ptymdirs[loc]);
- (void)strcat(ptymloc, "ptyLNN");
- mlen = strlen(ptymloc);
-
- /* generate the slave pty path */
- (void)strcpy(ptysloc, ptysdirs[loc]);
- (void)strcat(ptysloc, "ttyLNN");
- slen = strlen(ptysloc);
-
- for (ltr = 0; ltrs[ltr] != '\0'; ltr++) {
- ptymloc[mlen - 3] = ltrs[ltr];
- ptymloc[mlen - 2] = '0';
- ptymloc[mlen - 1] = '0';
- if (stat(ptymloc, &stb)) /* no ptyL00 ... */
- break; /* go try old style names */
-
- for (num = 0; nums[num] != '\0'; num++)
- for (num2 = 0; nums[num2] != '\0'; num2++) {
- ptymloc[mlen - 2] = nums[num];
- ptymloc[mlen - 1] = nums[num2];
- if ((*mfd = open(ptymloc, O_RDWR)) < 0) /* no master */
- continue; /* try next num */
-
- ptysloc[slen - 3] = ltrs[ltr];
- ptysloc[slen - 2] = nums[num];
- ptysloc[slen - 1] = nums[num2];
-
- /*
- ** NOTE: changed to only stat the slave device; see
- ** comments all over the place about job control ...
- */
- if (fstat(*mfd, &m_stbuf) < 0
- || stat(ptysloc, &s_stbuf) < 0) {
- close(*mfd);
- continue;
- }
- /*
- ** sanity check: are the minor numbers the same??
- */
- if (minor(m_stbuf.st_rdev) != minor(s_stbuf.st_rdev)) {
- close(*mfd);
- continue; /* try next num */
- }
-
- /* else we got both a master and a slave pty */
- got_one:(void)chmod(ptysloc, 0622);
- /* not readable */
- if (mname != NULL)
- (void)strcpy(mname, ptymloc);
- if (sname != NULL)
- (void)strcpy(sname, ptysloc);
- return 0; /* return OK */
- }
- }
-
- /* now, check old-style names */
- /* the 1st name-space ptyp0-ptyof */
- /* generate the master pty path */
- (void)strcpy(ptymloc, ptymdirs[loc]);
- (void)strcat(ptymloc, "ptyLN");
- mlen = strlen(ptymloc);
-
- /* generate the slave pty path */
- (void)strcpy(ptysloc, ptysdirs[loc]);
- (void)strcat(ptysloc, "ttyLN");
- slen = strlen(ptysloc);
-
- for (ltr = 0; oltrs[ltr] != '\0'; ltr++) {
- ptymloc[mlen - 2] = oltrs[ltr];
- ptymloc[mlen - 1] = '0';
- if (stat(ptymloc, &stb)) /* no ptyL0 ... */
- continue; /* try next ltr */
-
- for (num = 0; onums[num] != '\0'; num++) {
- ptymloc[mlen - 1] = onums[num];
- if ((*mfd = open(ptymloc, O_RDWR)) < 0) /* no master */
- continue; /* try next num */
-
- ptysloc[slen - 2] = oltrs[ltr];
- ptysloc[slen - 1] = onums[num];
-
- /*
- ** NOTE: changed to only stat the slave device; see
- ** comments all over the place about job control ...
- */
- if (fstat(*mfd, &m_stbuf) < 0 || stat(ptysloc, &s_stbuf) < 0) {
- close(*mfd);
- continue;
- }
- /*
- ** sanity check: are the minor numbers the same??
- */
- if (minor(m_stbuf.st_rdev) != minor(s_stbuf.st_rdev)) {
- close(*mfd);
- continue; /* try next num */
- }
-
- /* else we got both a master and a slave pty */
- goto got_one;
- }
- }
- }
- /* we failed in our search--we now try the slow brute-force method */
- for (loc = 0; ptymdirs[loc] != NULL; loc++) {
- DIR *dirp;
- struct dirent *dp;
-
- if ((dirp = opendir(ptymdirs[loc])) == NULL) /* no directory ... */
- continue; /* so try next one */
-
- (void)strcpy(ptymloc, ptymdirs[loc]);
- mlen = strlen(ptymloc);
- (void)strcpy(ptysloc, ptysdirs[loc]);
- slen = strlen(ptysloc);
-
- while ((dp = readdir(dirp)) != NULL) {
- /* stat, open, go for it, else continue */
- ptymloc[mlen] = '\0';
- (void)strcat(ptymloc, dp->d_name);
-
- if (stat(ptymloc, &m_stbuf)
- || (m_stbuf.st_mode & S_IFMT) != S_IFCHR
- || major(m_stbuf.st_rdev) != PTY_MASTER_MAJOR_NUMBER)
- continue;
-
- if ((*mfd = open(ptymloc, O_RDWR)) < 0) /* busy master */
- continue; /* try next entry */
-
- ptysloc[slen] = '\0'; /* guess at corresponding slave name */
- (void)strcat(ptysloc, dp->d_name);
- if (ptysloc[slen] == 'p')
- ptysloc[slen] = 't';
-
- if (stat(ptysloc, &s_stbuf) < 0
- || minor(m_stbuf.st_rdev) != minor(s_stbuf.st_rdev)) {
- close(*mfd);
- continue;
- }
- goto got_one;
- }
-
- closedir(dirp);
- }
-
- /* we were not able to get the master/slave pty pair */
- return -1;
-}
-
-namesp3(mfd, mname, sname, loc)
- int *mfd, loc;
- char *mname, *sname;
-{
- int ltr, num, num2, num3;
- register int mlen, slen;
-
- /* first, try the new naming convention */
- /* generate the master pty path */
- (void)strcpy(ptymloc, ptymdirs[loc]);
- (void)strcat(ptymloc, "ptyLNNN");
- mlen = strlen(ptymloc);
-
- /* generate the slave pty path */
- (void)strcpy(ptysloc, ptysdirs[loc]);
- (void)strcat(ptysloc, "ttyLNNN");
- slen = strlen(ptysloc);
-
- for (ltr = 0; ltrs[ltr] != '\0'; ltr++) {
- ptymloc[mlen - 4] = ltrs[ltr];
- ptymloc[mlen - 3] = '0';
- ptymloc[mlen - 2] = '0';
- ptymloc[mlen - 1] = '0';
- if (stat(ptymloc, &stb)) /* no ptyL00 ... */
- break; /* go try old style names */
-
- for (num = 0; nums[num] != '\0'; num++)
- for (num2 = 0; nums[num2] != '\0'; num2++)
- for (num3 = 0; nums[num3] != '\0'; num3++) {
- ptymloc[mlen - 3] = nums[num];
- ptymloc[mlen - 2] = nums[num2];
- ptymloc[mlen - 1] = nums[num3];
- if ((*mfd = open(ptymloc, O_RDWR)) < 0) /* no master */
- continue; /* try next num */
-
- ptysloc[slen - 4] = ltrs[ltr];
- ptysloc[slen - 3] = nums[num];
- ptysloc[slen - 2] = nums[num2];
- ptysloc[slen - 1] = nums[num3];
-
- /*
- ** NOTE: changed to only stat the slave device; see
- ** comments all over the place about job control ...
- */
- if (fstat(*mfd, &m_stbuf) < 0
- || stat(ptysloc, &s_stbuf) < 0) {
- close(*mfd);
- continue;
- }
- /*
- ** sanity check: are the minor numbers the same??
- */
- if (minor(m_stbuf.st_rdev) != minor(s_stbuf.st_rdev)) {
- close(*mfd);
- continue; /* try next num */
- }
-
- /* else we got both a master and a slave pty */
- (void)chmod(ptysloc, 0622); /* not readable */
- if (mname != NULL)
- (void)strcpy(mname, ptymloc);
- if (sname != NULL)
- (void)strcpy(sname, ptysloc);
- return 0; /* return OK */
- }
- }
- return 1;
-}
-#endif
+++ /dev/null
-#
-# Copyright (c) 1988 Regents of the University of California.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms are permitted
-# provided that the above copyright notice and this paragraph are
-# duplicated in all such forms and that any documentation, advertising
-# materials, and other materials related to such redistribution and
-# use acknowledge that the software was developed by the University
-# of California, Berkeley. The name of the University may not be
-# used to endorse or promote products derived from this software
-# without specific prior written permission. THIS SOFTWARE IS PROVIDED
-# ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-# WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
-# FITNESS FOR A PARTICULAR PURPOSE.
-#
-# @(#)Makefile 5.1 (Berkeley) 9/20/88
-#
-srcdir=@srcdir@
-include @TOP_OBJDIR@/src/config/Makefile.config
-
-
-INCLUDES=-I${TOP_OBJDIR}/src/config -I${TOP_INCDIR}
-CFLAGS= ${DBUG} ${INCLUDES} ${XCFLAGS}
-LIBC= /lib/libc.a
-OBJS= rcmd.o ../inetd/ta-rauth.o herror.o
-MAN=
-SRCS= rsh.c rcmd.c ../inetd/ta-rauth.c herror.c AFS_component_version_number.c
-AFSLIBS = ${TOP_LIBDIR}/libkauth.a ${TOP_LIBDIR}/libubik.a \
- ${TOP_LIBDIR}/libauth.a ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a \
- ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
- ${TOP_LIBDIR}/libdes.a ${TOP_LIBDIR}/libcmd.a \
- ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a
-LIBS = ${AFSLIBS}
-
-include ../config/Makefile.version
-
-all: rsh
-
-rsh: rsh.o ${OBJS} ${LIBS}
- ${CC} -o $@ ${CFLAGS} rsh.o ${OBJS} ${LIBS} ${XLIBS}
-
-rlogin: rlogin.o ${OBJS} ${LIBS}
- ${CC} -o $@ ${CFLAGS} rlogin.o ${OBJS} ${LIBS} ${XLIBS}
-
-rlogin.o: rlogin.c AFS_component_version_number.c
-rsh.o: rsh.c AFS_component_version_number.c
-
-../rlogind/herror.o: ../rlogind/herror.c
- (cd ../rlogind ; $(MAKE) herror.o )
-../inetd/ta-rauth.o : ../inetd/ta-rauth.c
- (cd ../inetd ; $(MAKE) ta-rauth.o DESTDIR=${DESTDIR})
-
-clean:
- $(RM) -f ${OBJS} core rsh *.BAK AFS_component_version_number.c rlogin rlogin.o rsh.o
-
-cleandir: clean
- $(RM) -f ${MAN} tags .depend
-
-depend: ${SRCS}
- mkdep -p ${CFLAGS} ${SRCS}
-
-install: rsh
- set -x; \
- case "${SYS_NAME}" in \
- hp* ) \
- ${INSTALL} -m 4755 -f rsh ${DESTDIR}${bindir}/remsh ;; \
- * ) \
- ${INSTALL} -m 4755 rsh ${DESTDIR}${bindir}/rsh ;; \
- esac
-
-dest: rsh
- set -x; \
- case "${SYS_NAME}" in \
- hp* ) \
- ${INSTALL} -m 4755 -f rsh ${DEST}/bin/remsh ;; \
- * ) \
- ${INSTALL} -m 4755 rsh ${DEST}/bin/rsh ;; \
- esac
+++ /dev/null
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#ifndef AFS_DARWIN_ENV
-#include <sys/types.h>
-#include <sys/uio.h>
-
-char *h_errlist[] = {
- "Error 0",
- "Unknown host", /* 1 HOST_NOT_FOUND */
- "Host name lookup failure", /* 2 TRY_AGAIN */
- "Unknown server error", /* 3 NO_RECOVERY */
- "No address associated with name", /* 4 NO_ADDRESS */
-};
-int h_nerr = { sizeof(h_errlist) / sizeof(h_errlist[0]) };
-
-#if defined(AFS_SUN_ENV)
-int h_errno;
-#else
-extern int h_errno;
-#endif
-
-/*
- * herror --
- * print the error indicated by the h_errno value.
- */
-herror(s)
- char *s;
-{
- struct iovec iov[4];
- register struct iovec *v = iov;
-
- if (s && *s) {
- v->iov_base = s;
- v->iov_len = strlen(s);
- v++;
- v->iov_base = ": ";
- v->iov_len = 2;
- v++;
- }
- v->iov_base =
- (u_int) h_errno < h_nerr ? h_errlist[h_errno] : "Unknown error";
- v->iov_len = strlen(v->iov_base);
- v++;
- v->iov_base = "\n";
- v->iov_len = 1;
- writev(2, iov, (v - iov) + 1);
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#ifdef aiws /*AIX*/
-#include <sys/types.h>
-#define MAXHOSTNAMELEN 64 /* use BSD's, not sys/param's */
-#define MAXPATHLEN 1024 /* from BSD */
-#include <sys/ioctl.h> /* for SIOCSPGRP */
-#endif
-#include <stdio.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <sys/param.h>
-#include <limits.h>
-#include <sys/file.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <unistd.h> /* select() prototype */
-#include <sys/types.h> /* fd_set on older platforms */
-#include <sys/time.h> /* struct timeval, select() prototype */
-#ifndef FD_SET
-# include <sys/select.h> /* fd_set on newer platforms */
-#endif
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <errno.h>
-#if defined(AFS_HPUX_ENV)
-/* HPUX uses a different call to set[res][gu]ids: */
-#define seteuid(newEuid) setresuid(-1, (newEuid), -1)
-#define setegid(newEgid) setresgid(-1, (newEgid), -1)
-#endif /* defined(AFS_HPUX_ENV) */
-#ifdef TCP_DEBUG
-#include <sys/syslog.h>
-# define DPRINTF(args) dprintf args
-dprintf(args)
- char *args;
-{
- char **argv;
- char buf[BUFSIZ];
- static char prefix[] = "rcmd: ";
-
- argv = &args;
- vsprintf(buf, argv[0], &argv[1]);
- syslog(LOG_DEBUG, "%s %s\n", prefix, buf);
-}
-#else
-# define DPRINTF(args)
-#endif
-#include <syslog.h>
-static _checkhost();
-
-#ifdef AFS_HPUX102_ENV
-int
-rmcd(ahost, rport, locuser, remuser, cmd, fd2p)
- char **ahost;
- int rport;
- const char *locuser, *remuser, *cmd;
- int *fd2p;
-#else
-#ifdef AFS_AIX32_ENV
-rcmd(ahost, rport, locuser, remuser, cmd, fd2p, retry)
- int retry;
-#else
-rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
-#endif
- char **ahost;
- u_short rport;
-#if defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
- const char *locuser, *remuser, *cmd;
-#else
- char *locuser, *remuser, *cmd;
-#endif
- int *fd2p;
-#endif
-{
- int s, timo = 1, pid;
- sigset_t oldset;
- sigset_t sigBlock;
- int someSignals[100];
- struct servent *sp, *getservbyport();
- struct sockaddr_in sin, from;
- char c;
- int lport = IPPORT_RESERVED - 1;
- struct hostent *hp;
- fd_set reads;
-
- memset((char *)someSignals, 0, sizeof(someSignals));
- someSignals[0] = 1 << (SIGURG - 1);
- sigBlock = *((sigset_t *) someSignals);
-
- pid = getpid();
- hp = gethostbyname(*ahost); /* CAUTION: this uses global static */
- /* storage. ANY OTHER CALLS to gethostbyname (including from within
- * syslog, eg) will trash the contents of hp. BE CAREFUL! */
- if (hp == 0) {
- herror(*ahost);
- return (-1);
- }
- *ahost = hp->h_name;
- /* was: syslog(LOG_ERR, "rcmd: host=%s, rport=%d, luser=%s,ruser=%s,cmd=%s,fd2p=%s\n", *ahost,rport,locuser,remuser,cmd,fd2p)
- * but that trashes hp... */
- sigprocmask(SIG_BLOCK, &sigBlock, &oldset);
- for (;;) {
- s = rresvport(&lport);
- if (s < 0) {
- if (errno == EAGAIN)
- fprintf(stderr, "socket: All ports in use\n");
- else
- perror("rcmd: socket");
- sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
- return (-1);
- }
-#ifdef AFS_AIX32_ENV
-#ifndef aiws
- fcntl(s, F_SETOWN, pid);
-#else
- /* since AIX has no F_SETOWN, we just do the ioctl */
- (void)ioctl(s, SIOCSPGRP, &pid);
-#endif
-#else
-#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV)
- fcntl(s, F_SETOWN, pid);
-#endif /* !defined(AIX) */
-#endif
- sin.sin_family = hp->h_addrtype;
-#ifdef AFS_OSF_ENV
- memcpy((caddr_t) & sin.sin_addr, hp->h_addr_list[0], hp->h_length);
-#else
- memcpy((caddr_t) & sin.sin_addr, hp->h_addr, hp->h_length);
-#endif
- sin.sin_port = rport;
- /* attempt to remote authenticate first... */
- sp = getservbyport((int)rport, "tcp");
- if (sp) {
- int ok = 0;
-
- switch (ta_rauth(s, sp->s_name, sin.sin_addr)) {
- case 0:
-#ifndef AFS_SGI_ENV
- fprintf(stderr, "No remote authentication\n");
-#endif
- close(s);
- s = rresvport(&lport);
- if (s < 0) {
- if (errno == EAGAIN)
- fprintf(stderr, "socket: All ports in use\n");
- else
- perror("rcmd: socket");
- sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
- return (-1);
- }
-#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV)
- fcntl(s, F_SETOWN, pid);
-#endif /* !defined(AIX) */
- break;
- case 1:
- ok = 1;
- break;
- case -1:
- fprintf(stderr, "Login incorrect.");
- exit(1);
- break;
- case -2:
- fprintf(stderr, "internal failure, ta_rauth\n");
- exit(errno);
- break;
- case -3:
- fprintf(stderr, "Cannot connect to remote machine\n");
- exit(errno);
- break;
- }
-
- if (ok) {
- break; /* from for loop */
- }
- }
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
- break;
- (void)close(s);
- if (errno == EADDRINUSE) {
- lport--;
- continue;
- }
- if (errno == ECONNREFUSED && timo <= 16) {
-#ifdef AFS_AIX32_ENV
- if (!retry) {
- return (-2);
- }
-#endif
- sleep(timo);
- timo *= 2;
- continue;
- }
- if (hp->h_addr_list[1] != NULL) {
- int oerrno = errno;
-
- fprintf(stderr, "connect to address %s: ",
- inet_ntoa(sin.sin_addr));
- errno = oerrno;
- perror(0);
- hp->h_addr_list++;
- memcpy((caddr_t) & sin.sin_addr, hp->h_addr_list[0],
- hp->h_length);
- fprintf(stderr, "Trying %s...\n", inet_ntoa(sin.sin_addr));
- continue;
- }
- perror(hp->h_name);
- sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
- return (-1);
- }
- lport--;
- if (fd2p == 0) {
- write(s, "", 1);
- lport = 0;
- } else {
- char num[8];
- int s2 = rresvport(&lport), s3;
- int len = sizeof(from);
- int maxfd = -1;
-
- if (s2 < 0)
- goto bad;
- listen(s2, 1);
- (void)sprintf(num, "%d", lport);
- if (write(s, num, strlen(num) + 1) != strlen(num) + 1) {
- perror("write: setting up stderr");
- (void)close(s2);
- goto bad;
- }
- FD_ZERO(&reads);
- FD_SET(s, &reads);
- if (maxfd < s)
- maxfd = s;
- FD_SET(s2, &reads);
- if (maxfd < s2)
- maxfd = s2;
- errno = 0;
- if (select(maxfd + 1, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)) {
- if (errno != 0)
- perror("select: setting up stderr");
- else
- fprintf(stderr,
- "select: protocol failure in circuit setup.\n");
- (void)close(s2);
- goto bad;
- }
- s3 = accept(s2, (struct sockaddr *)&from, &len);
- (void)close(s2);
- if (s3 < 0) {
- perror("accept");
- lport = 0;
- goto bad;
- }
- *fd2p = s3;
- from.sin_port = ntohs((u_short) from.sin_port);
- if (from.sin_family != AF_INET || from.sin_port >= IPPORT_RESERVED
- || from.sin_port < IPPORT_RESERVED / 2) {
- fprintf(stderr, "socket: protocol failure in circuit setup.\n");
- goto bad2;
- }
- }
- (void)write(s, locuser, strlen(locuser) + 1);
- (void)write(s, remuser, strlen(remuser) + 1);
- (void)write(s, cmd, strlen(cmd) + 1);
- errno = 0;
- if (read(s, &c, 1) < 0) {
- perror(*ahost);
- goto bad2;
- }
- if (c != 0) {
-#ifdef AFS_OSF_ENV
- /*
- * Two different protocols seem to be used;
- * one prepends a "message" byte with a "small"
- * number; the other one just sends the message
- */
- if (isalnum(c))
- (void)write(2, &c, 1);
-
-#endif
- while (read(s, &c, 1) == 1) {
- (void)write(2, &c, 1);
- if (c == '\n')
- break;
- }
- goto bad2;
- }
- sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
- return (s);
- bad2:
- if (lport)
- (void)close(*fd2p);
- bad:
- (void)close(s);
- sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
- return (-1);
-}
-
-#ifndef AFS_AIX32_ENV
-rresvport(alport)
- int *alport;
-{
- struct sockaddr_in sin;
- int s;
-
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- return (-1);
- for (;;) {
- sin.sin_port = htons((u_short) * alport);
- if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
- return (s);
- if (errno != EADDRINUSE) {
- (void)close(s);
- return (-1);
- }
- (*alport)--;
- if (*alport == IPPORT_RESERVED / 2) {
- (void)close(s);
- errno = EAGAIN; /* close */
- return (-1);
- }
- }
-}
-#endif
-
-int _check_rhosts_file = 1;
-
-#if defined(AFS_HPUX102_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-ruserok(rhost, superuser, ruser, luser)
- const char *rhost;
- int superuser;
- const char *ruser, *luser;
-#else
-ruserok(rhost, superuser, ruser, luser)
- int superuser;
- char *rhost;
- char *ruser, *luser;
-#endif
-{
- FILE *hostf;
- char fhost[MAXHOSTNAMELEN];
- int first = 1;
- register char *sp, *p;
- int baselen = -1;
- int suid, sgid;
- int group_list_size = -1;
- gid_t groups[NGROUPS_MAX];
- sp = rhost;
- p = fhost;
- while (*sp) {
- if (*sp == '.') {
- if (baselen == -1)
- baselen = sp - rhost;
- *p++ = *sp++;
- } else {
- *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
- }
- }
- *p = '\0';
- hostf = superuser ? (FILE *) 0 : fopen("/etc/hosts.equiv", "r");
- again:
- if (hostf) {
- if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
- (void)fclose(hostf);
-#ifdef AFS_OSF_ENV
- if (first == 0) {
- (void)seteuid(suid);
- (void)setegid(sgid);
- if (group_list_size >= 0)
- (void)setgroups(group_list_size, groups);
- }
-#endif
- return (0);
- }
- (void)fclose(hostf);
- }
- if (first == 1 && (_check_rhosts_file || superuser)) {
- struct stat sbuf;
- struct passwd *pwd, *getpwnam();
- char pbuf[MAXPATHLEN];
-
- first = 0;
- suid = geteuid();
- sgid = getegid();
- group_list_size = getgroups(NGROUPS_MAX, groups);
- if ((pwd = getpwnam(luser)) == NULL)
- return (-1);
- if (setegid(pwd->pw_gid) >= 0)
- (void)initgroups(luser, pwd->pw_gid);
- (void)seteuid(pwd->pw_uid);
- (void)strcpy(pbuf, pwd->pw_dir);
- (void)strcat(pbuf, "/.rhosts");
- if ((hostf = fopen(pbuf, "r")) == NULL)
- goto bad;
- /*
- * if owned by someone other than user or root or if
- * writeable by anyone but the owner, quit
- */
- if (fstat(fileno(hostf), &sbuf) || sbuf.st_uid
- && sbuf.st_uid != pwd->pw_uid || sbuf.st_mode & 022) {
- fclose(hostf);
- goto bad;
- }
- goto again;
- }
- bad:
- if (first == 0) {
- (void)seteuid(suid);
- (void)setegid(sgid);
- if (group_list_size >= 0)
- (void)setgroups(group_list_size, groups);
- }
- return (-1);
-}
-
-/* don't make static, used by lpd(8) */
-_validuser(hostf, rhost, luser, ruser, baselen)
- char *rhost, *luser, *ruser;
- FILE *hostf;
- int baselen;
-{
- char *user;
- char ahost[MAXHOSTNAMELEN * 4];
- register char *p;
-#ifdef AFS_AIX32_ENV
-#include <arpa/nameser.h>
- int hostmatch, usermatch;
- char domain[MAXDNAME], *dp;
-
- dp = NULL;
- if (getdomainname(domain, sizeof(domain)) == 0)
- dp = domain;
-#endif
- while (fgets(ahost, sizeof(ahost), hostf)) {
-#ifdef AFS_AIX32_ENV
- hostmatch = usermatch = 0;
- p = ahost;
- if (*p == '#' || *p == '\n') /* ignore comments and blanks */
- continue;
- while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
- p++;
- if (*p == ' ' || *p == '\t') {
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- user = p;
- while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
- p++;
- } else
- user = p;
- *p = '\0';
- /*
- * + - anything goes
- * +@<name> - group <name> allowed
- * -@<name> - group <name> disallowed
- * -<name> - host <name> disallowed
- */
- if (ahost[0] == '+' && ahost[1] == 0)
- hostmatch = 1;
- else if (ahost[0] == '+' && ahost[1] == '@')
- hostmatch = innetgr(ahost + 2, rhost, NULL, dp);
- else if (ahost[0] == '-' && ahost[1] == '@') {
- if (innetgr(ahost + 2, rhost, NULL, dp))
- return (-1);
- } else if (ahost[0] == '-') {
- if (_checkhost(rhost, ahost + 1, baselen))
- return (-1);
- } else
- hostmatch = _checkhost(rhost, ahost, baselen);
- if (user[0]) {
- if (user[0] == '+' && user[1] == 0)
- usermatch = 1;
- else if (user[0] == '+' && user[1] == '@')
- usermatch = innetgr(user + 2, NULL, ruser, dp);
- else if (user[0] == '-' && user[1] == '@') {
- if (hostmatch && innetgr(user + 2, NULL, ruser, dp))
- return (-1);
- } else if (user[0] == '-') {
- if (hostmatch && !strcmp(user + 1, ruser))
- return (-1);
- } else
- usermatch = !strcmp(user, ruser);
- } else
- usermatch = !strcmp(ruser, luser);
- if (hostmatch && usermatch)
- return (0);
-#else
- p = ahost;
- while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
- *p = isupper(*p) ? tolower(*p) : *p;
- p++;
- }
- if (*p == ' ' || *p == '\t') {
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- user = p;
- while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
- p++;
- } else
- user = p;
- *p = '\0';
- if (_checkhost(rhost, ahost, baselen)
- && !strcmp(ruser, *user ? user : luser)) {
- return (0);
- }
-#endif
- }
- return (-1);
-}
-
-static
-_checkhost(rhost, lhost, len)
- char *rhost, *lhost;
- int len;
-{
- static char ldomain[MAXHOSTNAMELEN + 1];
- static char *domainp = NULL;
- static int nodomain = 0;
- register char *cp;
-
-#ifdef AFS_AIX32_ENV
- struct hostent *hp;
- long addr;
-
- /*
- * check for ip address and do a lookup to convert to hostname
- */
- if (isinet_addr(lhost) && (addr = inet_addr(lhost)) != -1
- && (hp = gethostbyaddr(&addr, sizeof(addr), AF_INET)))
- lhost = hp->h_name;
-
-#endif
- if (len == -1) {
-#ifdef AFS_AIX32_ENV
- /* see if hostname from file has a domain name */
- for (cp = lhost; *cp; ++cp) {
- if (*cp == '.') {
- len = cp - lhost;
- break;
- }
- }
-#endif
- return (!strcmp(rhost, lhost));
- }
- if (strncmp(rhost, lhost, len))
- return (0);
- if (!strcmp(rhost, lhost))
- return (1);
-#ifdef AFS_AIX32_ENV
- if (*(lhost + len) != '\0' && *(rhost + len) != '\0')
-#else
- if (*(lhost + len) != '\0')
-#endif
- return (0);
- if (nodomain)
- return (0);
- if (!domainp) {
- if (gethostname(ldomain, sizeof(ldomain)) == -1) {
- nodomain = 1;
- return (0);
- }
- ldomain[MAXHOSTNAMELEN] = '\0';
- if ((domainp = strchr(ldomain, '.')) == (char *)NULL) {
- nodomain = 1;
- return (0);
- }
- for (cp = ++domainp; *cp; ++cp)
- if (isupper(*cp))
- *cp = tolower(*cp);
- }
- return (!strcmp(domainp, rhost + len + 1));
-}
+++ /dev/null
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-/*
- * rlogin - remote login
- */
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#if !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_SGI_ENV) && !defined(AFS_LINUX20_ENV)
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <sgtty.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <netdb.h>
-
-# ifndef TIOCPKT_WINDOW
-# define TIOCPKT_WINDOW 0x80
-# endif /* TIOCPKT_WINDOW */
-
-char *malloc(), *getenv();
-struct passwd *getpwuid();
-char *name;
-int rem;
-char cmdchar = '~';
-int eight;
-int litout;
-char *speeds[] = { "0", "50", "75", "110", "134", "150", "200", "300",
- "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400"
-};
-char term[256] = "network";
-extern int errno;
-int lostpeer();
-#ifndef COMPAT
-int dosigwinch = 0;
-int nosigwin = 0;
-struct winsize winsize;
-int sigwinch(), oob();
-#else /* COMPAT */
-#define sigmask(s) (1 << (s-1))
-int oob();
-#endif /* COMPAT */
-
-#ifdef AFS_AIX32_ENV
-#if defined(NLS) || defined(KJI)
-#include <locale.h>
-#endif
-#endif
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char **argv;
-{
- char *host, *cp;
- struct sgttyb ttyb;
- struct passwd *pwd;
- struct servent *sp;
- int uid, options = 0, oldmask;
- int on = 1;
-
-#if defined(AFS_AIX32_ENV) && (defined(NLS) || defined(KJI))
- setlocale(LC_ALL, "");
-#endif
-
- host = strrchr(argv[0], '/');
- if (host)
- host++;
- else
- host = argv[0];
- argv++, --argc;
- if (!strcmp(host, "rlogin"))
- host = *argv++, --argc;
- another:
- if (argc > 0 && !strcmp(*argv, "-d")) {
- argv++, argc--;
- options |= SO_DEBUG;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-l")) {
- argv++, argc--;
- if (argc == 0)
- goto usage;
- name = *argv++;
- argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-e", 2)) {
- cmdchar = argv[0][2];
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-8")) {
- eight = 1;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-L")) {
- litout = 1;
- argv++, argc--;
- goto another;
- }
-#ifndef COMPAT
- if (argc > 0 && !strcmp(*argv, "-w")) {
- nosigwin++;
- argv++, argc--;
- goto another;
- }
-#endif /* COMPAT */
- if (host == 0)
- goto usage;
- if (argc > 0)
- goto usage;
- pwd = getpwuid(getuid());
- if (pwd == 0) {
- fprintf(stderr, "Who are you?\n");
- exit(1);
- }
- sp = getservbyname("login", "tcp");
- if (sp == 0) {
- fprintf(stderr, "rlogin: login/tcp: unknown service\n");
- exit(2);
- }
- cp = getenv("TERM");
- if (cp)
- strcpy(term, cp);
- if (ioctl(0, TIOCGETP, &ttyb) == 0) {
- strcat(term, "/");
- strcat(term, speeds[ttyb.sg_ospeed]);
- }
-#ifndef COMPAT
-#ifdef TIOCGWINSZ
- (void)ioctl(0, TIOCGWINSZ, &winsize);
-#else
- (void)ioctl(0, TIOCGSIZE, &winsize);
-#endif
-#endif /* COMPAT */
- signal(SIGPIPE, lostpeer);
- signal(SIGURG, oob);
- oldmask = sigblock(sigmask(SIGURG));
- rem = rcmd(&host, sp->s_port, pwd->pw_name,
-#ifdef AFS_AIX32_ENV
- name ? name : pwd->pw_name, term, 0, 0);
-#else
- name ? name : pwd->pw_name, term, 0);
-#endif
- if (rem < 0)
- exit(1);
- if (options & SO_DEBUG
- && setsockopt(rem, SOL_SOCKET, SO_DEBUG, &on, sizeof(on)) < 0)
- perror("rlogin: setsockopt (SO_DEBUG)");
- uid = getuid();
- if (setuid(uid) < 0) {
- perror("rlogin: setuid");
- exit(1);
- }
- doit(oldmask);
- /*NOTREACHED*/ usage:
- fprintf(stderr,
- "usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ] [ -w ]\n");
- exit(1);
-}
-
-#define CRLF "\r\n"
-
-int child;
-int catchild();
-int writeroob();
-
-int defflags, tabflag;
-int deflflags;
-char deferase, defkill;
-struct tchars deftc;
-struct ltchars defltc;
-struct tchars notc = { -1, -1, -1, -1, -1, -1 };
-struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
-
-doit(oldmask)
-{
- int exit();
- struct sgttyb sb;
-
- ioctl(0, TIOCGETP, (char *)&sb);
- defflags = sb.sg_flags;
- tabflag = defflags & TBDELAY;
- defflags &= ECHO | CRMOD;
- deferase = sb.sg_erase;
- defkill = sb.sg_kill;
- ioctl(0, TIOCLGET, (char *)&deflflags);
- ioctl(0, TIOCGETC, (char *)&deftc);
- notc.t_startc = deftc.t_startc;
- notc.t_stopc = deftc.t_stopc;
- ioctl(0, TIOCGLTC, (char *)&defltc);
- signal(SIGINT, SIG_IGN);
- signal(SIGHUP, exit);
- signal(SIGQUIT, exit);
- child = fork();
- if (child == -1) {
- perror("rlogin: fork");
- done();
- }
- if (child == 0) {
- mode(1);
- sigsetmask(oldmask);
- reader();
- sleep(1);
- prf("\007Connection closed.");
- exit(3);
- }
-#ifndef COMPAT
- signal(SIGURG, writeroob);
-#endif /* COMPAT */
- sigsetmask(oldmask);
- signal(SIGCHLD, catchild);
-#ifndef COMPAT
- if (!nosigwin)
- signal(SIGWINCH, sigwinch);
-#endif /* COMPAT */
- writer();
- prf("Closed connection.");
- done();
-}
-
-done()
-{
-
- mode(0);
- if (child > 0 && kill(child, SIGKILL) >= 0)
- wait((int *)0);
- exit(0);
-}
-
-#ifndef COMPAT
-/*
- * This is called when the reader process gets the out-of-band (urgent)
- * request to turn on the window-changing protocol.
- */
-writeroob()
-{
-
- if (dosigwinch == 0)
- sendwindow();
- dosigwinch = 1;
-}
-#endif /* COMPAT */
-catchild()
-{
- int status;
- int pid;
-
- again:
- pid = wait3(&status, WNOHANG | WUNTRACED, 0);
- if (pid == 0)
- return;
- /*
- * if the child (reader) dies, just quit
- */
- if (pid < 0 || pid == child && !WIFSTOPPED(status))
- done();
- goto again;
-}
-
-/*
- * writer: write to remote: 0 -> line.
- * ~. terminate
- * ~^Z suspend rlogin process.
- * ~^Y suspend rlogin process, but leave reader alone.
- */
-writer()
-{
- char c;
- register n;
- register bol = 1; /* beginning of line */
- register local = 0;
-
- for (;;) {
- n = read(0, &c, 1);
- if (n <= 0) {
- if (n < 0 && errno == EINTR)
- continue;
- break;
- }
- /*
- * If we're at the beginning of the line
- * and recognize a command character, then
- * we echo locally. Otherwise, characters
- * are echo'd remotely. If the command
- * character is doubled, this acts as a
- * force and local echo is suppressed.
- */
- if (bol) {
- bol = 0;
- if (c == cmdchar) {
- bol = 0;
- local = 1;
- continue;
- }
- } else if (local) {
- local = 0;
- if (c == '.' || c == deftc.t_eofc) {
- echo(c);
- break;
- }
- if (c == defltc.t_suspc || c == defltc.t_dsuspc) {
- bol = 1;
- echo(c);
- stop(c);
- continue;
- }
- if (c != cmdchar)
- write(rem, &cmdchar, 1);
- }
- if (write(rem, &c, 1) == 0) {
- prf("line gone");
- break;
- }
- bol = c == defkill || c == deftc.t_eofc || c == '\r' || c == '\n';
- }
-}
-
-echo(c)
- register char c;
-{
- char buf[8];
- register char *p = buf;
-
- c &= 0177;
- *p++ = cmdchar;
- if (c < ' ') {
- *p++ = '^';
- *p++ = c + '@';
- } else if (c == 0177) {
- *p++ = '^';
- *p++ = '?';
- } else
- *p++ = c;
- *p++ = '\r';
- *p++ = '\n';
- write(1, buf, p - buf);
-}
-
-stop(cmdc)
- char cmdc;
-{
- mode(0);
- signal(SIGCHLD, SIG_IGN);
- kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
- signal(SIGCHLD, catchild);
- mode(1);
-#ifndef COMPAT
- sigwinch(); /* check for size changes */
-#endif /* COMPAT */
-}
-
-#ifndef COMPAT
-sigwinch()
-{
- struct winsize ws;
-
- if (dosigwinch && !nosigwin && ioctl(0, TIOCGWINSZ, &ws) == 0
- && memcmp(&ws, &winsize, sizeof(ws))) {
- winsize = ws;
- sendwindow();
- }
-}
-
-/*
- * Send the window size to the server via the magic escape
- */
-sendwindow()
-{
- char obuf[4 + sizeof(struct winsize)];
- struct winsize *wp = (struct winsize *)(obuf + 4);
-
- obuf[0] = 0377;
- obuf[1] = 0377;
- obuf[2] = 's';
- obuf[3] = 's';
- wp->ws_row = htons(winsize.ws_row);
- wp->ws_col = htons(winsize.ws_col);
- wp->ws_xpixel = htons(winsize.ws_xpixel);
- wp->ws_ypixel = htons(winsize.ws_ypixel);
- (void)write(rem, obuf, sizeof(obuf));
-}
-#endif /* COMPAT */
-oob()
-{
- int out = 1 + 1, atmark;
- char waste[BUFSIZ], mark;
- struct sgttyb sb;
- static int didnotify = 0;
-
- ioctl(1, TIOCFLUSH, (char *)&out);
- for (;;) {
- int rv;
- if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
- perror("ioctl");
- break;
- }
- if (atmark)
- break;
- rv = read(rem, waste, sizeof(waste));
- if (rv <= 0)
- break;
- }
- recv(rem, &mark, 1, MSG_OOB);
- if (didnotify == 0 && (mark & TIOCPKT_WINDOW)) {
- /*
- * Let server know about window size changes
- */
- kill(getppid(), SIGURG);
- didnotify = 1;
- }
- if (eight)
- return;
- if (mark & TIOCPKT_NOSTOP) {
- ioctl(0, TIOCGETP, (char *)&sb);
- sb.sg_flags &= ~CBREAK;
- sb.sg_flags |= RAW;
- ioctl(0, TIOCSETN, (char *)&sb);
- notc.t_stopc = -1;
- notc.t_startc = -1;
- ioctl(0, TIOCSETC, (char *)¬c);
- }
- if (mark & TIOCPKT_DOSTOP) {
- ioctl(0, TIOCGETP, (char *)&sb);
- sb.sg_flags &= ~RAW;
- sb.sg_flags |= CBREAK;
- ioctl(0, TIOCSETN, (char *)&sb);
- notc.t_stopc = deftc.t_stopc;
- notc.t_startc = deftc.t_startc;
- ioctl(0, TIOCSETC, (char *)¬c);
- }
-}
-
-/*
- * reader: read from remote: line -> 1
- */
-reader()
-{
- char rb[BUFSIZ];
- register int cnt;
-
- signal(SIGTTOU, SIG_IGN);
- {
- int pid = getpid();
- fcntl(rem, F_SETOWN, pid);
- }
- for (;;) {
- cnt = read(rem, rb, sizeof(rb));
- if (cnt == 0)
- break;
- if (cnt < 0) {
- if (errno == EINTR)
- continue;
- break;
- }
- write(1, rb, cnt);
- }
-}
-
-mode(f)
-{
- struct tchars *tc;
- struct ltchars *ltc;
- struct sgttyb sb;
- int lflags;
-
- ioctl(0, TIOCGETP, (char *)&sb);
- ioctl(0, TIOCLGET, (char *)&lflags);
- switch (f) {
-
- case 0:
- sb.sg_flags &= ~(CBREAK | RAW | TBDELAY);
- sb.sg_flags |= defflags | tabflag;
- tc = &deftc;
- ltc = &defltc;
- sb.sg_kill = defkill;
- sb.sg_erase = deferase;
- lflags = deflflags;
- break;
-
- case 1:
- sb.sg_flags |= (eight ? RAW : CBREAK);
- sb.sg_flags &= ~defflags;
- /* preserve tab delays, but turn off XTABS */
- if ((sb.sg_flags & TBDELAY) == XTABS)
- sb.sg_flags &= ~TBDELAY;
- tc = ¬c;
- ltc = &noltc;
- sb.sg_kill = sb.sg_erase = -1;
- if (litout)
- lflags |= LLITOUT;
- break;
-
- default:
- return;
- }
- ioctl(0, TIOCSLTC, (char *)ltc);
- ioctl(0, TIOCSETC, (char *)tc);
- ioctl(0, TIOCSETN, (char *)&sb);
- ioctl(0, TIOCLSET, (char *)&lflags);
-}
-
- /*VARARGS*/
-prf(f, a1, a2, a3, a4, a5)
- char *f;
-{
- fprintf(stderr, f, a1, a2, a3, a4, a5);
- fprintf(stderr, CRLF);
-}
-
-lostpeer()
-{
- signal(SIGPIPE, SIG_IGN);
- prf("\007Connection closed.");
- done();
-}
-#else
-
-#include "AFS_component_version_number.c"
-
-main(argc, argv)
- int argc;
- char *argv[];
-{
- printf("afs rlogin: Not supported for this system ...\n");
-}
-#endif /* !defined(AFS_HPUX_ENV) */
+++ /dev/null
-.\" Copyright (c) 1983 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)rsh.1 6.2 (Berkeley) 9/20/88
-.\"
-.TH RSH 1 "September 20, 1988"
-.UC 5
-.SH NAME
-rsh \- remote shell
-.SH SYNOPSIS
-.B rsh
-host
-[
-.B \-l
-username
-] [
-.B \-n
-] command
-.br
-host
-[
-.B \-l
-username
-] [
-.B \-n
-] command
-.SH DESCRIPTION
-.I Rsh
-connects to the specified
-.I host,
-and executes the specified \fIcommand\fR.
-.I Rsh
-copies its standard input to the remote command, the standard
-output of the remote command to its standard output, and the
-standard error of the remote command to its standard error.
-Interrupt, quit and terminate signals are propagated to the remote
-command; \fIrsh\fP normally terminates when the remote command does.
-.PP
-The remote username used is the same as your local username,
-unless you specify a different remote name with the
-.B \-l
-option.
-This remote name must be equivalent (in the sense of
-.IR rlogin (1C))
-to the originating account; no provision
-is made for specifying a password with a command.
-.PP
-If you omit
-.I command,
-then instead of executing a single command, you will be logged in
-on the remote host using
-.IR rlogin (1C).
-.PP
-Shell metacharacters which are not quoted are interpreted
-on local machine, while quoted metacharacters are interpreted on
-the remote machine.
-Thus the command
-.PP
-\ \ \ rsh otherhost cat remotefile >> localfile
-.PP
-appends the remote file
-.I remotefile
-to the localfile
-.I localfile,
-while
-.PP
-\ \ \ rsh otherhost cat remotefile ">>" otherremotefile
-.PP
-appends
-.I remotefile
-to
-.I otherremotefile.
-.PP
-Host names are given in the file /etc/hosts. Each host
-has one standard name (the first name given in the file), which
-is rather long and unambiguous, and optionally one or more nicknames.
-The host names for local machines are also commands in the directory
-/usr/hosts; if you put this directory in your search path
-then the
-.B rsh
-can be omitted.
-.SH FILES
-.ta 2i
-/etc/hosts
-.br
-/usr/hosts/*
-.DT
-.SH SEE ALSO
-rlogin(1)
-.SH BUGS
-If you are using
-.IR csh (1)
-and put a
-.IR rsh (1)
-in the background without redirecting its input
-away from the terminal, it will block even if no reads
-are posted by the remote command. If no input is desired
-you should redirect the input of
-.I rsh
-to /dev/null using the
-.B \-n
-option.
-.PP
-You cannot run an interactive command
-(like
-.IR rogue (6)
-or
-.IR vi (1));
-use
-.IR rlogin (1).
-.PP
-Stop signals stop the local \fIrsh\fP process only; this is arguably
-wrong, but currently hard to fix for reasons too complicated to
-explain here.
+++ /dev/null
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-RCSID
- ("$Header$");
-
-#include <unistd.h> /* select() prototype */
-#include <sys/types.h> /* fd_set on older platforms */
-#include <sys/time.h> /* struct timeval, select() prototype */
-#ifndef FD_SET
-# include <sys/select.h> /* fd_set on newer platforms */
-#endif
-#include <sys/socket.h>
-#ifdef AFS_SUN5_ENV
-#define BSD_COMP
-#endif
-#include <sys/ioctl.h>
-#include <sys/file.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <pwd.h>
-#include <netdb.h>
-
-#ifdef AFS_AIX32_ENV
-/*#ifdef MSG
-#include "rsh_msg.h"
-#define MSGSTR(n,s) NLgetamsg(MF_RSH, MS_RSH, n, s)
-#else*/
-#define MSGSTR(n,s) s
-/*#endif*/
-
-#ifdef KAUTH
-#include <afs/auth.h>
-#include <afs/cellconfig.h>
-#endif /* KAUTH */
-#endif
-
-#ifdef AFS_HPUX_ENV
-#include <sys/stat.h>
-extern char **environ;
-char **vp;
-#define RSHNAME "remsh"
-#else
-#define RSHNAME "rsh"
-#endif /* AFS_HPUX_ENV */
-
-/*
- * rsh - remote shell
- */
-/* VARARGS */
-int error();
-
-int errno;
-int options;
-int rfd2;
-int nflag;
-void sendsig();
-
-#define mask(s) (1 << ((s) - 1))
-#if defined(AFS_AIX32_ENV) && (defined(NLS) || defined(KJI))
-#include <locale.h>
-#endif
-
-#include "AFS_component_version_number.c"
-
-/*
- * rlogin directory
- *
- * We don't really need a definition for AFS_SGI_ENV since SGI's own rsh
- * does the right thing.
- *
- * In some older platforms, such as SunOS 4.x, rlogin lives in /usr/ucb.
- * But for all our currently supported platforms for AFS 3.5, it's in /usr/bin.
- */
-#ifdef AFS_SGI_ENV
-#define _PATH_RLOGIN "/usr/bsd/rlogin"
-#else
-#define _PATH_RLOGIN "/usr/bin/rlogin"
-#endif
-
-main(argc, argv0)
- int argc;
- char **argv0;
-{
- int rem, pid;
- char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
- register int cc;
- int asrsh = 0;
- struct passwd *pwd;
- fd_set readfrom, ready;
- int one = 1;
- struct servent *sp;
-
- sigset_t oset;
- sigset_t sigBlock;
- int someSignals[100];
-
-#ifdef AFS_HPUX_ENV
- int fd;
- struct stat stat_buf;
- char *clientname;
-#endif
-#if defined(AFS_AIX32_ENV)
- struct sigaction ign_act, save_old_act;
-#ifdef KAUTH
- int pass_tokens;
-#endif /* KAUTH */
-
-#if defined(AFS_AIX32_ENV) && (defined(NLS) || defined(KJI))
- setlocale(LC_ALL, "");
-#endif
-
-#ifdef notdef
- /*
- * If we're being called as a non-afs version of the program, and if AFS extensions
- * have been loaded, run the AFS version of the program.
- */
- check_and_run_afs_vers(argv);
-#endif
- memset(&ign_act, 0, sizeof(ign_act));
- ign_act.sa_handler = SIG_IGN;
-#endif
- host = strrchr(argv[0], '/');
- if (host)
- host++;
- else
- host = argv[0];
- argv++, --argc;
-#ifdef AFS_HPUX_ENV
- /* if invoked as something other than remsh or rsh, use the
- * invocation name as the host name to connect to (clever).
- */
- if (!strcmp(host, "remsh") || !strcmp(host, "rsh")) {
- clientname = host;
- host = *argv++, --argc;
- asrsh = 1;
- } else {
- clientname = "remsh";
- }
-#else
- if (!strcmp(host, RSHNAME)) {
- if (argc == 0)
- goto usage;
- if (*argv[0] != '-') {
- host = *argv++, --argc;
- asrsh = 1;
- } else
- host = 0;
- }
-#endif
-#ifdef KAUTH
- pass_tokens = (int)getenv("KAUTH");
- if (pass_tokens) {
- pass_tokens = (!strcmp((char *)pass_tokens, "afs"));
- }
-#endif /* KAUTH */
-#ifdef AFS_HPUX_ENV
- /* make sure file descriptors 0, 1, and 2 are open */
- for (fd = 0; fd <= 2; fd++) {
- if (fstat(fd, &stat_buf) != 0) {
- if (open("/dev/null", O_RDWR) < 0) {
- fprintf(stderr, "%s: ", clientname);
- perror("open:");
- exit(1);
- }
- }
- }
- /* save a copy of original environment in case we exec rlogin */
- {
- int vecsize = 0, envsize = 0, i = 0;
- vp = environ;
- while (vp != (char **)NULL && *vp != (char *)NULL) {
- vecsize++;
- envsize += strlen(*vp) + 1;
- vp++;
- }
- vp = (char **)malloc((vecsize + 1) * sizeof(char *));
- cp = malloc(envsize);
- while (i < vecsize) {
- vp[i] = cp;
- strcpy(vp[i], environ[i]);
- while (*cp != (char)NULL)
- cp++;
- cp++;
- i++;
- }
- }
-
- /* clear timers, close open files, and wipe out environment */
- cleanenv(&environ, "LANG", "LANGOPTS", "NLSPATH", "LOCALDOMAIN",
- "HOSTALIASES", 0);
-#endif
- another:
- if (argc > 0 && !strcmp(*argv, "-l")) {
- argv++, argc--;
- if (argc > 0)
- user = *argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- argv++, argc--;
- nflag++;
-#ifdef AFS_SUN_ENV
- (void)close(0);
- (void)open("/dev/null", 0);
-#endif
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-d")) {
- argv++, argc--;
- options |= SO_DEBUG;
- goto another;
- }
-#ifdef KAUTH
- if (argc > 0 && !strcmp(*argv, "-v")) {
- argv++, argc--;
- pass_tokens = 1;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-V")) {
- argv++, argc--;
- pass_tokens = 0;
- goto another;
- }
-#endif /* KAUTH */
- /*
- * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
- * to work
- *
- * There must be a better way to do this! -jmb
- */
- if (argc > 0 && !strncmp(*argv, "-L", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-w", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-e", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-8", 2)) {
- argv++, argc--;
- goto another;
- }
-#ifdef AFS_HPUX_ENV
- if (argc > 0 && !strncmp(*argv, "-7", 2)) {
- argv++, argc--;
- goto another;
- }
-#endif
- if (host == 0) {
- if (argc == 0)
- goto usage;
- host = *argv++, --argc;
- asrsh = 1;
- }
- if (argv[0] == 0) {
- if (asrsh)
- *argv0 = "rlogin";
-
-#ifdef AFS_HPUX_ENV
- execve(_PATH_RLOGIN, argv0, vp);
-#else
- execv(_PATH_RLOGIN, argv0);
-#endif
- perror(_PATH_RLOGIN);
- exit(1);
- }
- pwd = getpwuid(getuid());
- if (pwd == 0) {
- fprintf(stderr, "who are you?\n");
- exit(1);
- }
- cc = 0;
- for (ap = argv; *ap; ap++)
- cc += strlen(*ap) + 1;
- cp = args = malloc(cc);
- for (ap = argv; *ap; ap++) {
- (void)strcpy(cp, *ap);
- while (*cp)
- cp++;
- if (ap[1])
- *cp++ = ' ';
- }
- sp = getservbyname("shell", "tcp");
- if (sp == 0) {
- fprintf(stderr, "%s: shell/tcp: unknown service\n", RSHNAME);
- exit(1);
- }
- rem = rcmd(&host, sp->s_port, pwd->pw_name,
-#ifdef AFS_AIX32_ENV
- user ? user : pwd->pw_name, args, &rfd2, /* long timeout? */
- 1);
-#else
- user ? user : pwd->pw_name, args, &rfd2);
-#endif
- if (rem < 0)
- exit(1);
- if (rfd2 < 0) {
- fprintf(stderr, "%s: can't establish stderr\n", RSHNAME);
- exit(2);
- }
- if (options & SO_DEBUG) {
- if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char *)&one, sizeof(one)) <
- 0)
- perror("setsockopt (stdin)");
- if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, (char *)&one, sizeof(one))
- < 0)
- perror("setsockopt (stderr)");
- }
- (void)setuid(getuid());
-
- memset((char *)someSignals, 0, sizeof(someSignals));
-#ifdef AFS_HPUX_ENV
- someSignals[0] =
- mask(SIGINT) | mask(SIGQUIT) | mask(SIGTERM) | mask(SIGHUP);
-#else
- someSignals[0] = mask(SIGINT) | mask(SIGQUIT) | mask(SIGTERM);
-#endif
- sigBlock = *((sigset_t *) someSignals);
- sigprocmask(SIG_BLOCK, &sigBlock, &oset);
-#ifdef AFS_AIX32_ENV
- (void)sigaction(SIGINT, &ign_act, &save_old_act);
- if (save_old_act.sa_handler != SIG_IGN)
- (void)signal(SIGINT, sendsig);
- (void)sigaction(SIGQUIT, &ign_act, &save_old_act);
- if (save_old_act.sa_handler != SIG_IGN)
- (void)signal(SIGQUIT, sendsig);
- (void)sigaction(SIGTERM, &ign_act, &save_old_act);
- if (save_old_act.sa_handler != SIG_IGN)
- (void)signal(SIGTERM, sendsig);
-#else
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, sendsig);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, sendsig);
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, sendsig);
-#ifdef AFS_HPUX_ENV
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
- signal(SIGHUP, sendsig);
- /* ignore the death of my child -- banish zombies! */
- signal(SIGCLD, SIG_IGN);
-#endif
-#endif
- if (nflag == 0) {
- pid = fork();
- if (pid < 0) {
- perror("fork");
- exit(1);
- }
- }
- ioctl(rfd2, FIONBIO, &one);
- ioctl(rem, FIONBIO, &one);
- if (nflag == 0 && pid == 0) {
- char *bp;
- int wc;
- fd_set rembits;
- (void)close(rfd2);
- reread:
- errno = 0;
- cc = read(0, buf, sizeof buf);
- if (cc <= 0)
- goto done;
- bp = buf;
- rewrite:
- FD_ZERO(&rembits);
- FD_SET(rem, &rembits);
- if (select(rem + 1, 0, &rembits, 0, 0) < 0) {
- if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- goto rewrite;
- }
- if (!FD_ISSET(rem, &rembits))
- goto rewrite;
- wc = write(rem, bp, cc);
- if (wc < 0) {
- if (errno == EWOULDBLOCK)
- goto rewrite;
- goto done;
- }
- cc -= wc;
- bp += wc;
- if (cc == 0)
- goto reread;
- goto rewrite;
- done:
- (void)shutdown(rem, 1);
- exit(0);
- }
- sigprocmask(SIG_SETMASK, &oset, (sigset_t *) 0);
- FD_ZERO(&readfrom);
- FD_SET(rfd2, &readfrom);
- FD_SET(rem, &readfrom);
- for (;;) {
- int maxfd;
- maxfd = -1;
- if (FD_ISSET(rfd2, &readfrom) && maxfd < rfd2)
- maxfd = rfd2;
- if (FD_ISSET(rem, &readfrom) && maxfd < rem)
- maxfd = rem;
- if (maxfd == -1)
- break;
- ready = readfrom;
- if (select(maxfd + 1, &ready, 0, 0, 0) < 0) {
- if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- continue;
- }
- if (FD_ISSET(rfd2, &ready)) {
- errno = 0;
- cc = read(rfd2, buf, sizeof buf);
- if (cc <= 0) {
- if (errno != EWOULDBLOCK)
- FD_CLR(rfd2, &readfrom);
- } else
- (void)write(2, buf, cc);
- }
- if (FD_ISSET(rem, &ready)) {
- errno = 0;
- cc = read(rem, buf, sizeof buf);
- if (cc <= 0) {
- if (errno != EWOULDBLOCK)
- FD_CLR(rem, &readfrom);
- } else
- (void)write(1, buf, cc);
- }
- }
- if (nflag == 0)
- (void)kill(pid, SIGKILL);
- exit(0);
- usage:
- fprintf(stderr, "usage: %s host [ -l login ] [ -n ] command\n", RSHNAME);
- exit(1);
-}
-
-void
-sendsig(signo)
- char signo;
-{
-
- (void)write(rfd2, &signo, 1);
-}