Did you leave the function qa_sort() there or remove it?
It should have stayed exactly as it was before.

All I did was write a function called bkscandir() that implements
what's written on the linux scandir() man page.  I took 10 minutes
looking for the BSD sources, then said forget it and wrote it
in the next 20 minutes.  Didn't want to waste too much time with
something that looked simple...

I've attached copies of my util.c and alias.c that you can
just drop into 1.0.8.  You will need to manually update
the prototype for get_du() (in qmailadmin.h) to be the following:

off_t get_du(const char*);


Thanks,

Brian

  > At 23:36 23/01/2003 -0500, you wrote:
  > 
  > Hi Brian, quick follow up .. I forgot one change when I manually edited the 
  > alias.c file (didn't change scandir to bkscandir), but the compile still 
  > fails when it gets to the qa_sort.
  > 
  > -- Steve
  > 
  > >Content-Type: TEXT/plain; charset=us-ascii
  > >Content-MD5: qWmg8rE8CezbPN2qsIWDBQ==
  > >
  > >
  > >I've updated alias.c and util.c to remove the fts_* functions
  > >and put in a new get_du() function.  Also, I've implemented
  > >the "scandir()" function and called it "bkscandir()".  I also
  > >fixed an obvious memory leak in the alias functions that used scandir().
  > >
  > >Going through the code it appears there's lots of memory leaks in there...
  > >
  > >This should allow all POSIX compatible systems to run
  > >the latest version.
  > >
  > >Finally...  I can add the vlimits() stuff in.
  > >
  > >Thanks,
  > >
  > >Brian
  > >Content-Type: TEXT/plain; name=qdiff; charset=us-ascii; x-unix-mode=0644
  > >Content-Description: qdiff
  > >Content-MD5: tw7QdOEV8Vqw7P+FoUbA7Q==
  > >
  > >Only in qmailadmin-1.0.8: Makefile
  > >diff -c qmailadmin-1.0.8.orig/alias.c qmailadmin-1.0.8/alias.c
  > >*** qmailadmin-1.0.8.orig/alias.c       Wed Jan 22 00:46:04 2003
  > >--- qmailadmin-1.0.8/alias.c    Thu Jan 23 23:10:11 2003
  > >***************
  > >*** 31,36 ****
  > >--- 31,40 ----
  > >   #include "qmailadminx.h"
  > >
  > >   char* dotqmail_alias_command(char* command);
  > >+ int bkscandir(const char *dirname,
  > >+               struct dirent ***namelist,
  > >+             int (*select)(struct dirent *),
  > >+             int (*compar)(const void *, const void *));
  > >
  > >   int show_aliases(void)
  > >   {
  > >***************
  > >*** 83,89 ****
  > >       return(0);
  > >     }
  > >
  > >!   n = scandir(".", &namelist, 0, qa_sort);
  > >
  > >     for (m=0; m<n; m++) {
  > >       mydirent=namelist[m];
  > >--- 87,93 ----
  > >       return(0);
  > >     }
  > >
  > >!   n = bkscandir(".", &namelist, 0, qa_sort);
  > >
  > >     for (m=0; m<n; m++) {
  > >       mydirent=namelist[m];
  > >***************
  > >*** 172,181 ****
  > >         fclose(fs);
  > >         k++;
  > >       }
  > >-     free(namelist[m]);
  > >     }
  > >-
  > >     closedir(mydir);
  > >     free(namelist);
  > >
  > >     if (AdminType == DOMAIN_ADMIN) {
  > >--- 176,186 ----
  > >         fclose(fs);
  > >         k++;
  > >       }
  > >     }
  > >     closedir(mydir);
  > >+   /* bk: fix memory leak */
  > >+   for (m=0; m<n; m++)
  > >+     free(namelist[m]);
  > >     free(namelist);
  > >
  > >     if (AdminType == DOMAIN_ADMIN) {
  > >***************
  > >*** 673,676 ****
  > >--- 678,738 ----
  > >       /* otherwise just report nothing */
  > >       return(NULL);
  > >     }
  > >+ }
  > >+
  > >+ /*
  > >+  * Brian Kolaci
  > >+  * quick implementation of the scandir() BSD function
  > >+  */
  > >+ int bkscandir(const char *dirname,
  > >+               struct dirent ***namelist,
  > >+             int (*select)(struct dirent *),
  > >+             int (*compar)(const void *, const void *))
  > >+ {
  > >+   int i;
  > >+   int entries;
  > >+   int esize;
  > >+   struct dirent* dp;
  > >+   struct dirent* dent;
  > >+   DIR * dirp;
  > >+
  > >+   *namelist = NULL;
  > >+   entries = esize = 0;
  > >+
  > >+   /* load the names */
  > >+   if ((dirp = opendir(dirname)) == NULL)
  > >+     return -1;
  > >+
  > >+   while ((dp = readdir(dirp)) != NULL) {
  > >+     if (select == NULL || (*select)(dp)) {
  > >+       if (entries >= esize) {
  > >+         void* mem;
  > >+         esize += 10;
  > >+         if ((mem = realloc(*namelist, esize * sizeof(struct dirent*))) 
  > >== NULL) {
  > >+           for (i = 0; i < entries; i++)
  > >+             free((*namelist)[i]);
  > >+           free(*namelist);
  > >+           closedir(dirp);
  > >+           return -1;
  > >+         }
  > >+         *namelist = (struct dirent**)mem;
  > >+       }
  > >+       if ((dent = (struct dirent*)malloc(sizeof(struct 
  > >dirent)+MAX_FILE_NAME)) == NULL) {
  > >+         for (i = 0; i < entries; i++)
  > >+           free((*namelist)[i]);
  > >+         free(*namelist);
  > >+         closedir(dirp);
  > >+         return -1;
  > >+       }
  > >+       memcpy(dent, dp, sizeof(*dp)+MAX_FILE_NAME);
  > >+       (*namelist)[entries] = dent;
  > >+       entries++;
  > >+     }
  > >+   }
  > >+   closedir(dirp);
  > >+
  > >+   /* sort them */
  > >+   if (compar)
  > >+     qsort((void*)*namelist, entries, sizeof(struct dirent*), compar);
  > >+   return entries;
  > >   }
  > >Common subdirectories: qmailadmin-1.0.8.orig/autom4te.cache and 
  > >qmailadmin-1.0.8/autom4te.cache
  > >diff -c qmailadmin-1.0.8.orig/cgi.c qmailadmin-1.0.8/cgi.c
  > >*** qmailadmin-1.0.8.orig/cgi.c Tue Aug  6 18:04:59 2002
  > >--- qmailadmin-1.0.8/cgi.c      Thu Jan 23 23:29:27 2003
  > >***************
  > >*** 27,33 ****
  > >   #include "config.h"
  > >   #include "qmailadmin.h"
  > >   #include "qmailadminx.h"
  > >- #include <syslog.h>
  > >
  > >   get_cgi()
  > >   {
  > >--- 27,32 ----
  > >Only in qmailadmin-1.0.8: config.h
  > >Only in qmailadmin-1.0.8: config.log
  > >Only in qmailadmin-1.0.8: config.status
  > >Only in qmailadmin-1.0.8: doconfig
  > >Common subdirectories: qmailadmin-1.0.8.orig/html and qmailadmin-1.0.8/html
  > >Common subdirectories: qmailadmin-1.0.8.orig/images and 
  > >qmailadmin-1.0.8/images
  > >diff -c qmailadmin-1.0.8.orig/qmailadmin.h qmailadmin-1.0.8/qmailadmin.h
  > >*** qmailadmin-1.0.8.orig/qmailadmin.h  Fri Oct 25 04:33:42 2002
  > >--- qmailadmin-1.0.8/qmailadmin.h       Thu Jan 23 21:31:45 2003
  > >***************
  > >*** 51,54 ****
  > >   char *get_quota_used(char*);           //jhopper prototype
  > >   int quota_to_bytes(char[], char*);     //jhopper prototype
  > >   int quota_to_megabytes(char[], char*); //jhopper prototype
  > >! double get_du(char*);                  //jhopper prototype
  > >--- 51,54 ----
  > >   char *get_quota_used(char*);           //jhopper prototype
  > >   int quota_to_bytes(char[], char*);     //jhopper prototype
  > >   int quota_to_megabytes(char[], char*); //jhopper prototype
  > >! off_t get_du(const char*);             //bk prototype
  > >Only in qmailadmin-1.0.8: stamp-h1
  > >diff -c qmailadmin-1.0.8.orig/user.c qmailadmin-1.0.8/user.c
  > >*** qmailadmin-1.0.8.orig/user.c        Fri Jan 17 22:11:01 2003
  > >--- qmailadmin-1.0.8/user.c     Thu Jan 23 23:29:34 2003
  > >***************
  > >*** 35,44 ****
  > >
  > >   #define HOOKS 1
  > >
  > >- #ifdef DEBUG
  > >- #include <syslog.h>
  > >- #endif
  > >-
  > >   #ifdef HOOKS
  > >   #define HOOK_ADDUSER 0
  > >   #define HOOK_DELUSER 1
  > >--- 35,40 ----
  > >diff -c qmailadmin-1.0.8.orig/util.c qmailadmin-1.0.8/util.c
  > >*** qmailadmin-1.0.8.orig/util.c        Fri Oct 25 04:33:42 2002
  > >--- qmailadmin-1.0.8/util.c     Thu Jan 23 23:30:11 2003
  > >***************
  > >*** 24,30 ****
  > >   #include <unistd.h>
  > >   #include <pwd.h>
  > >   #include <dirent.h>
  > >- #include <fts.h>
  > >   #include "config.h"
  > >   #include "qmailadmin.h"
  > >   #include "qmailadminx.h"
  > >--- 24,29 ----
  > >***************
  > >*** 259,311 ****
  > >       double size;
  > >
  > >       size = get_du(dir);
  > >!     if (size != 0) {
  > >           size = size / 1048576;  // Convert to MBs.
  > >       }
  > >!     sprintf(tmpbuff, "%-2.2f", size);
  > >       tmpstr = tmpbuff;
  > >       return tmpstr;
  > >   }
  > >   int quota_to_bytes(char returnval[], char *quota) {
  > >       char *tmpstr;
  > >!     unsigned long tmpint;
  > >
  > >       if (quota == NULL) { return 1; }
  > >!     if (tmpint = atoi(quota)) { tmpint = tmpint * 1048576; }
  > >       else { return 1; }
  > >!     sprintf(returnval, "%i", tmpint);
  > >       return 0;
  > >   }
  > >   int quota_to_megabytes(char returnval[], char *quota) {
  > >       char *tmpstr;
  > >!     unsigned long tmpint;
  > >
  > >       if (quota == NULL) { return 1; }
  > >!     if (tmpint = atoi(quota)) {
  > >!          if (tmpint != 0) { tmpint = tmpint / 1048576; }
  > >       }
  > >       else { return 0; }
  > >!     sprintf(returnval, "%i", tmpint);
  > >       return 0;
  > >   }
  > >- double get_du(char *path) {
  > >-     FTS *fileheir;
  > >-     FTSENT *fsentry;
  > >-     char **dirnames;
  > >-     ssize_t size = 0;
  > >
  > >!     dirnames = malloc(2 * sizeof(char*));
  > >!     dirnames[0] = path;
  > >!     dirnames[1] = NULL;
  > >
  > >!     fileheir = fts_open(dirnames, FTS_PHYSICAL, NULL);
  > >!     while ((fsentry = fts_read(fileheir)) != NULL) {
  > >!         if (fsentry->fts_number == 0) {
  > >!             size = size + fsentry->fts_statp->st_size;
  > >!             fsentry->fts_number = 1;
  > >!         }
  > >       }
  > >!     fts_close(fileheir);
  > >!     free(dirnames);
  > >!     return size;
  > >   }
  > >--- 258,325 ----
  > >       double size;
  > >
  > >       size = get_du(dir);
  > >!     if (size > 0) {
  > >           size = size / 1048576;  // Convert to MBs.
  > >       }
  > >!     sprintf(tmpbuff, "%-2.2lf", size);
  > >       tmpstr = tmpbuff;
  > >       return tmpstr;
  > >   }
  > >   int quota_to_bytes(char returnval[], char *quota) {
  > >       char *tmpstr;
  > >!     double tmp;
  > >
  > >       if (quota == NULL) { return 1; }
  > >!     if (tmp = atol(quota)) { tmp *= 1048576; }
  > >       else { return 1; }
  > >!     sprintf(returnval, "%-2.2lf", tmp);
  > >       return 0;
  > >   }
  > >   int quota_to_megabytes(char returnval[], char *quota) {
  > >       char *tmpstr;
  > >!     double tmp;
  > >
  > >       if (quota == NULL) { return 1; }
  > >!     if (tmp = atol(quota)) {
  > >!          if (tmp != 0) { tmp /= 1048576.0; }
  > >       }
  > >       else { return 0; }
  > >!     sprintf(returnval, "%-2.2lf", tmp);
  > >       return 0;
  > >   }
  > >
  > >! /*
  > >!  * Brian Kolaci
  > >!  * updated function that doesn't require fts_*
  > >!  */
  > >! off_t get_du(const char *dir_name)
  > >! {
  > >!   DIR *dirp;
  > >!   struct dirent *dp;
  > >!   struct stat statbuf;
  > >!   off_t file_size = 0;
  > >!   char *tmpstr;
  > >
  > >!   if (dir_name == NULL)
  > >!     return 0;
  > >!
  > >!   if (chdir(dir_name) == -1)
  > >!     return 0;
  > >!
  > >!   if ((dirp = opendir(".")) == NULL)
  > >!     return 0;
  > >!
  > >!   while ((dp=readdir(dirp)) != NULL) {
  > >!     if (!strcmp(dp->d_name, "..") || !strcmp(dp->d_name, "."))
  > >!       continue;
  > >!     if ((tmpstr=strstr(dp->d_name, ",S=")) != NULL) {
  > >!       file_size += atol(tmpstr+3);
  > >!     } else if (stat(dp->d_name,&statbuf)==0 && (statbuf.st_mode & 
  > >S_IFDIR) ) {
  > >!       file_size += get_du(dp->d_name);
  > >       }
  > >!   }
  > >!   closedir(dirp);
  > >!   if (dir_name != NULL && strcmp(dir_name, ".." ) && strcmp(dir_name, "." 
))
  > >!     chdir("..");
  > >!   return(file_size);
  > >   }
  > 
/* 
 * Copyright (C) 1999-2002 Inter7 Internet Technologies, Inc. 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include <pwd.h>
#include <errno.h>
#include <dirent.h>
#include <vpopmail.h>
#include <vauth.h>
#include "config.h"
#include "qmailadmin.h"
#include "qmailadminx.h"

char* dotqmail_alias_command(char* command);
int bkscandir(const char *dirname,
              struct dirent ***namelist,
	      int (*select)(struct dirent *),
	      int (*compar)(const void *, const void *));

int show_aliases(void)
{
  if ( AdminType!=DOMAIN_ADMIN ) {
    sprintf(StatusMessage, "%s", get_html_text("142"));
    vclose();
    exit(0);
  }
  send_template("show_alias.html");
  return 0;
}

int qa_sort(const void * a, const void * b)
{
  return strcasecmp ((*(const struct dirent **) a)->d_name,
                     (*(const struct dirent **) b)->d_name);
}


show_dotqmail_lines(char *user, char *dom, time_t mytime, char *dir)
{
 int moreusers=0;
 DIR *mydir;
 struct dirent *mydirent;
 FILE *fs;
 char alias_user[MAX_FILE_NAME];
 char alias_name[MAX_FILE_NAME];
 char *alias_name_from_command;
 int i,j,stop,k,startnumber;
 int m,n;
 struct dirent **namelist;

  if ( AdminType!=DOMAIN_ADMIN ) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    vclose();
    exit(0);
  }

  if (atoi(Pagenumber)==0) {
    *Pagenumber='1';
  }

  startnumber = MAXALIASESPERPAGE * (atoi(Pagenumber) - 1);
  k=0;

  if ( (mydir = opendir(".")) == NULL ) {
    fprintf(actout,"<tr><td colspan=\"4\">");
    fprintf(actout,"%s %d", get_html_text("143"), 1);
    fprintf(actout,"</td></tr>");
    return(0);
  }

  n = bkscandir(".", &namelist, 0, qa_sort);
  
  for (m=0; m<n; m++) {
    mydirent=namelist[m];
    /*
     *  don't read files that are really ezmlm-idx listowners,
     *  i.e. .qmail-user-owner
     *   
     */ 
    if ( strncmp(".qmail-", mydirent->d_name, 7) == 0 ) {
      if ( strstr(mydirent->d_name, "-owner") != NULL ) continue; 
      if ( strstr(mydirent->d_name, "-default") != NULL ) continue; 

      if ( k < startnumber ) {
        k++; 
        continue;
      }
      if ( k >MAXALIASESPERPAGE + startnumber) {
        moreusers=1;
        break;
      }

      if ( (fs=fopen(mydirent->d_name,"r"))==NULL) {
        fprintf(actout,"<tr><td colspan=\"4\">");
        fprintf(actout,"%s %s", get_html_text("144"), mydirent->d_name);
        fprintf(actout,"</td></tr>\n");
        fclose(fs);
        continue;
      }
      memset(TmpBuf2,0,MAX_BUFF);
      fgets( TmpBuf2, MAX_BUFF, fs);
      alias_name_from_command = dotqmail_alias_command(TmpBuf2);
      if ( alias_name_from_command != NULL ) {
                          
        /* first case checks if the file beginnning is an email
         * and the function is not being called to display forwards,
         * the second case checks if the file beginning is an user, and
         * the type is not an alias 
         */
                            
        for(i=7,j=0;j<MAX_FILE_NAME-1&&mydirent->d_name[i]!=0;++i,++j) {
          alias_name[j] = mydirent->d_name[i];
          if ( alias_name[j] == ':' ) alias_name[j] = '.';
        }
        alias_name[j] = 0;
        stop=0;

        fprintf(actout, "<tr>\n");
        fprintf(actout, "<td align=\"left\">%s</td>\n", alias_name);
        fprintf(actout, "<td align=\"left\">");
        while (!stop) {
          alias_name_from_command = dotqmail_alias_command(TmpBuf2);
                
          /* check to see if it is an invalid line , 
           * if so skip to next
           */
          if (alias_name_from_command == NULL ) {
            if (fgets(TmpBuf2, 500, fs)==NULL) { 
              stop=1;
            }
            continue;
          }
                    
          strcpy(alias_user, alias_name_from_command);
                
          if (fgets(TmpBuf2, 500, fs) == NULL) {
            stop=1;
            fprintf(actout, "%s ", alias_user);
          } else {
            fprintf(actout, "%s, ", alias_user);
          }
        }
        fprintf(actout, "</td>\n");
                
        fprintf(actout, "<td align=\"center\">");
        fprintf(actout, "<a href=\"%s/com/moddotqmail?user=%s&dom=%s&time=%d&modu=%s\">",
          CGIPATH,user,dom,mytime,alias_name);
        fprintf(actout, "<img src=\"/images/qmailadmin/delete.png\" border=\"0\"></a>");
        fprintf(actout, "</td>\n");
        fprintf(actout, "<td align=\"center\">");
        fprintf(actout, "<a href=\"%s/com/deldotqmail?user=%s&dom=%s&time=%d&modu=%s\">",
          CGIPATH,user,dom,mytime,alias_name);
        fprintf(actout, "<img src=\"/images/qmailadmin/delete.png\" border=\"0\"></a>");
        fprintf(actout, "</td>\n");
        fprintf(actout, "</tr>\n");
      }
      fclose(fs);
      k++;
    }
  }
  closedir(mydir);
  /* bk: fix memory leak */
  for (m=0; m<n; m++)
    free(namelist[m]);
  free(namelist);

  if (AdminType == DOMAIN_ADMIN) {
    fprintf(actout, "<tr><td align=\"right\" colspan=\"4\">");
    fprintf(actout, "[&nbsp;");
    if(atoi(Pagenumber) > 1 ) {
      fprintf(actout, "<a href=\"%s/com/showforwards?user=%s&dom=%s&time=%d&page=%d\">%s</a>",
        CGIPATH,user,dom,mytime,atoi(Pagenumber)-1?atoi(Pagenumber)-1:atoi(Pagenumber),get_html_text("135"));
      fprintf(actout, "&nbsp;|&nbsp;");
    }
    fprintf(actout, "<a href=\"%s/com/showforwards?user=%s&dom=%s&time=%d&page=%s\">%s</a>",
      CGIPATH,user,dom,mytime,Pagenumber,get_html_text("136"));
    fprintf(actout, "&nbsp;|&nbsp;");
    if (moreusers) {
      fprintf(actout, "<a href=\"%s/com/showforwards?user=%s&dom=%s&time=%d&page=%d\">%s</a>",
        CGIPATH,user,dom,mytime,atoi(Pagenumber)+1,get_html_text("137"));    
      fprintf(actout, "&nbsp;]");
    }
    fprintf(actout, "</td></tr>");                                    
  }
}

/* 
 * This Function shows the inside of a .qmail file, 
 * with the edit mode
 *
 */
int show_dotqmail_file(char *user) 
{
 FILE *fs;
 char alias_user[MAX_FILE_NAME];
 char *alias_name_from_command;
 char *dot_file;
 int l,j;

  if ( AdminType!=DOMAIN_ADMIN ) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    vclose();
    exit(0);
  }
    
  l = strlen(user);
  dot_file= strcat(strcpy(malloc(8 + l), ".qmail-"), user);

  for(j=8;dot_file[j]!=0;j++) {
    if (dot_file[j]=='.') {
      dot_file[j] = ':';
    }
  }

  if ( (fs=fopen(dot_file,"r"))==NULL) {
    sprintf(StatusMessage,"%s %s<br>\n", get_html_text("144"), dot_file);
    vclose();
    exit(0);
  }
                
  fprintf(actout, "<tr>");
  fprintf(actout, "<td align=\"center\"><b>%s</b></td>", user);
  fprintf(actout, "<td align=\"left\">&nbsp;</td>");
  fprintf(actout, "<td align=\"left\">&nbsp;</td>");
  fprintf(actout, "</tr>");
    
  memset(TmpBuf2, 0, MAX_BUFF);

  while (fgets( TmpBuf2, MAX_BUFF, fs) != NULL) {
    alias_name_from_command = dotqmail_alias_command(TmpBuf2);
                        
    /* check to see if it is an invalid line , if so skip to next*/
    if (alias_name_from_command == NULL ) continue;

    strcpy(alias_user, alias_name_from_command);
                
    fprintf(actout, "<tr>\n");
    fprintf(actout, "<td align=\"left\">&nbsp;</td>\n");
    fprintf(actout, "<td align=\"center\">%s</td>\n", alias_user);
    fprintf(actout, "<td align=\"center\">\n");
    fprintf(actout, "<form method=\"post\" name=\"moddotqmail\" action=\"%s/com/moddotqmailnow\">\n", CGIPATH);
    fprintf(actout, "<input type=\"hidden\" name=\"user\" value=\"%s\">\n", 
      Username);
    fprintf(actout, "<input type=\"hidden\" name=\"dom\" value=\"%s\">\n", 
      Domain);
    fprintf(actout, "<input type=\"hidden\" name=\"time\" value=\"%i\">\n", 
      Mytime);
    fprintf(actout, "<input type=\"hidden\" name=\"modu\" value=\"%s\">\n", 
      user);
    fprintf(actout, "<input type=\"hidden\" name=\"linedata\" value=\"%s\">\n",
      TmpBuf2);
    fprintf(actout, "<input type=\"hidden\" name=\"action\" value=\"delentry\">\n");
    fprintf(actout, "<input type=\"image\" border=\"0\" src=\"/images/qmailadmin/delete.png\">\n");
    fprintf(actout, "</form>\n");
    fprintf(actout, "</td>\n");
    fprintf(actout, "</tr>\n");
  }
  fclose(fs);
}

int onevalidonly(char *user) {
 FILE *fs;
 char *alias_name_from_command;
 char *dot_file;
 int l,j;

  l = strlen(user);
  dot_file= strcat(strcpy(malloc(8 + l), ".qmail-"), user);
  for(j=8;dot_file[j]!=0;j++) {
    if (dot_file[j]=='.') {
      dot_file[j] = ':';
    }
  }

  if ( (fs=fopen(dot_file,"r"))==NULL) {
    sprintf(StatusMessage,"%s %s<br>\n", get_html_text("144"),
    dot_file);
    vclose();
    exit(0);
  }
            
  j=0;
  while( fgets( TmpBuf2, MAX_BUFF, fs) != NULL ) {
    alias_name_from_command = dotqmail_alias_command(TmpBuf2);
    /* check to see if it is an invalid line , if so skip to next */
    if (alias_name_from_command == NULL ) continue;
        
    j++;
  }
  fclose(fs);

  if (j <2 ) return (1);
  else return (0);

}



moddotqmail()
{
  if ( AdminType!=DOMAIN_ADMIN ) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    vclose();
    exit(0);
  }
  send_template("mod_dotqmail.html");
}

moddotqmailnow() 
{
 struct vqpasswd *pw;

  if ( strcmp(ActionUser,"default")==0) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    vclose();
    exit(0);
  }

  if (strcmp(Action,"delentry")==0) {
    if (onevalidonly(ActionUser) ) {
      sprintf(StatusMessage, "%s\n", get_html_text("149"));
      moddotqmail();
      vclose();
      exit(0);
    }
        
    if (dotqmail_del_line(ActionUser,LineData) ) {
      sprintf(StatusMessage, "%s %d\n", get_html_text("150"), 1);
      moddotqmail();
      vclose();
      exit(0);
    }
    sprintf(StatusMessage, "%s\n", get_html_text("151") );
    moddotqmail();
    vclose();
    exit(0);
    
  } else if (strcmp(Action,"addremote")==0) {
    if (check_email_addr(Newu) ) {
      sprintf(StatusMessage, "%s %s\n", get_html_text("148"), Newu);
      moddotqmail();
      vclose();
      exit(0);
    }
    sprintf(TmpBuf2, "&%s\n",Newu);
    
    if (dotqmail_add_line(ActionUser,TmpBuf2)) {
      sprintf(StatusMessage, "%s %d\n", get_html_text("150"), 2);
      moddotqmail();
      vclose();
      exit(0);
    }
    sprintf(StatusMessage,"%s %s\n", get_html_text("152"), Newu);
    moddotqmail();
    vclose();
    exit(0);
    
  } else if (strcmp(Action,"addlocal")==0) {
    if ( !vauth_getpw(Newu, Domain) ) {
      sprintf(StatusMessage, "%s %s\n", Newu, get_html_text("153"));
      moddotqmail();
      vclose();
      exit(0);
    }
    pw = vauth_getpw( Newu, Domain );        
    sprintf(TmpBuf2, "%s/Maildir/\n",pw->pw_dir);
                                                                    
    if (dotqmail_add_line(ActionUser,TmpBuf2)) {
      sprintf(StatusMessage, "%s %d\n", get_html_text("150"), 3);
      moddotqmail();
      vclose();
      exit(0);
    }
    sprintf(StatusMessage, "%s %s\n", Newu, get_html_text("154"));
    moddotqmail();
    vclose();
    exit(0);
  } else {
    sprintf(StatusMessage, "%s\n", get_html_text("155"));
    vclose();
    exit(0);
  }
}

adddotqmail()
{

  if (!(strcmp(AliasType, "alias"))) {
    count_aliases();
    load_limits();
    if ( MaxAliases != -1 && CurAliases >= MaxAliases ) {
      sprintf(StatusMessage, "%s %d\n",  
      get_html_text("156"), MaxAliases);
      show_menu();
      vclose();
      exit(0);
    }
    send_template( "add_alias.html" );

  } else if (!(strcmp(AliasType, "forward"))) {
    count_forwards();
    load_limits();
    if ( MaxForwards != -1 && CurForwards >= MaxForwards ) {
      sprintf(StatusMessage, "%s %d\n", 
      get_html_text("157"), MaxForwards);
      show_menu();
      vclose();
      exit(0);
    }
    send_template( "add_forward.html" );

  } else {    
    fprintf(actout, "%s\n", get_html_text("159"));
    show_menu();
    vclose();
    exit(0);
  }
}


adddotqmailnow()
{
 struct vqpasswd *pw;
 int err;

  if (AdminType!=DOMAIN_ADMIN && 
      !(AdminType==USER_ADMIN && strcmp(ActionUser, Username)==0)) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    vclose();
    exit(0);
  }

  if (!(strcmp(AliasType, "alias"))) {
    count_aliases();
    load_limits();
    if ( MaxAliases != -1 && CurAliases >= MaxAliases ) {
      sprintf(StatusMessage, "%s %d\n", get_html_text("156"), MaxAliases);
      send_template( "add_alias.html" );
      vclose();
      exit(0);
    }

  } else if (!(strcmp(AliasType, "forward"))) {
    count_forwards();
    load_limits();
    if ( MaxForwards != -1 && CurForwards >= MaxForwards ) {
      sprintf(StatusMessage, "%s %d\n", get_html_text("157"), MaxForwards);
      send_template( "add_forward.html" );
      vclose();
      exit(0);
    }
  }

  err = 0;

  /* check to see if we already have a user with this name */
  if (err = fixup_local_name(Alias)) {
    sprintf(StatusMessage, "%s %s\n", get_html_text("160"), Alias);
  }

  if (!(strcmp(AliasType, "alias")) && !err ) {
    if (!err && (err = (vauth_getpw( ActionUser, Domain ) == NULL)))
      sprintf(StatusMessage, "%s\n", get_html_text("161"));

  } else if (!(strcmp(AliasType, "forward")) && !err) {

    if (err = ( check_email_addr(ActionUser)) ) {
      sprintf(StatusMessage, "%s %s\n", get_html_text("162"), ActionUser);

    } else if ( err = (strlen(Alias)<=0) ) {
      sprintf(StatusMessage, "%s %s\n", get_html_text("163"), Alias);

    } else if (err = ( fixup_local_name(Alias)) ) {
      sprintf(StatusMessage, "%s %s\n", get_html_text("163"), Alias);
    }

  } else if (!err) {
    err=1;
    sprintf(StatusMessage, "%s\n", get_html_text("164")); 
  }

  if (err) {
    adddotqmail();
    vclose();
    exit(0);
  }

  if (!err) {
    if  (!(strcmp(AliasType, "alias"))) {
      pw = vauth_getpw( ActionUser, Domain );
      sprintf(TmpBuf2, "%s/Maildir/\n", pw->pw_dir);
      dotqmail_add_line(Alias, TmpBuf2);
    } else if  (!(strcmp(AliasType, "forward"))) {
      sprintf(TmpBuf2, "&%s\n", ActionUser);
      dotqmail_add_line(Alias, TmpBuf2);
    } else { 
      err=1; 
    }
  }

  if (err) {
    sprintf(StatusMessage, "%s %s %s %s\n", get_html_text("165"), 
      AliasType, Alias, ActionUser);
  } else {
    sprintf(StatusMessage, "%s %s %s %s\n", get_html_text("166"), 
      AliasType, Alias, ActionUser);
  }
  show_forwards(Username,Domain,Mytime,RealDir);

}

deldotqmail()
{

  if ( AdminType!=DOMAIN_ADMIN ) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    vclose();
    exit(0);
  }
  send_template( "del_forward_confirm.html" );

}

deldotqmailnow()
{

  if (AdminType!=DOMAIN_ADMIN && 
       !(AdminType==USER_ADMIN && !strcmp(ActionUser, Username))) {
    sprintf(StatusMessage,"%s", get_html_text("142"));
    show_menu(Username, Domain, Mytime);
    vclose();
    exit(0);
  }


  /* check to see if we already have a user with this name */
  if (fixup_local_name(ActionUser)) {
    sprintf(StatusMessage,"%s %s\n", get_html_text("160"), Alias);
    deldotqmail();
    vclose();
    exit(0);
  }

  if (!(dotqmail_delete_files(ActionUser))) {
    sprintf(StatusMessage, "%s %s %s\n", get_html_text("167"), 
      Alias, ActionUser);
  } else {
    sprintf(StatusMessage, "%s %s %s\n", get_html_text("168"), 
      Alias, ActionUser);
  }

  /* don't display aliases/forwards if we just deleted the last one */
  count_aliases();
  count_forwards();
  if((CurForwards + CurAliases) == 0) {
    show_menu(Username, Domain, Mytime);
  } else {
    show_forwards(Username,Domain,Mytime,RealDir);
  }
}

count_aliases()
{
 DIR *mydir;
 struct dirent *mydirent;
 FILE *fs;
 char *alias_name_from_command;

  /* FIXME: Do some caching here. */

  CurAliases = 0;
  if ( (mydir = opendir(".")) == NULL ) {
    fprintf(actout,"%s %s<br>\n", get_html_text("144"), "1");
    fprintf(actout, "</table>");
    return(0);
  }


  while( (mydirent=readdir(mydir)) != NULL ) {

    /*
     *  don't read files that are really ezmlm-idx listowners,
     *  i.e. .qmail-user-owner
     */ 
    if ( strncmp(".qmail-", mydirent->d_name, 7) == 0 && 
         ( strstr(mydirent->d_name, ".qmail-owner") != NULL || 
           strstr(mydirent->d_name, "-list-owner") == NULL )) {

      if ( (fs=fopen(mydirent->d_name,"r"))==NULL) {
        fprintf(actout,"%s %s<br>\n", get_html_text("144"), mydirent->d_name);
        continue;
      }
      memset(TmpBuf2,0,MAX_BUFF);
      fgets( TmpBuf2, 500, fs);
      alias_name_from_command = dotqmail_alias_command(TmpBuf2);
      if ( alias_name_from_command != NULL ) {
        if (strstr(alias_name_from_command,"@")==NULL) {
          ++CurAliases;
        }
      }
      fclose(fs);
    }
  }
  closedir(mydir);
}


char* dotqmail_alias_command(char* command)
{
 int len;
 static char user[501];
 char* s;

  if (command == NULL) return NULL;

  /* find the first space and stop the command there */
  len=0;
  while( command[len]!=0 && isspace(command[len])==0 ) ++len;
  command[len] = 0;

    
  /* If it ends with a slash and starts with a / or . then
   * this is a Maildir delivery, local alias
   */
  if( (command[len - 1]=='/') && (command[0] =='/') || (command[0] =='.') ) { 
    strcpy(user, command); user[len - 1] = '\0';

    if ((s = strrchr(user, '/')) == NULL) return NULL;
    if (strcmp(s, "/Maildir") != 0) return NULL;

    *s = '\0';
    if ((s = strrchr(user, '/')) == NULL) return NULL;

    return (s+1);
        
  /* if it's an email address then display the forward */
  } else if ( !check_email_addr( (command+1) ) ){
    strcpy(user, command); 
    s = user;    
    *s = '\0';

    if (command[0] == '&' ) return (s+1);
    else return (command);

  /* if it is a program then */
  } else if ( command[0] == '|' ) {

    /* do not display ezmlm programs */
    if ( strstr(command, "ezmlm" ) != 0 ) return(NULL);

    /* do not display autorespond programs */
    if ( strstr(command, "autorespond" ) != 0 ) return(NULL);

    /* otherwise, display the program */
    return(command);

  } else {

    /* otherwise just report nothing */
    return(NULL);
  }
}

/*
 * Brian Kolaci
 * quick implementation of the scandir() BSD function
 */
int bkscandir(const char *dirname,
              struct dirent ***namelist,
	      int (*select)(struct dirent *),
	      int (*compar)(const void *, const void *))
{
  int i;
  int entries;
  int esize;
  struct dirent* dp;
  struct dirent* dent;
  DIR * dirp;

  *namelist = NULL;
  entries = esize = 0;

  /* load the names */
  if ((dirp = opendir(dirname)) == NULL)
    return -1;

  while ((dp = readdir(dirp)) != NULL) {
    if (select == NULL || (*select)(dp)) {
      if (entries >= esize) {
        void* mem;
        esize += 10;
        if ((mem = realloc(*namelist, esize * sizeof(struct dirent*))) == NULL) {
          for (i = 0; i < entries; i++)
            free((*namelist)[i]);
          free(*namelist);
          closedir(dirp);
          return -1;
        }
        *namelist = (struct dirent**)mem;
      }
      if ((dent = (struct dirent*)malloc(sizeof(struct dirent)+MAX_FILE_NAME)) == NULL) {
        for (i = 0; i < entries; i++)
          free((*namelist)[i]);
        free(*namelist);
        closedir(dirp);
        return -1;
      }
      memcpy(dent, dp, sizeof(*dp)+MAX_FILE_NAME);
      (*namelist)[entries] = dent;
      entries++;
    }
  }
  closedir(dirp);

  /* sort them */
  if (compar)
    qsort((void*)*namelist, entries, sizeof(struct dirent*), compar);
  return entries;
}
/* 
 * Copyright (C) 1999-2002 Inter7 Internet Technologies, Inc. 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <dirent.h>
#include "config.h"
#include "qmailadmin.h"
#include "qmailadminx.h"

extern FILE *lang_fs;
extern FILE *color_table;


check_local_user( user )
 char *user;
{
 struct stat buf;
 int i,j;

  strcpy(TmpBuf, ".qmail-");
  for(i=0,j=7;user[i]!=0;++i,++j){
    if ( user[i] == '.' ) TmpBuf[j] = ':'; 
    else TmpBuf[j] = user[i];
  }
  TmpBuf[j] = 0;

  if ( stat(TmpBuf, &buf) == 0 ) return(-1);
  if ( vauth_getpw(user, Domain)) return(-1);

  return(0);
}

show_counts()
{
  count_users();
  count_aliases();
  count_forwards();
  count_autoresponders();
  count_mailinglists();

  fprintf(actout, "Pop accounts   = %d<BR>\n", CurPopAccounts);
  fprintf(actout, "Aliases        = %d<BR>\n", CurAliases);
  fprintf(actout, "Forwards       = %d<BR>\n", CurForwards);
  fprintf(actout, "Autoresponders = %d<BR>\n", CurAutoResponders);
  fprintf(actout, "Mailing lists  = %d<BR>\n", CurMailingLists);

}

check_email_addr( addr )
 char *addr;
{
 char *taddr = addr;


  if(strlen(taddr)<0) return(1);
  for(taddr=addr;*taddr!=0;++taddr) {
    if(!isalnum(*taddr) && !ispunct(*taddr)) {
      return(1);
    }
  }

  /* force to lower */
  lowerit(addr);

  for(taddr=addr;*taddr!='@'&&*taddr!=0;++taddr) {
    if ( isspace(*taddr) ) return(1);
    if(ispunct(*taddr) && 
       *taddr!='.' && *taddr!='-' && *taddr!='+' && *taddr!='=' &&
       *taddr!='_') {
      return(1);
    }
  }

  /* if just a user name with no @domain.com then bad */
  if (*taddr==0) return(1);

  /* Look for a sub domain */
  for(;*taddr!='.'&&*taddr!=0;++taddr);

  if (*taddr==0) return(1);
  return(0);
}

fixup_local_name( addr )
 char *addr;
{
 char *taddr = addr;

  /* don't allow zero length user names */
  if(strlen(taddr)<=0) return(1);

  /* force it to lower case */
  lowerit(addr);

  /* check for valid email address */
  for(taddr=addr;*taddr!=0;++taddr) {

    if(!isalnum(*taddr) && !ispunct(*taddr)) return(1);
    if(isspace(*taddr)) return(1);

    if(ispunct(*taddr)&&*taddr!='-'&&*taddr!='.'&&*taddr!='_' &&
               *taddr!='+' && *taddr!='=') {
      if(*taddr!='.') return(1);
    }
  }

  /* if we made it here, everything is okay */
  return(0);
}

ack(msg, c)
 char *msg;
 int c;
{
  fprintf(actout,"%s\n", msg);
  fprintf(actout,"</BODY></HTML>\n", msg);
  vclose();
  exit(0);
}

upperit( instr )
 char *instr;
{
  while(*instr!=0) {
    if ( islower(*instr) ) *instr = toupper(*instr);
    ++instr;
  }
}

char *safe_getenv(char *var)
{
 char *s;

  s = getenv(var);
  if ( s == NULL ) return("");
  return(s);
}

char *strstart(sstr, tstr)
 char *sstr;
 char *tstr;
{
 char *ret_str;

  ret_str = sstr;
  if ( sstr == NULL || tstr == NULL ) return(NULL);

  while ( *sstr != 0 && *tstr != 0 ) {
    if ( *sstr != *tstr ) return(NULL);
    ++sstr;
    ++tstr;
  }

  if ( *tstr == 0 ) return(ret_str);
  return(NULL);

}

int open_lang( char *lang)
{
 char tmpbuf[200];
 char *tmpstr;
 struct stat mystat;

  /* do not read lang files with path control characters */
  if ( strstr(lang,".")!=NULL || strstr(lang,"/")!=NULL ) return(-1);

  if ( lang_fs == NULL ) {
    tmpstr = getenv(QMAILADMIN_TEMPLATEDIR);
    if (tmpstr == NULL ) tmpstr = HTMLLIBDIR;

    snprintf(tmpbuf, 200, "%s/%s", tmpstr, lang);

    /* do not open symbolic links */ 
    if (lstat(tmpbuf, &mystat)==-1 || S_ISLNK(mystat.st_mode)) return(-1);

    if ( (lang_fs=fopen(tmpbuf, "r"))==NULL) return(-1);
  }
  return(0);
}

char *get_html_text( char *index )
{
 char *tmpbuf;
 char *tmpstr;

  tmpbuf = malloc(400);

  if (lang_fs == NULL) return("");

  rewind(lang_fs);
  while(fgets(tmpbuf,400,lang_fs)!=NULL){
    tmpstr = strtok(tmpbuf, " ");
    if (strcmp(tmpstr, index) == 0 ) {
      tmpstr = strtok(NULL, "\n");
      return(tmpstr);
    }    
  }
  return("");
}

int open_colortable()
{
 char tmpbuf[200];
 char *tmpstr;

  tmpstr = getenv(QMAILADMIN_TEMPLATEDIR);
  if (tmpstr == NULL ) tmpstr = HTMLLIBDIR;

  snprintf(tmpbuf, 200, "%s/colortable", tmpstr);
  if ( (color_table=fopen(tmpbuf, "r"))==NULL) return(-1);
  return(0);
}

char *get_color_text( char *index )
{
 char *tmpbuf;
 char *tmpstr;

  tmpbuf = malloc(400);

  if (color_table == NULL) return("");

  rewind(color_table);
  while(fgets(tmpbuf,400,color_table)!=NULL){
    tmpstr = strtok(tmpbuf, " ");
    if (strcmp(tmpstr, index) == 0 ) {
      tmpstr = strtok(NULL, "\n");
      return(tmpstr);
    }    
  }
  return("");
}
char *get_quota_used(char *dir) {
    char *tmpstr;
    char tmpbuff[MAX_BUFF];
    double size;

    size = get_du(dir);
    if (size > 0) {
        size = size / 1048576;  // Convert to MBs.
    }
    sprintf(tmpbuff, "%-2.2lf", size);
    tmpstr = tmpbuff;
    return tmpstr;
}
int quota_to_bytes(char returnval[], char *quota) {
    char *tmpstr;
    double tmp;

    if (quota == NULL) { return 1; }
    if (tmp = atol(quota)) { tmp *= 1048576; }
    else { return 1; }
    sprintf(returnval, "%-2.2lf", tmp);
    return 0;
}
int quota_to_megabytes(char returnval[], char *quota) {
    char *tmpstr;
    double tmp;

    if (quota == NULL) { return 1; }
    if (tmp = atol(quota)) {
         if (tmp != 0) { tmp /= 1048576.0; }
    }
    else { return 0; }
    sprintf(returnval, "%-2.2lf", tmp);
    return 0;
}

/*
 * Brian Kolaci
 * updated function that doesn't require fts_*
 */
off_t get_du(const char *dir_name)
{
  DIR *dirp;
  struct dirent *dp;
  struct stat statbuf;
  off_t file_size = 0;
  char *tmpstr;

  if (dir_name == NULL)
    return 0;

  if (chdir(dir_name) == -1)
    return 0;

  if ((dirp = opendir(".")) == NULL)
    return 0;

  while ((dp=readdir(dirp)) != NULL) {
    if (!strcmp(dp->d_name, "..") || !strcmp(dp->d_name, "."))
      continue;
    if ((tmpstr=strstr(dp->d_name, ",S=")) != NULL) {
      file_size += atol(tmpstr+3);
    } else if (stat(dp->d_name,&statbuf)==0 && (statbuf.st_mode & S_IFDIR) ) {
      file_size += get_du(dp->d_name);
    }
  }
  closedir(dirp);
  if (dir_name != NULL && strcmp(dir_name, ".." ) && strcmp(dir_name, "." ))
    chdir("..");
  return(file_size);
}

Reply via email to