retiring tty mode "EXTPROC"

From: Poul-Henning Kamp <phk_at_phk.freebsd.dk>
Date: Fri, 11 Jun 2004 17:41:50 +0200
The following patch retires the EXTPROC mode from our tty code.

This option is used to support RFC1116 LINEMODE in telnetd, but
given that TCP/IP over X.25 networks is not common any more,
that telnet is mostly used to manage local devices these days
and that many programs, including our default shell, uses the
tty in raw mode, this has outlived its utility.


Index: bin/stty/key.c
===================================================================
RCS file: /home/ncvs/src/bin/stty/key.c,v
retrieving revision 1.18
diff -u -r1.18 key.c
--- bin/stty/key.c	6 Apr 2004 20:06:53 -0000	1.18
+++ bin/stty/key.c	11 Jun 2004 12:42:58 -0000
_at__at_ -54,7 +54,6 _at__at_
 void	f_dec(struct info *);
 void	f_ek(struct info *);
 void	f_everything(struct info *);
-void	f_extproc(struct info *);
 void	f_ispeed(struct info *);
 void	f_nl(struct info *);
 void	f_ospeed(struct info *);
_at__at_ -81,7 +80,6 _at__at_
 	{ "dec",	f_dec,		0 },
 	{ "ek",		f_ek,		0 },
 	{ "everything",	f_everything,	0 },
-	{ "extproc",	f_extproc,	F_OFFOK },
 	{ "ispeed",	f_ispeed,	F_NEEDARG },
 	{ "new",	f_tty,		0 },
 	{ "nl",		f_nl,		F_OFFOK },
_at__at_ -190,19 +188,6 _at__at_
 }
 
 void
-f_extproc(struct info *ip)
-{
-
-	if (ip->off) {
-		int tmp = 0;
-		(void)ioctl(ip->fd, TIOCEXT, &tmp);
-	} else {
-		int tmp = 1;
-		(void)ioctl(ip->fd, TIOCEXT, &tmp);
-	}
-}
-
-void
 f_ispeed(struct info *ip)
 {
 
Index: bin/stty/print.c
===================================================================
RCS file: /home/ncvs/src/bin/stty/print.c,v
retrieving revision 1.19
diff -u -r1.19 print.c
--- bin/stty/print.c	6 Apr 2004 20:06:53 -0000	1.19
+++ bin/stty/print.c	11 Jun 2004 12:49:45 -0000
_at__at_ -116,7 +116,6 _at__at_
 	put("-flusho", FLUSHO, 0);
 	put("-pendin", PENDIN, 0);
 	put("-nokerninfo", NOKERNINFO, 0);
-	put("-extproc", EXTPROC, 0);
 
 	/* input flags */
 	tmp = tp->c_iflag;
Index: lib/libedit/tty.c
===================================================================
RCS file: /home/ncvs/src/lib/libedit/tty.c,v
retrieving revision 1.7
diff -u -r1.7 tty.c
--- lib/libedit/tty.c	1 Oct 2001 08:41:25 -0000	1.7
+++ lib/libedit/tty.c	11 Jun 2004 12:50:56 -0000
_at__at_ -67,7 +67,7 _at__at_
 		{"oflag:", (OPOST | ONLCR), ONLRET},
 		{"cflag:", 0, 0},
 		{"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
-		(NOFLSH | ECHONL | EXTPROC | FLUSHO)},
+		(NOFLSH | ECHONL | FLUSHO)},
 		{"chars:", 0, 0},
 	},
 	{
_at__at_ -75,7 +75,7 _at__at_
 		{"oflag:", (OPOST | ONLCR), ONLRET},
 		{"cflag:", 0, 0},
 		{"lflag:", ISIG,
-		(NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
+		(NOFLSH | ICANON | ECHO | ECHOK | ECHONL | IEXTEN | FLUSHO)},
 		{"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
 			    C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
 		    C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
_at__at_ -362,9 +362,6 _at__at_
 #ifdef	ALTWERASE
 	{"altwerase", ALTWERASE, MD_LIN},
 #endif /* ALTWERASE */
-#ifdef	EXTPROC
-	{"extproc", EXTPROC, MD_LIN},
-#endif /* EXTPROC */
 
 #if defined(VINTR)
 	{"intr", C_SH(C_INTR), MD_CHAR},
Index: lib/libedit/tty.h
===================================================================
RCS file: /home/ncvs/src/lib/libedit/tty.h,v
retrieving revision 1.4
diff -u -r1.4 tty.h
--- lib/libedit/tty.h	1 Oct 2001 08:41:25 -0000	1.4
+++ lib/libedit/tty.h	11 Jun 2004 12:51:08 -0000
_at__at_ -106,10 +106,6 _at__at_
 #  define PARENB 0
 # endif /* PARENB */
 
-# ifndef EXTPROC
-#  define EXTPROC 0
-# endif /* EXTPROC */
-
 # ifndef FLUSHO
 #  define FLUSHO  0
 # endif /* FLUSHO */
Index: libexec/telnetd/Makefile
===================================================================
RCS file: /home/ncvs/src/libexec/telnetd/Makefile,v
retrieving revision 1.23
diff -u -r1.23 Makefile
--- libexec/telnetd/Makefile	24 Jul 2003 17:19:15 -0000	1.23
+++ libexec/telnetd/Makefile	11 Jun 2004 13:35:20 -0000
_at__at_ -12,7 +12,7 _at__at_
 SRCS=		global.c slc.c state.c sys_term.c telnetd.c \
 		termstat.c utility.c
 
-CFLAGS+=	-DLINEMODE -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON \
+CFLAGS+=	-DLINEMODE -DEXTPROC=0 -DUSE_TERMIO -DDIAGNOSTICS -DOLD_ENVIRON \
 		-DENV_HACK \
 		-I${TELNETDIR} -DINET6
 
Index: share/man/man4/termios.4
===================================================================
RCS file: /home/ncvs/src/share/man/man4/termios.4,v
retrieving revision 1.28
diff -u -r1.28 termios.4
--- share/man/man4/termios.4	8 Sep 2003 19:57:19 -0000	1.28
+++ share/man/man4/termios.4	11 Jun 2004 14:13:41 -0000
_at__at_ -1286,8 +1286,6 _at__at_
 and
 .Dv LNEXT
 */
-.It Dv EXTPROC
-/* external processing */
 .It Dv TOSTOP
 /* stop background jobs from output */
 .It Dv FLUSHO
Index: sys/kern/tty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty.c,v
retrieving revision 1.218
diff -u -r1.218 tty.c
--- sys/kern/tty.c	11 Jun 2004 11:16:24 -0000	1.218
+++ sys/kern/tty.c	11 Jun 2004 12:49:30 -0000
_at__at_ -50,10 +50,8 _at__at_
  *	o Handle CLOCAL consistently for ptys.  Perhaps disallow setting it.
  *	o Don't allow input in TS_ZOMBIE case.  It would be visible through
  *	  FIONREAD.
- *	o Do the new sio locking stuff here and use it to avoid special
- *	  case for EXTPROC?
  *	o Lock PENDIN too?
- *	o Move EXTPROC and/or PENDIN to t_state?
+ *	o Move PENDIN to t_state?
  *	o Wrap most of ttioctl in spltty/splx.
  *	o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
  *	o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
_at__at_ -372,111 +370,109 _at__at_
 
 	if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
 		CLR(c, 0x80);
-	if (!ISSET(lflag, EXTPROC)) {
-		/*
-		 * Check for literal nexting very first
-		 */
-		if (ISSET(tp->t_state, TS_LNCH)) {
-			SET(c, TTY_QUOTE);
-			CLR(tp->t_state, TS_LNCH);
-		}
-		/*
-		 * Scan for special characters.  This code
-		 * is really just a big case statement with
-		 * non-constant cases.  The bottom of the
-		 * case statement is labeled ``endcase'', so goto
-		 * it after a case match, or similar.
-		 */
+	/*
+	 * Check for literal nexting very first
+	 */
+	if (ISSET(tp->t_state, TS_LNCH)) {
+		SET(c, TTY_QUOTE);
+		CLR(tp->t_state, TS_LNCH);
+	}
+	/*
+	 * Scan for special characters.  This code
+	 * is really just a big case statement with
+	 * non-constant cases.  The bottom of the
+	 * case statement is labeled ``endcase'', so goto
+	 * it after a case match, or similar.
+	 */
 
-		/*
-		 * Control chars which aren't controlled
-		 * by ICANON, ISIG, or IXON.
-		 */
-		if (ISSET(lflag, IEXTEN)) {
-			if (CCEQ(cc[VLNEXT], c)) {
-				if (ISSET(lflag, ECHO)) {
-					if (ISSET(lflag, ECHOE)) {
-						(void)ttyoutput('^', tp);
-						(void)ttyoutput('\b', tp);
-					} else
-						ttyecho(c, tp);
-				}
-				SET(tp->t_state, TS_LNCH);
-				goto endcase;
-			}
-			if (CCEQ(cc[VDISCARD], c)) {
-				if (ISSET(lflag, FLUSHO))
-					CLR(tp->t_lflag, FLUSHO);
-				else {
-					ttyflush(tp, FWRITE);
+	/*
+	 * Control chars which aren't controlled
+	 * by ICANON, ISIG, or IXON.
+	 */
+	if (ISSET(lflag, IEXTEN)) {
+		if (CCEQ(cc[VLNEXT], c)) {
+			if (ISSET(lflag, ECHO)) {
+				if (ISSET(lflag, ECHOE)) {
+					(void)ttyoutput('^', tp);
+					(void)ttyoutput('\b', tp);
+				} else
 					ttyecho(c, tp);
-					if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
-						ttyretype(tp);
-					SET(tp->t_lflag, FLUSHO);
-				}
-				goto startoutput;
 			}
+			SET(tp->t_state, TS_LNCH);
+			goto endcase;
 		}
-		/*
-		 * Signals.
-		 */
-		if (ISSET(lflag, ISIG)) {
-			if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
-				if (!ISSET(lflag, NOFLSH))
-					ttyflush(tp, FREAD | FWRITE);
+		if (CCEQ(cc[VDISCARD], c)) {
+			if (ISSET(lflag, FLUSHO))
+				CLR(tp->t_lflag, FLUSHO);
+			else {
+				ttyflush(tp, FWRITE);
 				ttyecho(c, tp);
-				if (tp->t_pgrp != NULL) {
-					PGRP_LOCK(tp->t_pgrp);
-					pgsignal(tp->t_pgrp,
-					    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
-					PGRP_UNLOCK(tp->t_pgrp);
-				}
-				goto endcase;
+				if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
+					ttyretype(tp);
+				SET(tp->t_lflag, FLUSHO);
 			}
-			if (CCEQ(cc[VSUSP], c)) {
-				if (!ISSET(lflag, NOFLSH))
-					ttyflush(tp, FREAD);
-				ttyecho(c, tp);
-				if (tp->t_pgrp != NULL) {
-					PGRP_LOCK(tp->t_pgrp);
-					pgsignal(tp->t_pgrp, SIGTSTP, 1);
-					PGRP_UNLOCK(tp->t_pgrp);
-				}
-				goto endcase;
+			goto startoutput;
+		}
+	}
+	/*
+	 * Signals.
+	 */
+	if (ISSET(lflag, ISIG)) {
+		if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
+			if (!ISSET(lflag, NOFLSH))
+				ttyflush(tp, FREAD | FWRITE);
+			ttyecho(c, tp);
+			if (tp->t_pgrp != NULL) {
+				PGRP_LOCK(tp->t_pgrp);
+				pgsignal(tp->t_pgrp,
+				    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
+				PGRP_UNLOCK(tp->t_pgrp);
 			}
+			goto endcase;
 		}
-		/*
-		 * Handle start/stop characters.
-		 */
-		if (ISSET(iflag, IXON)) {
-			if (CCEQ(cc[VSTOP], c)) {
-				if (!ISSET(tp->t_state, TS_TTSTOP)) {
-					SET(tp->t_state, TS_TTSTOP);
-					(*tp->t_stop)(tp, 0);
-					return (0);
-				}
-				if (!CCEQ(cc[VSTART], c))
-					return (0);
-				/*
-				 * if VSTART == VSTOP then toggle
-				 */
-				goto endcase;
+		if (CCEQ(cc[VSUSP], c)) {
+			if (!ISSET(lflag, NOFLSH))
+				ttyflush(tp, FREAD);
+			ttyecho(c, tp);
+			if (tp->t_pgrp != NULL) {
+				PGRP_LOCK(tp->t_pgrp);
+				pgsignal(tp->t_pgrp, SIGTSTP, 1);
+				PGRP_UNLOCK(tp->t_pgrp);
 			}
-			if (CCEQ(cc[VSTART], c))
-				goto restartoutput;
+			goto endcase;
 		}
-		/*
-		 * IGNCR, ICRNL, & INLCR
-		 */
-		if (c == '\r') {
-			if (ISSET(iflag, IGNCR))
+	}
+	/*
+	 * Handle start/stop characters.
+	 */
+	if (ISSET(iflag, IXON)) {
+		if (CCEQ(cc[VSTOP], c)) {
+			if (!ISSET(tp->t_state, TS_TTSTOP)) {
+				SET(tp->t_state, TS_TTSTOP);
+				(*tp->t_stop)(tp, 0);
 				return (0);
-			else if (ISSET(iflag, ICRNL))
-				c = '\n';
-		} else if (c == '\n' && ISSET(iflag, INLCR))
-			c = '\r';
+			}
+			if (!CCEQ(cc[VSTART], c))
+				return (0);
+			/*
+			 * if VSTART == VSTOP then toggle
+			 */
+			goto endcase;
+		}
+		if (CCEQ(cc[VSTART], c))
+			goto restartoutput;
 	}
-	if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
+	/*
+	 * IGNCR, ICRNL, & INLCR
+	 */
+	if (c == '\r') {
+		if (ISSET(iflag, IGNCR))
+			return (0);
+		else if (ISSET(iflag, ICRNL))
+			c = '\n';
+	} else if (c == '\n' && ISSET(iflag, INLCR))
+		c = '\r';
+	if (ISSET(lflag, ICANON)) {
 		/*
 		 * From here on down canonical mode character
 		 * processing takes place.
_at__at_ -664,8 +660,7 _at__at_
 	 * externally.
 	 */
 	CLR(c, ~TTY_CHARMASK);
-	if (c == '\t' &&
-	    ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
+	if (c == '\t' && ISSET(oflag, OXTABS)) {
 		c = 8 - (tp->t_column & 7);
 		if (!ISSET(tp->t_lflag, FLUSHO)) {
 			s = spltty();		/* Don't interrupt tabs. */
_at__at_ -998,13 +993,6 _at__at_
 		}
 		tp->t_iflag = t->c_iflag;
 		tp->t_oflag = t->c_oflag;
-		/*
-		 * Make the EXTPROC bit read only.
-		 */
-		if (ISSET(tp->t_lflag, EXTPROC))
-			SET(t->c_lflag, EXTPROC);
-		else
-			CLR(t->c_lflag, EXTPROC);
 		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
 		if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
 		    t->c_cc[VTIME] != tp->t_cc[VTIME])
_at__at_ -2119,7 +2107,7 _at__at_
 	int savecol;
 	int tabc, s;
 
-	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
+	if (!ISSET(tp->t_lflag, ECHO))
 		return;
 	CLR(tp->t_lflag, FLUSHO);
 	if (ISSET(tp->t_lflag, ECHOE)) {
_at__at_ -2261,8 +2249,7 _at__at_
 	if (!ISSET(tp->t_state, TS_CNTTB))
 		CLR(tp->t_lflag, FLUSHO);
 	if ((!ISSET(tp->t_lflag, ECHO) &&
-	     (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
-	    ISSET(tp->t_lflag, EXTPROC))
+	     (c != '\n' || !ISSET(tp->t_lflag, ECHONL))))
 		return;
 	if (ISSET(tp->t_lflag, ECHOCTL) &&
 	    ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
Index: sys/kern/tty_pty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.123
diff -u -r1.123 tty_pty.c
--- sys/kern/tty_pty.c	11 Jun 2004 11:16:24 -0000	1.123
+++ sys/kern/tty_pty.c	11 Jun 2004 12:50:08 -0000
_at__at_ -334,7 +334,6 _at__at_
 	tp->t_oproc = ptsstart;
 	tp->t_stop = ptsstop;
 	(void)ttyld_modem(tp, 1);
-	tp->t_lflag &= ~EXTPROC;
 	pt = dev->si_drv1;
 	pt->pt_prison = td->td_ucred->cr_prison;
 	pt->pt_flags = 0;
_at__at_ -692,28 +691,6 _at__at_
 			return(0);
 		}
 	}
-	if (cmd == TIOCEXT) {
-		/*
-		 * When the EXTPROC bit is being toggled, we need
-		 * to send an TIOCPKT_IOCTL if the packet driver
-		 * is turned on.
-		 */
-		if (*(int *)data) {
-			if (pt->pt_flags & PF_PKT) {
-				pt->pt_send |= TIOCPKT_IOCTL;
-				ptcwakeup(tp, FREAD);
-			}
-			tp->t_lflag |= EXTPROC;
-		} else {
-			if ((tp->t_lflag & EXTPROC) &&
-			    (pt->pt_flags & PF_PKT)) {
-				pt->pt_send |= TIOCPKT_IOCTL;
-				ptcwakeup(tp, FREAD);
-			}
-			tp->t_lflag &= ~EXTPROC;
-		}
-		return(0);
-	}
 	error = ttyioctl(dev, cmd, data, flag, td);
 	if (error == ENOTTY) {
 		if (pt->pt_flags & PF_UCNTL &&
_at__at_ -729,29 +706,6 _at__at_
 	/*
 	 * If external processing and packet mode send ioctl packet.
 	 */
-	if ((tp->t_lflag&EXTPROC) && (pt->pt_flags & PF_PKT)) {
-		switch(cmd) {
-		case TIOCSETA:
-		case TIOCSETAW:
-		case TIOCSETAF:
-#ifdef COMPAT_43
-		case TIOCSETP:
-		case TIOCSETN:
-#endif
-#if defined(COMPAT_43)
-		case TIOCSETC:
-		case TIOCSLTC:
-		case TIOCLBIS:
-		case TIOCLBIC:
-		case TIOCLSET:
-#endif
-			pt->pt_send |= TIOCPKT_IOCTL;
-			ptcwakeup(tp, FREAD);
-			break;
-		default:
-			break;
-		}
-	}
 	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
 		&& CCEQ(cc[VSTART], CTRL('q'));
 	if (pt->pt_flags & PF_NOSTOP) {
Index: sys/sys/termios.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/termios.h,v
retrieving revision 1.19
diff -u -r1.19 termios.h
--- sys/sys/termios.h	7 Apr 2004 04:19:49 -0000	1.19
+++ sys/sys/termios.h	11 Jun 2004 12:48:18 -0000
_at__at_ -166,7 +166,6 _at__at_
 #define ALTWERASE	0x00000200	/* use alternate WERASE algorithm */
 #endif  /*_POSIX_SOURCE */
 #define	IEXTEN		0x00000400	/* enable DISCARD and LNEXT */
-#define EXTPROC         0x00000800      /* external processing */
 #define TOSTOP		0x00400000	/* stop background jobs from output */
 #ifndef _POSIX_SOURCE
 #define FLUSHO		0x00800000	/* output being flushed (state) */
Index: sys/sys/ttycom.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/ttycom.h,v
retrieving revision 1.20
diff -u -r1.20 ttycom.h
--- sys/sys/ttycom.h	10 May 2004 02:24:56 -0000	1.20
+++ sys/sys/ttycom.h	11 Jun 2004 12:33:44 -0000
_at__at_ -122,7 +122,7 _at__at_
 #define	TIOCCONS	_IOW('t', 98, int)	/* become virtual console */
 #define	TIOCSCTTY	 _IO('t', 97)		/* become controlling tty */
 						/* 97-90 tun; some conflicts */
-#define	TIOCEXT		_IOW('t', 96, int)	/* pty: external processing */
+/* WAS: #define	TIOCEXT	_IOW('t', 96, int)	   pty: external processing */
 #define	TIOCSIG		 _IO('t', 95)		/* pty: generate signal */
 #define	TIOCDRAIN	 _IO('t', 94)		/* wait till output drained */
 						/* 92-90 tap; some conflicts */
Index: usr.bin/mail/tty.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/mail/tty.c,v
retrieving revision 1.6
diff -u -r1.6 tty.c
--- usr.bin/mail/tty.c	30 Jun 2002 05:25:06 -0000	1.6
+++ usr.bin/mail/tty.c	11 Jun 2004 12:42:07 -0000
_at__at_ -74,9 +74,6 _at__at_
 #ifndef TIOCSTI
 	sig_t savequit;
 #else
-# ifdef TIOCEXT
-	int extproc, flag;
-# endif /* TIOCEXT */
 #endif /* TIOCSTI */
 
 	savetstp = signal(SIGTSTP, SIG_DFL);
_at__at_ -100,14 +97,6 _at__at_
 	if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
 		(void)signal(SIGQUIT, SIG_DFL);
 #else
-# ifdef		TIOCEXT
-	extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0);
-	if (extproc) {
-		flag = 0;
-		if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0)
-			warn("TIOCEXT: off");
-	}
-# endif	/* TIOCEXT */
 	if (setjmp(intjmp))
 		goto out;
 	saveint = signal(SIGINT, ttyint);
_at__at_ -154,13 +143,6 _at__at_
 		tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
 	(void)signal(SIGQUIT, savequit);
 #else
-# ifdef		TIOCEXT
-	if (extproc) {
-		flag = 1;
-		if (ioctl(fileno(stdin), TIOCEXT, &flag) < 0)
-			warn("TIOCEXT: on");
-	}
-# endif	/* TIOCEXT */
 #endif
 	(void)signal(SIGINT, saveint);
 	return (errs);

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk_at_FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
Received on Fri Jun 11 2004 - 13:41:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:56 UTC