--- icqgetty.h-is-new-	Sun Feb 11 04:47:53 2001
+++ icqgetty.h	Sun Feb 11 06:27:39 2001
@@ -0,0 +1,16 @@
+#ifndef ICQ_H
+#define ICQ_H 42
+
+#include "mytermio.h" 	    /* strange things happen with this */
+#define THISISICQGETTY 42
+#define ICQHOME "/home/icq" /* no '/' NEEDED at the end for mICQ */
+#define ICQUID 39           /* irc - should take this from passwd */
+#define ICQGID 65534        /* should take this from passwd */
+#define ICQBASEDIR "/tmp/icq/" /* should not be compiled it */
+#define ICQBINARY  "/usr/local/bin/micq" /* coz is not in gettys path */
+#define ICQRCNAME ".micqrc"
+#define ICQRCTEMPLATE "/tmp/icq/.micqrc" /* 123456789 is UIN placeholder */
+#define CONSOLE "/tmp/icq/icqgetty.log"  /* where to log if syslog not used */
+#define GDB_FRIENDLY	                 /* suppress SIGHUP */
+#define DEBUG 0777			 /* D_ALL is 0777 */
+#endif
--- tune.h-	Sun Feb  2 03:17:01 1997
+++ tune.h	Sun Feb 11 05:20:27 2001
@@ -17,6 +17,12 @@
 **	Any use of this software is at the user's own risk.
 */
 
+/* ********************************************************************* */
+
+#include "icqgetty.h"	/* INCLUDING THIS WILL MUTATE GETTY A BIT - ERIC */
+
+/* ********************************************************************* */
+
 #define	boolean	 int			/* does your cc know about boolean? */
 #define	DEF_CFL	 (CS8)			/* default word-len/parity */
 #define	DEF_CONNECT "CONNECT\\s\\A\r\n"	/* default CONNECT string */
@@ -36,6 +42,19 @@
 #define SYSLOG				/* log everything via syslog */
 
 /* compiling without DEBUG defined probably will not work */
+#ifdef THISISICQGETTY
+
+/* ********************************************************************* */
+
+#undef LOGUTMP
+#undef SYSLOG
+/* #undef FIDO */
+/* #undef WARNCASE */
+#undef SETTERM
+
+/* ********************************************************************* */
+
+#endif
 
 /*  define your ERASE and KILL characters here
  */
@@ -54,7 +73,9 @@
 /*  Where to find things
  */
 
+#ifndef CONSOLE
 #define	CONSOLE	 "/usr/adm/getty.log"	/* error log if not using syslog */
+#endif
 #ifndef FSSTND
 #define	DEFAULTS "/etc/default/%s"	/* name of defaults file */
 #else
--- funcs.c-	Sun Feb 11 04:41:50 2001
+++ funcs.c	Sun Feb 11 04:41:24 2001
@@ -226,20 +226,8 @@
 
 		/* set c_cc[] chars to reasonable values
 		 */
-#if defined __GLIBC__ && __GLIBC__ >= 2
-#ifdef _POSIX_VDISABLE
-#if _POSIX_VDISABLE != -1
-		for (i=0; i < NCC; i++)
-			setterm.c_cc[i] = _POSIX_VDISABLE;
-#else
-		for (i=0; i < NCC; i++)
-			setterm.c_cc[i] = 0;
-#endif
-#endif
-#else
 		for (i=0; i < NCC; i++)
 			setterm.c_cc[i] = CNUL;
-#endif
 		setterm.c_cc[VINTR] = Cintr;
 		setterm.c_cc[VQUIT] = CQUIT;
 		setterm.c_cc[VERASE] = Cerase;
@@ -468,11 +456,8 @@
 	register int expfail = EXPFAIL;
 	register retval = FAIL;
 	char ch, *p, word[MAXLINE+1], buf[MAXBUF];
-#if defined __GLIBC__ && __GLIBC__ >= 2
-	sig_t oldalarm = NULL;
-#else
 	sig_t (*oldalarm)() = NULL;
-#endif
+
 	if (strequal(s, "\"\"")) {	/* ("") used as a place holder */
 		debug(D_INIT, "EXPECT: ([nothing])");
 		return(SUCCESS);
@@ -577,12 +562,9 @@
 /*
 **	expalarm() - called when expect()'s SIGALRM goes off
 */
-#if defined __GLIBC__ && __GLIBC__ >= 2
-sig_t expalarm(int sig)
-#else
+
 sig_t
 expalarm()
-#endif
 {
 	longjmp(env, 1);
 }
@@ -604,6 +586,7 @@
 	register int count;
 	register int lower = 0;
 	register int upper = 0;
+
 	int tsynccount=0;
 	int yoohoocount=0;
 	char ch, *p;
@@ -735,6 +718,28 @@
 		termio->c_oflag |= OLCUC;
 		termio->c_lflag |= XCASE;
 	}
+
+
+#ifdef THISISICQGETTY
+
+/* ********************************************************** */
+
+	lower = 0;
+	for (p=name; *p; p++)
+	{ if (!isdigit(*p))
+	  { debug(D_RUN, "icq login name is not a number");
+	    return(NONAME);
+	  }
+	  lower++;
+	}
+	if (lower>9 || lower<6)
+	{ debug(D_RUN, "login name is too short or too long");
+	  return(NONAME);
+	}
+
+/* ********************************************************** */
+
+#endif
 
 	debug(D_RUN, "returned (SUCCESS), name=(%s)", name);
 	return(SUCCESS);
--- main.c-	Sun Feb 11 04:41:50 2001
+++ main.c	Sun Feb 11 06:41:49 2001
@@ -229,6 +229,14 @@
 #else
 	MyName =	"getty";
 #endif /* UUGETTY */
+#ifdef THISISICQGETTY
+	/* *********************************************************** */
+
+	MyName =	"ICQgetty";
+
+	/* *********************************************************** */
+
+#endif
 }
 
 
@@ -1006,6 +1014,19 @@
 	struct utmp	*utmp;
 	int		cbaud, i;
 	TERMIO		termio;
+#ifdef THISISICQGETTY
+
+/* *************************************************************** */
+
+	char * icqargs[2];
+	char * icqenv[2];
+	char icqrc[4096];
+	char * bufp;
+	int j;
+
+/* *************************************************************** */
+
+#endif	
 	
 
 	for(;;) {
@@ -1083,7 +1104,12 @@
 #ifdef SETTERM
 				setenv("TERM", term, TRUE);
 #endif /* SETTERM */
+#ifndef THISISICQGETTY
+
+/* ******************************************************************* */
+
 				debug(D_RUN, "execing login");
+
 #if defined __GLIBC__ && __GLIBC__ >= 2
 				(void) execl(loginprog, 
 				  "login", buf, (char *)NULL);
@@ -1109,6 +1135,134 @@
 				       strerror(errno));
 #endif
 				exit(FAIL);
+				
+/* ******************************************************************* */
+
+#endif
+#ifdef THISISICQGETTY
+
+/* **************************************************************** */
+
+/* buf has username (uin here) - set(e)uid, set(e)gid, chdir (0=ok),
+ * 1 directory per UIN, created on demand
+ * set env var HOME (mICQ needs no other env vars)
+ * ICQUID ICQGID ICQBASEDIR ICQBINARY ICQRCNAME ICQRCTEMPLATE 
+ *   are set in icqgetty.h
+ * set*id is done twice coz there are saved-ids
+ */
+	/* setgid first coz only root may do it in general! */
+	
+	if (setgroups(0,NULL))
+	{ debug(D_RUN, "setgroups for icq failed"); exit(FAIL); }
+	
+	if (setgid(ICQGID))
+	{ debug(D_RUN, "setgid for icq failed"); exit(FAIL); }
+	if (setegid(ICQGID))
+	{ debug(D_RUN, "setegid for icq failed"); exit(FAIL); }
+/*
+	if (seteuid(ICQUID))
+	{ debug(D_RUN, "seteuid for icq failed"); exit(FAIL); }
+*/
+	if (setuid(ICQUID))
+	{ debug(D_RUN, "setuid for icq failed"); exit(FAIL); }
+	
+	if (setgid(ICQGID))
+	{ debug(D_RUN, "setgid 2 for icq failed"); exit(FAIL); }
+	if (setegid(ICQGID))
+	{ debug(D_RUN, "setegid 2 for icq failed"); exit(FAIL); }
+	if (seteuid(ICQUID))
+	{ debug(D_RUN, "seteuid 2 for icq failed"); exit(FAIL); }
+	if (setuid(ICQUID))
+	{ debug(D_RUN, "setuid 2 for icq failed"); exit(FAIL); }
+	
+	icqargs[0] = strdup("icq"); /* NULL if malloc fails */
+	icqargs[1] = NULL;
+
+	i = strlen(ICQBASEDIR) + strlen(buf) + 16;
+	icqenv[0] = malloc(i);
+	if (icqenv[0] == NULL)
+	{ debug(D_RUN, "out of memory for icq environment");
+	  exit(FAIL);
+	};
+	icqenv[1] = NULL;
+	icqenv[0][0] = '\0';
+	j = snprintf(icqenv[0],i,"HOME=%s/%s/",ICQBASEDIR,buf);
+	if (j<0 || j>i) { exit(FAIL); /* should never happen */ }
+
+ 	if (chdir(ICQBASEDIR))
+ 	{ debug(D_RUN, "chdir icq base dir failed");
+ 	  exit(FAIL);
+ 	};
+ 	if ((i=mkdir(buf,448 /* 0700 */)))
+ 	{ if (errno != EEXIST)
+ 	  { debug(D_RUN, "per uin directory error");
+ 	    exit(FAIL);
+ 	  } else
+  	  { /* We this directory was not new */
+  	  }
+  	} else
+  	{  /* we have just created a new dir */
+  	  	/* looks like this is a new UIN so create .micqrc for it */
+		icqrc[0] = '\0';
+		j = snprintf(icqrc,4095,"%s",ICQRCTEMPLATE);
+		/* use snprintf so we know strlen */
+		/* strncpy does not terminate buffer if string is too long */
+		if (j<0 || j>4000) { exit(FAIL); /* should never happen */ }
+		i = open(icqrc,O_RDONLY);
+		if (i<0) 
+		{ debug(D_RUN, "could not open icqrc template");
+		  exit(FAIL);
+		}
+		j = read(i,icqrc,4095); /* keeping j for writing! */
+		if (j<200 || j>4000)
+		{ debug(D_RUN, "icqrc template is too big or too small");
+		  exit(FAIL);
+		};
+		close(i);
+		bufp = strstr(icqrc,"123456789");
+		if (bufp == NULL)
+		{ debug(D_RUN, "icqrc is missing 123456789 placeholder UIN");
+		  exit(FAIL);
+		}
+		for (i=0; i < (9-strlen(buf)); i++)
+		{ bufp[0] = ' '; /* or '0' -- padding */ 
+		  bufp++;
+		}
+		for (i=0; i<strlen(buf); i++)
+		{ bufp[i] = buf[i];
+		}
+	 	if (chdir(icqenv[0]+5 /* skip "HOME=" */))
+	  	{ debug(D_RUN, "chdir icq base dir failed");
+	 	  exit(FAIL);
+	 	};
+		i = open(ICQRCNAME,O_WRONLY|O_EXCL|O_CREAT, 384 /* 0600 */);
+		if (i<0) 
+		{ debug(D_RUN, "could not create new icqrc");
+		  printf("error creating file: %s\n",strerror(errno));
+		  exit(FAIL);
+		}
+		if (write(i,icqrc,j) != j)
+		{ debug(D_RUN, "error writing new icqrc");
+		  exit(FAIL);
+		}
+		close(i);
+	} /* creating new UIN directory and icqrc finished */
+ 
+ 	if (chdir(icqenv[0]+5 /* skip "HOME=" */))
+ 	{ debug(D_RUN, "chdir icq base dir failed");
+ 	  exit(FAIL);
+ 	};
+ 	debug(D_RUN, "execing micq");
+	(void) execve(ICQBINARY, icqargs, icqenv );
+
+	logerr("execve %s binary with arg %s and env %s failed",
+	       ICQBINARY, icqargs[0], icqenv[0] );
+
+				exit(FAIL);
+
+/* **************************************************************** */
+
+#endif
 
 			case BADSPEED:
 				GtabId = gtab->next_id;
