> First a quick review of the new features added to the 5.4.18 release:
> 
> o The option of running a script each time a user or domain is added,
> deleted or modified.  This can be used for sending notification
> messages, maintaining a list of valid users and what ever else you may
> need to do.  See README.onchange
> 
> o Complete alias handling.  With this version you can add an address to
> an alias, delete an address from an alias, delete an entire alias, or
> delete all aliases from a domain.  That pretty much takes care of all
> the possibilities for unordered aliases.  Full support is available in
> cdb and MySQL back ends.  The MySQL code can be used as a template for
> other back ends.
> 

Attached is a patch for 5.4.18 to enable alias line removal from .qmail 
based aliases and the implementation of alias line removal using the 
valias command line program.

Am I meant to be posting patches here (such as my previous double free 
problem in vpalias.c) or to another list ?
diff -uPr vpopmail-5.4.18.orig/configure vpopmail-5.4.18/configure
--- vpopmail-5.4.18.orig/configure      2006-12-31 04:41:21.000000000 +0000
+++ vpopmail-5.4.18/configure   2007-01-05 09:21:29.000000000 +0000
@@ -6620,19 +6620,19 @@
   1*|y*|Y*)
         echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
-        if test "$USE_SQL" != 1
-        then
-                { { echo "$as_me:$LINENO: error: valias option is only 
supported in the SQL authentication modules" >&5
-echo "$as_me: error: valias option is only supported in the SQL authentication 
modules" >&2;}
-   { (exit 1); exit 1; }; }
-        else
+#        if test "$USE_SQL" != 1
+#        then
+#                { { echo "$as_me:$LINENO: error: valias option is only 
supported in the SQL authentication modules" >&5
+#echo "$as_me: error: valias option is only supported in the SQL 
authentication modules" >&2;}
+#   { (exit 1); exit 1; }; }
+#        else
                 VALIAS=1
 
 cat >>confdefs.h <<_ACEOF
 #define VALIAS $VALIAS
 _ACEOF
 
-        fi
+#        fi
         ;;
   *)
         echo "$as_me:$LINENO: result: no" >&5
diff -uPr vpopmail-5.4.18.orig/valias.c vpopmail-5.4.18/valias.c
--- vpopmail-5.4.18.orig/valias.c       2006-12-19 21:02:47.000000000 +0000
+++ vpopmail-5.4.18/valias.c    2007-01-05 09:21:29.000000000 +0000
@@ -37,8 +37,9 @@
 
 #define VALIAS_SELECT 0
 #define VALIAS_INSERT 1
-#define VALIAS_DELETE 2
-#define VALIAS_NAMES  3
+#define VALIAS_REMOVE 2
+#define VALIAS_DELETE 3
+#define VALIAS_NAMES  4
 
 int AliasAction;
 int AliasExists;
@@ -116,6 +117,23 @@
                }
                break;
 
+       case VALIAS_REMOVE:
+               /* check to see if it already exists */
+               AliasExists = 0;
+               tmpalias = valias_select( Alias, Domain );
+               while (tmpalias != NULL ) {
+                       if (strcmp (tmpalias, AliasLine) == 0) AliasExists = 1;
+                       tmpalias = valias_select_next();
+               }
+               if (AliasExists) {
+                       valias_remove( Alias, Domain, AliasLine );
+               } else {
+                       fprintf (stderr, "Error: alias %s -> %s does not 
exist.\n",
+                               Email, AliasLine);
+                       vexit(-1);
+               }
+               break;
+
        case VALIAS_DELETE:
                valias_delete( Alias, Domain );
                break;
@@ -136,6 +154,7 @@
        printf("         -s ( show aliases, can use just domain )\n");
        printf("         -d ( delete alias )\n");
        printf("         -i alias_line (insert alias line)\n");
+       printf("         -r alias_line (remove alias line)\n");
        printf("\n");
        printf("Example: valias -i [EMAIL PROTECTED] [EMAIL PROTECTED]");
        printf("         (adds alias from [EMAIL PROTECTED] to [EMAIL 
PROTECTED]");
@@ -154,7 +173,7 @@
        memset(AliasLine, 0, sizeof(AliasLine));
        AliasAction = VALIAS_SELECT;
 
-       while( (c=getopt(argc,argv,"vnsdi:")) != -1 ) {
+       while( (c=getopt(argc,argv,"vnsr:di:")) != -1 ) {
                switch(c) {
                case 'v':
                        printf("version: %s\n", VERSION);
@@ -165,6 +184,10 @@
                case 's':
                        AliasAction = VALIAS_SELECT;
                        break;
+               case 'r':
+                       AliasAction = VALIAS_REMOVE;
+                       snprintf(AliasLine, sizeof(AliasLine), "%s", optarg);
+                       break;
                case 'd':
                        AliasAction = VALIAS_DELETE;
                        break;
diff -uPr vpopmail-5.4.18.orig/vpalias.c vpopmail-5.4.18/vpalias.c
--- vpopmail-5.4.18.orig/vpalias.c      2006-12-19 21:02:47.000000000 +0000
+++ vpopmail-5.4.18/vpalias.c   2007-01-05 09:23:09.000000000 +0000
@@ -1,3 +1,4 @@
+#ifndef VALIAS 
 /*
  * $Id: vpalias.c,v 1.6.2.14 2006/12/19 21:02:47 rwidmer Exp $
  * Copyright (C) 2000-2004 Inter7 Internet Technologies, Inc.
@@ -16,8 +17,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
-#include "config.h"
-#ifndef VALIAS 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -25,6 +24,7 @@
 #include <sys/stat.h>
 #include <dirent.h>
 #include <unistd.h>
+#include "config.h"
 #include "vpopmail.h"
 #include "vauth.h"
 
@@ -110,48 +110,78 @@
     return(alias_line);
 }
 
-int valias_insert( char *alias, char *domain, char *alias_line)
+int valias_insert( char *alias, char *domain, char *insert_alias_line)
 {
- int i;
+ int cntr = 0, i;
  char *tmpstr;
- char Dir[156];
+ char qmail[156];
+ char tmpqmail[156];
+ char tmpalias[156];
  char *p;
  uid_t uid;
  gid_t gid;
  FILE *fs;
+ FILE *tmpfs;
 
     if ( alias == NULL ) return(VA_NULL_POINTER);
     if ( domain == NULL ) return(VA_NULL_POINTER);
     if ( alias_line == NULL ) return(VA_NULL_POINTER);
     if ( strlen(alias) > MAX_PW_NAME ) return(VA_USER_NAME_TOO_LONG);
     if ( strlen(domain) > MAX_PW_DOMAIN ) return(VA_DOMAIN_NAME_TOO_LONG);
-    if ( strlen(alias_line) >= MAX_ALIAS_LINE ) return(VA_ALIAS_LINE_TOO_LONG);
+    if ( strlen(insert_alias_line) >= MAX_ALIAS_LINE ) 
return(VA_ALIAS_LINE_TOO_LONG);
 
-    if ((tmpstr = vget_assign(domain, Dir, sizeof(Dir), &uid, &gid )) == NULL) 
{
+    if ((tmpstr = vget_assign(domain, qmail, sizeof(qmail), &uid, &gid )) == 
NULL) {
        printf("invalid domain, not in qmail assign file\n");
        return(-1);
     }
 
+    // copy across the directory
+    strncpy(tmpqmail, qmail, sizeof(tmpqmail));
+
     // create dotqmail filename, converting '.' to ':' as we go
-    strncat(Dir, "/.qmail-", sizeof(Dir)-strlen(Dir)-1);
-    i = strlen(Dir);
-    for (p = alias; (i < (int)sizeof(Dir) - 1) && (*p != '\0'); p++)
-      Dir[i++] = (*p == '.' ? ':' : *p);
-    Dir[i] = '\0';
-       
-    if ( (fs = fopen(Dir, "a")) == NULL ) {
+    strncat(qmail, "/.qmail-", sizeof(qmail)-strlen(qmail)-1);
+    i = strlen(qmail);
+    for (p = alias; (i < (int)sizeof(qmail) - 1) && (*p != '\0'); p++)
+      qmail[i++] = (*p == '.' ? ':' : *p);
+    qmail[i] = '\0';
+
+    // create tmp dotqmail filename, converting '.' to ':' as we go
+    strncat(tmpqmail, "/.tmp.qmail-", sizeof(tmpqmail)-strlen(tmpqmail)-1);
+    i = strlen(tmpqmail);
+    for (p = alias; (i < (int)sizeof(tmpqmail) - 1) && (*p != '\0'); p++)
+      tmpqmail[i++] = (*p == '.' ? ':' : *p);
+    tmpqmail[i] = '\0';
+
+    fs = fopen(qmail, "r");
+    if ( (tmpfs = fopen(tmpqmail, "w")) == NULL ) {
+       fclose(fs);
        return(-1);
     }
-    chmod(Dir,0600);
-    chown(Dir,uid,gid);
+    chmod(tmpqmail,0600);
+    chown(tmpqmail,uid,gid);
 
-    fprintf(fs, "%s\n", alias_line);
-    fclose(fs);
+    // add on a newline for inserting
+    snprintf(tmpalias, sizeof(tmpalias), "%s\n", insert_alias_line);
+
+    // loop thru copying across the alias lines
+    if ( fs != NULL ) {
+       while ( fgets(alias_line, sizeof(alias_line), fs) != NULL ) {
+          fputs(alias_line, tmpfs);
+           cntr++;
+        }
+       fclose(fs);
+       unlink(qmail);
+    }
+
+    fputs(tmpalias, tmpfs);
+    fclose(tmpfs);
+    link(tmpqmail, qmail);
+    unlink(tmpqmail);
 
 #ifdef ONCHANGE_SCRIPT
     if( allow_onchange ) {
        /* tell other programs that data has changed */
-       snprintf ( onchange_buf, MAX_BUFF, "[EMAIL PROTECTED] - %s", alias, 
domain, alias_line );
+       snprintf ( onchange_buf, MAX_BUFF, "[EMAIL PROTECTED] - %s", alias, 
domain, insert_alias_line );
        call_onchange ( "valias_insert" );
        }
 #endif
@@ -159,13 +189,87 @@
     return(0);
 }
 
-int valias_remove( char *alias, char *domain, char *alias_line)
+int valias_remove( char *alias, char *domain, char *remove_alias_line)
 {
-  fprintf (stderr, "Error: valias_remove() not implemented for non-SQL 
backends.\n");
-  return -1;
+ int cntr = 0, i;
+ char *tmpstr;
+ char qmail[156];
+ char tmpqmail[156];
+ char tmpalias[156];
+ char *p;
+ uid_t uid;
+ gid_t gid;
+ FILE *fs;
+ FILE *tmpfs;
+
+    if ( alias == NULL ) return(VA_NULL_POINTER);
+    if ( domain == NULL ) return(VA_NULL_POINTER);
+    if ( alias_line == NULL ) return(VA_NULL_POINTER);
+    if ( strlen(alias) > MAX_PW_NAME ) return(VA_USER_NAME_TOO_LONG);
+    if ( strlen(domain) > MAX_PW_DOMAIN ) return(VA_DOMAIN_NAME_TOO_LONG);
+    if ( strlen(remove_alias_line) >= MAX_ALIAS_LINE ) 
return(VA_ALIAS_LINE_TOO_LONG);
+
+    if ((tmpstr = vget_assign(domain, qmail, sizeof(qmail), &uid, &gid )) == 
NULL) {
+       printf("invalid domain, not in qmail assign file\n");
+       return(-1);
+    }
+
+    // copy across the directory
+    strncpy(tmpqmail, qmail, sizeof(tmpqmail));
+
+    // create dotqmail filename, converting '.' to ':' as we go
+    strncat(qmail, "/.qmail-", sizeof(qmail)-strlen(qmail)-1);
+    i = strlen(qmail);
+    for (p = alias; (i < (int)sizeof(qmail) - 1) && (*p != '\0'); p++)
+      qmail[i++] = (*p == '.' ? ':' : *p);
+    qmail[i] = '\0';
+
+    // create tmp dotqmail filename, converting '.' to ':' as we go
+    strncat(tmpqmail, "/.tmp.qmail-", sizeof(tmpqmail)-strlen(tmpqmail)-1);
+    i = strlen(tmpqmail);
+    for (p = alias; (i < (int)sizeof(tmpqmail) - 1) && (*p != '\0'); p++)
+      tmpqmail[i++] = (*p == '.' ? ':' : *p);
+    tmpqmail[i] = '\0';
+
+    fs = fopen(qmail, "r");
+    if ( (tmpfs = fopen(tmpqmail, "w")) == NULL ) {
+       fclose(fs);
+       return(-1);
+    }
+    chmod(tmpqmail,0600);
+    chown(tmpqmail,uid,gid);
+
+    // add on a newline for comparing
+    snprintf(tmpalias, sizeof(tmpalias), "%s\n", remove_alias_line);
+
+    // loop thru copying across the alias lines
+    if ( fs != NULL ) {
+       while ( fgets(alias_line, sizeof(alias_line), fs) != NULL ) {
+           if ( strcmp(alias_line, tmpalias) != 0) {
+               fputs(alias_line, tmpfs);
+               cntr++;
+           }
+        }
+       fclose(fs);
+       unlink(qmail);
+    }
+
+    fclose(tmpfs);
+    if ( cntr > 0 ) link(tmpqmail, qmail);
+    unlink(tmpqmail);
+
+#ifdef ONCHANGE_SCRIPT
+    if( allow_onchange ) {
+       /* tell other programs that data has changed */
+       snprintf ( onchange_buf, MAX_BUFF, "[EMAIL PROTECTED] - %s", alias, 
domain, remove_alias_line );
+       call_onchange ( "valias_remove" );
+       }
+#endif
+
+    return(0);
 }
 
-int valias_delete( char *alias, char *domain)
+int valias_delete( char *alias, char *domain )
 {
  char *tmpstr;
  char Dir[156];
@@ -305,10 +409,13 @@
         }
       }
     }
-    if (num_names < max_names) {
+    if (num_names < max_names && num_names > 0) {
       new_names = realloc( names, num_names * sizeof(char *) );
       if (new_names != NULL)
        names = new_names;
+    } else if (num_names == 0) {
+      free(names);
+      names = NULL;
     }
 
     if (mydir!=NULL) {

Reply via email to