Subject: bin/32964: mail(1): implement the unalias command
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Johan Veenhuizen <veenhuizen@users.sourceforge.net>
List: netbsd-bugs
Date: 03/02/2006 01:05:01
>Number:         32964
>Category:       bin
>Synopsis:       mail(1): implement the unalias command
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 02 01:05:00 +0000 2006
>Originator:     Johan Veenhuizen
>Release:        NetBSD 3.0
>Organization:
	
>Environment:
	
	
System: NetBSD carola.zapto.org 3.0 NetBSD 3.0 (CAROLA) #1: Tue Feb 28 12:46:17 CET 2006 jpv@carola.zapto.org:/usr/src/sys/arch/i386/compile/CAROLA i386
Architecture: i386
Machine: i386
>Description:
	mail(1) does not implement the unalias command
	although it is documented in the man page.
>How-To-Repeat:
	
>Fix:
	Apply this patch:

Index: cmd3.c
===================================================================
RCS file: /cvsroot/src/usr.bin/mail/cmd3.c,v
retrieving revision 1.27
diff -u -r1.27 cmd3.c
--- cmd3.c	19 Jul 2005 23:07:10 -0000	1.27
+++ cmd3.c	2 Mar 2006 00:40:46 -0000
@@ -46,6 +46,7 @@
  *
  * Still more user commands.
  */
+static int delgroup(const char *);
 static int diction(const void *, const void *);
 
 /*
@@ -504,6 +505,53 @@
 }
 
 /*
+ * The unalias command takes a list of alises
+ * and discards the remembered groups of users.
+ */
+int
+unalias(void *v)
+{
+	char **argv = v;
+	char **ap;
+
+	for (ap = argv; *ap != NULL; ap++)
+		if (delgroup(*ap) == -1)
+			(void)printf("No such alias: \"%s\"\n", *ap);
+	return 0;
+}
+
+/*
+ * Delete the named group alias. Return zero if the group was
+ * successfully deleted, or -1 if there was no such group.
+ */
+static int
+delgroup(const char *name)
+{
+	struct grouphead *gh, *p;
+	struct group *g;
+	int h;
+
+	h = hash(name);
+	for (gh = groups[h], p = NULL; gh != NULL; p = gh, gh = gh->g_link)
+		if (strcmp(gh->g_name, name) == 0) {
+			if (p == NULL)
+				groups[h] = gh->g_link;
+			else
+				p->g_link = gh->g_link;
+			while (gh->g_list != NULL) {
+				g = gh->g_list;
+				gh->g_list = g->ge_link;
+				free(g->ge_name);
+				free(g);
+			}
+			free(gh->g_name);
+			free(gh);
+			return 0;
+		}
+	return -1;
+}
+
+/*
  * Sort the passed string vecotor into ascending dictionary
  * order.
  */
Index: cmdtab.c
===================================================================
RCS file: /cvsroot/src/usr.bin/mail/cmdtab.c,v
retrieving revision 1.10
diff -u -r1.10 cmdtab.c
--- cmdtab.c	7 Aug 2003 11:14:36 -0000	1.10
+++ cmdtab.c	2 Mar 2006 00:40:46 -0000
@@ -69,6 +69,7 @@
 	{ "page",	more,		MSGLIST,	0,	MMNDEL },
 	{ "More",	More,		MSGLIST,	0,	MMNDEL },
 	{ "Page",	More,		MSGLIST,	0,	MMNDEL },
+	{ "unalias",	unalias,	M|RAWLIST,	1,	1000 },
 	{ "unread",	unread,		MSGLIST,	0,	MMNDEL },
 	{ "!",		shell,		I|STRLIST,	0,	0 },
 	{ "copy",	copycmd,	M|STRLIST,	0,	0 },
Index: extern.h
===================================================================
RCS file: /cvsroot/src/usr.bin/mail/extern.h,v
retrieving revision 1.22
diff -u -r1.22 extern.h
--- extern.h	5 Jan 2006 02:13:41 -0000	1.22
+++ extern.h	2 Mar 2006 00:40:46 -0000
@@ -148,6 +148,7 @@
 void	 holdsigs(void);
 int	 ifcmd(void *);
 int	 igfield(void *);
+int	 unalias(void *);
 struct ignoretab;
 int	 ignore1(char *[], struct ignoretab *, const char *);
 int	 igshow(struct ignoretab *, const char *);

>Unformatted: