From: seth@ctr.columbia.edu (Seth Robertson)
Subject: Finger enhancements (to 1.37)
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sun, 8 Nov 1992 17:50:43 GMT

Here are some hacks I have found useful:

MOTD -- Prepend a file on non-specific requests
SHORT -- Unless specifically asked, only output one line per user

Also, I included three utility programs which I hacked off a few years
ago for finger 1.10 They can be used to clean up the userdata file
(get rid of deleted users, etc) or to print a list of users sorted
in the order of last login.

If you have any questions, let me know.


                                        -Seth Robertson
                                         seth@ctr.columbia.edu

--- ./.orig/src/in.fingerd.c	Mon Oct 26 22:14:19 1992
+++ ./src/in.fingerd.c	Sun Nov  8 22:08:09 1992
@@ -18,7 +18,20 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+/*
 
+The following changes have been made:
+
+MOTD -- if defined, this should contain the name of the file which
+        contains information which should be prepended to non-specific
+	finger requests
+
+SHORT -- If defined, by default, you only get one line per user
+	 (with that line being the line with the least idle time)
+
+*/
+
+
 #include <stdio.h>
 #include <config.h>
 
@@ -325,6 +338,9 @@
 {
   register int i, f, len;
   int match_free, match_all;
+#ifdef SHORT
+  int match_full_all, SaveUser = 0;
+#endif /*SHORT*/
   int packets_output, face;
   FINGER_PACKET **hpackets, **upackets;
   CLIENT **get_clients ();
@@ -394,7 +410,13 @@
     }
 
   match_free = (xstricmp (user, ".free") == 0);
+
+#ifdef SHORT
+  match_full_all = (xstricmp (user, ".all") == 0);
+  match_all = (match_full_all || !*user);
+#else /*SHORT*/
   match_all = ((xstricmp (user, ".all") == 0) || !*user);
+#endif /*SHORT*/
 
   /* ".users" returns a listing of everyone in the userdata file. */
   if (xstricmp (user, ".users") == 0)
@@ -608,6 +630,21 @@
 	}
 	return;
       }
+
+
+#ifdef MOTD
+  {
+    FILE *fin = fopen(MOTD,"r");
+    char buf[128];
+
+    if (fin)			/* Error if we cannot find it? */
+      {
+	while (fgets(buf,128,fin))
+	  fputs(buf,stdout);
+	close(fin);
+      }
+  }
+#endif /*MOTD*/
   
   warn_if_not_recent (HOSTDATA, stream);
 
@@ -633,6 +670,29 @@
 
   for (i = 0; hpackets[i]; i++)
     {
+#ifdef SHORT
+      if (match_all && !match_full_all && !all_users)
+        {
+	  /* We are searching for the record with the least amount of idle time */
+
+	  /* If the name was the same as it was last time... */
+	  if (xstricmp(hpackets[SaveUser]->name,hpackets[i]->name) == 0)
+	    {
+	      /* and the idle time we had down previously was longer */
+	      if (hpackets[SaveUser]->idle_time > hpackets[i]->idle_time)
+		{               /* Then keep the new idle time */
+		  SaveUser = i;
+		}
+	    }
+	  else                  /* Otherwise we want to print the record we found */
+	    {
+	      ascii_packet (hpackets[SaveUser], stream, packets_output == 0);
+	      packets_output++;
+	      SaveUser = i;
+	    }
+	}
+      else
+#endif /*SHORT*/
       if (match_all || (xstricmp (user, hpackets[i]->name) == 0))
 	{
 	  ascii_packet (hpackets[i], stream, packets_output == 0);
@@ -639,6 +699,15 @@
 	  packets_output++;
 	}
     }
+
+#ifdef SHORT
+  /* Make sure the last record is printed */
+  if (match_all && !all_users && hpackets[SaveUser] )
+    {
+      ascii_packet (hpackets[SaveUser], stream, packets_output == 0);
+      packets_output++;
+    }
+#endif /*SHORT*/
 
   /* If no packets were output, and the caller wanted to match everybody,
      sorry, there is no one logged in anywhere that we know of.  But if the
--- /dev/null	Sun Nov  8 15:19:27 1992
+++ ./src/read_userdata.c	Sun Nov  8 22:29:29 1992
@@ -0,0 +1,38 @@
+/* Reads the userdata file in from standard in and outputs a
+ * list of last login times and user names.
+ *
+ * This is so that you can get a sorted list of when everyone
+ * last logged in
+ *
+ * Use it like:  read_userdata < /foo/userdata | sort -rn | user-to-time > /tmp/list
+ */
+
+#include <stdio.h>
+
+#include <general.h>
+#include <client.h>
+#include <getservhost.h>
+#include <packet.h>
+
+main()
+{
+  FINGER_PACKET check;
+  long current = (long)time ((long *)NULL);
+
+  while (fread(&check,sizeof(check),1,stdin))
+    {
+      if (!getpwnam(check.name))
+	{
+	  fprintf(stderr,"Deleting %s\n",check.name);
+	  continue;
+	}
+
+      if (check.login_time > current)
+	{
+	  fprintf(stderr,"%s was in the future\n",check.name);
+	  check.login_time = 31536000; /* Magic number that I hopefully will remember */
+	}
+
+      printf("%d %-8.8s\n",check.login_time,check.name);
+    }
+}
--- /dev/null	Sun Nov  8 15:19:27 1992
+++ ./src/reset_userdata.c	Sun Nov  8 22:29:30 1992
@@ -0,0 +1,39 @@
+/*
+** This routine takes the userdata file as standard in and
+** if the user does not exist any more, delete's him, otherwise
+** if the user's login time is from the future, it changes
+** the login time to a magic date that I'll never remember.
+**
+** Sometime you get alot of these in your database and you
+** need to clear them out.
+*/
+
+#include <stdio.h>
+
+#include <general.h>
+#include <client.h>
+#include <getservhost.h>
+#include <packet.h>
+
+main()
+{
+  FINGER_PACKET check;
+  long current = (long)time ((long *)NULL);
+
+  while (fread(&check,sizeof(check),1,stdin))
+    {
+      if (!getpwnam(check.name))
+	{
+	  fprintf(stderr,"Deleting %s\n",check.name);
+	  continue;
+	}
+
+      if (check.login_time > current)
+	{
+	  fprintf(stderr,"%s was in the future\n",check.name);
+	  check.login_time = 31536000; /* Magic number that I hopefully will remember */
+	}
+
+      fwrite(&check,sizeof(check),1,stdout);
+    }
+}
--- /dev/null	Sun Nov  8 15:19:27 1992
+++ ./src/user-to-time.c	Sun Nov  8 22:29:30 1992
@@ -0,0 +1,20 @@
+/* This converts the dates generated by read_userdata to an ASCII format
+ *
+ * Use it like:  read_userdata < /foo/userdata | sort -rn | user-to-time > /tmp/list
+ */
+
+#include <stdio.h>
+
+main()
+{
+  char buf[80];
+  unsigned long ltime;
+  char name[80];
+
+  while (fgets(buf,80,stdin))
+    {
+      sscanf(buf,"%lu %8c",&ltime,name);
+
+      printf("%8s  %s",name,ctime(&ltime));
+    }
+}

Newsgroups: gnu.gcc.bug