/*
 * AUTHOR: Pedro Lineu Orso                             orso@brturbo.com
 *                                                            1998, 2004
 * ADMUSER, Squid, Apache User Administrator       http://sarg-squid.org
 * ---------------------------------------------------------------------
 *
 *  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, USA.
 *
 */


#include "conf.h"

#define MAXLEN 1024
#define hhex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || \
                  ((x) >= 'A' && (x) <= 'F'))
#define null ""
#define pwd_file_default "/usr/local/squid/etc/passwd"

char            Msg[MAXLEN];
char            buf[MAXLEN];
char            search_arg[255];
char 		template[30]="/var/tmp/admuser.XXXXXX";
int	        from=1;
int		fd;
FILE           *fpw,
               *tmp;

main(argc, argv)
    int             argc;
    char           *argv[];
{

    char            user[255];
    char            pass[255];
    char            olduser[255];
    char            Action[255];
    char	    ConfigFile[255];
    char            PwdFile[MAXLEN]="/usr/local/etc/admuser/pwd_files";
    char	    BgColor[255]="white";
    char	    TiColor[255]="green";
    char	    TxColor[255]="blue";
    char	    RuColor[255]="red";
    char	    Logo[MAXLEN]="";
    char	    Width[MAXLEN]="80";
    char	    Height[MAXLEN]="80";
    char	    Header[MAXLEN];
    char	    BgImage[MAXLEN]="";
    char            InputBuffer[1024];
    char	    function[2];
    char            warea[255];
    char	    action[20];
    char           *pContentLength;
    char           *str;
    char           *cpw,
                    salt[3];
    int             ContentLength;
    int             i;
    int             x;
    int             ok = 0;

    fpw = NULL;
    tmp = NULL;

    buf[0]='\0';
    Action[0]='\0';
    Msg[0]='\0';
    search_arg[0]='\0';
    strcpy(ShowInfo,"on");

    /* Set the Real UID to the Effective UID so that access(2) works */
    setuid(geteuid());

    strcpy(Header,msg09);

    sprintf(ConfigFile,"%s/admuser.conf",PREFIX);
    if (access(ConfigFile, R_OK) == 0) { 
       getconf(ConfigFile,PwdFile,BgColor,TxColor,TiColor,RuColor,Logo,Width,Height,Header,BgImage);
    }

    if(argc>1) {
       if(strncmp(argv[1],"change",6) == 0) {
          change_user(argv[1],TiColor,Header,null);
          return;
       }
       if(strncmp(argv[1],"remove",6) == 0) {
          confirm_remove_user(argv[1],TiColor,Header);
          return;
       }
       if(strncmp(argv[1],"expire",6) == 0) {
          expire_pwd(argv[1],TiColor,Header,null);
          return;
       }
       if(strncmp(argv[1],msg19,strlen(msg19)) == 0) {
          disable_user(argv[1],TiColor,Header);
          return;
       }
       if(strncmp(argv[1],msg29,strlen(msg29)) == 0) {
          enable_user(argv[1],TiColor,Header);
          return;
       }
       if(strncmp(argv[1],"adduser",7) == 0) {
          add_user(argv[1],TiColor,Header,null);
          return;
       }
       if(strncmp(argv[1],"sort",4) == 0) {
          sort_pwd_file(argv[1],TiColor,Header);
          return;
       }
       if(strncmp(argv[1],"read",4) == 0) {
          strcpy(warea,argv[1]);
          getword(function,warea,'&');
          function[strlen(function)-1]='\0';
          getword(PwdFile,warea,'&');
          PwdFile[strlen(PwdFile)-1]='\0';
          from=atoi(warea);
          read_pwd_file(PwdFile,TiColor,Header,null,null,null,from,null);
          return;
       }
    }

    if (strcmp(getenv("REQUEST_METHOD"), "GET") == 0) {
	UserForm(BgColor,TxColor,TiColor,RuColor,Logo,Width,Height,Header,BgImage,PwdFile);
	return;
    }

    pContentLength = getenv("CONTENT_LENGTH");

    if (pContentLength != NULL)
	ContentLength = atoi(pContentLength);
    else
	ContentLength = 0;


    if (ContentLength > sizeof(InputBuffer) - 1) {
	ContentLength = sizeof(InputBuffer) - 1;
    }
    i = 0;

    while (i < ContentLength) {
	x = fgetc(stdin);
	if (x == EOF)
	    break;
	InputBuffer[i++] = x;
    }

    InputBuffer[i] = '\0';
    ContentLength = i;
    fix_string(InputBuffer);

    getword(function, InputBuffer, '=');
    getword(function, InputBuffer, '&');

    // Authenticating
    if(strncmp(function,"0",1) == 0) {
       getword(user,InputBuffer,'=');
       getword(user,InputBuffer,'&');
       getword(pass,InputBuffer,'=');
       getword(pass,InputBuffer,'&');
       go_Authenticate(user, pass, PwdFile, BgColor, TxColor, TiColor, RuColor, Logo, Width, Height, Header, BgImage);
    }

    // Reading password file
    if(strncmp(function,"1",1) == 0) {
       getword(PwdFile,InputBuffer,'=');
       getword(PwdFile,InputBuffer,'&');
       if(strlen(PwdFile) == 1) {
          Herror(msg08, fpw, tmp);
          return;
       }
       if(access(PwdFile, F_OK) != 0) {
	  sprintf(Msg, "%s: %s",msg40, PwdFile);
          Herror(Msg, fpw, tmp);
          return;
       }
       if(access(PwdFile, R_OK) != 0) {
	  sprintf(Msg, "%s: %s",msg41, PwdFile);
          Herror(Msg, fpw, tmp);
          return;
       }
       read_pwd_file(PwdFile,TiColor,Header,null,null,null,from,null);
       return;
    }

    // Changing user
    if(strncmp(function,"2",1) == 0) {
       getword(user,InputBuffer,'=');
       getword(user,InputBuffer,'&');
       getword(pass,InputBuffer,'=');
       getword(pass,InputBuffer,'&');
       if(strncmp(NcsaPlus,"on",2) == 0) {
          getword(ip,InputBuffer,'=');
          getword(ip,InputBuffer,'&');
       }
       getword(olduser,InputBuffer,'=');
       getword(olduser,InputBuffer,'&');
       getword(PwdFile,InputBuffer,'=');
       getword(PwdFile,InputBuffer,'&');
       getword(warea,InputBuffer,'=');
       getword(warea,InputBuffer,'&');
       from=atoi(warea);
       getword(action,InputBuffer,'=');
       getword(action,InputBuffer,'&');
       if(strcmp(action,msg24) == 0) {
          read_pwd_file(PwdFile,TiColor,Header,null,null,null,from,null);
          return;
       }
       go_change_user(user, pass, olduser, PwdFile, TiColor, Header, from);
       return;
    }

    // Adding user
    if(strncmp(function,"3",1) == 0) {
       getword(user,InputBuffer,'=');
       getword(user,InputBuffer,'&');
       getword(pass,InputBuffer,'=');
       getword(pass,InputBuffer,'&');
       if(strncmp(NcsaPlus,"on",2) == 0) {
          getword(ip,InputBuffer,'=');
          getword(ip,InputBuffer,'&');
       }
       getword(PwdFile,InputBuffer,'=');
       getword(PwdFile,InputBuffer,'&');
       getword(action,InputBuffer,'=');
       getword(action,InputBuffer,'&');
       if(strcmp(action,msg24) == 0) {
          read_pwd_file(PwdFile,TiColor,Header,null,null,null,from,null);
          return;
       }
       go_add_user(user, pass, PwdFile, TiColor, Header);
       return;
    }

    // Removing user
    if(strncmp(function,"4",1) == 0) {
       getword(user,InputBuffer,'=');
       getword(user,InputBuffer,'&');
       getword(PwdFile,InputBuffer,'=');
       getword(PwdFile,InputBuffer,'&');
       getword(warea,InputBuffer,'=');
       getword(warea,InputBuffer,'&');
       getword(action,InputBuffer,'=');
       getword(action,InputBuffer,'&');
       if(strcmp(action,msg32) == 0) {
          read_pwd_file(PwdFile,TiColor,Header,null,null,null,warea,null);
          return;
       }
       remove_user(user, PwdFile, TiColor, Header, warea);
       return;
    }

    // Searching user
    if(strncmp(function,"5",1) == 0) {
       getword(PwdFile,InputBuffer,'=');
       getword(PwdFile,InputBuffer,'&');
       getword(search_arg,InputBuffer,'=');
       getword(search_arg,InputBuffer,'&');
       read_pwd_file(PwdFile,TiColor,Header,null,null,null,from,search_arg);
       return;
    }
     
    return;
}


void
getword(char *word, char *line, char stop)
{
    int             x = 0,
                    y;

    for (x = 0; ((line[x]) && (line[x] != stop)); x++)
	word[x] = line[x];

    word[x] = '\0';
    if (line[x])
	++x;
    y = 0;

    while ((line[y++] = line[x++]));
}


void
Herror(char *msg, FILE * fpw, FILE * tmp)
{
   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("  <meta http-equiv=refresh content=\"5; url=admuser.cgi\">\n");
   printf("</head>\n");
   printf("<center>\n");
   printf("<br><br><br><br>\n");
   printf("<table border=0 bgcolor=black cellpadding=10>\n");
   printf("<tr><td><font color=red size=+1>%s</font></td></tr>\n", msg);
   printf("</center></table>\n");
   printf("<br><center><font size=-1 color=black>%s...</font></center>\n",msg07);
   if (fpw)
      fclose(fpw);
   if (tmp) {
      fclose(tmp);
      unlink(tmp);
   }

   fflush(stdout);
   return;
}


void
Xerror(char *msg)
{
   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("</head>\n");
   printf("<center>\n");
   printf("<br><br><br><br>\n");
   printf("<table border=0 bgcolor=black cellpadding=10>\n");
   printf("<tr><td><font color=red size=+1>%s</font></td></tr>\n", msg);
   printf("</center></table>\n");

   fflush(stdout);
   exit(-1);
}


void
putline(FILE * f, char *l)
{
    int             x;

    for (x = 0; l[x]; x++)
	fputc(l[x], f);
// fputc('\n',f);
}


static unsigned char itoa64[] =	/*
				 * 0 ... 63 => ascii - 64 
				 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

to64(s, v, n)
    register char  *s;
    register long   v;
    register int    n;
{
    while (--n >= 0) {
	*s++ = itoa64[v & 0x3f];
	v >>= 6;
    }
}


static void
fix_string(str)
        unsigned char   *str;
{
        unsigned char   *dest = str;

        while (str[0])
        {
                if (str[0] == '+')
                        dest[0] = ' ';
                else if (str[0] == '%' && hhex(str[1]) && hhex(str[2]))
                {
                        dest[0] = (unsigned char) htoi(str + 1);
                        str += 2;
                }
                else
                        dest[0] = str[0];

                str++;
                dest++;
        }

        dest[0] = '\0';
	return;

}


static int multiple_pwd(char *pwdfile)
{

   char warea[255];
   int lines=0;

   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s", msg02, pwdfile);
      Xerror(Msg);
   }

   while (fgets(buf, MAXLEN, fpw) != NULL) {
      if(strncmp(buf,"#",1) == 0)
         continue;
      strcpy(warea,buf);
      lines++;
   }
   fclose(fpw);

   if(lines == 1)
      getword(pwdfile,warea,';');
   return(lines);
}


static int
htoi(s)
        unsigned char   *s;
{
        int     value;
        char    c;

        c = s[0];
        if (isupper(c))
                c = tolower(c);
        value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;

        c = s[1];
        if (isupper(c))
                c = tolower(c);
        value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;

        return (value);
}


void space2us(char * user) {
   int len=strlen(user);
   for(len=strlen(user);len;len--) {
      if(user[len]==' ')
         user[len]='_';
   }
}

void getconf(char *ConfigFile, char *PwdFile, char *BgColor, char *TxColor, char *TiColor, char *RuColor, char *Logo, char *Width, char *Height, char *Header, char *BgImage)
{
        
        FILE *fp_in;
        char buf[255];
        char wbuf[255];
	char Msg[255];
	char *str;
	int lenbuf;

        if ((fp_in = fopen(ConfigFile, "r")) == NULL) {
            sprintf(Msg, "%s %s", msg05, ConfigFile);
	    Xerror(Msg);
	}

	while (fgets(buf, MAXLEN, fp_in) != NULL) {
	   if((str=(char *) strstr(buf,"#")) != (char *) NULL) 
	      continue;

           if(strstr(buf,"\n") != 0)
              buf[strlen(buf)-1]='\0';

           lenbuf=strlen(buf);
           while((lenbuf)&&buf[lenbuf-1]==' ')
              buf[--lenbuf]='\0';

           if(strstr(buf,"password_file") != 0) {
              getword(wbuf,buf,' ');
              strcpy(PwdFile,buf);
              strcpy(pwdfile2,buf);
           }

           if(strstr(buf,"background_color") != 0) {
              getword(wbuf,buf,' ');
              strcpy(BgColor,buf);
           }

           if(strstr(buf,"text_color") != 0) {
              getword(wbuf,buf,' ');
              strcpy(TxColor,buf);
           }

           if(strstr(buf,"title_color") != 0) {
              getword(wbuf,buf,' ');
              strcpy(TiColor,buf);
           }

           if(strstr(buf,"logo_image") != 0) {
              getword(wbuf,buf,' ');
              strcpy(Logo,buf);
           }

           if(strstr(buf,"background_image") != 0) {
              getword(wbuf,buf,' ');
              strcpy(BgImage,buf);
           }

           if(strstr(buf,"show_info") != 0) {
              getword(wbuf,buf,' ');
              strcpy(ShowInfo,buf);
           }

           if(strstr(buf,"ncsa_plus") != 0) {
              getword(wbuf,buf,' ');
              strcpy(NcsaPlus,buf);
           }

           if(strstr(buf,"image_size") != 0) {
              getword(wbuf,buf,' ');
              getword(Width,buf,' ');
              strcpy(Height,buf);
           }

           if(strstr(buf,"header") != 0) {
              getword(wbuf,buf,'"');
              getword(Header,buf,'"');
           }

	}
	
        fclose(fp_in);
	return;
}


eperror(s)
register char *s;
{
   perror("admuser.cgi");
   exit(1);

}


void get_pwd_files(char *pwdfile)
{

   int count=0;
   char fpwd[255];
   char alias[255];

   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   while(fgets(buf, MAXLEN, fpw) != NULL) {
      buf[strlen(buf)-1]='\0';
      if(strcmp(buf,"/etc/passwd") == 0 || strcmp(buf,"/etc/shadow") == 0 \
		|| strncmp(buf,"#",1) == 0 || strncmp(buf," ",1) == 0)
         continue;
      if(strstr(buf,";") != 0) {
         getword(fpwd,buf,';');
         strcpy(alias,buf);
      } else {
         strcpy(fpwd,buf);
         bzero(alias,255);
      }

      printf("<option value='%s'>%s\n",fpwd,alias);
      count++;
   }

   if(!count)
      printf("<option values='%s'>%s\n",pwd_file_default,pwd_file_default);
   fclose(fpw);
   return;
}


void read_pwd_file(char *pwdfile, char *ticolor, char *header, char *msg, char *fuser, char *msg2, int from, char *search)
{
   char read_user[255];
   char read_pwd[255];
   char read_ip[25];
   char read_changed[25];
   char status[30];
   char able[30];
   char able2[30];
   char color[10];
   char ucolor[10];
   char tcolor[10];
   char xcolor[10];
   int  lines=1;
   int  lnum;
   int  count=0;
   unsigned long int nreg=0;
   int  p1=0, p2=0, p3=0, p4=0;

   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   while(fgets(buf, MAXLEN, fpw) != NULL)
      nreg++;
   fclose(fpw);

   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   if((from==0)||(from > nreg))
      from=nreg-14;
   if(from<=0)
      from=1;
   lnum=from;

   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("</head>\n");
   printf("<center>\n");
   printf("<font color=%s size=+1>%s</font>\n",ticolor,header);
   printf("<table border=0 cellpadding=0 cellspacing=2>\n");
   printf("<tr><td></td><th><font size=-2 color=gray>%s:</font></th><td><font size=-2>%s</font></td><td></td><td></td><th><font size=-2 color=gray>%s:</th><td><font size=-2>%ld",msg20,pwdfile,msg25,nreg);

   if(strncmp(NcsaPlus,"on",2) == 0)
      printf("<td></td><td></td><th><font size=-2 color=gray>%s:</font></th><td><font size=-2>NCSA_PLUS</font></td></tr>\n",msg48);
   else
      printf("<td></td><td></td><th><font size=-2 color=gray>%s:</font></th><td><font size=-2>NCSA</font></td></tr>\n",msg48);
    
   printf("</table>\n");
   printf("<table border=0 cellpadding=0 cellspacing=2>\n");
   printf("<tr><td></td></tr>\n");
   printf("<tr><td></td></tr>\n");
   printf("<tr><td></td></tr>\n");

   if(strncmp(NcsaPlus,"on",2) == 0)
      printf("<tr><td></td><th bgcolor=lavender><font size=-1>%s</font></th><td></td><td></td><th bgcolor=lavender><font size=-1>%s</font></th><td></td><td></td><th bgcolor=lavender><font size=-1>%s</font></th><td></td><td></td><th align=center colspan=10 bgcolor=lavender><font size=-1>%s</font></th></tr>\n",msg15,msg49,msg50,msg16);
   else
      printf("<tr><td></td><th bgcolor=lavender>%s</th><td></td><td></td><th align=center colspan=7 bgcolor=lavender>%s</th ></tr>\n",msg15,msg16);

   count=0;
   while(fgets(buf, MAXLEN, fpw) != NULL && lines <= 15) {
      if(strlen(search)>0) {
         if(strstr(buf,search) == 0)
            continue;
      }
      count++;
      if(count < from)
         continue;
      getword(read_user,buf,':');
      getword(read_pwd,buf,':');
      getword(read_changed,buf,':');
      getword(read_ip,buf,'\n');
 
      if(strncmp(read_ip,"*",1) == 0)
         strcpy(read_ip,msg51);

      if(strncmp(read_pwd,"*",1) == 0) {
         strcpy(able,msg29);
         strcpy(color,"green");
         strcpy(ucolor,"red");
      } else {
         strcpy(able,msg19);
         strcpy(color,"red");
         strcpy(ucolor,"green");
      }

      strcpy(status," ");
      if(strcmp(read_user,fuser) == 0)
         strcpy(status,msg2);

      tt=atoi(read_changed);
      t=localtime(&tt);
      strftime(timebuf, 127, "%Y/%b/%d", t);

      if(strncmp(timebuf,"1969/Dec/31",11) == 0) {
         strcpy(tcolor,"orange");
         strcpy(xcolor,"green");
         sprintf(timebuf,"%s",msg54);
         strcpy(able2,msg53);
      } else {
         strcpy(tcolor,"green");
         strcpy(xcolor,"orange");
         strcpy(able2,msg52);
      }

      if(strncmp(NcsaPlus,"on",2) == 0)
         printf("<tr><td align=right><font size=-2 color=gray>%d</font></td><td bgcolor=beige><font size=-1 color=%s>%s</font></td><td></td><td></td><td align=center bgcolor=beige><font size=-1 color=%s>%s</font></td><td></td><td></td><td align=center bgcolor=beige><font size=-1>%s</font></td><td></td><td></td><td><font size=-1><a href='admuser.cgi?change&%s&%s&%d'><font size=-1>%s</font></a></font></td><td></td><td></td><td><font size=-1><a href='admuser.cgi?remove&%s&%s&%d'><font size=-1>%s</font></a></font></td><td></td><td></td><td><a href='admuser.cgi?%s&%s&%s&%d'><font size=-1 color=%s>%s</font></a></font></td><td></td><td></td><td><font size=-1><a href='admuser.cgi?expire&%s&%s&%d'><font size=-1 color=%s>%s</font></a></font></td></tr>\n",lnum,ucolor,read_user,tcolor,timebuf,read_ip,read_user,pwdfile,from,msg17,read_user,pwdfile,from,msg18,able,read_user,pwdfile,from,color,able,read_user,pwdfile,from,xcolor,able2);
      else
         printf("<tr><td align=right><font size=-2 color=gray>%d</font></td><td bgcolor=beige><font size=-1 color=%s>%s</font></td><td><font color=red size=-2>%s</font></td><td></td><td><font size=-1><a href='admuser.cgi?change&%s&%s&%d'><font size=-1>%s</font></a></font></td><td></td><td></td><td><font size=-1><a href='admuser.cgi?remove&%s&%s&%d'><font size=-1>%s</font></a></font></td><td></td><td></td><td><a href='admuser.cgi?%s&%s&%s&%d'><font size=-1 color=%s>%s</font></a></font></tr>\n",lnum,ucolor,read_user,status,read_user,pwdfile,from,msg17,read_user,pwdfile,from,msg18,able,read_user,pwdfile,from,color,able);
      lines++;
      lnum++;
   }

   printf("</table>\n");
   printf("</center>\n");

   p1=(lnum<nreg) ? lnum : nreg ;
   p2=((p1+14)<=nreg) ? p1+14 : nreg ;

   p3=(from<=15) ? 1 : from-15;
   p4=((p3+14)<=nreg) ? p3+14 : nreg ;

   printf("<center>\n");
   printf("<table>\n");

   if(strlen(msg)>2)
      printf("<tr><td></td><td align=left><a href='admuser.cgi?adduser&%s'><font size=-1>%s</font></a></td><td><font color=red size=-2>%s</td><td><a href='admuser.cgi?sort&%s'><font size=-1>%s</font></a></td><td><a href='admuser.cgi'><font size=-1>%s</font></a></td>\n",pwdfile,msg33,msg,pwdfile,msg47,msg26);
   else
      printf("<tr><td></td><td align=left><a href='admuser.cgi?adduser&%s'><font size=-1>%s</font></a></td><td><a href='admuser.cgi?sort&%s'><font size=-1>%s</font></a></td><td><a href='admuser.cgi'><font size=-1>%s</font></a></td>\n",pwdfile,msg33,pwdfile,msg47,msg26);

   printf("<form action='admuser.cgi' method=POST>\n");
   printf("<input type=hidden name=function value='5'>\n");
   printf("<input type=hidden name=pwdfile value='%s'>\n",pwdfile);
   printf("<td></td><td><font size=-1>%s <input type=text name=arg size=10></font><font size=-2> <input type=submit name=go value=' %s '></font></td></tr>\n",msg46,msg22);
   printf("</form>\n");

   printf("<tr>");
   if(from==1)
      printf("<td></td>");
   if((p1<nreg)||(p1==lnum))
      printf("<td><a href='admuser.cgi?read&%s&%d'><font size=-1>%s</font></a><font size=-1 color=gray> (%d-%d)</font></td>",pwdfile,p1,msg42,p1,p2);
   else printf("<td></td>");
   if(from>1)
      printf("<td><a href='admuser.cgi?read&%s&%d'><font size=-1>%s</font></a><font size=-1 color=gray> (%d-%d)</font></td>",pwdfile,p3,msg43,p3,p4);
   printf("<td><a href='admuser.cgi?read&%s&1'><font size=-1>%s</font></a></td><td><a href='admuser.cgi?read&%s&0'><font size=-1>%s</font></a></td><td></td><td></td></tr>\n",pwdfile,msg44,pwdfile,msg45);
   printf("</table>\n");
   if(strcmp(ShowInfo,"on") == 0)
      printf("<font size=-2><a href='%s'>%s-%s</a></font>\n",URL,PGM,VERSION);
   printf("</center>\n");
   printf("</html>\n");
   fclose(fpw);
   return;

}


void change_user(char *arg, char *ticolor, char *header, char *msg)
{
   char function[20];
   char user[255];
   char wuser[255];
   char pwdfile[255];
   char pass[255];
   char wfrom[6];
   int  from=0;

   pass[0]='\0';
   getword(function,arg,'&');
   function[strlen(function)-1]='\0';
   getword(user,arg,'&');
   user[strlen(user)-1]='\0';
   strcpy(wuser,user);
   getword(pwdfile,arg,'&');
   pwdfile[strlen(pwdfile)-1]='\0';
   getword(wfrom,arg,'&');
   from=atoi(wfrom);

   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   bzero(ip,30);
   while(fgets(buf, MAXLEN, fpw) != NULL) {
      if(strncmp(buf,user,strlen(user)) == 0) {
         getword(zbuf,buf,':');
         getword(zbuf,buf,':');
         getword(zbuf,buf,':');
         getword(ip,buf,'\n');
      }
   }

   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("</head>\n");
   printf("<h3 align=center><font color=%s>%s</font></h3>\n",ticolor,header);
   printf("<center>%s: <font color=red>%s</font>\n",msg21,user);
   printf("<br><br>\n");
   printf("<table border=1 cellpadding=5 bgcolor=beige>\n");
   printf("<form action='admuser.cgi' method=POST>\n");
   printf("<input type=hidden name=function value='2'>\n");
   printf("<tr><td align=right><font size=-1>%s</font></td><td align=left><input type=text name=user value='%s'></td></tr>\n",msg04,user);
   printf("<tr><td align=right><font size=-1>%s</font></td><td align=left><input type=password name=pass value='%s'></td></tr>\n",msg23,pass);

   if(strncmp(NcsaPlus,"on",2) == 0)
      printf("<tr><td align=right><font size=-1>%s (%s)</font></td><td align=left><input type=text name=ipaddr value='%s'></td></tr>\n",msg55,msg56,ip);

   printf("</table>");
   printf("<br><br><font size=-1>\n");
   printf("<input type=hidden name=olduser value='%s'>\n",wuser);
   printf("<input type=hidden name=pwdfile value='%s'>\n",pwdfile);
   printf("<input type=hidden name=from value='%d'>\n",from);
   printf("<input type=submit name=go value=' %s '>\n",msg22);
   printf("<input type=submit name=go value='%s'>\n",msg24);
   printf("</font>\n");
   printf("</form>\n");
   if(strlen(msg) > 0)
      printf("<table cellpadding=10><tr><th bgcolor=black><font color=red size=+1>%s</font></th></tr></table>\n",msg);
   printf("</center>\n");
   printf("</html>\n");
   return;
}


void go_change_user(char *user, char *pass, char *olduser, char *pwdfile, char *ticolor, char *header, int from)
{

   char *cpw;
   char salt[3];
   char wuser[255];
   char pwd[255];
   char changed[20];
   char ip2[20];

   space2us(user);

   if(strlen(user) < 1) {
      read_pwd_file(pwdfile,ticolor,header,null,user,msg35,from,null);
      return;
   }
   tmp = NULL;
   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   fd = mkstemp(template);
   if((fd == -1 ) || ((tmp = fdopen (fd, "w+" )) == NULL)  ) {
      sprintf(Msg, "1%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   while(fgets(buf, MAXLEN, fpw) != NULL) {
      strcpy(zbuf,buf);
      getword(wuser,buf,':');

      if(strncmp(NcsaPlus,"on",2) == 0) {
         getword(pwd,buf,':');
         getword(changed,buf,':');
         getword(ip2,buf,'\n');
         if(strlen(ip)<4) strcpy(ip2,"*");
         if(strcmp(ip,ip2) != 0) strcpy(ip2,ip);
      } else getword(pwd,buf,'\n');

      if(strncmp(wuser,olduser,strlen(olduser)) == 0) {
          if(strlen(pass) == 0)
             strcpy(pass,pwd);
          (void) srand((int) time((time_t *) NULL));
	  to64(&salt[0], rand(), 2);
	  cpw = crypt(pass, salt);
          if(strncmp(NcsaPlus,"on",2) == 0) {
             tt=time(NULL);
	     sprintf(zbuf, "%s:%s:%d:%s\n",user,cpw,tt,ip2);
	  } else sprintf(zbuf, "%s:%s\n",user,cpw);
      }
      putline(tmp, zbuf);
   }
   fclose(tmp);

   if((tmp = fopen(template, "r")) == NULL) {
      sprintf(Msg, "2%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   authfiles(pwdfile);
   if((fpw = fopen(pwdfile, "w")) == NULL) {
      sprintf(Msg, "%s",msg02);
      Herror(Msg, fpw, fpw);
      return;
   }

   while (fgets(buf, MAXLEN, tmp) != NULL)
      fputs(buf,fpw);

   fclose(fpw);
   fclose(tmp);
   unlink(template);

   read_pwd_file(pwdfile,ticolor,header,null,user,msg35,from,null);
   return;
}


void remove_user(char *user, char *pwdfile, char *ticolor, char *header, char *wfrom)
{

   int from=0;
 
   from=atoi(wfrom);

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   tmp = NULL;
   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   fd = mkstemp(template);
   if((fd == -1 ) || ((tmp = fdopen (fd, "w+" )) == NULL)  ) {
      sprintf(Msg, "3%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   while(fgets(buf, MAXLEN, fpw) != NULL) {
      if(strncmp(buf,user,strlen(user)) == 0)
         continue;
      putline(tmp, buf);
   }
   fclose(tmp);

   if((tmp = fopen(template, "r")) == NULL) {
      sprintf(Msg, "4%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   authfiles(pwdfile);
   if((fpw = fopen(pwdfile, "w")) == NULL) {
      sprintf(Msg, "%s",msg02);
      Herror(Msg, fpw, fpw);
      return;
   }

   while (fgets(buf, MAXLEN, tmp) != NULL)
      fputs(buf,fpw);

   fclose(fpw);
   fclose(tmp);
   unlink(template);

   read_pwd_file(pwdfile,ticolor,header,null,null,null,from,null);

   return;

}


void expire_pwd(char *arg, char *ticolor, char *header, char *msg)
{
   char function[20];
   char user[255];
   char pwd[255];
   char changed[2];
   char auth_ip[20];
   char wuser[255];
   char pwdfile[255];
   char wfrom[6];
   int  from=0;

   getword(function,arg,'&');
   function[strlen(function)-1]='\0';
   getword(user,arg,'&');
   user[strlen(user)-1]='\0';
   strcpy(wuser,user);
   getword(pwdfile,arg,'&');
   pwdfile[strlen(pwdfile)-1]='\0';
   getword(wfrom,arg,'&');
   from=atoi(wfrom);

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   tmp = NULL;
   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   fd = mkstemp(template);
   if((fd == -1 ) || ((tmp = fdopen (fd, "w+" )) == NULL)  ) {
      sprintf(Msg, "5%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }


   while(fgets(buf, MAXLEN, fpw) != NULL) {
      strcpy(zbuf,buf);
      buf[strlen(buf)-1]='\0';
      getword(wuser,buf,':');
      getword(pwd,buf,':');
      getword(changed,buf,':');
      getword(auth_ip,buf,'\n');
      tt=time(NULL);
      if(strcmp(wuser,user) == 0) {
         if(strcmp(changed,"1") == 0)
            sprintf(zbuf,"%s:%s:%d:%s\n",wuser,pwd,tt,auth_ip);
         else sprintf(zbuf,"%s:%s:1:%s\n",wuser,pwd,auth_ip);
      }
      putline(tmp, zbuf);

   }
   fclose(tmp);

   if((tmp = fopen(template, "r")) == NULL) {
      sprintf(Msg, "6%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   authfiles(pwdfile);
   if((fpw = fopen(pwdfile, "w")) == NULL) {
      sprintf(Msg, "%s",msg02);
      Herror(Msg, fpw, fpw);
      return;
   }

   while (fgets(buf, MAXLEN, tmp) != NULL)
      fputs(buf,fpw);

   fclose(fpw);
   fclose(tmp);
   unlink(template);

   read_pwd_file(pwdfile,ticolor,header,null,null,null,from,null);

   return;
}


void disable_user(char *arg, char *ticolor, char *header)
{
   char function[20];
   char user[255];
   char wuser[255];
   char pwdfile[255];
   char pass[255];
   char wfrom[6];
   int  from=0;
   int  count=0;

   pass[0]='\0';
   getword(function,arg,'&');
   function[strlen(function)-1]='\0';
   getword(user,arg,'&');
   user[strlen(user)-1]='\0';
   strcpy(wuser,user);
   getword(pwdfile,arg,'&');
   pwdfile[strlen(pwdfile)-1]='\0';
   getword(wfrom,arg,'&');
   from=atoi(wfrom);

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   tmp = NULL;
   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   fd = mkstemp(template);
   if((fd == -1 ) || ((tmp = fdopen (fd, "w+" )) == NULL)  ) {
      sprintf(Msg, "7%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   while(fgets(buf, MAXLEN, fpw) != NULL) {
      buf[strlen(buf)-1]='\0';
      getword(wuser,buf,':');
      if(strcmp(wuser,user) == 0) {
         if(strncmp(buf,"*",1) == 0) {
            read_pwd_file(pwdfile,ticolor,header,null,null,null,from,null);
            return;
         }
         sprintf(pass,"%s:*%s\n",wuser,buf);
         strcpy(buf,pass);
      } else {
         sprintf(pass,"%s:%s\n",wuser,buf);
         strcpy(buf,pass);
      }
      putline(tmp, buf);
   }
   fclose(tmp);

   if((tmp = fopen(template, "r")) == NULL) {
      sprintf(Msg, "8%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   authfiles(pwdfile);
   if((fpw = fopen(pwdfile, "w")) == NULL) {
      sprintf(Msg, "%s",msg02);
      Herror(Msg, fpw, fpw);
      return;
   }

   while (fgets(buf, MAXLEN, tmp) != NULL)
      fputs(buf,fpw);

   fclose(fpw);
   fclose(tmp);
   unlink(template);

   read_pwd_file(pwdfile,ticolor,header,null,null,null,from,null);

   return;

}


void authfiles(char *file)
{
   FILE *fpx, *fpi;
   char work1[1024];
   char work2[1024];
   char conf[1024];

   sprintf(conf,"%s/admuser.conf",PREFIX);
   fpi=fopen(conf, "r");
   while (fgets(work1, 1024, fpi) != NULL) {
      if(strstr(work1,"\n") != 0)
         work1[strlen(work1)-1]='\0';
      if(strstr(work1,"password_file") != 0) {
         getword(pwdfile2,work1,' ');
         strcpy(pwdfile2,work1);
      }
   }
   fclose(fpi);

   fpx=fopen(pwdfile2, "r");
   while(fgets(work1, 1024, fpx) != NULL) {
      work1[strlen(work1)-1]='\0';
      if(strstr(work1,";") != 0) {
         getword(work2,work1,';');
      } else 
         strcpy(work2, work1);
      if(strcmp(work2, file) == 0) {
         fclose(fpx);
         return;
      }
   }
   fclose(fpx);
   sprintf(Msg, "%s: %s",msg13, file);
   Xerror(Msg);
}


void enable_user(char *arg, char *ticolor, char *header)
{
   char function[20];
   char user[255];
   char wuser[255];
   char pwdfile[255];
   char pass[255];
   char wfrom[6];
   int  from=0;

   pass[0]='\0';
   getword(function,arg,'&');
   function[strlen(function)-1]='\0';
   getword(user,arg,'&');
   user[strlen(user)-1]='\0';
   getword(pwdfile,arg,'&');
   pwdfile[strlen(pwdfile)-1]='\0';
   getword(wfrom,arg,'&');
   from=atoi(wfrom);

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   tmp = NULL;
   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   fd = mkstemp(template);
   if((fd == -1 ) || ((tmp = fdopen (fd, "w+" )) == NULL)  ) {
      sprintf(Msg, "9%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   while(fgets(buf, MAXLEN, fpw) != NULL) {
      buf[strlen(buf)-1]='\0';
      getword(wuser,buf,':');
      if(strcmp(wuser,user) == 0) {
         sprintf(pass,"%s:%s\n",wuser,buf+1);
         strcpy(buf,pass);
      } else {
         sprintf(pass,"%s:%s\n",wuser,buf);
         strcpy(buf,pass);
      }
      putline(tmp, buf);
   }
   fclose(tmp);

   if((tmp = fopen(template, "r")) == NULL) {
      sprintf(Msg, "a%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }

   authfiles(pwdfile);
   if((fpw = fopen(pwdfile, "w")) == NULL) {
      sprintf(Msg, "%s",msg02);
      Herror(Msg, fpw, fpw);
      return;
   }

   while (fgets(buf, MAXLEN, tmp) != NULL)
      fputs(buf,fpw);

   fclose(fpw);
   fclose(tmp);
   unlink(template);

   read_pwd_file(pwdfile,ticolor,header,null,null,null,from,null);

   return;

}


void add_user(char *arg, char *ticolor, char *header, char *msg)
{
   char function[20];
   char pwdfile[255];

   getword(function,arg,'&');
   function[strlen(function)-1]='\0';
   getword(pwdfile,arg,'&');

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("</head>\n");
   printf("<h3 align=center><font color=%s>%s</font></h3>\n",ticolor,header);
   printf("<h4 align=center>%s</h4>\n",msg33);
   printf("<center>\n");
   printf("<font size=-1><b>%s</b>: %s</font><br><br>\n",msg20,pwdfile);
   printf("<table border=1 cellpadding=5 bgcolor=beige>\n");
   printf("<form action='admuser.cgi' method=POST>\n");
   printf("<input type=hidden name=function value='3'>\n");
   printf("<tr><td align=right><font size=-1>%s</font></td><td align=left><input type=text name=user></td></tr>\n",msg04);
   printf("<tr><td align=right><font size=-1>%s</font></td><td align=left><input type=password name=pass></td></tr>\n",msg23);
   if(strncmp(NcsaPlus,"on",2) == 0)
      printf("<tr><td align=right><font size=-1>%s (%s)</font></td><td align=left><input type=text name=ipaddr></td></tr>\n",msg55,msg56);
   printf("</table>");
   printf("<br><br><font size=-1>\n");
   printf("<input type=hidden name=pwdfile value='%s'>\n",pwdfile);
   printf("<input type=submit name=go value=' %s '>\n",msg22);
   printf("<input type=submit name=go value='%s'>\n",msg24);
   printf("</font>\n");
   printf("</form>\n");
   if(strlen(msg) > 0)
      printf("<table cellpadding=10><tr><th bgcolor=black><font color=red size=+1>%s</font></th></tr></table>\n",msg);
   printf("</center>\n");
   printf("</html>\n");
   return;
}


void go_add_user(char *user, char *pass, char *pwdfile, char *ticolor, char *header)
{

   char *cpw;
   char salt[3];
   char wuser[255];

   space2us(user);

   if(strlen(user) < 1) {
      sprintf(wuser,"adduser\\&%s",pwdfile);
      add_user(wuser,ticolor,header,msg36);
      return;
   }
   if(strlen(pass) < 1) {
      sprintf(wuser,"adduser\\&%s",pwdfile);
      add_user(wuser,ticolor,header,msg37);
      return;
   }

   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }
   while(fgets(buf, MAXLEN, fpw) != NULL) {
      getword(wuser,buf,':');
      if(strcmp(wuser,user) == 0) {
         read_pwd_file(pwdfile,ticolor,header,msg34,null,null,from,null);
         return;
      }
   }
   fclose(fpw);

   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "a")) == NULL) {
      sprintf(Msg, "%s %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   (void) srand((int) time((time_t *) NULL));
   to64(&salt[0], rand(), 2);
   cpw = crypt(pass, salt);
   if(strncmp(NcsaPlus,"on",2) == 0) {
      if(strlen(ip) < 4) strcpy(ip,"*");
      tt=time(NULL);
      sprintf(buf, "%s:%s:%d:%s\n",user,cpw,tt,ip);
   } else sprintf(buf, "%s:%s\n", user, cpw);
   putline(fpw, buf);
   fclose(fpw);

   sprintf(wuser,"%s&%s",pwdfile,pwdfile);
   sort_pwd_file(wuser,ticolor,header);
   
   return;
}


void confirm_remove_user(char *arg, char *ticolor, char *header)
{

   char function[20];
   char user[255];
   char pwdfile[255];
   char from[6];

   getword(function,arg,'&');
   function[strlen(function)-1]='\0';
   getword(user,arg,'&');
   user[strlen(user)-1]='\0';
   getword(pwdfile,arg,'&');
   pwdfile[strlen(pwdfile)-1]='\0';
   getword(from,arg,'&');

   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("</head>\n");
   printf("<h3 align=center><font color=%s>%s</font></h3>\n",ticolor,header);
   printf("<h4 align=center>%s: <font color=red>%s</font></h4>\n",msg38,user);
   printf("<center>\n");
   printf("<br><br>%s?<br>\n",msg39);
   printf("<table>\n");
   printf("<form action='admuser.cgi' method=POST>\n");
   printf("<input type=hidden name=function value='4'>\n");
   printf("</table>");
   printf("<font size=-1>\n");
   printf("<input type=hidden name=user value='%s'>\n",user);
   printf("<input type=hidden name=pwdfile value='%s'>\n",pwdfile);
   printf("<input type=hidden name=from value='%s'>\n",from);
   printf("<input type=submit name=go value='%s'>\n",msg31);
   printf("<input type=submit name=go value='%s'>\n",msg32);
   printf("</font>\n");
   printf("</form>\n");
   printf("</center>\n");
   printf("</html>\n");
   return;
}


static void strip_latin(char *line)
{
   char buf[255];
   char warea[255];

   while(strstr(line,"&") != 0){
      getword(warea,line,'&');
      strncat(warea,line,1);
      getword(buf,line,';');
      strcat(warea,line);
      strcpy(line,warea);
   }

   return;

}


static void UserForm(char *bgcolor, char *txcolor, char *ticolor, char *rucolor, char *logo, char *width, char *height, char *header, char *bgimage, char *PwdFile, char *authpwd)
{

   if(multiple_pwd(PwdFile) == 1) {
      read_pwd_file(PwdFile,ticolor,header,null,null,null,from,null);
      return;
   }

   printf("Content-type: text/html\n");
   puts("\n");
   printf("<html>\n");
   printf("<head>\n");
   printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
   printf("  <title>User Administration Utility</title>\n");
   printf("</head>\n");
   printf("<body bgcolor=%s text=%s background='%s'>\n",bgcolor,txcolor,bgimage);
 
   if(strlen(logo) > 0)
      printf("<h3 align=center><img src='%s' border=0 align=absmiddle width=%s height=%s><font color=%s>%s</font></h3>\n",logo,width,height,ticolor,header);
    else
      printf("<h3 align=center><font color=%s>%s</font></h3>\n",ticolor,header);
 
   printf("<br><br><br>\n");
   printf("<center>\n");
   printf("<form action='admuser.cgi' method=POST>\n");
   printf("%s<br>\n",msg06);
   printf("<input type=hidden name=function value='1'>\n");
   printf("<select name=pwdfile>\n");
   printf("<option value=' '> \n");

   if(access(PwdFile,R_OK) == 0)
      get_pwd_files(PwdFile);
    else
      printf("<option value='%s'>%s",pwd_file_default,pwd_file_default);
 
   printf("</select>\n");
   printf("<br><br>\n");
   printf("<font size=-1>\n");
   printf("<br><br><br>\n");
   printf("<font size=-1>\n");
   printf("<input type=submit name=go value='%s'>\n",msg22);
   printf("</font>\n");
   printf("</form>\n");
   printf("<br><br>\n");
   if(strcmp(ShowInfo,"on") == 0)
      printf("<font size=-2><a href='%s'>%s-%s</a></font>\n",URL,PGM,VERSION);
   printf("</body>\n");
   printf("</center>\n");
   printf("</html>\n");

   fflush(stdout);
   return;

}


void sort_pwd_file(char *arg, char *ticolor, char *header)
{

   char pwdfile[255];
   char command[80];
   int  from=1;

   getword(pwdfile,arg,'&');
   strcpy(pwdfile,arg);

   if(access(pwdfile, W_OK) != 0) {
      sprintf(Msg, "%s: %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   fd = mkstemp(template);
   if((fd == -1 ) || ((tmp = fdopen (fd, "w+" )) == NULL)  ) {
      sprintf(Msg, "%s",msg03);
      Herror(Msg, fpw, tmp);
      return;
   }
   sprintf(command,"sort -o %s %s",template,pwdfile);
   system(command);

   if((tmp=fopen(template, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, tmp);
      Herror(Msg, fpw, tmp);
      return;
   }
   authfiles(pwdfile);
   if((fpw=fopen(pwdfile, "w")) == NULL) {
      sprintf(Msg, "%s %s",msg01, pwdfile);
      Herror(Msg, fpw, tmp);
      return;
   }

   while(fgets(buf, MAXLEN, tmp) != NULL)
      fputs(buf,fpw);

   fclose(fpw);
   fclose(tmp);
   unlink(template);

   read_pwd_file(pwdfile,ticolor,header,null,null,null,from,null);
   return;
}


static void go_Authenticate(char *user, char *pass, char *authpwd, char *pwdfile, char *bgcolor, char *txcolor, char *ticolor, char *rucolor, char *logo, char *width, char *height, char *header, char *bgimage)
{

   char wuser[255];
   int  ok=0;

   if(access(authpwd, F_OK) != 0) {
      sprintf(Msg, "%s: %s",msg40, authpwd);
      Xerror(Msg);
   }
   if(access(authpwd, R_OK) != 0) {
      sprintf(Msg, "%s: %s",msg41, authpwd);
      Xerror(Msg);
   }
   authfiles(pwdfile);
   if((fpw=fopen(authpwd, "r")) == NULL) {
      sprintf(Msg, "%s %s",msg41, authpwd);
      Herror(Msg, fpw, tmp);
      return;
   }

   while(fgets(buf, MAXLEN, fpw) != NULL) {
      buf[strlen(buf)-1]='\0';
      getword(wuser,buf,':');
      if(strcmp(user,wuser) == 0) {
         if(strcmp(buf, crypt(pass, buf)) == 0)
            ok++;
      }
   }
   fclose(fpw);
   if(!ok)
      Xerror(msg13);

   UserForm(bgcolor,txcolor,ticolor,rucolor,logo,width,height,header,bgimage,pwdfile,null);

   return;
}
