[Pkg-wmaker-commits] [wmbiff] 01/77: interactive password prompting support for imap - leave password in the : format blank to use

Doug Torrance dtorrance-guest at moszumanska.debian.org
Thu Aug 20 03:01:01 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to tag wmbiff_0_4_0
in repository wmbiff.

commit 12be48c3d92d25ff5459ca1ddc6a21ba38404271
Author: bluehal <bluehal>
Date:   Thu Apr 4 08:51:50 2002 +0000

    interactive password prompting support for imap - leave password in the : format blank to use
---
 wmbiff/Client.h        |  17 ++--
 wmbiff/Imap4Client.c   |  75 +++++++++++----
 wmbiff/Makefile        |   7 +-
 wmbiff/Pop3Client.c    |   8 +-
 wmbiff/passwordMgr.c   | 252 +++++++++++++++++++++++++++++++++++++++++++++++++
 wmbiff/passwordMgr.h   |   4 +
 wmbiff/sample.wmbiffrc |   9 +-
 wmbiff/test-make.sh    |  25 +++++
 8 files changed, 358 insertions(+), 39 deletions(-)

diff --git a/wmbiff/Client.h b/wmbiff/Client.h
index 231f7e2..f7f002d 100644
--- a/wmbiff/Client.h
+++ b/wmbiff/Client.h
@@ -1,4 +1,4 @@
-/* $Id: Client.h,v 1.12 2002/03/12 23:53:15 bluehal Exp $ */
+/* $Id: Client.h,v 1.13 2002/04/04 08:51:50 bluehal Exp $ */
 /* Author : Scott Holden ( scotth at thezone.net )
    Modified : Yong-iL Joh ( tolkien at mizi.com )
    Modified : Jorge Garc�a ( Jorge.Garcia at uv.es )
@@ -57,16 +57,9 @@ typedef struct _mbox_t {
 			int serverPort;
 			int localPort;
 			char authList[100];
-		} pop;
-		struct {
-			char password[32];
-			char userName[32];
-			char serverName[256];
-			int serverPort;
-			int localPort;
-			char authList[100];
-			unsigned int dossl:1;
-		} imap;
+			unsigned int dossl:1,	/* use tls. */
+			 interactive_password:1;	/* prompt the user if we can't login / password is empty */
+		} pop_imap;
 	} u;
 
 	FILE *(*open) (Pop3);
@@ -75,6 +68,8 @@ typedef struct _mbox_t {
 	time_t prevtime;
 	time_t prevfetch_time;
 	int loopinterval;			/* loop interval for this mailbox */
+
+	const char *askpass;		/* command to execute to get a password, if needed */
 } mbox_t;
 
 #define BUF_SIZE 1024
diff --git a/wmbiff/Imap4Client.c b/wmbiff/Imap4Client.c
index 4052d00..f6f42ec 100644
--- a/wmbiff/Imap4Client.c
+++ b/wmbiff/Imap4Client.c
@@ -13,6 +13,7 @@
 #include "Client.h"
 #include "charutil.h"
 #include "tlsComm.h"
+#include "passwordMgr.h"
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -24,7 +25,7 @@
 #include <dmalloc.h>
 #endif
 
-#define	PCU	(pc->u).imap
+#define	PCU	(pc->u).pop_imap
 
 #ifdef __LCLINT__
 void asprintf( /*@out@ */ char **out, char *fmt, ...);
@@ -42,6 +43,7 @@ static struct fdmap_struct {
 	/*@owned@ */ struct connection_state *cs;
 } fdmap[FDMAP_SIZE];
 
+static void ask_user_for_password(Pop3 pc, int bFlushCache);
 
 /* authentication callbacks */
 #ifdef WITH_GCRYPT
@@ -75,8 +77,8 @@ static struct connection_state *state_for_pcu(Pop3 pc)
 	char *connection_id;
 	struct connection_state *retval = NULL;
 	int i;
-	asprintf(&connection_id, "%s|%s|%s|%d", PCU.userName,
-			 PCU.password, PCU.serverName, PCU.serverPort);
+	asprintf(&connection_id, "%s|%s|%d", PCU.userName,
+			 PCU.serverName, PCU.serverPort);
 	for (i = 0; i < FDMAP_SIZE; i++)
 		if (fdmap[i].user_password_server_port != NULL &&
 			(strcmp(connection_id,
@@ -96,8 +98,8 @@ static void bind_state_to_pcu(Pop3 pc,
 	if (scs == NULL) {
 		abort();
 	}
-	asprintf(&connection_id, "%s|%s|%s|%d", PCU.userName,
-			 PCU.password, PCU.serverName, PCU.serverPort);
+	asprintf(&connection_id, "%s|%s|%d", PCU.userName,
+			 PCU.serverName, PCU.serverPort);
 	for (i = 0; i < FDMAP_SIZE && fdmap[i].cs != NULL; i++);
 	if (i == FDMAP_SIZE) {
 		/* should never happen */
@@ -258,6 +260,8 @@ int imap_checkmail(Pop3 pc)
 
 	/* if it's not in the cache, try to open */
 	if (scs == NULL) {
+		IMAP_DM(pc, DEBUG_INFO, "Need new connection to %s@%s\n",
+				PCU.userName, PCU.serverName);
 		(void) pc->open(pc);
 		scs = state_for_pcu(pc);
 	}
@@ -290,7 +294,7 @@ int imap4Create(Pop3 pc, const char *const str)
 	struct re_registers regs;
 	int i, matchedchars;
 	const char *regexes[] = {
-		".*imaps?:([^: ]{1,32}):([^@]{1,32})@([^/: ]+)(/[^: ]+)?(:[0-9]+)? *",
+		".*imaps?:([^: ]{1,32}):([^@]{0,32})@([^/: ]+)(/[^: ]+)?(:[0-9]+)? *",
 		".*imaps?:([^: ]{1,32}) ([^ ]{1,32}) ([^/: ]+)(/[^: ]+)?( [0-9]+)? *",
 		NULL
 	};
@@ -334,6 +338,8 @@ int imap4Create(Pop3 pc, const char *const str)
 	/* copy matches where they belong */
 	copy_substring(PCU.userName, regs.start[1], regs.end[1], str);
 	copy_substring(PCU.password, regs.start[2], regs.end[2], str);
+	if (PCU.password[0] == '\0')
+		PCU.interactive_password = 1;
 	copy_substring(PCU.serverName, regs.start[3], regs.end[3], str);
 	if (regs.start[4] != -1)
 		copy_substring(pc->path, regs.start[4] + 1, regs.end[4], str);
@@ -378,20 +384,31 @@ static int authenticate_plaintext(Pop3 pc,
 		goto plaintext_failed;
 	}
 
-	/* login */
-	tlscomm_printf(scs, "a001 LOGIN %s \"%s\"\r\n", PCU.userName,
-				   PCU.password);
-	if (!tlscomm_expect(scs, "a001 ", buf, BUF_SIZE)) {
-		IMAP_DM(pc, DEBUG_ERROR,
-				"Did not get a response to the LOGIN command.\n");
-		goto plaintext_failed;
-	}
+	ask_user_for_password(pc, 0);
+	do {
+		/* login */
+		tlscomm_printf(scs, "a001 LOGIN %s \"%s\"\r\n", PCU.userName,
+					   PCU.password);
+		if (!tlscomm_expect(scs, "a001 ", buf, BUF_SIZE)) {
+			IMAP_DM(pc, DEBUG_ERROR,
+					"Did not get a response to the LOGIN command.\n");
+			goto plaintext_failed;
+		}
+
+		if (buf[5] != 'O') {
+			IMAP_DM(pc, DEBUG_ERROR, "IMAP Login failed.\n");
+			/* if we're prompting the user, ask again, else fail */
+			if (PCU.interactive_password) {
+				PCU.password[0] = '\0';
+				ask_user_for_password(pc, 1);	/* 1=overwrite the cache */
+			} else {
+				goto plaintext_failed;
+			}
+		} else {
+			return (1);
+		}
+	} while (1);
 
-	if (buf[5] != 'O') {
-		IMAP_DM(pc, DEBUG_ERROR, "IMAP Login failed.\n");
-		goto plaintext_failed;
-	}
-	return (1);
   plaintext_failed:
 	return (0);
 }
@@ -420,6 +437,7 @@ static int authenticate_md5(Pop3 pc,
 
 	strcpy(buf, PCU.userName);
 	strcat(buf, " ");
+	ask_user_for_password(pc, 0);
 	gmh = gcry_md_open(GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
 	gcry_md_setkey(gmh, PCU.password, strlen(PCU.password));
 	gcry_md_write(gmh, (unsigned char *) buf2, strlen(buf2));
@@ -452,3 +470,22 @@ static int authenticate_md5(Pop3 pc,
 	return 0;
 }
 #endif
+
+static void ask_user_for_password(Pop3 pc, int bFlushCache)
+{
+	/* see if we already have a password, as provided in the config file, or
+	   already requested from the user. */
+	if (PCU.interactive_password) {
+		if (strlen(PCU.password) == 0) {
+			/* we need to grab the password from the user. */
+			const char *password;
+			IMAP_DM(pc, DEBUG_INFO, "asking for password %d\n",
+					bFlushCache);
+			password =
+				passwordFor(PCU.userName, PCU.serverName, pc, bFlushCache);
+			if (password != NULL) {
+				strcpy(PCU.password, password);
+			}
+		}
+	}
+}
diff --git a/wmbiff/Makefile b/wmbiff/Makefile
index 4ef3c27..ea5f600 100644
--- a/wmbiff/Makefile
+++ b/wmbiff/Makefile
@@ -1,6 +1,6 @@
 # Makefile for wmbiff
 #
-# $Id: Makefile,v 1.28 2002/03/26 16:30:32 jordi Exp $
+# $Id: Makefile,v 1.29 2002/04/04 08:51:50 bluehal Exp $
 
 # Disable gnutls crypto?
 #WITHOUT_CRYPTO=	1
@@ -24,7 +24,7 @@ CFLAGS?=	-O2 -Wall -Wpointer-arith
 # Nothing below here should need to be changed
 ###########################################################
 
-WMBIFF_VERSION=	"0.3.8"
+WMBIFF_VERSION=	"0.4.0pre1"
 EXTRAFLAGS=	-DWMBIFF_VERSION='$(WMBIFF_VERSION)' 
 
 # Default linux owners
@@ -74,7 +74,7 @@ INSTALL_FILE?=	$(INSTALL) -p -o $(INSTALL_USER) -g $(INSTALL_GROUP) -m 644
 OBJS =	wmbiff.o socket.o \
 	Pop3Client.o LicqClient.o mboxClient.o \
 	maildirClient.o Imap4Client.o tlsComm.o \
-	ShellClient.o \
+	ShellClient.o passwordMgr.o\
 	../wmgeneral/wmgeneral.o \
 	../wmgeneral/misc.o \
 	../wmgeneral/list.o \
@@ -84,6 +84,7 @@ all: wmbiff
 
 Imap4Client.o: Imap4Client.c Client.h Makefile
 Pop3Client.o: Pop3Client.c Client.h Makefile
+passwordMgr.o: passwordMgr.c passwordMgr.h Client.h Makefile
 wmbiff.o: wmbiff-master.xpm wmbiff.c Client.h
 
 .c.o:
diff --git a/wmbiff/Pop3Client.c b/wmbiff/Pop3Client.c
index 0508c82..edab0dd 100644
--- a/wmbiff/Pop3Client.c
+++ b/wmbiff/Pop3Client.c
@@ -1,4 +1,4 @@
-/* $Id: Pop3Client.c,v 1.9 2002/03/12 23:53:15 bluehal Exp $ */
+/* $Id: Pop3Client.c,v 1.10 2002/04/04 08:51:50 bluehal Exp $ */
 /* Author : Scott Holden ( scotth at thezone.net )
    Modified : Yong-iL Joh ( tolkien at mizi.com )
    Modified : Jorge Garc�a ( Jorge.Garcia at uv.es )
@@ -18,7 +18,7 @@
 #include <dmalloc.h>
 #endif
 
-#define	PCU	(pc->u).pop
+#define	PCU	(pc->u).pop_imap
 #define POP_DM(pc, lvl, args...) DM(pc, lvl, "pop3: " args)
 
 #ifdef WITH_GCRYPT
@@ -162,7 +162,7 @@ int pop3Create(Pop3 pc, const char *str)
 	 */
 	const char *regexes[] = {
 		"pop3:([^: ]{1,32}) ([^ ]{1,32}) ([^: ]+)( [0-9]+)? *",
-		"pop3:([^: ]{1,32}):([^@]{1,32})@([^: ]+)(:[0-9]+)? *",
+		"pop3:([^: ]{1,32}):([^@]{0,32})@([^: ]+)(:[0-9]+)? *",
 		NULL
 	};
 
@@ -276,8 +276,6 @@ static FILE *authenticate_apop(Pop3 pc, FILE * fp, char *apop_str)
 		/* server doesn't support apop. */
 		return (NULL);
 	}
-	POP_DM(pc, DEBUG_INFO, "APOP challenge: %s\n", apop_str);
-	strcat(apop_str, PCU.password);
 
 	gmh = gcry_md_open(GCRY_MD_MD5, 0);
 	gcry_md_write(gmh, (unsigned char *) apop_str, strlen(apop_str));
diff --git a/wmbiff/passwordMgr.c b/wmbiff/passwordMgr.c
new file mode 100644
index 0000000..d4c8357
--- /dev/null
+++ b/wmbiff/passwordMgr.c
@@ -0,0 +1,252 @@
+/* passwordMgr.c 
+ * Author: Neil Spring 
+ */
+/* this module implements a password cache: the goal is to
+   allow multiple wmbiff mailboxes that are otherwise
+   independent get all their passwords while only asking the
+   user for an account's password once. */
+/* NOTE: it will fail if a user has different passwords for
+   pop vs. imap on the same server; this seems too far
+   fetched to be worth complexity */
+
+/* NOTE: it verifies that the askpass program, which, if
+   given with a full path, must be owned either by the user
+   or by root.  There may be decent reasons not to do
+   this. */
+
+/* Intended properties: 1) exit()s if the user presses
+   cancel from askpass - this is detected by no output from
+   askpass.  2) allows the caller to remove a cached entry
+   if it turns out to be wrong, and prompt the user
+   again. This might be poor if the askpass program is
+   replaced with something non-interactive. */
+
+#include "passwordMgr.h"
+#include "Client.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+typedef struct password_binding_struct {
+	struct password_binding_struct *next;
+	char user[32];
+	char server[255];
+	char password[32];
+} *password_binding;
+
+password_binding pass_list = NULL;
+
+/* verifies that askpass_fname, if it has no spaces, exists as 
+   a file, is owned by the user or by root, and is not world 
+   writeable.   This is just a sanity check, and is not intended 
+   to ensure the integrity of the password-asking program. */
+static int permissions_ok(Pop3 pc, const char *askpass_fname)
+{
+	struct stat st;
+	if (index(askpass_fname, ' ')) {
+		DM(pc, DEBUG_ERROR,
+		   "askpass has a space in it; not verifying ownership/permissions on '%s'\n",
+		   askpass_fname);
+		return (1);
+	}
+	if (stat(askpass_fname, &st)) {
+		DM(pc, DEBUG_ERROR, "Can't stat askpass program: '%s'\n",
+		   askpass_fname);
+		DM(pc, DEBUG_ERROR, "For your own good, use a full pathname.\n");
+		return (0);
+	}
+	if (st.st_uid != 0 && st.st_uid != getuid()) {
+		DM(pc, DEBUG_ERROR,
+		   "askpass program isn't owned by you or root: '%s'\n",
+		   askpass_fname);
+		return (0);
+	}
+	if (st.st_mode & S_IWOTH) {
+		DM(pc, DEBUG_ERROR,
+		   "askpass program is world writable: '%s'\n", askpass_fname);
+		return (0);
+	}
+	return (1);
+}
+
+const char *passwordFor(const char *username,
+						const char *servername, Pop3 pc, int bFlushCache)
+{
+
+	password_binding p;
+
+	/* find the binding */
+	for (p = pass_list;
+		 p != NULL
+		 && (strcmp(username, p->user) != 0 ||
+			 strcmp(servername, p->server) != 0); p = p->next);
+
+	/* if so, return the password */
+	if (p != NULL) {
+		if (p->password[0] != '\0') {
+			if (bFlushCache == 0)
+				return (p->password);
+			/* else fall through, overwrite */
+		} else if (pc) {
+			/* if we've asked, but received nothing, disable this box */
+			pc->open = NULL;
+			pc->checkMail = NULL;
+			return (NULL);
+		}
+	} else {
+		p = (password_binding)
+			malloc(sizeof(struct password_binding_struct));
+	}
+
+	/* else, try to get it. */
+	if (pc->askpass != NULL) {
+		/* check that the executed file is a good one. */
+		if (permissions_ok(pc, pc->askpass)) {
+			char buf[255];
+			FILE *fp;
+			int l;
+			int exit_status;
+			strcpy(p->user, username);
+			strcpy(p->server, servername);
+			sprintf(buf, "%s 'password for wmbiff: %s@%s'",
+					pc->askpass, username, servername);
+
+			DM(pc, DEBUG_INFO, "passmgr: invoking %s\n", buf);
+			fp = popen(buf, "r");
+
+			if (fgets(p->password, 32, fp) == NULL) {
+				/* this likely means that the user cancelled, and doesn't
+				   want us to keep asking about the password. */
+				DM(pc, DEBUG_ERROR,
+				   "passmgr: fgets password failed, exiting\n");
+				DM(pc, DEBUG_ERROR,
+				   "passmgr: (it looks like you pressed 'cancel')\n");
+				/* this seems like the sanest thing to do, for now */
+				exit(EXIT_FAILURE);
+			}
+
+			exit_status = pclose(fp);
+			if (exit_status != 0) {
+				if (exit_status == -1) {
+					/* an expected case with the signal handler */
+					DM(pc, DEBUG_INFO,
+					   "passmgr: pclose from '%s' failed: %s\n", buf,
+					   strerror(errno));
+				} else {
+					DM(pc, DEBUG_ERROR,
+					   "passmgr: '%s' returne non-zero exit status %d\n",
+					   buf, exit_status);
+				}
+			}
+
+			/* chomp; */
+			l = strlen(p->password) - 1;
+			if (p->password[l] == '\n')
+				p->password[l] = '\0';
+			p->next = pass_list;
+			pass_list = p;
+			return (p->password);
+		}
+	}
+
+	return (NULL);
+}
+
+#ifdef TEST_PASS_MGR
+int main(int argc, char *argv[])
+{
+	const char *b;
+	mbox_t m;
+
+	/* sh is almost certainly conforming; owned by root, etc. */
+	if (!permissions_ok(NULL, "/bin/sh")) {
+		printf("FAILURE: permission checker failed on /bin/sh.");
+		exit(EXIT_FAILURE);
+	}
+	/* tmp is definitely bad; and better be og+w */
+	if (permissions_ok(NULL, "/tmp")) {
+		printf("FAILURE: permission checker failed on /tmp.");
+		exit(EXIT_FAILURE);
+	}
+	/* TODO: also find some user-owned binary that shouldn't be g+w */
+	printf("SUCCESS: permission checker sanity check went well.\n");
+
+	/* *** */
+	m.askpass = "echo xlnt; #";
+
+	b = passwordFor("bill", "ted", &m, 0);
+	if (strcmp(b, "xlnt") != 0) {
+		printf("FAILURE: expected 'xlnt' got '%s'\n", b);
+		exit(EXIT_FAILURE);
+	}
+	printf("SUCCESS: expected 'xlnt' got '%s'\n", b);
+
+	/* *** */
+	m.askpass = "should be cached";
+	b = passwordFor("bill", "ted", &m, 0);
+	if (strcmp(b, "xlnt") != 0) {
+		printf("FAILURE: expected 'xlnt' got '%s'\n", b);
+		exit(EXIT_FAILURE);
+	}
+
+	printf("SUCCESS: cached 'xlnt' correctly\n");
+
+	/* *** */
+	m.askpass = "echo abcdefghi1abcdefghi2abcdefghi3a; #";
+
+	b = passwordFor("abbot", "costello", &m, 0);
+	if (strcmp(b, "abcdefghi1abcdefghi2abcdefghi3a") != 0) {
+		printf
+			("FAILURE: expected 'abcdefghi1abcdefghi2abcdefghi3a' got '%s'\n",
+			 b);
+		exit(EXIT_FAILURE);
+	}
+	printf
+		("SUCCESS: expected 'abcdefghi1abcdefghi2abcdefghi3ab' got '%s'\n",
+		 b);
+
+	/* try overflowing the buffer */
+	m.askpass = "echo abcdefghi1abcdefghi2abcdefghi3ab; #";
+	b = passwordFor("laverne", "shirley", &m, 0);
+	/* should come back truncated to fill the buffer */
+	if (strcmp(b, "abcdefghi1abcdefghi2abcdefghi3a") != 0) {
+		printf
+			("FAILURE: expected 'abcdefghi1abcdefghi2abcdefghi3a' got '%s'\n",
+			 b);
+		exit(EXIT_FAILURE);
+	}
+	printf
+		("SUCCESS: expected 'abcdefghi1abcdefghi2abcdefghi3ab' got '%s'\n",
+		 b);
+
+	/* make sure we still have the old one */
+	b = passwordFor("bill", "ted", &m, 0);
+	if (strcmp(b, "xlnt") != 0) {
+		printf("FAILURE: expected 'xlnt' got '%s'\n", b);
+		exit(EXIT_FAILURE);
+	}
+	printf("SUCCESS: expected 'xlnt' got '%s'\n", b);
+
+	/* what it's like if ssh-askpass is cancelled - should drop the mailbox */
+	m.askpass = "echo -n ; #";
+	b = passwordFor("abort", "me", &m, 0);
+	if (strcmp(b, "") != 0) {
+		printf("FAILURE: expected '' got '%s'\n", b);
+		exit(EXIT_FAILURE);
+	}
+	printf("SUCCESS: expected '' got '%s'\n", b);
+
+	/* what it's like if ssh-askpass is ok'd with an empty password. */
+	m.askpass = "echo ; #";
+	b = passwordFor("try", "again", &m, 0);
+	if (strcmp(b, "") != 0) {
+		printf("FAILURE: expected '' got '%s'\n", b);
+		exit(EXIT_FAILURE);
+	}
+	printf("SUCCESS: expected '' got '%s'\n", b);
+
+	exit(EXIT_SUCCESS);
+}
+#endif
diff --git a/wmbiff/passwordMgr.h b/wmbiff/passwordMgr.h
new file mode 100644
index 0000000..11d0621
--- /dev/null
+++ b/wmbiff/passwordMgr.h
@@ -0,0 +1,4 @@
+#include "Client.h"
+
+const char *passwordFor(const char *username,
+						const char *servername, Pop3 pc, int bFlushCache);
diff --git a/wmbiff/sample.wmbiffrc b/wmbiff/sample.wmbiffrc
index 660456b..c59cd82 100644
--- a/wmbiff/sample.wmbiffrc
+++ b/wmbiff/sample.wmbiffrc
@@ -1,10 +1,17 @@
-# $Id: sample.wmbiffrc,v 1.8 2002/03/06 07:15:08 bluehal Exp $
+# $Id: sample.wmbiffrc,v 1.9 2002/04/04 08:51:50 bluehal Exp $
 #
 # See wmbiffrc(5) for more info.
 #
 # Global interval -- seconds between check mailboxes
 interval=60
 
+# Global askpass -- choose a password acting program
+# that behaves like ssh-askpass
+# the commented version below is likely to work on RedHat 
+# systems; wmbiff's default is likely to work on Debian
+# systems with ssh-askpass installed.
+#askpass = /usr/libexec/openssh/x11-ssh-askpass
+
 ### First string ###
 
 # Label, that will be displayed
diff --git a/wmbiff/test-make.sh b/wmbiff/test-make.sh
new file mode 100755
index 0000000..6ab3686
--- /dev/null
+++ b/wmbiff/test-make.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# a short script to make sure that wmbiff builds under various
+# options.  this is not necessary for normal users, and is 
+# intended as a last-minute sanity check before a release.
+echo NO-CRYPTO BUILD
+make clean
+WITHOUT_CRYPTO=1 make 
+
+echo NORMAL BUILD
+make clean
+make 
+
+echo DEBUG BUILD
+make clean
+DEBUG=1 make 
+
+# doesn't really work on non -bsd
+if test `uname` != 'Linux'; then
+ echo LIKE BSD 
+ make clean
+ EXT_GNU_REGEX_LIB=1 make
+fi
+
+# like I said... before a release.
+make clean

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmbiff.git



More information about the Pkg-wmaker-commits mailing list