#!/usr/bin/perl -wT

#----------------------------------------------------------------------
# heading     : lapsch@yahoo.com
# description : Multi user accounts
# navigation  : 100 100
#
# 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.
#----------------------------------------------------------------------
#######################################################################
# INSTALLATION
#######################################################################
# To install this script do:
# cp $ThisScriptName /etc/e-smith/web/functions/
# ln -s ../../../functions/$ThisScriptName /etc/e-smith/web/panels/manager/cgi-bin/$ThisScriptName
# chmod 4750 /etc/e-smith/web/functions/$ThisScriptName
# chown root.admin /etc/e-smith/web/functions/$ThisScriptName
#######################################################################
#----------------------------------------------------------------------
# Otherwise it you won't run correctly
#----------------------------------------------------------------------
# Last Update 11-06-01 at 9:48pm
#######################################################################

package esmith;

use strict;
use CGI qw(:all);
use CGI::Carp qw/fatalsToBrowser/;

use esmith::cgi;
use esmith::config;
use esmith::util;
use esmith::db;

sub showInitial ($$$);
sub GenShowInitial ($$$);
sub mainBODY($$$);
sub mainBODY($$$);
sub UploadTxt ($$);
sub generateTXT ($$$$);
sub genEmailForward ($$);
sub genGroups ($$);
sub parseUserData($$$$);
sub define_dates;
sub addShowInitial ($$$);
sub performCreate ($$$);
sub getCreateData($$$$);
sub performCreateUser ($$$$$$$$$$$$);
sub delShowInitial ($$$);
sub delMainBODY($$$);
sub performDel ($$$);
sub getDeleteData($$$$);
sub performDeleteUser ($$$$);
sub pwdShowInitial($$$);
sub performPwd($$$);
sub performPasswdUser ($$$);
sub viewShowInitial ($$$);
sub performView ($$$);
sub modMainBODY($$$);
sub modShowInitial ($$$);
sub performModifyUser ($$$);
sub getModData ($$$$);
sub performModUser ($$$$);
sub genEmailForwardMod ($$);
sub ViewMainBODY($$$);
sub updateShowInitial($$$);
sub updateMainBODY($$$);
sub performUpdateUsers ($$$);
sub getUpData($$$$$);
sub performCheckUser ($$$$$);
sub Help($);
sub hlplnk($);
sub imexShowInitial ($$$);
sub performExport($$$);
sub performImport($$$);
sub getImData($$$$);

#######################################################################
# ONLY CHANGE THE VALUES OF THIS VARIABLES BELOW ######################
#######################################################################
my $DEFAULT_UPLOAD_DIR = '/home/e-smith/files/users/admin/home/.multiuseraccounts'; 
my $EventDir = '/etc/e-smith/events';

# File sizes are limited to $MAX_SIZE_UPLOAD (0 No limit), 
# larger files will return an 'Internal Server Error'.
my $MAX_SIZE_UPLOAD = 1440; # KB
#######################################################################
# DO NOT EDIT ANYTHING BELOW, UNLESS YOU KNOW WHAT YOURE DOING ########
#######################################################################


#----------------------------------------------------------------------


BEGIN
{
    # Clear PATH and related environment variables so that calls to
    # external programs do not cause results to be tainted. See
    # "perlsec" manual page for details.

    $ENV {'PATH'} = '';
    $ENV {'SHELL'} = '/bin/bash';
    delete $ENV {'ENV'};
}

esmith::util::setRealToEffective ();

my %conf;
tie %conf, 'esmith::config';

my ($NextIdCount, $d, $URL);
my %id;

my %accounts;
tie %accounts, 'esmith::config', '/home/e-smith/accounts';

my $q = new CGI;

my $message = "Directory \"$DEFAULT_UPLOAD_DIR\" does not exist" if (!-d $DEFAULT_UPLOAD_DIR) ;

#===========================================================


if (! grep (/^state$/, $q->param))
{
    showInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
}
elsif ($q->param ('state') eq "genForm")
{
    GenShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
}
elsif ($q->param ('state') eq "performGenerate")
{
    UploadTxt ($q, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'addForm')
{
    addShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'performCreate')
{
    performCreate ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'delForm')
{
    delShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'performDel')
{
    performDel ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'pwdForm')
{
    pwdShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'performPwd')
{
    performPwd ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'viewForm')
{
    viewShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'performView')
{
    performView ($q, $message, $DEFAULT_UPLOAD_DIR); 
}
elsif ($q->param('state') eq 'modForm')
{
    modShowInitial($q, $message, $DEFAULT_UPLOAD_DIR); 
}
elsif ($q->param('state') eq 'performModify')
{
    performModifyUser($q, $message, $DEFAULT_UPLOAD_DIR); 
}
elsif ($q->param('state') eq 'compForm')
{
    updateShowInitial($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif ($q->param('state') eq 'performUpdate')
{
    performUpdateUsers($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif($q->param('state') eq 'Help')
{
   my $about = $q->param('about');		
   Help($about);
}
elsif($q->param('state') eq 'imexForm')
{
     imexShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif($q->param('state') eq 'performExport')
{
	performExport($q, $message, $DEFAULT_UPLOAD_DIR);
}
elsif($q->param('state') eq 'performImport')
{
	performImport($q, $message, $DEFAULT_UPLOAD_DIR);
}
else
{
    esmith::cgi::genStateError ($q, \%conf);
}

exit (0);

#===========================================================


#------------------------------------------------------------
# subroutine to display initial form
#------------------------------------------------------------

sub showInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------
	
    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Add or remove many users');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable	
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&mainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub mainBODY($$$)
	{
	print hlplnk('Index');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }
	    

		my $description = <<END_TEXT;
This will allow you to add/delete many user accounts at once.
You will provide a text with user information, one user per line,
and this script will add or delete them. You may already have a file
with the format needed or if you supply some information this file can
be generated for you, with the correct format. 
The format of the file will be:<p>
<table border=1>
<tr>
<td><font size=-1>FName</td>
<td><font size=-1>LName</font></td>
<td><font size=-1>User</font></td>
<td><font size=-1>Pwd</font></td>
<td><font size=-1>Dept</font></td>
<td><font size=-1>Comp</font></td>
<td><font size=-1>Addr</font></td>
<td><font size=-1>City</font></td>
<td><font size=-1>Phone</font></td>
<td><font size=-1>Email</font></td>
<td><font size=-1>FEmail</font></td>
<td><font size=-1>Groups</font></td>
</tr></table>
<p>

END_TEXT

		print $q->p ($description);		
																			
		print $q->hr;
		
		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=genForm"},
			'Click here'),
		 'to <b>upload and/or generate</b> user accounts.');

		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=addForm"},
			'Click here'),
		 'to <b>create user accounts</b> from a text file.');

		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=pwdForm"},
			'Click here'),
		 'to <b>set password</b> for user accounts from a text file.');

		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=delForm"},
			'Click here'),
		 'to <b>delete user accounts</b> from text file.');

		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=modForm"},
			'Click here'),
		 'to <b>modify users</b> with new data from a text file.');

		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=compForm"},
			'Click here'),
		 'to <b>update user accounts</b> from the system with user accounts from a text file
		  and generate a list of users that need to be add or remove');

		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=viewForm"},
			'Click here'),
		 'to <b>view/delete text file/s</b> in your upload dir.');
		 
		print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=imexForm"},
			'Click here'),
		 'to <b>import/export</b> user information.');
		 
		
	esmith::cgi::genFooter ($q);
	exit;
	}
}


#------------------------------------------------------------
#
#------------------------------------------------------------


#################################################################
###### Upload txt file begins.
#################################################################


sub GenShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Generate accounts');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&GenMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub GenMainBODY($$$)
	{
	print hlplnk('GenInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;
	
		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }

		my $description = <<END_TEXT;
This will allow you to generate the text
file needed to create multiple users at 
once. The format of the file will be:<p>
<table border=1>
<tr>
<td><font size=-1>FName</td>
<td><font size=-1>LName</font></td>
<td><font size=-1>User</font></td>
<td><font size=-1>Pwd</font></td>
<td><font size=-1>Dept</font></td>
<td><font size=-1>Comp</font></td>
<td><font size=-1>Addr</font></td>
<td><font size=-1>City</font></td>
<td><font size=-1>Phone</font></td>
<td><font size=-1>Email</font></td>
<td><font size=-1>FEmail</font></td>
<td><font size=-1>Groups</font></td>
</tr></table>
<p>
END_TEXT

		print $q->p ($description);
		print $q->hr;

		#For uploading txt files
		print start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));

		print "Enter the file to process: <br>", filefield('uploadTXT','','30');

		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;  	
	
		my ($index,$select,$return);
				
		my @TempData = @dirData;		
	
		if (!$opsdir)
		{
			$select = "<p>Or choose one of the your upload files:\n<br>";
			$select .= "<SELECT NAME=\"PrevFile\">\n";

			
				foreach $index (0 .. $#TempData)
				{
					if($q->param('PrevFile') eq $TempData[$index])
					{
					$return .= "<OPTION SELECTED VALUE=\"$TempData[$index]\">$TempData[$index]\n";
					}
					elsif ($TempData[$index] =~ m/\.((\w{1})?up|gIm)$/)
					{
					$return .= "<OPTION VALUE=\"$TempData[$index]\">$TempData[$index]\n";
					}
				}  
			print "$select\n$return\n</SELECT>\n" if $return;
		
		}
		else
		{
		print "<p>$opsdir";
		}
		
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');
		       
		my $deflt;
		if($q->param('Separator'))
		{
		$deflt = $q->param('Separator');
		}
		else
		{
		$deflt = 'tab';
		}

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => $deflt,
			     -labels  => \%spacelabels);
		$deflt = $q->param('MySeparator');
		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11 value=\"$deflt\">\n";

		print "<p>What delimiter should I use to save generated file : <br>\n";
	
		my %SpaceLabels = ('tab'   => 'Tab',
			'same' => 'Same as input',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'SaveSeparator',
			     -values  => ['tab', 'same', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'same',
			     -labels  => \%SpaceLabels);
			     
		print " If other: <input type=\"text\" name=\"MySaveSeparator\" maxlength=10 size=11>\n";
		
		print "<p>Should I enclose each field : (leave blank for no)<br>\n";
		print '	<SELECT NAME="EncloseGen">
				<OPTION selected VALUE=> 
				<OPTION VALUE="Double">Double quote ("field")
				<OPTION VALUE="Single">Single quote (\'field\')
			</SELECT>';
		
		print "<p>\n";
		################
		print "How should the usernames be generated?\n<p>
			By default I will take the first letter of the first name  
			and combine it with the last name and make these letters lowercase.
			This means that John Doe will have a username of jdoe.
			
			<p>
			Make username look like :			
			<SELECT NAME=\"UNameSep\">
				<OPTION selected VALUE=\"default\">jdoe (default)
				<OPTION VALUE=\".\">j.doe (period)
				<OPTION VALUE=\"-\">j-doe (hyphen)
				<OPTION VALUE=\"_\">j_doe (underscore)
			</SELECT>
								
			<p>
			Should I append anything to username? 
			(leave blank for no)			
			<p>
			<table border=1>
			<tr>
			<td align=center><font size=-1> A </td>
			<td align=center><font size=-1> B </font></td>			
			<td align=center><font size=-1> C </font></td>
			<td align=center><font size=-1> D </font></td>
			<td align=center><font size=-1> E </font></td>
			<td align=center><font size=-1> F </font></td>
			<td align=center><font size=-1> G </font></td>
			<td align=center><font size=-1> H </font></td>
			<td align=center><font size=-1> I </font></td>
			<td align=center><font size=-1> J </font></td>			
			</tr>
			<tr>
			<td align=center><font size=-1>FName</td>
			<td align=center><font size=-1>LName</font></td>			
			<td align=center><font size=-1>Dept</font></td>
			<td align=center><font size=-1>Comp</font></td>
			<td align=center><font size=-1>Addr</font></td>
			<td align=center><font size=-1>City</font></td>
			<td align=center><font size=-1>Phone</font></td>	
			<td align=center><font size=-1> -<br>hyphen</font></td>
			<td align=center><font size=-1> _<br>underscore</font></td>
			<td align=center><font size=-1> .<br>period</font></td>		
			</tr></table>				
			<p>
			Take field : 
			<SELECT NAME=\"TakeField\">
				<OPTION selected VALUE=> 
				<OPTION VALUE=\"A\">A
				<OPTION VALUE=\"B\">B
				<OPTION VALUE=\"C\">C
				<OPTION VALUE=\"D\">D
				<OPTION VALUE=\"E\">E
				<OPTION VALUE=\"F\">F
				<OPTION VALUE=\"G\">G				
				<OPTION VALUE=\"H\">H
				<OPTION VALUE=\"I\">I
				<OPTION VALUE=\"J\">J
			</SELECT>
			 
			put it in : 			
			<SELECT NAME=\"PutItIn\">
				<OPTION selected VALUE=> 
				<OPTION VALUE=\"Front\">Front
				<OPTION VALUE=\"Back\">Back
			</SELECT>
			
			of field :
			<SELECT NAME=\"OfField\">
				<OPTION selected VALUE=> 
				<OPTION VALUE=\"A\">A
				<OPTION VALUE=\"B\">B
				<OPTION VALUE=\"C\">C
				<OPTION VALUE=\"D\">D
				<OPTION VALUE=\"E\">E
				<OPTION VALUE=\"F\">F
				<OPTION VALUE=\"G\">G
				<OPTION VALUE=\"H\">H
				<OPTION VALUE=\"I\">I
				<OPTION VALUE=\"J\">J
			</SELECT>
			<br>
			Then append this to the			
			<SELECT NAME=\"AppendTo\">
				<OPTION selected VALUE=> 
				<OPTION VALUE=\"Front\">Front
				<OPTION VALUE=\"Back\">Back
			</SELECT>
			of Username.
			
			\n";
		################
		print "<p><b>
		This fields will be the same for all the users if the user's field is blank,
		if the user's field is already set it will not be change.
		</b><p>\n";
	
		my ($pawd);
		$pawd = "	
		<SELECT NAME=\"PwdIs\">
		<OPTION VALUE=\"pwdIsnone\">Don't set password
		<OPTION  VALUE=\"pwdIsgen\">Generate Password
		<OPTION  VALUE=\"pwdIstxt\">Use password from text file
		<OPTION SELECTED VALUE=\"pwdIsname\">Password equals username
		</SELECT>\n";
		
		my $pmsg = reset;
		$pmsg .= '&nbsp;'x5 . submit('submit',' Process File ') . "\n";
	
		print $q->table ({border => 0, cellspacing => 0, cellpadding => 4},
	
		$q->Tr (esmith::cgi::genCell ($q, "Password:"),
		esmith::cgi::genCell ($q, "$pawd")),

	        esmith::cgi::genNameValueRow ($q,
                                      "Department",
                                      "department",
                                      db_get_prop (\%conf, 'ldap', 'defaultDepartment')),

        	esmith::cgi::genNameValueRow ($q,
                                      "Company",
                                      "company",
                                      db_get_prop (\%conf, 'ldap', 'defaultCompany')),

	        esmith::cgi::genNameValueRow ($q,
                                      "Street address",
                                      "street",
                                      db_get_prop (\%conf, 'ldap', 'defaultStreet')),

	        esmith::cgi::genNameValueRow ($q,
                                      "City",
                                      "city",
                                      db_get_prop (\%conf, 'ldap', 'defaultCity')),

	        esmith::cgi::genNameValueRow ($q,
                                      "Phone number",
                                      "phone",
                                      db_get_prop (\%conf, 'ldap', 'defaultPhoneNumber')),

	        $q->Tr (esmith::cgi::genCell ($q, "Email delivery:"),
		genEmailForward ($q, '')),

		esmith::cgi::genNameValueRow ($q,
				      "Forwarding address",
				      "forwardAddress",
				      'USERNAME@'),

        	$q->Tr (esmith::cgi::genCell ($q, "Group memberships:"),
	        esmith::cgi::genCell ($q, genGroups ($q, ''))),

		$q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performGenerate'),

		$q->Tr (esmith::cgi::genCell ($q, " "),
	        esmith::cgi::genCell ($q, $pmsg))); # These are the reset/submit buttons

		print $q->endform;
		
		print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');
			
	esmith::cgi::genFooter ($q);
	exit;
	}
}


#------------------------------------------------------------
#
#------------------------------------------------------------

sub UploadTxt ($$)
{
my($q, $upload_dir) = @_;
my($file_query, $file_name, $size, $buff, $time, $bytes_count, $prev_file, $message);

	$file_query = $q->param('uploadTXT');
	$prev_file = $q->param('PrevFile');

	if ($file_query =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $file_query;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
			
			#file name must begin with and alpha-numeric character
			if ($file_name !~ m/^[a-zA-Z0-9]/)
			{
			$file_name='';
			}
			
		
			if (! $file_name) 
			{
				$message = "Bad file name\n";
				GenShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			$file_name .= "-".&define_dates.".up";			


			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				GenShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			
		    ###### For some reason this line below will cause an 'Internal Server error'
		    ###### the logs will say 'Premature end of script headers'.
		    ###### if you use '||' instead of 'or'
		    open(FILE,">$upload_dir/$file_name") or &GenShowInitial($q, "Error opening file $file_name for writing, $!", $DEFAULT_UPLOAD_DIR) && exit;
		    binmode FILE;
		    while ($bytes_count = read($file_query,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {
		    	$file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");
		    	$message = "Could not upload $d\n";
			GenShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
			exit;
		    } 
		    else 
		    {
		    	$message = "<b>Generating file</b><br>Uploaded succesfully and saved as:<br>$file_name<br>($size bytes)";
			generateTXT ($q, $message, $upload_dir, $file_name);
			exit;
		     }

	}
	elsif ($prev_file =~ m/\w/)
	{
		$message = "<b>Generating file</b><br>Using previous file:<br>$prev_file<br>\n";	
		generateTXT($q, $message, $upload_dir, $prev_file);
		exit;
	}
	else
	{
	my $message = "You did not provide a file. Click the Browse button and select a text file.";
	GenShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
	}
}

#------------------------------------------------------------
#
#------------------------------------------------------------

sub genEmailForward ($$)
{
    my ($q, $currentSetting) = @_;

    if ((! defined $currentSetting) || ($currentSetting eq ''))
    {
	$currentSetting = 'local';
    } 

    my %emailLabels = ('local'   => 'Deliver email locally',
		       'forward' => 'Forward to address below',
		       'both'    => 'Both deliver locally and forward');

    return esmith::cgi::genCell ($q, $q->popup_menu (-name    => 'emailForward',
						     -values  => ['local', 'forward', 'both'],
						     -default => $currentSetting,
						     -labels  => \%emailLabels));
}

sub genEmailForwardMod ($$)
{
    my ($q, $currentSetting) = @_;

    if ((! defined $currentSetting) || ($currentSetting eq ''))
    {
	$currentSetting = 'txt';
    } 

    my %emailLabels = ('local'   => 'Deliver email locally',
		       'forward' => 'Forward to address below',
		       'both'    => 'Both deliver locally and forward',
		       'txt'     => 'Use value from text file');
		       

    return esmith::cgi::genCell ($q, $q->popup_menu (-name    => 'emailForward',
						     -values  => ['local', 'forward', 'both', 'txt'],
						     -default => $currentSetting,
						     -labels  => \%emailLabels));
}

sub genGroups ($$)
{
    my ($q, $user) = @_;

    my $key;
    my $value;

    my @groups = ();
    my @selected = ();

    foreach (sort keys %accounts)
    {
	if (db_get_type(\%accounts, $_) eq "group")
	{
	    push @groups, $_;
	    if ($user ne '')
	    {
		my @members =
		    split (/,/, db_get_prop(\%accounts, $_, "Members"));

		if (grep (/^$user$/, @members))
		{
		    push @selected, $_;
		}
	    }
	}
    }

    @groups = sort @groups;
    my $count = scalar @groups;

    my $out;

    if ($count > 0)
    {
	$out = $q->table ({border => 1, cellspacing => 1, cellpadding => 4});

	$out .= $q->Tr ($q->td ('&nbsp;'),
		        esmith::cgi::genSmallCell ($q, $q->b ('Group')),
		        esmith::cgi::genSmallCell ($q, $q->b ('Description')));

	my $group;
	foreach $group (@groups)
	{
	    my $checked = "";
	    if (grep (/^$group$/, @selected))
	    {
		$checked = "checked";
	    }

	    $out .=
		$q->Tr (
			$q->td (
				"<input type=\"checkbox\""
				. " name=\"groupMemberships\""
				. " $checked value=\"$group\">"
			    ),
			esmith::cgi::genSmallCell ($q, $group),
			esmith::cgi::genSmallCell (
				$q,
				db_get_prop(\%accounts, $group, "Description")
			    )
		    );
	}

	$out .= '</table>';
    }
    else
    {
	$out = $q->b ('Not applicable (no groups defined yet).');
    }

    return $out;
}

#------------------------------------------------------
#
#------------------------------------------------------

sub generateTXT($$$$)
{  
my ($q, $msg, $upload_dir, $file_name) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my $separator;
my $lnk;

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or $message .= "<p>Could not remove file use another name, DO NOT use \"$d\"";
		}
	GenShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
	exit;
	}


	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	my @uploadData = ();
                                                   
	    open(FILE,"<$upload_dir/$file_name") or die(&GenMainBODY($q, "Error opening file $file_name for reading, error $!", "$DEFAULT_UPLOAD_DIR"));
	    @uploadData = <FILE> ;
	    close(FILE);

	my $line;
	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");
	

my ($UserNameErrors, $Genfile_name, $SS, $MS) = &parseUserData($q, $separator, $upload_dir, $file_name);

if ($SS eq 'same')
{
	if ($sep eq 'other' and $mysep)
	{	
	$SS = $sep;
	$MS = $mysep;
	}
	else
	{
	$SS = $sep;
	}
}
	
if ($UserNameErrors)
{
print $q->p("$UserNameErrors");
}

print startform(-method => 'POST', -action => $q->url (-absolute => 1));
	print "<input type=hidden name=state value=performCreate>
	<input type=hidden name=Separator value=\"$SS\">
	<input type=hidden name=MySeparator value=\"$MS\">
	<input type=hidden name=GenAcctsTXT value=\"$Genfile_name\">
	<input type=submit value='Click here to create users using this data'>
	\n";
print endform;

print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');

esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------
#
#------------------------------------------------------

sub parseUserData($$$$)
{
my ($q, $S, $upload_dir, $file_name) = @_ ;

my $lines = 0;
my $UserNameErrors = '';
my %Names;
my $genAREA;
my $i;
my $count;
my $maxAcctNameLength = defined $conf{'maxAcctNameLength'} ? $conf{'maxAcctNameLength'} : 12;
my $UNameSep = $q->param('UNameSep');

###########################
my $sep = $q->param('SaveSeparator');
my $mysep = $q->param('MySaveSeparator');
my $enclose = $q->param('EncloseGen');
my $SS ='';
my $enc = '';

	if($enclose eq 'Double')
	{
	$enc = '"';	
	}
	elsif($enclose eq 'Single')
	{
	$enc = "'";	
	}
	else
	{
	$enc = '';	
	}

	if ($sep eq 'other' and $mysep)
	{
	$SS = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$SS = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$SS = ',';
	}
	elsif ($sep eq 'space')
	{
	$SS = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$SS = ';';
	}
	elsif ($sep eq 'colon')
	{
	$SS = ':';
	}
	else
	{
	$SS = $S;
	}
######################



	if (($UNameSep ne 'default') and ($UNameSep eq '.') or ($UNameSep eq '-') or ($UNameSep eq '_'))
	{
	$UNameSep = $UNameSep;
	}
	else
	{
	$UNameSep = '';
	}

open (LOG, "<$upload_dir/$file_name") or die(&GenMainBODY($q, "Unable to read $upload_dir/$file_name", "$DEFAULT_UPLOAD_DIR"));
my @uploadData = <LOG>;
close (LOG);

	my $p = 0;
	foreach $i (@uploadData)
	{
	$p++;
	chomp($i);

	#This removes all the extra spaces. allowing only one space between characters
	$i =~ s/[ ]{2,999}//g;
	$i =~ s/\n//g;
	$i =~ s/\r//g;	
	$i =~ s/\"//g;
	$i =~ s/\'//g;
	$i =~ s/\`//g;
	#print $q->br("<b>$p</b> $i");

		if ($i =~ m/\w*$S\w*/i)
		{
		#get the values that we need
		my ($FirstName,
		$LastName,
		$UserName,
		$Passwd,
		$Department,
		$Company,
		$Street,
		$City,
		$Phone,
		$Email,
		$EmailAddress,
		@Groups) = split(/$S/,$i);
						
		$FirstName =~ s/\"//g;
		$LastName =~ s/\"//g;	
		$FirstName =~ s/\'//g;
		$LastName =~ s/\'//g;
		$FirstName =~ s/\`//g;
		$LastName =~ s/\`//g;
		
		#print "<br><b>$p</b> Name \"<b>$FirstName $LastName</b>\"<br>";	
		$genAREA .= "$enc$FirstName$enc$SS$enc$LastName$enc";	

		#User input data
		my $pwd = $q->param('PwdIs');
		my $dept = $q->param('department');
		my $com = $q->param('company');
		my $str = $q->param('street');
		my $city = $q->param('city');
		my $phone = $q->param('phone');
		my $eF = $q->param('emailForward');
		my $eFA = $q->param('forwardAddress');
		my @groups = $q->param('groupMemberships');
		
			if (!$Department){$Department = $dept;}
			if (!$Company){$Company = $com;}
			if (!$Street){$Street = $str;}
			if (!$City){$City = $city;}
			if (!$Phone){$Phone = $phone;}
	
		#First lets do what the user did not do		
			if (!$UserName or $UserName != m/^[a-z]/i)
			{
			my @F = split(" ",$FirstName);
			my @L = split(" ",$LastName);
			@F = split("-",$F[0]);
			@L = split("-",$L[0]);
			my @FL = split("",$F[0]);
			my @LL = split("",$L[0]);
			my $OGName = '';
			$UserName = lc("$FL[0]$UNameSep$L[0]");
			
			my @UsernameLetters = split("",$UserName);
			
			#now take care of the maxlenght						
    				if (length $UserName > $maxAcctNameLength)
    				{	
    				my $Length = 0;
    				$UserName = '';
    					until($Length == $maxAcctNameLength)
    					{    					
    					$UserName .= $UsernameLetters[$Length];
    					$Length++;
    					}
    				}
			
			#now append
			my $TakeField = $q->param('TakeField');
			if($TakeField)
			{
			my %LTS = '';
			$LTS{'A'} = $FirstName;
			$LTS{'B'} = $LastName;
			$LTS{'C'} = $Department;
			$LTS{'D'} = $Company;
			$LTS{'E'} = $Street;
			$LTS{'F'} = $City;
			$LTS{'G'} = $Phone;
			$LTS{'H'} = '-';
			$LTS{'I'} = '_';
			$LTS{'J'} = '.';
			my $appentThis = '';
			my $PutItIn = $q->param('PutItIn');
			my $OfField = $q->param('OfField');
				if($PutItIn eq 'Back')
				{
				$appentThis = "$LTS{$OfField}$LTS{$TakeField}";
				}
				elsif($PutItIn eq 'Front')
				{
				$appentThis = "$LTS{$TakeField}$LTS{$OfField}";
				}
				else
				{
				$appentThis = $LTS{$TakeField};
				}
							
			my $AppendTo = $q->param('AppendTo');
			
				if($AppendTo eq 'Back')
				{
				$UserName = "$UserName$appentThis";
				}
				elsif($AppendTo eq 'Front')
				{
				$UserName = "$appentThis$UserName";
				}	
				
				my @UserLetters = split("",$UserName);
			
				#now take care of the maxlenght						
    				if (length $UserName > $maxAcctNameLength)
    				{	
    				my $Length = 0;
    				$UserName = '';
    					until($Length == $maxAcctNameLength)
    					{    					
    					$UserName .= $UserLetters[$Length];
    					$Length++;
    					}
    				}
									
			}
						
    			$OGName = $UserName;	
			
			#This will store the username so we dont use it again
			my $key = $UserName;
			my $value = 1;
				#First check if the generate name was already use
				if ($Names{$key})
				{
				my $found = 'no';
				my $count = 1;
				 	#the name is taken, append a number at the end
				 	#and see if that name is taken, if it is then
				 	#increment that number until the name is ok.
					until ($found eq 'yes')
					{
					$UserName = "$OGName$count";
					###--------------
						if (length $UserName > $maxAcctNameLength)
    						{	
    						@UsernameLetters = split("",$OGName);
    						my $Length = 0;
    						$UserName = '';
    						my $twelve = $maxAcctNameLength - length($count);
    							until($Length == $twelve)
    							{    							
    							$UserName .= $UsernameLetters[$Length];
    							$Length++;
    							}
    						$UserName = "$UserName$count";
    						}
					###--------------
						#check current system accounts to see
						#if a user with this name already 
						#exist, and check if we already used that name
						if ((db_get_type(\%accounts, $UserName) ne "user") and (!$Names{$UserName}))
						{
		       				$found = 'yes'; #this name is not taken
						$Names{$UserName} = 1;
						}
					$count++
					}
				} 
				#we have not use the name, but check if its an existing account
				elsif (db_get_type(\%accounts, $UserName) eq "user")
				{
				my $found = 'no';
				my $count = 1;
				 	#the name is taken, append a number at the end
				 	#and see if that name is taken, if it is then
				 	#increment that number until the name is ok.
					until ($found eq 'yes')
					{
					$UserName = "$OGName$count";						
					###--------------
						if (length $UserName > $maxAcctNameLength)
    						{	
    						@UsernameLetters = split("",$OGName);
    						my $Length = 0;
    						$UserName = '';
    						my $twelve = $maxAcctNameLength - length($count);
    							until($Length == $twelve)
    							{    							
    							$UserName .= $UsernameLetters[$Length];
    							$Length++;
    							}
    						$UserName = "$UserName$count";
    						}
					###--------------
						#check current system accounts to see
						#if a user with this name already 
						#exist, and check if we already used that name
						if ((db_get_type(\%accounts, $UserName) ne "user") and (!$Names{$UserName}))
						{
		       				$found = 'yes'; #this name is not taken
						$Names{$UserName} = 1;
						}
					$count++
					}
				}
		                else
				{
				#the name was not use so use it now.
				$Names{$key} = $value;
				}
			}
			#print "UserName \"<b>$UserName</b>\"<br>";
			$genAREA .= "$SS$enc$UserName$enc";		

			if ($pwd eq 'pwdIsnone')
			{
				$Passwd = '';
			}
			elsif ($pwd eq 'pwdIsgen')
			{
				# maximum password length, 
				# not including 1 numeric character
				my $passlen=5;  
				my $pwword="";
				my $maxi=24;
				my $character='';
				my @randlist=();
					for ($i=0;$i<$passlen;$i++)
					{
			          	$character=int(rand(24)+1);
			          	$character=$character+66;
			           	$character=chr($character);
			          	$pwword=$pwword.$character;
			           	}
				$character=int(rand(9)+1);
				$pwword=$pwword.$character;
				$Passwd=lc($pwword);
			}
			elsif ($pwd eq 'pwdIsname')
			{
				$Passwd = $UserName;	
			}
			elsif ($pwd eq 'pwdIstxt')
			{
				$Passwd = $Passwd;
			}
		#print "Password \"<b>$Passwd</b>\"<br>";
		$genAREA .= "$SS$enc$Passwd$enc";		

			
		#print "Department \"<b>$Department</b>\"<br>";
		$genAREA .= "$SS$enc$Department$enc";
			
		#print "Company \"<b>$Company</b>\"<br>"; 
		$genAREA .= "$SS$enc$Company$enc";
			
		#print "Address \"<b>$Street</b>\"<br>";
		$genAREA .= "$SS$enc$Street$enc";
			
		#print "City \"<b>$City</b>\"<br>"; 
		$genAREA .= "$SS$enc$City$enc";	 
			
		#print "Phone \"<b>$Phone</b>\"<br>";
		$genAREA .= "$SS$enc$Phone$enc";	 
	
			if (!$Email)
			{
			$Email = $eF;
			}
		#print "Email Delivery \"<b>$Email</b>\"<br>";  
		$genAREA .= "$SS$enc$Email$enc";	 
		 
			if ($Email eq 'forward' or $Email eq 'both')
			{		
				if (!$EmailAddress)
				{
				$EmailAddress = $eFA;
				$EmailAddress =~ s/USERNAME/$UserName/;
				}
			#print "Forward Address \"<b>$EmailAddress</b>\"<br>";   
			$genAREA .= "$SS$enc$EmailAddress$enc";	 
			}
			elsif ($Email eq 'local')
			{
			$genAREA .= "$SS$enc$enc";	 
			}


			if (!@Groups)
			{
			@Groups = @groups;
			}
		#print "Group Membership \"<b>@Groups</b>\"<br>";  
		$genAREA .= "$SS$enc@Groups$enc\n";	 
		
		}
		else
		{
		$UserNameErrors .= "<b>$p</b> $i<br>\n";
		}
	}

	#print the form tag so some browsers display this correctly
	print startform(-method => 'POST', -action => $q->url (-absolute => 1));
	#print a nice textarea with all accounts	
	print $q->p ("<TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$genAREA</TEXTAREA>\n");
	print $q->endform;

	#save generate data and check to see if they used previous file
	if ($file_name =~ m/(.*)\.up/ or $file_name =~ m/(.*)\.Gar/)
	{
	my $tmp = $1 ;	
	my $lkg_name = "$tmp"."-g1.gen";
		if (-e "$upload_dir/$lkg_name")
		{
		my $found='no';
			if ($lkg_name =~ m/(.*\-\w{3}_.*_\d{4}_\d{2}_\d{2}_\d{2}\-g)(\d{1,})/)
			{
			$lkg_name="$1"; 
			$count="$2";
			}
	
			until ($found eq 'yes')
			{
			$count++;
			$file_name = "$lkg_name$count";
			$file_name .= ".gen";
				if (!-e "$upload_dir/$file_name") 
				{
				$found = 'yes';
				}
			}
		}
		else
		{
		$file_name = "$tmp"."-g1.gen";
		}
	}
	$file_name =~ s/\.up/\.gen/;
	my $NewDate = &define_dates ;
	$file_name =~ s/\w{3}_\d{1,2}[a-z]{1,2}_\d{4}_\d{1,2}_\d{1,2}_\d{1,2}/$NewDate/ if $file_name =~ m/\w{3}_\d{1,2}[a-z]{1,2}_\d{4}_\d{1,2}_\d{1,2}_\d{1,2}/;
	
	#print "<p> New file name is: \"$file_name\"\n</p>\n";
	
	$file_name =~ m/^(.*)$/;
	$file_name = $1;
	
	open (LOG, ">$upload_dir/$1") or die(&GenMainBODY($q, "Unable to save generated data $upload_dir/$file_name", "$DEFAULT_UPLOAD_DIR"));
	print LOG $genAREA;
	close (LOG);	
	
	print "Generated file saved as <br>\n\"<b>$file_name</b>\"<br>\n";
	
	$UserNameErrors = "<p><font color=red><B>Bad lines</b></font>\n<p>" . $UserNameErrors if $UserNameErrors;
	return ("$UserNameErrors", $file_name, $sep, $mysep);
}

#######################################################
sub define_dates 
{
my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst,$current_date);
   ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime(time);

   $year += 1900;
 
   my @months = ("XX","Jan","Feb","Mar","Apr","May","Jun","Jul",
              "Aug","Sep","Oct","Nov","Dec");

   my @days = ("XX","1st","2nd","3rd","4th","5th","6th","7th","8th","9th","10th",
            "11th","12th","13th","14th","15th","16th","17th","18th","19th",
            "20th","21st","22nd","23rd","24th","25th","26th","27th","28th",
            "29th","30th","31st");

   $current_date = $months[($month + 1)]."_".$days[$day]."_".$year."_".$hour;
   if ($minute < 10) {$current_date = "$current_date"."_0$minute";}
   else {$current_date = "$current_date"."_$minute";}

   if ($second < 10) {$current_date = "$current_date"."_0$second";}
   else {$current_date = "$current_date"."_$second";}

return $current_date;
}

#################################################################
###### Upload txt file ends.
#################################################################

#################################################################
###### Create users from txt file begins.
#################################################################

sub addShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Create many user accounts');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&addMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub addMainBODY($$$)
	{
	print hlplnk('CreateInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }

		my $description = <<END_TEXT;
This will allow you to create many user accounts from
a text file. The format of the file must be:<p>
<table border=1>
<tr>
<td><font size=-1>FName</td>
<td><font size=-1>LName</font></td>
<td><font size=-1>User</font></td>
<td><font size=-1>Pwd</font></td>
<td><font size=-1>Dept</font></td>
<td><font size=-1>Comp</font></td>
<td><font size=-1>Addr</font></td>
<td><font size=-1>City</font></td>
<td><font size=-1>Phone</font></td>
<td><font size=-1>Email</font></td>
<td><font size=-1>FEmail</font></td>
<td><font size=-1>Groups</font></td>
</tr></table>
<p>
END_TEXT

		print $q->p ($description);
		print $q->hr;

		#For uploading txt files
		print start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));

		print "User information file: ", filefield('AcctsTXT','','30');
		
		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;

		my ($index,$select,$return);

		
		

		if (!$opsdir)
		{
			$select = "<p>Or choose a one of the generated files:\n<br>";
			$select .= "<SELECT NAME=\"GenAcctsTXT\">\n";

			
				foreach $index (0 .. $#dirData) 
				{
				$return .= "<OPTION VALUE=\"$dirData[$index]\">$dirData[$index]\n" if $dirData[$index] =~ m/\.gen/;
				}  
			print "$select\n$return\n</SELECT>\n" if $return;
		
		}
		else
		{
		print "<p>$opsdir";
		}
	
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'tab',
			     -labels  => \%spacelabels);

		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11>\n";
		print "<br>\n";

		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performCreate');

		my $pmsg = reset;
		$pmsg .= '&nbsp;'x5 . submit('submit',' Process File ') . "\n";
		print "<p>$pmsg\n";		

		print $q->endform;
		
	print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');
	
	esmith::cgi::genFooter ($q);
	exit;
	}
}

#------------------------------------------------------------
#
#------------------------------------------------------------

sub performCreate ($$$)
{

my($q, $msg, $upload_dir) = @_;

my($accts_file, $file_name, $genaccts_file, $bytes_count, $size, $buff, $message);

	if ($q->param('AcctsTXT'))
	{
	$accts_file = $q->param('AcctsTXT');
	}
	elsif ($q->param('GenAcctsTXT'))
	{
	$genaccts_file = $q->param('GenAcctsTXT');
	}

	if ($accts_file =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $accts_file ;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
		
			if (! $file_name) 
			{
				$message = 'Bad file name';
				addShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			$file_name .= "-".&define_dates.".Aup";			

			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				addShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
		    ###### For some reason this line below will cause an 'Internal Server error'
		    ###### the logs will say 'Premature end of script headers'.
		    ###### if you use '||' instead of 'or'
		    open(FILE,">$upload_dir/$file_name") or die(&addShowInitial($q, "Error opening file $file_name for writing, $!", $DEFAULT_UPLOAD_DIR));
		    binmode FILE;
		    while ($bytes_count = read($accts_file,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {
		    	$file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");
		    	$message = "Could not upload $file_name\n";
			addShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
			exit;
		    } 
		    else 
		    {
		    	$message = "<b>Creating accounts</b><br>Uploaded succesfully and saved as:<br>$file_name<br>($size bytes)";
			getCreateData ($q, $message, $upload_dir, $file_name);
			exit;
		     }

	}
	elsif ($genaccts_file =~ m/\w/)
	{
		$message = "<b>Creating accounts</b><br>Using previous generate file:<br>$genaccts_file<br>\n";	
		getCreateData ($q, $message, $upload_dir, $genaccts_file);
		exit;
	}
	else
	{
	my $message = "You did not provide a file. Click the Browse button and select a text file.";
	addShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
	}

}

#------------------------------------------------------
#
#------------------------------------------------------

sub getCreateData($$$$)
{  
my ($q, $msg, $upload_dir, $file_name) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my $i;
my $separator;
my ($FirstName,
$LastName,
$acctName,
$Passwd,
$Department,
$Company,
$Street,
$City,
$Phone,
$Email,
$EmailAddress,
@Groups);

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or ($message .= "<p>Could not remove file use another name, DO NOT use \"$d\"");
		}
	addShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
	exit;
	}


	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	my @uploadData = ();

	    open(FILE,"<$upload_dir/$file_name") or die(&addShowInitial($q, "Error opening file $file_name for reading, error $!", "$DEFAULT_UPLOAD_DIR"));
	    @uploadData = <FILE> ;
	    close(FILE);

	my $line;
	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");

		
my ($txtAREA, $BadAREA, $create) = &parseDataFile($q, $separator, $upload_dir, $file_name);

print $q->p ("Total accounts created <b>$create</b>\n");

print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Log</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$txtAREA</TEXTAREA>\n");
print endform;
	
if ($BadAREA)
{
print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Errors</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$BadAREA</TEXTAREA>\n");
print endform;
}

print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');

esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------
#
#------------------------------------------------------

sub parseDataFile($$$$)
{
my ($q, $S, $upload_dir, $file_name) = @_ ;

my $create;
my $count = 0;
my $txtAREA;
my $BadAREA;
my $ttxtAREA;
my $tBadAREA;
my $i;

open (LOG, "<$upload_dir/$file_name") or die(&addMainBODY($q, "Unable to read $upload_dir/$file_name", "$DEFAULT_UPLOAD_DIR"));
my @uploadData = <LOG>;
close (LOG);

	my $p = 0;
	my $status=0;
	my $stat=0;
	foreach $i (@uploadData)
	{
	$p++;
	$status++;
	$stat++;
	chomp($i);
	#print a dot foreach user being work on so the browser displays something and 
	#does not timeout

		if ($status <= 35)
		{
			if ($stat <= 5)
			{
			print ".\n" ;
			}
			else
			{
			print "&nbsp;&nbsp;.\n";
			$stat=1;
			}
		}
		else
		{
		print "<br>.\n";
		$status=1;
		}

	#This removes all the extra spaces. allowing only one space between characters
	$i =~ s/[ ]{2,999}//g;
	$i =~ s/\n//g;
	$i =~ s/\r//g;
	$i =~ s/\"//g;
	$i =~ s/\'//g;
	$i =~ s/\`//g;


		if ($i =~ m/\w*$S\w*/i)
		{
		#get the values that we need
		my ($FirstName,
		$LastName,
		$UserName,
		$Passwd,
		$Department,
		$Company,
		$Street,
		$City,
		$Phone,
		$Email,
		$EmailAddress,
		@Groups) = split(/$S/,$i);
		
		($ttxtAREA, $tBadAREA, $create) = &performCreateUser($FirstName,
				$LastName,
				$UserName,
				$Passwd,
				$Department,
				$Company,
				$Street,
				$City,
				$Phone,
				$Email,
				$EmailAddress,
				@Groups);
		$count += $create;
		$txtAREA .= $ttxtAREA;
		$BadAREA .= $tBadAREA;
		}
		else
		{
		$BadAREA .= "Bad line $p\n$i\n";
		next;
		}
	}
return ($txtAREA, $BadAREA, $count);
}


#------------------------------------------------------------
#
#------------------------------------------------------------

sub performCreateUser ($$$$$$$$$$$$)
{
    my ($FirstName, 
	$LastName,
	$UserName,
	$Passwd,
	$Department,
	$Company,
	$Street,
	$City,
	$Phone,
	$Email,
	$EmailAddress,
	@Groups) = @_;

my $txtAREA = '';
my $BadAREA = '';
my $create = 0;
my $error = 0;


    #------------------------------------------------------------
    # Validate parameters and untaint them
    #------------------------------------------------------------

    my $acctName = $UserName;
    if ($acctName =~ /^([a-z][\-\_\.a-z0-9]*)$/)
    {
	$acctName = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\" : bad account name\n";
	return ($txtAREA, $BadAREA, $create);
    }
    my $maxAcctNameLength = defined $conf{'maxAcctNameLength'} ?
	$conf{'maxAcctNameLength'} : 12;
    if (length $acctName > $maxAcctNameLength)
    {
	$BadAREA .= "Error: \"$acctName\": too long, max $maxAcctNameLength characters\n";
	return ($txtAREA, $BadAREA, $create);
    }


    my $firstName = $FirstName;
    if ($firstName =~ /^\s*([a-zA-Z0-9\'\.\-\s]+?)\s*$/)
    {
	$firstName = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected or missing characters in first name: $firstName\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $lastName = $LastName;
    if ($lastName =~ /^\s*([a-zA-Z0-9\'\.\-\s]+?)\s*$/)
    {
	$lastName = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected or missing characters in last name: $lastName\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $department = $Department;
    if ($department =~ /^([^\|]*)$/)
    {
	$department = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected characters in department: $department\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $company = $Company;
    if ($company =~ /^([^\|]*)$/)
    {
	$company = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected characters in company: $company\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $street = $Street;
    if ($street =~ /^([^\|]*)$/)
    {
	$street = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected characters in street address: $street\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $city = $City;
    if ($city =~ /^([^\|]*)$/)
    {
	$city = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected characters in city: $city\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $phone = $Phone;
    if ($phone =~ /^([^\|]*)$/)
    {
	$phone = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected characters in phone number: $phone\n";
	return ($txtAREA, $BadAREA, $create);
    }

    my $emailForward = $Email;
    if ($emailForward =~ /^(.*)$/)
    {
	$emailForward = $1;
    }
    else
    {
	$emailForward = "";
    }

    my $forwardAddress = $EmailAddress;
    if (($emailForward eq 'local') && ($forwardAddress =~ /^([^\|]*)$/))
    {
	$forwardAddress = $1;
    }
    elsif (($emailForward ne 'local') && ($forwardAddress =~ /^([^\|]+)$/))
    {
	$forwardAddress = $1;
    }
    else
    {
	$BadAREA .= "Error: \"$acctName\": unexpected or missing characters in email forwarding address: $forwardAddress\n";
	return ($txtAREA, $BadAREA, $create);
    }

    # This script will not make pseudonyms
    #my ($dot_pseudonym, $underbar_pseudonym)
    # 	= makePseudonyms($firstName, $lastName);

    #------------------------------------------------------------
    # Looks good. Find out if this account has been taken or there is
    # a name clash with the pseudonyms
    #------------------------------------------------------------

    if (db_get(\%accounts, $acctName))
    {
	my $type = db_get_type(\%accounts, $acctName);

	if ($type eq "pseudonym")
	{
	    my $acct = db_get_prop(\%accounts, $acctName, "Account");
	    my $acct_type = db_get_type(\%accounts, $acct);

	    $BadAREA .= "Error: \"$acctName\": clashes with pseudonym"
		    . " details for $acct_type account $acct"
		    . " \"$acctName\" is a pseudonym for $acct\n";
	return ($txtAREA, $BadAREA, $create);
	}
	else
	{
	    $BadAREA .= "Error: \"$acctName\": is an existing $type account\n";
	    return ($txtAREA, $BadAREA, $create);
	}

    }

#    if (db_get(\%accounts, $dot_pseudonym))
#    {
#	my $type = db_get_type(\%accounts, $dot_pseudonym);
#
#	if ($type eq "pseudonym")
#	{
#	    my $acct = db_get_prop(\%accounts, $dot_pseudonym, "Account");
#	    my $acct_type = db_get_type(\%accounts, $acct);
#
#	    $BadAREA .= "Error: \"$acctName\": first and last name details for account"
#		    . " \"$acctName\" clash with pseudonym details for"
#		    . " $acct_type account \"$acct\"."
#		    . "$dot_pseudonym is a pseudonym for $acct\n";
#	return ($txtAREA, $BadAREA, $create);
#	}
#	else
#	{
#	    $BadAREA .= "Error: \"$acctName\": first and last name details for account"
#		    . " \"$acctName\" clash with an existing $type"
#		    . " account $dot_pseudonym\n";
#	return ($txtAREA, $BadAREA, $create);
#	}
#
#    }
#
#    if (db_get(\%accounts, $underbar_pseudonym))
#    {
#	my $type = db_get_type(\%accounts, $underbar_pseudonym);
#
#	if ($type eq "pseudonym")
#	{
#	    my $acct = db_get_prop(\%accounts, $underbar_pseudonym, "Account");
#	    my $acct_type = db_get_type(\%accounts, $acct);
#
#	    $BadAREA .= "Error: \"$acctName\": first and last name details for account"
#		     . " \"$acctName\" clash with pseudonym details for"
#		     . " $acct_type account \"$acct\"."
#		    . " $underbar_pseudonym is a pseudonym for $acct\n";
#	return ($txtAREA, $BadAREA, $create);
#	}
#	else
#	{
#	    $BadAREA .= "Error: \"$acctName\": first and last name details for account"
#		     . " \"$acctName\" clash with an existing $type"
#		     . " account $underbar_pseudonym\n";
#	return ($txtAREA, $BadAREA, $create);
#	}
#    }

    my $userID = getNextFreeID();

    #------------------------------------------------------------
    # Account is available! Update accounts database.
    #------------------------------------------------------------

    db_set(\%accounts, $acctName, "user");
    db_set_prop(\%accounts, $acctName, 'FirstName', $firstName);
    db_set_prop(\%accounts, $acctName, 'LastName', $lastName);
    db_set_prop(\%accounts, $acctName, 'Phone', $phone);
    db_set_prop(\%accounts, $acctName, 'Company', $company);
    db_set_prop(\%accounts, $acctName, 'Dept', $department);
    db_set_prop(\%accounts, $acctName, 'City', $city);
    db_set_prop(\%accounts, $acctName, 'Street', $street);
    db_set_prop(\%accounts, $acctName, 'EmailForward', $emailForward);
    db_set_prop(\%accounts, $acctName, 'ForwardAddress', $forwardAddress);
    db_set_prop(\%accounts, $acctName, 'PasswordSet', "no");
    db_set_prop(\%accounts, $acctName, 'Uid', $userID);
    db_set_prop(\%accounts, $acctName, 'Gid', $userID);

    untie %accounts;

    #------------------------------------------------------------
    # Signal the create-user event.
    #------------------------------------------------------------
    
    if (-d "$EventDir/multi-user-create")
    {
    system ("/sbin/e-smith/signal-event", "multi-user-create", "$acctName") == 0 || $error++;
    }
    else
    {                                                                          
    system ("/sbin/e-smith/signal-event", "user-create", "$acctName") == 0 || $error++;
    }
      
     
     if ($error)
     {	 
     $BadAREA .= "\"$acctName\": Error occurred while creating user.\n";
     return ($txtAREA, $BadAREA, $create);	
     }

#    #------------------------------------------------------------
#    # Signal the pseudonym-create event for each pseudonym
#    #------------------------------------------------------------
#
#    system(
#	    "/sbin/e-smith/signal-event",
#	    "pseudonym-create",
#	    "$dot_pseudonym",
#	    "$acctName"
#	) == 0 || $error++;
#   
#     if ($error)
#     {	 
#     $BadAREA .= "\"$acctName\": Error occurred while creating $dot_pseudonym.\n";
#     return ($txtAREA, $BadAREA, $create);	
#     }
#
#    system(
#	    "/sbin/e-smith/signal-event",
#	    "pseudonym-create",
#	    "$underbar_pseudonym",
#	    "$acctName"
#	) == 0 || $error++;
#
#     if ($error)
#     {	 
#     $BadAREA .= "\"$acctName\": Error occurred while creating $underbar_pseudonym.\n";
#     return ($txtAREA, $BadAREA, $create);	
#     }
#
    tie %accounts, 'esmith::config', '/home/e-smith/accounts';
    

    #------------------------------------------------------------
    # Add user to any relevant groups
    #------------------------------------------------------------

    my @groups = @Groups;

    my $group;
    foreach $group (@groups)
    {
	# untaint group so that we can use it in "system" call later

	if ($group =~ /^(.*)$/)
	{
	    $group = $1;
	}
	else
	{
	    $group = "";
	}

	db_set_prop(\%accounts, $group, "Members",
	db_get_prop(\%accounts, $group, "Members") . ",$acctName");
	
	untie %accounts;

	if (-d "$EventDir/multi-group-modify")
    	{    	
    	system ("/sbin/e-smith/signal-event", "multi-group-modify", "$group") == 0 || $error++; 
    	}
    	else
    	{
	system ("/sbin/e-smith/signal-event", "group-modify", "$group") == 0 || $error++; 
	}

     if ($error)
     {	 
     $BadAREA .= "\"$acctName\": Error occurred while updating group.\n";
     return ($txtAREA, $BadAREA, $create);	
     }

	tie %accounts, 'esmith::config', '/home/e-smith/accounts';
    }
       
     if ($error)
     {	 
     $BadAREA .= "Could not created user account \"$acctName\"\n";
     }
     else
     {
     $txtAREA .= "Successfully created user account \"$acctName\"\n";
     $create = 1;	

     my ($ttxtAREA, $tBadAREA, $not);
     #change password only if password is set
     ($ttxtAREA, $tBadAREA, $not) = performPasswdUser ($q, $acctName, $Passwd) if $Passwd;	
      $txtAREA .= $ttxtAREA if $ttxtAREA;
      $BadAREA .= $tBadAREA if $tBadAREA;
     }

return ($txtAREA, $BadAREA, $create);
}

#------------------------------------------------------------
#
#------------------------------------------------------------

sub makePseudonyms ($$)
{
    #------------------------------------------------------------
    # Generate First.Last and First_Last pseudonyms
    #------------------------------------------------------------

    my ($firstName, $lastName) = @_;

    my $dot_pseudonym = "$firstName $lastName";

    $dot_pseudonym =~ s/^\s+//;		# Strip leading whitespace
    $dot_pseudonym =~ s/\s+$//;		# Strip trailing whitespace
    $dot_pseudonym =~ s/\s+/ /g;	# Multiple spaces become single spaces
    $dot_pseudonym =~ s/\s/./g;		# Change all spaces to dots
    $dot_pseudonym = lc $dot_pseudonym;	# Change to lower case

    my $underbar_pseudonym = $dot_pseudonym;
    $underbar_pseudonym =~ s/\./_/g;	# Change dots to underbars

    return ($dot_pseudonym, $underbar_pseudonym);
}

sub getNextFreeID
{
    my $minid = $conf{'MinUid'};
    $minid = 5000 unless $minid;

    my $maxid = 1 << 31;

    # Take note of all the used uids and gids from the passwd entries

    while ((undef, undef, my $uid, my $gid) = getpwent)
    {
	++$id{$uid} if ($uid > $minid);
	++$id{$gid} if ($gid > $minid);
    }

    # Take note of all the used gids from the group entries

    while ((undef, undef, my $gid) = getgrent)
    {
	++$id{$gid} if ($gid > $minid);
    }

    # Find the first free id

    #only set $NextIdCount the first time. The second time add to it.
	if(!$NextIdCount)
	{
	$NextIdCount = $minid + 1;
	}
	else
	{
	++$NextIdCount;
	}

    while ($NextIdCount < $maxid)
    {
	return $NextIdCount
	    unless (exists $id{$NextIdCount});

	++$NextIdCount;
    }
}

#################################################################
###### Create users from txt file ends.
#################################################################

#################################################################
###### Delete users from txt file begins.
#################################################################

sub delShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Delete many user accounts');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&delMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub delMainBODY($$$)
	{
	print hlplnk('DelInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }
	    else
	    {
		my $description = <<END_TEXT;
This will allow you to delete many user accounts from
a text file. The format of the file must be:<p>
<table border=1>
<tr>
<td><font size=-1>FName</td>
<td><font size=-1>LName</font></td>
<td><font size=-1>User</font></td>
<td><font size=-1>Pwd</font></td>
<td><font size=-1>Dept</font></td>
<td><font size=-1>Comp</font></td>
<td><font size=-1>Addr</font></td>
<td><font size=-1>City</font></td>
<td><font size=-1>Phone</font></td>
<td><font size=-1>Email</font></td>
<td><font size=-1>FEmail</font></td>
<td><font size=-1>Groups</font></td>
</tr></table>
<p>
END_TEXT

		print $q->p ($description);
		print $q->hr;

		#For uploading txt files
		print start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));

		print "User information file: ", filefield('AcctsTXT','','30');
		
		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;  	
	
		my ($index,$select,$return);

		
		
			
		if (!$opsdir)
		{		
			$select = "<p>Or choose a one of the generated files:\n<br>";
			$select .= "<SELECT NAME=\"GenAcctsTXT\">\n";

			
				foreach $index (0 .. $#dirData) 
				{
				$return .= "<OPTION VALUE=\"$dirData[$index]\">$dirData[$index]\n" if $dirData[$index] =~ m/\.gen/;
				}  
			print "$select\n$return\n</SELECT>\n" if $return;
		
		}
		else
		{
		print "<p>$opsdir";
		}
	
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'tab',
			     -labels  => \%spacelabels);

		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11>\n";
		print "<br>\n";

		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performDel');

		my $pmsg = reset;
		$pmsg .= '&nbsp;'x5 . submit('submit',' Process File ') . "\n";
		print "<p>$pmsg\n";		

		print $q->endform;
	    }
	print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');
	
	esmith::cgi::genFooter ($q);
	exit;
	}
}

#------------------------------------------------------------
#
#------------------------------------------------------------

sub performDel ($$$)
{

my($q, $msg, $upload_dir) = @_;

my($accts_file, $file_name, $genaccts_file, $bytes_count, $size, $buff, $message);

	if ($q->param('AcctsTXT'))
	{
	$accts_file = $q->param('AcctsTXT');
	}
	elsif ($q->param('GenAcctsTXT'))
	{
	$genaccts_file = $q->param('GenAcctsTXT');
	}

	if ($accts_file =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $accts_file ;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
		
			if (! $file_name) 
			{
				$message = 'Bad file name';
				delShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			$file_name .= "-".&define_dates.".Dup";

			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				delShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
		    ###### For some reason this line below will cause an 'Internal Server error'
		    ###### the logs will say 'Premature end of script headers'.
		    ###### if you use '||' instead of 'or'
		    open(FILE,">$upload_dir/$file_name") or die(&delShowInitial($q, "Error opening file $file_name for writing, $!", $DEFAULT_UPLOAD_DIR));
		    binmode FILE;
		    while ($bytes_count = read($accts_file,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {
		    	$file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");
		    	$message = "Could not upload $file_name\n";
			delShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
			exit;
		    } 
		    else 
		    {
		    	$message = "<b>Deleting accounts</b><br>Uploaded succesfully and saved as:<br>$file_name<br>($size bytes)";
			getDeleteData ($q, $message, $upload_dir, $file_name);
			exit;
		     }

	}
	elsif ($genaccts_file =~ m/\w/)
	{
		$message = "<b>Deleting accounts</b><br>Using previous generate file:<br>$genaccts_file<br>\n";	
		getDeleteData ($q, $message, $upload_dir, $genaccts_file);
		exit;
	}
	else
	{
	my $message = "You did not provide a file. Click the Browse button and select a text file.";
	delShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
	}

}

#------------------------------------------------------
#
#------------------------------------------------------

sub getDeleteData($$$$)
{  
my ($q, $msg, $upload_dir, $file_name) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my $i;
my $separator;

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or ($message .= "<p>Could not remove file use another name, DO NOT use \"$d\"");
		}
	delShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
	exit;
	}


	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	my @uploadData = ();

	    open(FILE,"<$upload_dir/$file_name") or die(&delShowInitial($q, "Error opening file $file_name for reading, error $!", "$DEFAULT_UPLOAD_DIR"));
	    @uploadData = <FILE> ;
	    close(FILE);

	my $line;
	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");

my ($txtAREA, $BadAREA, $deleted) = &performDeleteUser($q, $separator, $upload_dir, $file_name);


print $q->p ("Total accounts deleted <b>$deleted</b>\n");

print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Log</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$txtAREA</TEXTAREA>\n");
print endform;
	
if ($BadAREA)
{
print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Errors</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$BadAREA</TEXTAREA>\n");
print endform;
}

print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');

esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------
#
#------------------------------------------------------

sub performDeleteUser ($$$$)
{
    my ($q, $S, $upload_dir, $file_name) = @_;

my $deleted = 0;
my $txtAREA;
my $BadAREA;
my $i;

my ($FirstName,
$LastName,
$acct,
$Passwd,
$Department,
$Company,
$Street,
$City,
$Phone,
$Email,
$EmailAddress,
@Groups) ;

open (LOG, "<$upload_dir/$file_name") or die(&delMainBODY($q, "Unable to read $upload_dir/$file_name", "$DEFAULT_UPLOAD_DIR"));
my @uploadData = <LOG>;
close (LOG);

	my $p = 0;
	my $status=0;
	my $stat=0;
	USER: foreach $i (@uploadData)
	{
	$p++;
	$status++;
	$stat++;
	chomp($i);
	#print a dot foreach user being work on so the browser displays something and 
	#does not timeout

		if ($status <= 35)
		{
			if ($stat <= 5)
			{
			print ".\n" ;
			}
			else
			{
			print "&nbsp;&nbsp;.\n";
			$stat=1;
			}
		}
		else
		{
		print "<br>.\n";
		$status=1;
		}

	#This removes all the extra spaces. allowing only one space between characters
	$i =~ s/[ ]{2,999}//g;
	$i =~ s/\n//g;
	$i =~ s/\r//g;	
	$i =~ s/\"//g;
	$i =~ s/\'//g;
	$i =~ s/\`//g;

		if ($i =~ m/\w*$S\w*/i)
		{
		#get the values that we need
		($FirstName,
		$LastName,
		$acct,
		$Passwd,
		$Department,
		$Company,
		$Street,
		$City,
		$Phone,
		$Email,
		$EmailAddress,
		@Groups) = split(/$S/,$i);
		}
		else
		{
		$BadAREA .= "Bad line $p\n$i\n";
		next USER;
		}


    #------------------------------------------------------------
    # Attempt to delete user
    #------------------------------------------------------------

	    if ($acct =~ /^([a-z][\-\_\.a-z0-9]*)$/)
	    {
		$acct = $1;
	    }
	    else
	    {
		$BadAREA .= "Error: internal failure while removing account \"$acct\"\n";
		next USER;
	    }

	    unless (db_get_type(\%accounts, $acct) eq "user")
	    {
	        $BadAREA .= "Error: account \"$acct\" is not an existing user account\n";
		next USER;
	    }

	    db_set_type(\%accounts, $acct, "user-deleted");

	#    $accounts {$acct} = "user-deleted|" . join ('|', %properties);

	    #------------------------------------------------------------
	    # First, find all "group" entries in the e-smith accounts database
	    # that contain this user.
	    #------------------------------------------------------------

	    my $key;
	    my $value;
	    my @groups = ();
	    while (($key,$value) = each %accounts)
	    {
		my ($type, %properties) = split (/\|/, $value, -1);
		if ($type eq 'group')
		{
		    #--------------------------------------------------
		    # Get a list of members and count the number of
		    # occurrences of this username. If greater than zero,
		    # add this group to the list.
		    #--------------------------------------------------
	
		    my $count = grep (/^$acct$/, split (/,/, $properties {'Members'}));
		    if ($count > 0)
		    {
			push (@groups, $key);
		    }
		}
	    }
	
	    #------------------------------------------------------------
	    # Next, for each group remove this user from the members list.
	    # Then signal the group-modify event so that the group is brought
	    # up to date. Make sure each group has at least one member; if
	    # the list is empty, add in user "admin".
	    #------------------------------------------------------------

	    my $group;
	    foreach $group (@groups)
	    {
		my $value = $accounts {$group};
		my ($type, %properties) = split (/\|/, $value, -1);
	
		my @members = split (/,/, $properties {'Members'});
		@members = grep (!/^$acct$/, @members);
	
		my $count = @members;
		if ($count == 0)
		{
		    @members = ('admin');
		}

		$properties{'Members'} = join(',', @members);
		$accounts {$group} = "group|" . join ('|', %properties);
	
		if (-d "$EventDir/multi-group-modify")
    		{    	    		
    		system ("/sbin/e-smith/signal-event", "multi-group-modify", "$group") == 0
		    or $BadAREA .= "Error occurred while updating group.\n" && next USER;
    		}
    		else
    		{		
		system ("/sbin/e-smith/signal-event", "group-modify", "$group") == 0
		    or $BadAREA .= "Error occurred while updating group.\n" && next USER;
		}	        
	    }

	    #------------------------------------------------------------
	    # Finally signal user-delete event
	    #------------------------------------------------------------
	    	if (-d "$EventDir/multi-user-delete")
    		{    	    		
    		system ("/sbin/e-smith/signal-event", "multi-user-delete", "$acct") == 0
		or $BadAREA .= "Error occurred while deleting user \"$acct\"\n" && next USER;
    		}
    		else
    		{
	    	system ("/sbin/e-smith/signal-event", "user-delete", "$acct") == 0
		or $BadAREA .= "Error occurred while deleting user \"$acct\"\n" && next USER;
		}
	    	delete $accounts {$acct};

	    #------------------------------------------------------------
	    # Remove any pseudonyms associated with this user
	    #------------------------------------------------------------

	    foreach (db_get(\%accounts))
	    {
		if (db_get_type(\%accounts, $_) eq "pseudonym")
		{
		    if (db_get_prop(\%accounts, $_, "Account") eq $acct)
		    {
			system(
				"/sbin/e-smith/signal-event",
				"pseudonym-delete",
				"$_"
			    ) == 0
			    or $BadAREA .= "Error occurred while deleting $_.\n" && next USER;
		    }
		}
	    }
	
	    $txtAREA .= "Successfully deleted user account \"$acct\"\n";
	    $deleted++;
	} #this ends the foreach loop

return ($txtAREA, $BadAREA, $deleted);
}
#################################################################
###### Delete users from txt file ends.
#################################################################
#################################################################
###### Password change from txt file begins.
#################################################################

sub pwdShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Set user account passwords');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&pwdMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub pwdMainBODY($$$)
	{
	print hlplnk('PwdInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }
	    else
            {

		my $description = <<END_TEXT;
This will allow you to set user account passwords from
a text file. The format of the file must be:<p>
<table border=1>
<tr>
<td><font size=-1>FName</td>
<td><font size=-1>LName</font></td>
<td><font size=-1>User</font></td>
<td><font size=-1>Pwd</font></td>
<td><font size=-1>Dept</font></td>
<td><font size=-1>Comp</font></td>
<td><font size=-1>Addr</font></td>
<td><font size=-1>City</font></td>
<td><font size=-1>Phone</font></td>
<td><font size=-1>Email</font></td>
<td><font size=-1>FEmail</font></td>
<td><font size=-1>Groups</font></td>
</tr></table>
<p>
END_TEXT

		print $q->p ($description);
		print $q->hr;

		#For uploading txt files
		print start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));

		print "User information file: ", filefield('AcctsTXT','','30');
		
		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;  	
	
		my ($index,$select,$return);

		
		
					
		if (!$opsdir)
		{		
			$select = "<p>Or choose a one of the generated files:\n<br>";
			$select .= "<SELECT NAME=\"GenAcctsTXT\">\n";

			
				foreach $index (0 .. $#dirData) 
				{
				$return .= "<OPTION VALUE=\"$dirData[$index]\">$dirData[$index]\n" if $dirData[$index] =~ m/\.gen/;
				}  
			print "$select\n$return\n</SELECT>\n" if $return;
		
		}
		else
		{
		print "<p>$opsdir";
		}
	
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'tab',
			     -labels  => \%spacelabels);

		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11>\n";
		print "<br>\n";

		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performPwd');

		my $pmsg = reset;
		$pmsg .= '&nbsp;'x5 . submit('submit',' Process File ') . "\n";
		print "<p>$pmsg\n";		

		print $q->endform;
     	   }
	
	print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');
	esmith::cgi::genFooter ($q);
	exit;
	}
}

#------------------------------------------------------------
#
#------------------------------------------------------------
sub performPwd($$$)
{
my ($q, $msg, $upload_dir) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my ($txtAREA, $BadAREA, $ttxtAREA, $tBadAREA, $chgpwd, $separator, $i, $count, $S);
my($accts_file, $file_name, $genaccts_file, $bytes_count, $size, $buff, $message);
my ($FirstName,
$LastName,
$acct,
$Passwd,
$Department,
$Company,
$Street,
$City,
$Phone,
$Email,
$EmailAddress,
@Groups);

$count=0;

	if ($q->param('AcctsTXT'))
	{
	$accts_file = $q->param('AcctsTXT');
	}
	elsif ($q->param('GenAcctsTXT'))
	{
	$genaccts_file = $q->param('GenAcctsTXT');
	}

	if ($accts_file =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $accts_file ;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
		
			if (! $file_name) 
			{
				$message = 'Bad file name';
				pwdShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			$file_name .= "-".&define_dates.".Pup";			

			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				pwdShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
		    ###### For some reason this line below will cause an 'Internal Server error'
		    ###### the logs will say 'Premature end of script headers'.
		    ###### if you use '||' instead of 'or'
		    open(FILE,">$upload_dir/$file_name") or die(&pwdShowInitial($q, "Error opening file $file_name for writing, $!", $DEFAULT_UPLOAD_DIR));
		    binmode FILE;
		    while ($bytes_count = read($accts_file,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {
		    	$file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");		   	
		    	$message = "Could not upload $file_name\n";
			pwdShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
			exit;
		    } 

	}
	elsif ($genaccts_file =~ m/\w/)
	{
		#$message = "Using previous generate file:<br>$genaccts_file<br>\n";	
		$file_name = $genaccts_file;
		#exit;
	}
	else
	{
	my $message = "You did not provide a file. Click the Browse button and select a text file.";
	pwdShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
	exit;
	}

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or $message .= "<p>Could not remove file use another name, DO NOT use \"$d\"";
		}
	pwdShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
	exit;
	}

	$S = $separator;

	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	$msg .= "<p><b>Setting passwords</b><br>Getting data from<br>$file_name";
	print $q->p ($msg);
	print $q->hr;

	my @uploadData = ();
                                                   
	    open(FILE,"<$upload_dir/$file_name") or die(&pwdMainBODY($q, "Error opening file $file_name for reading, error $!", "$DEFAULT_UPLOAD_DIR"));
	    @uploadData = <FILE> ;
	    close(FILE);

	my $line;
	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");
	
	my $p = 0;
	my $status=0;
	my $stat=0;
	foreach $i (@uploadData)
	{
	$p++;
	$status++;
	$stat++;
	chomp($i);
	#print a dot foreach user being work on so the browser displays something and 
	#does not timeout

		if ($status <= 35)
		{
			if ($stat <= 5)
			{
			print ".\n" ;
			}
			else
			{
			print "&nbsp;&nbsp;.\n";
			$stat=1;
			}
		}
		else
		{
		print "<br>.\n";
		$status=1;
		}

	#This removes all the extra spaces. allowing only one space between characters
	$i =~ s/[ ]{2,999}//g;
	$i =~ s/\n//g;
	$i =~ s/\r//g;	
	$i =~ s/\"//g;
	$i =~ s/\'//g;
	$i =~ s/\`//g;

		if ($i =~ m/\w*$S\w*/i)
		{
		#get the values that we need
		($FirstName,
		$LastName,
		$acct,
		$Passwd,
		$Department,
		$Company,
		$Street,
		$City,
		$Phone,
		$Email,
		$EmailAddress,
		@Groups) = split(/$S/,$i);
		}
		else
		{
		$BadAREA .= "Bad line $p\n$i\n";
		next;
		}
	($ttxtAREA, $tBadAREA, $chgpwd) = performPasswdUser ($q, $acct, $Passwd);
	$count += $chgpwd;
	$txtAREA .= $ttxtAREA;
	$BadAREA .= $tBadAREA;
	}
	
print $q->p ("Total passwords set <b>$count</b>\n");

print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Log</b></font>".
"<p>\n<TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$txtAREA</TEXTAREA>\n");
print endform;
	
if ($BadAREA)
{
print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Errors</b></font>".
"<p>\n<TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$BadAREA</TEXTAREA>\n");
print endform;
}

print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');



esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------------
#
#------------------------------------------------------------

sub performPasswdUser ($$$)
{
    my ($q, $acct, $newPass) = @_;
	
    my ($txtAREA, $BadAREA, $chgpwd); 
    $chgpwd=0;	

    #------------------------------------------------------------
    # Attempt to change user password
    #------------------------------------------------------------


    if ($acct =~ /^([a-z][\-\_\.a-z0-9]*)$/)
    {
	$acct = $1;
    }
    else
    {
	$BadAREA .= "Error: internal failure while changing password for account \"$acct\"\n";
	return ($txtAREA, $BadAREA, $chgpwd);
    }


    if ($newPass =~ /^([ -~]+)$/)
    {
	$newPass = $1;
    }
    else
    {
	$BadAREA .= "Error: password must contain only printable characters.\n";
	return ($txtAREA, $BadAREA, $chgpwd);
    }

    my $newPassVerify = $newPass;	


    esmith::util::setUserPassword ($acct, $newPass);

    #------------------------------------------------------------
    # update the user's PasswordSet field in the accounts database
    #------------------------------------------------------------

    my $value = $accounts {$acct};

    my ($type, %properties) = split (/\|/, $value, -1);
    $properties {'PasswordSet'} = 'yes';

    $accounts {$acct} = "user|" . join('|', %properties);

	my $errors;
    system ("/sbin/e-smith/signal-event password-modify ${acct}") == 0
        or $errors=1;

	return ($txtAREA, "Error occurred while modifying password for ${acct}.\n", $chgpwd) if $errors;

    $txtAREA .= "Successfully changed password for user account $acct.\n";
    $chgpwd = 1;	
return ($txtAREA, $BadAREA, $chgpwd);
}

#################################################################
###### Password change from txt file ends.
#################################################################
#################################################################
###### View txt file begins.
#################################################################

sub viewShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'View/Delete text file/s');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&viewMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub viewMainBODY($$$)
	{
	print hlplnk('ViewInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }

		my $description = <<END_TEXT;
This will allow you to view or delete text files you uploaded or were generated
and is store in your upload dir<br>$DEFAULT_UPLOAD_DIR
<p>

END_TEXT

		print $q->p ($description);
		print $q->hr;

		#For uploading txt files
		print startform(-method => 'POST', -action => $q->url (-absolute => 1));

			
		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;

		my ($index,$select,$return);

		if (!$opsdir)
		{
			print "<p>You can only view one file at a time, but you can delete
			multiple files at once. If you select multiple files and choose to view
			you will only be able to see the first file.
			<p>Hold down the 'Shift' or 'Ctrl' key to select multiple files.";

			print "<p>Choose a file/s:\n<br>\n";

			print "<SELECT NAME=\"TXTfile\" MULTIPLE SIZE=\"10\">\n";

			#
				foreach $index (0 .. $#dirData)
				{
				my $Tfile = $DEFAULT_UPLOAD_DIR."/".$dirData[$index];
					if(-f $Tfile)
					{
					print "<OPTION VALUE=\"$dirData[$index]\">$dirData[$index]\n" if $dirData[$index] =~ m/\w/;
					}
				}  
			print "</SELECT>\n";
			
			print "<p><input type=radio name=EorV value='view'> View
				<input type=radio name=EorV value='delete'> Delete\n<p>";
		
		}
		else
		{
		print "<p>$opsdir";
		}
	
		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performView');

		print $q->submit('submit',' Process File ') . "\n";
		
		print $q->endform;
		
		print $q->p ($q->a ({href => $q->url (-absolute => 1)},'Click here'), 'to go back to the menu.');
			
	esmith::cgi::genFooter ($q);
	exit;
	}
}

#------------------------------------------------------------
#
#------------------------------------------------------------

sub performView ($$$)
{
    my ($q, $msg, $upload_dir) = @_;
    
    my $EorV = $q->param('EorV');
    my($file_name, $message, $d, $CNDelete, $errors, $Deleted);
    $errors = 0 ;
    $Deleted = "<b>Successfully removed:</b><br>\n";
    $CNDelete = "<b>Could not delete:</b><br>\n";
    my @files = $q->param('TXTfile');
    $file_name = $files[0];
	
   if($EorV eq 'delete')
   {
   	foreach $d (@files)
   	{   		
   		$d =~ /^(.*?)$/ ;
	        $d = $1;   		   		
   		my $mesg;
		unlink("$upload_dir/$d") or $mesg = $!;
		
		$errors++ if (-e "$upload_dir/$d");
		
			if($errors)
			{
			$CNDelete .= "$d : $mesg<br>\n";
			}
			else
			{
			$Deleted .= "$d<br>\n";
			}
	}
	
	if($errors)
	{
	$msg = "$CNDelete<p>$Deleted\n";
	}
	else
	{
	$msg = $Deleted;
	}
     viewShowInitial ($q, $msg, $DEFAULT_UPLOAD_DIR);
   }
   elsif($EorV eq 'view')
   {
	if ($file_name =~ m/\w/)
	{
		$msg .= "<p><b>Displaying file</b>:<br>$file_name<br>\n";	
	}

	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	my @uploadData = ();
                                                   
	    open(FILE,"<$upload_dir/$file_name") or die(&viewMainBODY($q, "Error opening file $file_name for reading, error $!", "$DEFAULT_UPLOAD_DIR"));
	    @uploadData = <FILE> ;
	    close(FILE);
	
	my($line, $lines);
	foreach $line (@uploadData)
	{
	# so that the browser displays this correctly
	$line =~ s/</\&lt\;/g;
	$line =~ s/>/\&gt\;/g;
	$lines .= $line;
	}

	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");

	print startform(-method => 'POST', -action => $q->url (-absolute => 1));
	print "<TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$lines</TEXTAREA>\n";
	print endform;
	
	print $q->p ($q->a ({href => $q->url (-absolute => 1) . '?state=viewForm'},'Click here'), 'to go select another file.');
		
	print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=performView&EorV=delete&TXTfile=$file_name"},'Click here'), 'to delete this file.');
	
	print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');
	
	
	esmith::cgi::genFooter ($q);
	exit;
   }
   else
   {
   viewShowInitial ($q, "Select view or delete", $DEFAULT_UPLOAD_DIR);
   }
}

#################################################################
###### View txt file ends.
#################################################################
#################################################################
###### Modified user from txt file begins.
#################################################################

sub modShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Modify users with data from text file');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&modMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub modMainBODY($$$)
	{
	print hlplnk('ModInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }
	    else
            {

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}

	my $description = <<END_TEXT;
This will allow you to modified user information 
with new data from a text file. 
The format of the file must be:<p>
<table border=1>
<tr>
<td><font size=-1>FName</td>
<td><font size=-1>LName</font></td>
<td><font size=-1>User</font></td>
<td><font size=-1>Pwd</font></td>
<td><font size=-1>Dept</font></td>
<td><font size=-1>Comp</font></td>
<td><font size=-1>Addr</font></td>
<td><font size=-1>City</font></td>
<td><font size=-1>Phone</font></td>
<td><font size=-1>Email</font></td>
<td><font size=-1>FEmail</font></td>
<td><font size=-1>Groups</font></td>
</tr></table>
<p>
END_TEXT

		print $q->p ($description);
		print $q->hr;

		#For uploading txt files
		print start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));

		print "Enter the file to process: ", filefield('uploadTXT','','30');

		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;  	
	
		my ($index,$select,$return);

		if (!$opsdir)
		{		
			$select = "<p>Or choose a file:\n<br>";
			$select .= "<SELECT NAME=\"TXTfile\">\n";

			
				foreach $index (0 .. $#dirData) 
				{
				$return .= "<OPTION VALUE=\"$dirData[$index]\">$dirData[$index]\n" if $dirData[$index] != m/^\.\.?/;
				}  
			print "$select\n$return\n</SELECT>\n" if $return;
		
		}
		else
		{
		print "<p>$opsdir";
		}
		
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'tab',
			     -labels  => \%spacelabels);

		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11>\n";
			
		print "<p>You can over write certain fields in file with the ones below, Just check the box below.
		If you do not want to over write one field but you want to over write the other fields, simply 
		leave that field blank and fill out the fields you want to over write.<p>
		<input type=checkbox name=overwrite value=yes> Over write fields in file with these below\n<p>";
	
		my ($pawd);
		$pawd = "	
		<SELECT NAME=\"PwdIs\">
		<OPTION VALUE=\"pwdIsnone\">Don't set password
		<OPTION  VALUE=\"pwdIsgen\">Generate Password
		<OPTION  VALUE=\"pwdIstxt\">Use password from text file
		<OPTION SELECTED VALUE=\"pwdIsname\">Password equals username
		</SELECT>\n";
		
		my $pmsg = reset;
		$pmsg .= '&nbsp;'x5 . submit('submit',' Process File ') . "\n";
	
		print $q->table ({border => 0, cellspacing => 0, cellpadding => 4},
	
		$q->Tr (esmith::cgi::genCell ($q, "Password:"),
		esmith::cgi::genCell ($q, "$pawd")),

	        esmith::cgi::genNameValueRow ($q,
                                      "Department",
                                      "department",
                                      db_get_prop (\%conf, 'ldap', 'defaultDepartment')),

        	esmith::cgi::genNameValueRow ($q,
                                      "Company",
                                      "company",
                                      db_get_prop (\%conf, 'ldap', 'defaultCompany')),

	        esmith::cgi::genNameValueRow ($q,
                                      "Street address",
                                      "street",
                                      db_get_prop (\%conf, 'ldap', 'defaultStreet')),

	        esmith::cgi::genNameValueRow ($q,
                                      "City",
                                      "city",
                                      db_get_prop (\%conf, 'ldap', 'defaultCity')),

	        esmith::cgi::genNameValueRow ($q,
                                      "Phone number",
                                      "phone",
                                      db_get_prop (\%conf, 'ldap', 'defaultPhoneNumber')),

	        $q->Tr (esmith::cgi::genCell ($q, "Email delivery:"),
		genEmailForwardMod($q, '')),

		esmith::cgi::genNameValueRow ($q,
				      "Forwarding address",
				      "forwardAddress",
				      'USERNAME@'),

        	$q->Tr (esmith::cgi::genCell ($q, "Group memberships:"),
	        esmith::cgi::genCell ($q, genGroups ($q, ''))),

		$q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performModify'),

		$q->Tr (esmith::cgi::genCell ($q, " "),
	        esmith::cgi::genCell ($q, $pmsg))); # These are the reset/submit buttons
           }

    	print $q->endform;
    	
    	print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');
    	
	esmith::cgi::genFooter ($q);
	exit;	
	}#sub ends
}

#------------------------------------------------------------
#
#------------------------------------------------------------
sub performModifyUser ($$$)
{
my($q, $msg, $upload_dir) = @_;

my($accts_file, $file_name, $genaccts_file, $bytes_count, $size, $buff, $message);

	if ($q->param('uploadTXT'))
	{
	$accts_file = $q->param('uploadTXT');
	}
	elsif ($q->param('TXTfile'))
	{
	$genaccts_file = $q->param('TXTfile');
	}

	if ($accts_file =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $accts_file ;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
		
			if (! $file_name) 
			{
				$message = 'Bad file name';
				modShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			$file_name .= "-".&define_dates.".Mup";			

			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				modShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
		    ###### For some reason this line below will cause an 'Internal Server error'
		    ###### the logs will say 'Premature end of script headers'.
		    ###### if you use '||' instead of 'or'
		    open(FILE,">$upload_dir/$file_name") or die(&modShowInitial($q, "Error opening file $file_name for writing, $!", $DEFAULT_UPLOAD_DIR));
		    binmode FILE;
		    while ($bytes_count = read($accts_file,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {		    
		    	$file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");		   	
		    	$message = "Could not upload $d\n";
			modShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
			exit;
		    } 
		    else 
		    {
		    	$message = "<b>Modifiying accounts</b><br>Uploaded succesfully and saved as:<br>$file_name<br>($size bytes)\n";
			getModData ($q, $message, $upload_dir, $file_name);
			exit;
		     }

	}
	elsif ($genaccts_file =~ m/\w/)
	{
		$message = "<b>Modifiying accounts</b><br>Using previous file:<br>$genaccts_file<br>\n";	
		getModData ($q, $message, $upload_dir, $genaccts_file);
		exit;
	}
	else
	{
	my $message = "You did not provide a file. Click the Browse button and select a text file.";
	modShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
	}
}

#------------------------------------------------------
#
#------------------------------------------------------

sub getModData($$$$)
{  
my ($q, $msg, $upload_dir, $file_name) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my $i;
my $separator;

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or ($message .= "<p>Could not remove file use another name, DO NOT use \"$d\"");
		}
	modShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
	exit;
	}


	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	my @uploadData = ();

	    open(FILE,"<$upload_dir/$file_name") or die(&modShowInitial($q, "Error opening file $file_name for reading, error $!", "$DEFAULT_UPLOAD_DIR"));
	    @uploadData = <FILE> ;
	    close(FILE);

	my $line;
	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");

my ($txtAREA, $BadAREA, $modified) = &performModUser($q, $separator, $upload_dir, $file_name);


print $q->p ("Total accounts modified <b>$modified</b>\n");

print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Log</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$txtAREA</TEXTAREA>\n");
print endform;
	
if ($BadAREA)
{
print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Errors</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$BadAREA</TEXTAREA>\n");
print endform;
}

print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');

esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------
#
#------------------------------------------------------

sub performModUser ($$$$)
{
    my ($q, $S, $upload_dir, $file_name) = @_;

my $modified = 0;
my $error = 0;
my $txtAREA;
my $BadAREA;
my $i;

my ($firstName,
$lastName,
$acctName,
$Passwd,
$department,
$company,
$street,
$city,
$phone,
$emailForward,
$forwardAddress,
@groups) ;

my $overwrite = $q->param('overwrite'); #value=yes

open (LOG, "<$upload_dir/$file_name") or die(&delMainBODY($q, "Unable to read $upload_dir/$file_name", "$DEFAULT_UPLOAD_DIR"));
my @uploadData = <LOG>;
close (LOG);

	my $p = 0;
	my $status=0;
	my $stat=0;
	MOD: foreach $i (@uploadData)
	{
	$p++;
	$status++;
	$stat++;
	chomp($i);
	#print a dot foreach user being work on so the browser displays something and 
	#does not timeout

		if ($status <= 35)
		{
			if ($stat <= 5)
			{
			print ".\n" ;
			}
			else
			{
			print "&nbsp;&nbsp;.\n";
			$stat=1;
			}
		}
		else
		{
		print "<br>.\n";
		$status=1;
		}

	#This removes all the extra spaces. allowing only one space between characters
	$i =~ s/[ ]{2,999}//g;
	$i =~ s/\n//g;
	$i =~ s/\r//g;	
	$i =~ s/\"//g;
	$i =~ s/\'//g;
	$i =~ s/\`//g;

		if ($i =~ m/\w*$S\w*/i)
		{
		#get the values that we need
		($firstName,
		$lastName,
		$acctName,
		$Passwd,
		$department,
		$company,
		$street,
		$city,
		$phone,
		$emailForward,
		$forwardAddress,
		@groups) = split(/$S/,$i);
		}
		else
		{
		$BadAREA .= "Bad line $p\n$i\n";
		next MOD;
		}
		
		## Check to see if we need to over write some fields ##		
		if($overwrite eq 'yes')
		{
		my $pwd = $q->param('PwdIs');
			if ($pwd eq 'pwdIsnone')
			{
				$Passwd = '';
			}
			elsif ($pwd eq 'pwdIsgen')
			{
				# maximum password length, 
				# not including 1 numeric character
				my $passlen=5;  
				my $pwword="";
				my $maxi=24;
				my $character='';
				my @randlist=();
					for ($i=0;$i<$passlen;$i++)
					{
			          	$character=int(rand(24)+1);
			          	$character=$character+66;
			           	$character=chr($character);
			          	$pwword=$pwword.$character;
			           	}
				$character=int(rand(9)+1);
				$pwword=$pwword.$character;
				$Passwd=lc($pwword);
			}
			elsif ($pwd eq 'pwdIsname')
			{
				$Passwd = $acctName;	
			}
			elsif ($pwd eq 'pwdIstxt')
			{
				$Passwd = $Passwd;
			}
				
		$department = $q->param('department') if $q->param('department');
		$company = $q->param('company') if $q->param('company');
		$street = $q->param('street') if $q->param('street');
		$city = $q->param('city') if $q->param('city');
		$phone = $q->param('phone') if $q->param('phone');
			if ($q->param('emailForward') ne 'txt')
			{
			$emailForward = $q->param('emailForward') if $q->param('emailForward');
			$forwardAddress = $q->param('forwardAddress') if $q->param('forwardAddress');
			}		
		$forwardAddress =~ s/USERNAME/$acctName/;
		@groups	= $q->param('groupMemberships')	if $q->param('groupMemberships');
		}

	    #------------------------------------------------------------
	    # Validate parameters and untaint them
	    #------------------------------------------------------------

	    if ($acctName =~ /^([a-z][\-\_\.a-z0-9]*)$/)
	    {
	        $acctName = $1;
	    }
	    else
	    {
		$BadAREA .= "Error: \"$acctName\" : bad account name\n";
		next MOD;
	    }

	    #------------------------------------------------------------
	    # Looks good. Make sure this is a valid account
	    #------------------------------------------------------------

	    unless (exists $accounts {$acctName})
	    {
	        $BadAREA .= "Error: account \"$acctName\" is not an existing account.\n";
	        next MOD;
	    }

	    if ($firstName =~ /^\s*([a-zA-Z0-9\'\.\-\s]+?)\s*$/)
	    {
	        $firstName = $1;
	    }
	    else
	    {
	        $BadAREA .= "\"$acctName\": unexpected or missing characters in first name: \"$firstName\"\n";
	        next MOD;
	    }
    
    if ($lastName =~ /^\s*([a-zA-Z0-9\'\.\-\s]+?)\s*$/)
    {
        $lastName = $1;
    }
    else
    {
        $BadAREA .= "\"$acctName\": unexpected or missing characters in last name: \"$lastName\"\n";
        next MOD;
    }
    
    if ($department =~ /^([^\|]*)$/)
    {
        $department = $1;
    }
    else
    {
        $BadAREA .= "\"$acctName\": unexpected characters in department: \"$department\"\n";
        next MOD;
    }

    if ($company =~ /^([^\|]*)$/)
    {
        $company = $1;
    }
    else
    {
        $BadAREA .= "\"$acctName\": unexpected characters in company: \"$company\"\n";
        next MOD;
    }

    if ($street =~ /^([^\|]*)$/)
    {
        $street = $1;
    }
    else
    {
        $BadAREA .= "\"$acctName\": unexpected characters in street address: \"$street\"\n";
        next MOD;
    }

    if ($city =~ /^([^\|]*)$/)
    {
        $city = $1;
    }
    else
    {
        $BadAREA .= "\"$acctName\": unexpected characters in city: \"$city\"\n";
        next MOD;
    }
   
    if ($phone =~ /^([^\|]*)$/)
    {
        $phone = $1;
    }
    else
    {
        $BadAREA .= "\"$acctName\": unexpected characters in phone number: \"$phone\"\n";
        next MOD;
    }
    
    if ($emailForward =~ /^(.*)$/)
    {
	$emailForward = $1;
    }
    else
    {
	$emailForward = "";
    }

    if (($emailForward eq 'local') && ($forwardAddress =~ /^([^\|]*)$/))
    {
	$forwardAddress = $1;
    }
    elsif (($emailForward ne 'local') && ($forwardAddress =~ /^([^\|]+)$/))
    {
	$forwardAddress = $1;
    }
    else
    {
	$BadAREA .= "\"$acctName\": unexpected or missing characters in email forwarding address: \"$forwardAddress\"\n";
	next MOD;
    }

    unless (db_get_type(\%accounts, $acctName) eq "user")
    {
        $BadAREA .= "Error: account \"$acctName\" is not an existing user account\n";
        next MOD;
    }


    #------------------------------------------------------------
    # Update accounts database and signal the user-modify event.
    #------------------------------------------------------------

    db_set_prop(\%accounts, $acctName, 'FirstName', $firstName);
    db_set_prop(\%accounts, $acctName, 'LastName', $lastName);
    db_set_prop(\%accounts, $acctName, 'Phone', $phone);
    db_set_prop(\%accounts, $acctName, 'Company', $company);
    db_set_prop(\%accounts, $acctName, 'Dept', $department);
    db_set_prop(\%accounts, $acctName, 'City', $city);
    db_set_prop(\%accounts, $acctName, 'Street', $street);
    db_set_prop(\%accounts, $acctName, 'EmailForward', $emailForward);
    db_set_prop(\%accounts, $acctName, 'ForwardAddress', $forwardAddress);

	if (-d "$EventDir/multi-user-modify")
    	{
    	system ("/sbin/e-smith/signal-event", "multi-user-modify", "$acctName") == 0 or $error++; 
    	}
    	else
    	{
    	system ("/sbin/e-smith/signal-event", "user-modify", "$acctName") == 0 or $error++; 
    	}
        
        if ($error)
     	{	 
     	$BadAREA .= "\"$acctName\": Error occurred while modifying user.\n";
     	next MOD;	
     	}

    #------------------------------------------------------------
    # Update any relevant groups using the following procedure:
    #
    # 1. Create a hash table called %state.
    #
    # 2. Visit all groups, setting the hash value to 2 if the
    #    user is currently in the group, and 0 if not.
    #
    # 3. Then visit all the selected groups (the new settings)
    #    from the HTML form, adding one to the hash value for
    #    each selected group.
    #
    # 4. Finally run through the %state hash table, updating groups:
    #    - if 0, user was not in group before or after - do nothing
    #    - if 1, user has been added to group          - update
    #    - if 2, user has been removed from group      - update
    #    - if 3, user was in group before and after    - do nothing
    #------------------------------------------------------------

    my %state = ();

    my $key;
    my $value;	# Already defined when checking account validity above

    while (($key,$value) = each %accounts)
    {
	my ($type, %properties) = split (/\|/, $value, -1);
	if ($type eq 'group')
	{
	    my @members = split (/,/, $properties {'Members'});
	    if (grep (/^$acctName$/, @members))
	    {
		$state {$key} = 2;
	    }
	    else
	    {
		$state {$key} = 0;
	    }
	}
    }

    my $group;
    foreach $group (@groups)
    {
	$state {$group} ++;
    }

    while (($key,$value) = each %state)
    {
	if ($value == 1)
	{
	    #----------------------------------------
	    # User was not in group before, but is now.
	    # Modify group to add user.
	    #----------------------------------------

	    my $value = $accounts {$key};
	    my ($type, %properties) = split (/\|/, $value, -1);
	    my @members = split (/,/, $properties {'Members'});
	    push @members, $acctName;
	    $properties{'Members'} = join(',', @members);
	    $accounts {$key} = "group|" . join ('|', %properties);

		if (-d "$EventDir/multi-group-modify")
    		{    		
    		system ("/sbin/e-smith/signal-event", "multi-group-modify", "$key") == 0 or $error++;
    		}
    		else
    		{
	    	system ("/sbin/e-smith/signal-event", "group-modify", "$key") == 0 or $error++;
	    	}
		
		if ($error)
     		{	 
     		$BadAREA .= "\"$acctName\": Error occurred while updating group\n";
     		next MOD;	
     		}
	}

	elsif ($value == 2)
	{
	    #----------------------------------------
	    # User was in group before, but is not now.
	    # Modify group to remove user.
	    #----------------------------------------

	    my $value = $accounts {$key};
	    my ($type, %properties) = split (/\|/, $value, -1);
	    my @members = split (/,/, $properties {'Members'});
	    @members = grep (!/^$acctName$/, @members);
	    $properties{'Members'} = join(',', @members);
	    $accounts {$key} = "group|" . join ('|', %properties);

		if (-d "$EventDir/multi-group-modify")
    		{    		
    		system ("/sbin/e-smith/signal-event", "multi-group-modify", "$key") == 0 or $error++;
    		}
    		else
    		{
	    	system ("/sbin/e-smith/signal-event", "group-modify", "$key") == 0 or $error++;
	    	}
		
		if ($error)
     		{	 
     		$BadAREA .= "\"$acctName\": Error occurred while updating group.\n";
     		next MOD;	
     		}
	}
    }

    untie %accounts;
    tie %accounts, 'esmith::config', '/home/e-smith/accounts';

	    $txtAREA .= "Successfully modified user account \"$acctName\"\n";
	    $modified++;
	} #this ends the foreach loop

return ($txtAREA, $BadAREA, $modified);
}
#################################################################
###### Modify users from txt file ends.
#################################################################

#################################################################
###### Update user accounts begins.
#################################################################
sub updateShowInitial($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------

    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Update user accounts');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&updateMainBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub updateMainBODY($$$)
	{
	print hlplnk('UpdateInit');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }

		my $description = <<END_TEXT;
This will take the file you provide and do two comparisons. First it
will take the current users from the system and see wether or not they
appear in the file. If they do not appear in the file, that means that
they can be disable/deleted, this will generate a file with all the users
that <b>need to be disable/deleted</b> from the system.<p>

Second, it will do the opposite, it will take the file and see wether 
or not a user from the file is found in the system. If a user
does not appear in the system, that means that they need to be added,
this will generate a file with all the users that <b>need to be 
added</b> to the system.

<p>I need a unique field that is different in each user and
that every user has, like a 10 character ID number ,
so that I can check the user's status. First and Last names will be used,
but some users may have the same first and last name, that is why I
need a second field, unless you know that there is no problem with 
First and Last name, then select "Only FName and LName" otherwise select
another field wich will be use along with First and Last name to distinguish each user.
Select a field below.
<p>
END_TEXT
		#For uploading txt files
		print start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));
		
		print $q->p ($description);
		print $q->hr;
		print $q->p ('
		<table border=1>
		<tr>
		<td><font size=-1>Only FName and LName</font></td>
		<td><font size=-1>User</font></td>
		<td><font size=-1>Dept</font></td>
		<td><font size=-1>Comp</font></td>
		<td><font size=-1>Addr</font></td>
		<td><font size=-1>City</font></td>
		<td><font size=-1>Phone</font></td>
		<td><font size=-1>FEmail</font></td>
		</tr>
		<tr>
		<td align=center><font size=-1><input type=radio name=uniqField value="onlyFnL"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="User"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="Dept"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="Comp"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="Addr"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="City"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="Phone"></font></td>
		<td align=center><font size=-1><input type=radio name=uniqField value="FEmail"></font></td>
		</tr>
		</table>
		');
		print "User information file: <br>", filefield('AcctsTXT','','30');
		
		my $opsdir;
		opendir(DIR, "$DEFAULT_UPLOAD_DIR") or $opsdir = "can't open directory $DEFAULT_UPLOAD_DIR: $!";
		my @dirData = readdir(DIR);
	    	closedir DIR;  	
	
		my ($index,$select,$return);

		if (!$opsdir)
		{		
			$select = "<p>Or choose a one of the upload files:\n<br>";
			$select .= "<SELECT NAME=\"GenAcctsTXT\">\n";

			
				foreach $index (0 .. $#dirData) 
				{
				$return .= "<OPTION VALUE=\"$dirData[$index]\">$dirData[$index]\n" if $dirData[$index] != m/^\.\.?/;
				}  
			print "$select\n$return\n</SELECT>\n" if $return;
		
		}
		else
		{
		print "<p>$opsdir";
		}
	
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'tab',
			     -labels  => \%spacelabels);

		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11>\n";
		print "<br>\n";

		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performUpdate');
		     
		my $pmsg = reset;
		$pmsg .= '&nbsp;'x5 . submit('submit',' Process File ') . "\n";
		print "<p>$pmsg\n";		

		print $q->endform;
		
	print $q->p ($q->a ({href => $q->url (-absolute => 1)},	'Click here'), 'to go back to the menu.');
	
	esmith::cgi::genFooter ($q);
	exit;
	}


exit;
}

#------------------------------------------------------------
#
#------------------------------------------------------------
sub performUpdateUsers ($$$)
{
my($q, $msg, $upload_dir) = @_;

my($accts_file, $file_name, $genaccts_file, $bytes_count, $size, $buff, $message, $uniq);
$uniq = $q->param('uniqField'); 

my @uniqs = ();
@uniqs = qw(onlyFnL User Dept Comp Addr City Phone FEmail);
my $found = 'no';

	foreach (@uniqs)
	{
	$found = 'yes' if $_ eq $uniq;
	}
			
	if ($found eq 'no')
	{
	$msg="You did not provide a unique field, you MUST select one. ";
	updateShowInitial($q, $msg, $upload_dir);
	}		
	
	if ($q->param('AcctsTXT'))
	{
	$accts_file = $q->param('AcctsTXT');
	}
	elsif ($q->param('GenAcctsTXT'))
	{
	$genaccts_file = $q->param('GenAcctsTXT');
	}

	if ($accts_file =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $accts_file ;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
		
			if (! $file_name) 
			{
				$message = 'Bad file name';
				updateShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
			$file_name .= "-".&define_dates.".Uup";			

			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				updateShowInitial ($q, $message, "$DEFAULT_UPLOAD_DIR");
				exit;
			}
		    ###### For some reason this line below will cause an 'Internal Server error'
		    ###### the logs will say 'Premature end of script headers'.
		    ###### if you use '||' instead of 'or'
		    open(FILE,">$upload_dir/$file_name") or die(&updateShowInitial($q, "Error opening file $file_name for writing, $!", $DEFAULT_UPLOAD_DIR));
		    binmode FILE;
		    while ($bytes_count = read($accts_file,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {
		        $file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");		   	
		    	$message = "Could not upload $d\n";
			updateShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
			exit;
		    } 
		    else 
		    {
		        $message = $q->a ({href => $q->url (-absolute => 1) . "?TXTfile=$file_name&EorV=view&state=performView", -target=>'_new'}, $file_name);
		    	$message = "<b>Updating accounts</b><br>Uploaded succesfully and saved as:<br>$message<br>($size bytes)\n";
			getUpData($q, $message, $upload_dir, $file_name, $uniq);
			exit;
		     }

	}
	elsif ($genaccts_file =~ m/\w/)
	{		
		$message = $q->a ({href => $q->url (-absolute => 1) . "?TXTfile=$genaccts_file&EorV=view&state=performView", -target=>'_new'}, $genaccts_file);
		$message = "<b>Updating accounts</b><br>Using previous file:<br>$message<br>\n";	
		getUpData($q, $message, $upload_dir, $genaccts_file, $uniq);
		exit;
	}
	else
	{
	my $message = "You did not provide a file. Click the Browse button and select a text file.";
	updateShowInitial ($q, $message, $DEFAULT_UPLOAD_DIR);
	}
}

#------------------------------------------------------
#
#------------------------------------------------------

sub getUpData($$$$$)
{  
my ($q, $msg, $upload_dir, $file_name, $uniq) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my $i;
my $separator;

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t"; 
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or ($message .= "<p>Could not remove file use another name, DO NOT use \"$d\"");
		}
	updateShowInitial($q, $message, "$DEFAULT_UPLOAD_DIR");
	exit;
	}


	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

 	&performCheckUser($q, $separator, $upload_dir, $file_name, $uniq);


esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------
#
#------------------------------------------------------

sub performCheckUser ($$$$$)
{
    my ($q, $S, $upload_dir, $file_name, $uniq) = @_;    

my ($delAREA, $addAREA, $BadAREA, $line, $TmP, $SysAcct, $FileAcct);

my $File_ok_users = 0;
my $Sys_ok_users = 0;
my $Total_File_users = 0;
my $Total_Sys_users = 0;
my $before = 0;

my ($firstName,
$lastName,
$acctName,
$Passwd,
$department,
$company,
$street,
$city,
$phone,
$emailForward,
$forwardAddress,
@groups,
@add_users,
@del_users) ;


	open (LOG, "<$upload_dir/$file_name") or die(&updateShowInitial($q, "Unable to read $upload_dir/$file_name", $DEFAULT_UPLOAD_DIR));
	my @UploadData = <LOG>;
	close (LOG);
	
	my @uploaddata = @UploadData ;	
	
	###############################################
	#this gets all the users that need to be added#
	###############################################
	
	my $count = 0;	
	foreach $line (@UploadData)
	{
	$count++; chomp($line);
	
	$line =~ s/[ ]{2,999}//g;
	$line =~ s/\n//g;
	$line =~ s/\r//g;	
	$line =~ s/\"//g;
	$line =~ s/\'//g;
	$line =~ s/\`//g;
	
		if ($line =~ m/\w*$S\w*/i)
		{
		($firstName,
		$lastName,
		$acctName,
		$Passwd,
		$department,
		$company,
		$street,
		$city,
		$phone,
		$emailForward,
		$forwardAddress,
		@groups) = split(/$S/,$line);
		
		$Total_File_users++;
		
		$before = $File_ok_users;
		
			#match name
			NAME: foreach $SysAcct (sort keys %accounts)
    			{	
	    			if (db_get_type(\%accounts, $SysAcct) eq "user")
	    			{	    	
	    				if((db_get_prop(\%accounts, $SysAcct, "FirstName") eq $firstName) 
	    				and (db_get_prop(\%accounts, $SysAcct, "LastName") eq $lastName))
	    				{	    					
	    					if($uniq eq 'onlyFnL')
						{			
							$File_ok_users++;
	    						last NAME ;	 
	     					}
					     	elsif ($uniq eq 'User')
					     	{
					     		if($acctName eq $SysAcct)
					     		{
					     		$File_ok_users++;
	    						last NAME ;
					     		}
					     	}
	    					elsif ($uniq eq 'Dept')
						{		
							if(db_get_prop(\%accounts, $SysAcct, "Dept") eq $department)
							{
							$File_ok_users++;
	    						last NAME ;
							}
						}
						elsif ($uniq eq 'Comp')
						{
							if(db_get_prop(\%accounts, $SysAcct, "Company") eq $company)
							{
							$File_ok_users++;
	    						last NAME ;
							}
						}
						elsif ($uniq eq 'Addr')
						{
							if(db_get_prop(\%accounts, $SysAcct, "Street") eq $street)
							{
							$File_ok_users++;
	    						last NAME ;
							}
						}
						elsif ($uniq eq 'City')
						{
							if(db_get_prop(\%accounts, $SysAcct, "City") eq $city)
							{
							$File_ok_users++;
	    						last NAME ;
							}
						}
						elsif ($uniq eq 'Phone')
						{
							if(db_get_prop(\%accounts, $SysAcct, "Phone") eq $phone)
							{
							$File_ok_users++;
	    						last NAME ;
							}
						}
						elsif($uniq eq 'FEmail')
						{
							if(db_get_prop(\%accounts, $SysAcct, "ForwardAddress") eq $forwardAddress)
							{
							$File_ok_users++;
	    						last NAME ;
							}
						}	    				   				
	    				}				
				}
			}			
			
			if($File_ok_users != $before+1)
			{
	    		push(@add_users, $line);
	    		}
		}
		else
		{
		$BadAREA .= "Bad line $count: $line\n";	
		}
	}		
	
	#################################################
	#this gets all the users that need to be deleted#
	#################################################
	foreach $acctName (sort keys %accounts)
    	{	
	    	if (db_get_type(\%accounts, $acctName) eq "user")
	    	{	
	    	my $FirstName = db_get_prop(\%accounts, $acctName, "FirstName");
	    	my $LastName = db_get_prop(\%accounts, $acctName, "LastName");
		my $Department = db_get_prop(\%accounts, $acctName, "Dept");
		my $Company = db_get_prop(\%accounts, $acctName, "Company");
		my $Street = db_get_prop(\%accounts, $acctName, "Street");
		my $City = db_get_prop(\%accounts, $acctName, "City");
		my $Phone = db_get_prop(\%accounts, $acctName, "Phone");
		my $EmailForward = db_get_prop(\%accounts, $acctName, "ForwardAddress");
		
		$Total_Sys_users++;
		
		$before = $Sys_ok_users;		
						
			NEXTS: foreach $line (@uploaddata)
			{
			chomp($line);
	
			$line =~ s/[ ]{2,999}//g;
			$line =~ s/\n//g;
			$line =~ s/\r//g;	
			$line =~ s/\"//g;
			$line =~ s/\'//g;
			$line =~ s/\`//g;
	
				if ($line =~ m/\w*$S\w*/i)
				{
				($firstName,
				$lastName,
				$FileAcct,
				$Passwd,
				$department,
				$company,
				$street,
				$city,
				$phone,
				$emailForward,
				$forwardAddress,
				@groups) = split(/$S/,$line);
		
						    				
	    				if(($FirstName eq $firstName) and ($LastName eq $lastName))
	    				{	    					
	    					if($uniq eq 'onlyFnL')
						{			
							$Sys_ok_users++;
	    						last NEXTS ;	 
	     					}
						elsif ($uniq eq 'User')
						{
							if($acctName eq $FileAcct)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}
	    					elsif ($uniq eq 'Dept')
						{		
							if($Department eq $department)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}
						elsif ($uniq eq 'Comp')
						{
							if($Company eq $company)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}
						elsif ($uniq eq 'Addr')
						{
							if($Street eq $street)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}
						elsif ($uniq eq 'City')
						{
							if($City eq $city)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}
						elsif ($uniq eq 'Phone')
						{
							if($Phone eq $phone)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}
						elsif($uniq eq 'FEmail')
						{
							if($EmailForward eq $forwardAddress)
							{
							$Sys_ok_users++;
	    						last NEXTS ;
							}
						}	    				   				
	    				}									
				}				
			}
				
			if($Sys_ok_users != $before+1)
			{
	    		push(@del_users, $acctName);
	    		}
		
		}
    	}	
    	
    	
    	
	###########################
		if($uniq eq 'onlyFnL')
		{
		print "<p>Using <b>Only First and Last name</b> to compare users\n<p>";
		}
		else
		{
		print "<p>Using <b>Full name and $uniq</b> to compare users\n<p>";
		}
			
	my  $percent = 100;				
	$percent = sprintf("%.1f%%",$percent);
	print "<table border=1><tr><th align=center colspan=2>System info</th><th align=center colspan=2>File info</th></tr>\n";
		print "<tr><td>System Accounts :</td><td><font color=red size=+1><b>$Total_Sys_users<br>$percent</font></b></td>\n";
    		print "<td>Lines/Users from file :</td><td><font color=red size=+1><b>$Total_File_users<br>$percent</font></b></td></tr>\n";
	
		$Sys_ok_users = int($Sys_ok_users);
		$percent = sprintf("%.1f%%", ($Sys_ok_users/$Total_Sys_users)*100);
		print "<tr><td>System OK users :</td><td><font color=red size=+1><b> $Sys_ok_users <br> $percent </b></font></td>\n";
		
			
		$File_ok_users = int($File_ok_users);
		$percent = sprintf("%.1f%%", ($File_ok_users/$Total_File_users)*100);
		print "<td>File OK users :</td><td><font color=red size=+1><b> $File_ok_users <br> $percent </b></font></td></tr>\n";
	
			
		my $total_del = @del_users;		
		$percent = sprintf("%.1f%%", ($total_del/$Total_Sys_users)*100);
		print "<tr><td>Accounts to delete :</td><td><font color=red size=+1><b> $total_del <br> $percent </b></font></td>\n";
		
		
		my $total_add = @add_users;
		$percent = sprintf("%.1f%%", ($total_add/$Total_File_users)*100);
		print "<td>Users to add :</td><td><font color=red size=+1><b> $total_add <br> $percent </b></font></td></tr>\n";
	
	print "</table>\n";
		
		
		my $add_file = "UpdateAddResults-".&define_dates.".Gar";
		
		open(FILE,">$upload_dir/$add_file") or die(&updateMainBODY($q, "Error saving update add results, $!", $DEFAULT_UPLOAD_DIR)) if ($total_add > 0) ;
		foreach $line (@add_users)
		{
		$addAREA .= "$line\n";
		print FILE "$line\n" if ($total_add > 0);
		}
		close(FILE) if ($total_add > 0);
		
		my $del_file = "UpdateDeleteResults-".&define_dates.".Gdr";
		
		open(FILE,">$upload_dir/$del_file") or die(&updateMainBODY($q, "Error saving update delete results, $!", $DEFAULT_UPLOAD_DIR)) if ($total_del > 0);
		foreach $line (@del_users)
		{
		$delAREA .= "$line\n";
		print FILE "$line\n" if ($total_del > 0);
		}
		close(FILE) if ($total_del > 0);
		
		my $sep = $q->param('Separator');
		my $mysep = $q->param('MySeparator');
						
		#if($addAREA)
		if($total_add > 0)
		{
		print startform(-method => 'POST', -action => $q->url (-absolute => 1));
		print $q->p ("<font size=+1 color=red><b>Users to add</b></font>\n");			
		print "<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$addAREA</TEXTAREA>\n";
		print "<input type=hidden name=state value=genForm>\n";
		print "<input type=hidden name=PrevFile value=$add_file>\n";
		print "<input type=hidden name=Separator value=$sep>\n";
		print "<input type=hidden name=MySeparator value=$mysep>\n";
		print "<p><input type=submit value=\"Generate user info\">\n";
		print endform;	
		}
		
		#if($delAREA)
		if($total_del > 0)
		{
		print startform(-method => 'POST', -action => $q->url (-absolute => 1));
		print $q->p ("<font size=+1 color=red><b>Users to delete</b></font>\n");			
		print "<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$delAREA</TEXTAREA>\n";
		print "<input type=hidden name=state value=performDel>\n"; 
		print "<input type=hidden name=GenAcctsTXT value=$del_file>\n";
		print "<input type=hidden name=Separator value=$sep>\n";
		print "<input type=hidden name=MySeparator value=$mysep>\n";
		print "<p><input type=submit value=\"Delete these users NOW!\">\n";
		print endform;			
		}
		
		if ($BadAREA)
		{
		print startform(-method => 'POST', -action => $q->url (-absolute => 1));
		print $q->p ("<font size=+1 color=red><b>Errors</b></font>\n");			
		print "<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$BadAREA</TEXTAREA>\n";
		print endform;	
		}		
		
	
	############################

esmith::cgi::genFooter ($q);
exit;
}#this ends the sub

#################################################################
###### Compare user accounts ends.
#################################################################
#################################################################
###### Import/export begins.
#################################################################
sub imexShowInitial ($$$)
{
    my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;


    #------------------------------------------------------------
    # If there's a message, we just finished an operation so show the
    # status report. If no message, this is a new list of accounts.
    #------------------------------------------------------------
	
    if ($msg eq '')
    {
	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Import/Export information.');
    }
    else
    {
	esmith::cgi::genHeaderNonCacheable	
	    ($q, \%conf, 'Operation status report');

	print $q->p ($msg);
	print $q->hr;
    }
	&imexBODY($q, '', $DEFAULT_UPLOAD_DIR);
	
	sub imexBODY($$$)
	{		
	print hlplnk('imex');
	my ($q, $msg, $DEFAULT_UPLOAD_DIR) = @_;

		if (!$msg eq '')
		{
		print $q->p ($msg);
		print $q->hr;
		}
	    #------------------------------------------------------------
	    # Look up accounts and user names
	    #------------------------------------------------------------
	    my @userAccounts = ();

	    foreach (sort keys %accounts)
	    {
		push (@userAccounts, $_)
		    if (db_get_type(\%accounts, $_) eq "user");
	    }
	
	    unless (scalar @userAccounts)
	    {
		print $q->h4 ('There are no user accounts in the system.');
	    }
	    

		my $description = <<END_TEXT;
This will allow you to import or export user imformation. If you import, this can allow you
to put the file in the correct format, so you don't have to use Excel. If you export, this will
retrieve all user information, except the password, so you can use the users data in other 
programs. This does not care of the format of the file, you can export it in what ever format 
you want in order to work with your other programs. If you import then you must let me know 
what is each field and the delimiter/separator.

END_TEXT
		
		print $q->p ($description);
																			
		print $q->hr;
		
		#import		
		print $q->p ("<b><font size=+2 color=red>Import</font></b>");
		
		#For uploading txt files
		print $q->start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));

		print "Enter the file to process: <br>", filefield('uploadTXT','','30');
			
		print "<p>Delimiter: ";
	
		my %spacelabels = ('tab'   => 'Tab',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');
		       
		my $deflt;
		if($q->param('Separator'))
		{
		$deflt = $q->param('Separator');
		}
		else
		{
		$deflt = 'tab';
		}

		print $q->popup_menu (-name => 'Separator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => $deflt,
			     -labels  => \%spacelabels);
		$deflt = $q->param('MySeparator');
		print " If other: <input type=\"text\" name=\"MySeparator\" maxlength=10 size=11 value=\"$deflt\">\n";

		print "<p>What delimiter should I use to save output file : <br>\n";
	
		my %SpaceLabels = ('tab'   => 'Tab',
			'same' => 'Same as input',
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'SaveSeparator',
			     -values  => ['tab', 'same', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'same',
			     -labels  => \%SpaceLabels);
			     
		print " If other: <input type=\"text\" name=\"MySaveSeparator\" maxlength=10 size=11>\n";
				
		print "<p>\n";
				
		my @fields = ("--BLANK--", "FullName", 
			      "FName", "LName", 
		              "User", "Pwd", 
		              "Dept", "Comp", 
		              "Addr", "City", 
		              "Phone", "Email", 
		              "FEmail", "Groups");
				
		print $q->table ({border => 1, cellspacing => 1, cellpadding => 4});
		print "<tr><td>\n";
		
		print "Put these in <b>order that they appear in the file</b>. Make sure to only
			select each field once. If a field is not present make sure to
			select \"--BLANK--\", you will probably need to select this for the last
			fields. All fields mark with a \"--BLANK--\" will be ignore. e.g.
			All these three examples are equal the same, all tell me that the 
			format of the file is:
			<p><pre>FName,LName,User,Pwd,,Comp,Addr,City,,Email,,</pre>
			
<pre>
--BLANK--     FName        --BLANK--
FName         LName        FName
LName         User         LName
User          Pwd          --BLANK--
Pwd           Comp         --BLANK--
--BLANK--     Addr         --BLANK--
Comp          City         --BLANK--
Addr          Email        User 
City          --BLANK--    Pwd  
--BLANK--     --BLANK--    Comp 
Email         --BLANK--    Addr 
--BLANK--     --BLANK--    City 
--BLANK--     --BLANK--    Email
</pre>                           
			<p>Note that the fields \"Dept\", \"Phone\", \"FEmail\", and \"Groups\" are not 
			in the file, so we leave them blank(put nothing, don't use a space), but the 
			delimiter/separator is still there.			
			\n";
		
		print "</td><td>\n";				
		print $q->table ({border => 1, cellspacing => 1, cellpadding => 4});
		
		my ($field, $count, $output, $selected);		
		foreach $count ( 0..$#fields)
		{		
		$output = "<SELECT NAME=\"field$count\">\n";		
			foreach $field(@fields)
			{
			$selected = 'SELECTED' if $fields[$count] eq $field;
			$output .= "<OPTION $selected VALUE=\"$field\"> $field \n";
			$selected = '';
			}
		$output .=  "</SELECT>\n";
		print $q->Tr (esmith::cgi::genSmallCell ($q, $output));	 
		}
		
		print "</table></td>\n";
		print "</tr></table>\n";
		
		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performImport');
		
		print $q->p(submit('submit',' Import File '), '&nbsp;'x5, reset);
		
		print $q->endform;
		
		print $q->p(hr);
							
		#export
		
		print $q->p ("<b><font size=+2 color=red>Export</font></b>");
				
		print $q->start_form(-method => 'POST', -action => $q->url (-absolute => 1));
				
		print "<p>What delimiter should I use to save output file : <br>\n";
	
		%SpaceLabels = '';
		%SpaceLabels = ('tab'   => 'Tab',		
		       'comma' => 'Comma',
		       'space'    => 'Space',
		       'semicolon' => 'Semicolon',
		       'colon' => 'Colon',
		       'other' => 'Other');

		print $q->popup_menu (-name => 'SaveSeparator',
			     -values  => ['tab', 'comma', 'space', 'semicolon', 'colon', 'other'],
			     -default => 'tab',
			     -labels  => \%SpaceLabels);
			     
		print " If other: <input type=\"text\" name=\"MySaveSeparator\" maxlength=10 size=11>\n";
		
		print "<p>Should I enclose each field : (leave blank for no)<br>\n";
		print '	<SELECT NAME="EncloseGen">
				<OPTION selected VALUE=> 
				<OPTION VALUE="Double">Double quote ("field")
				<OPTION VALUE="Single">Single quote (\'field\')
				<OPTION VALUE="other">Other
			</SELECT>';
		print " If other: Begin <input type=\"text\" name=\"MyEnclose1\" maxlength=10 size=3>
				End <input type=\"text\" name=\"MyEnclose2\" maxlength=10 size=3>
			\n";
		
		print $q->p ("Only if FullName is selected, separate FName and LName by a comma?\n
				<input type='checkbox' name='FbyC' value='1'>\n");
		
		print "<p>\n";
				
		@fields = ("-Delimiter-","--BLANK--", "FullName", 
			      "FName", "LName", 
		              "User", 
		              "Dept", "Comp", 
		              "Addr", "City", 
		              "Phone", "Email", 
		              "FEmail", "Groups");
		
		print $q->table ({border => 1, cellspacing => 1, cellpadding => 4});
		print "<tr><td>\n";
		
		print "Put these in the order that you want them to appear in the output file. 
			You can select each field more then once. If you don't want/need a field 
			make sure to select \"--BLANK--\". All fields mark with a \"--BLANK--\" 
			will be ignore. If you want an empty field select \"-Delimiter-\".
			<b>This will NOT</b> use the password field, this means that you can not
			get the users password, this will only retrieve all other information.
			Here is one examples :<p>
					
<pre>FullName,User,,,FEmail<br>
\"John Doe\",\"jdoe\",\"\",\"\",\"jdoe\@domain.com\"</pre>
<pre>
--BLANK--
FullName  
FName
LName
--BLANK-- 
--BLANK-- 
--BLANK-- 
User       
-Delimiter-
-Delimiter-
--BLANK--
--BLANK-- 
FEmail    
--BLANK--  
</pre>                     			
			\n";
		
		print "</td><td>\n";				
		print $q->table ({border => 1, cellspacing => 1, cellpadding => 4});
		
	
		foreach $count ( 0..$#fields)
		{		
		$output = "<SELECT NAME=\"field$count\">\n";		
			foreach $field(@fields)
			{
			$selected = 'SELECTED' if $fields[$count] eq $field;
			$output .= "<OPTION $selected VALUE=\"$field\"> $field \n";
			$selected = '';
			}
		$output .=  "</SELECT>\n";
		print $q->Tr (esmith::cgi::genSmallCell ($q, $output));	 
		}
		
		print "</table></td>\n";
		print "</tr></table>\n";	
		
		print $q->hidden (-name => 'state',
		      -override => 1,
		      -default => 'performExport');	
		 
		print $q->p(submit('submit',' Export File '), '&nbsp;'x5, reset);
		print "\n";
		print $q->endform;
		
	esmith::cgi::genFooter ($q);	
	exit;
	}
}
#-----------------------------------------------
#
#-----------------------------------------------
sub performImport($$$)
{
	my ($q, $message, $upload_dir) = @_;
	
	my($file_name,$size,$import_file,$bytes_count,$buff);
	
	if ($q->param('uploadTXT'))
	{
	$import_file = $q->param('uploadTXT');
	}
	

	if ($import_file =~ m/\w/) 
	{
			$size = $bytes_count =0;
			$_ = $import_file ;
			s/\w://;
			s/([^\/\\]+)$//;
			$_ = $1;	
			s/\.\.+//g;
			s/\s+//g;
			$file_name = $_;
		
			if (! $file_name) 
			{
				$message = 'Bad file name';
				imexShowInitial ($q, $message, $upload_dir);
				exit;
			}
			$file_name .= "-".&define_dates.".Iup";			

			if (-e "$upload_dir/$file_name") 
		        {
				$message = "A file named \"$file_name\" already exist";
				imexShowInitial ($q, $message, $upload_dir);
				exit;
			}
		    
		    open(FILE,">$upload_dir/$file_name") or die(&imexShowInitial($q, "Error opening file $file_name for writing, $!", $upload_dir));
		    binmode FILE;
		    while ($bytes_count = read($import_file,$buff,2096)) 
		    {
		    	$size += $bytes_count;
		        print FILE $buff;
		    }
		    close(FILE);

		    if ((stat "$upload_dir/$file_name")[7] <= 0) 
		    {
		        $file_name =~ /^(.*?)$/ ;
	        	$d = $1;
			unlink("$upload_dir/$d");		   	
		    	$message = "Could not upload $d\n";
			imexShowInitial($q, $message, $upload_dir);
			exit;
		    }
		    else
		    {
		        $message = $q->a ({href => $q->url (-absolute => 1) . "?TXTfile=$file_name&EorV=view&state=performView", -target=>'_new'}, $file_name);
		    	$message = "<b>Importing information</b><br>Uploaded succesfully and saved as:<br>$message<br>($size bytes)\n";
			getImData($q, $message, $upload_dir, $file_name);
			exit;
		     }

	}
	else
	{
	my $message = "You did not provide a file to import. Click the Browse button and select a file.";
	imexShowInitial($q, $message, $upload_dir);
	}
}
#------------------------------------------------------
#
#------------------------------------------------------

sub getImData($$$$)
{
my ($q, $msg, $upload_dir, $file_name) = @_ ;

# First check the delimiter
my $sep = $q->param('Separator');
my $mysep = $q->param('MySeparator');
my $i;
my $SS;
my $separator;

	if ($sep eq 'other' and $mysep)
	{
	$separator = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$separator = "\t";
	}
	elsif ($sep eq 'comma')
	{
	$separator = ',';
	}
	elsif ($sep eq 'space')
	{
	$separator = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$separator = ';';
	}
	elsif ($sep eq 'colon')
	{
	$separator = ':';
	}
	else
	{
	my $message = "Import: Choose a delimiter for the file and upload it again";
		if (-e "$upload_dir/$file_name")
		{
		$file_name =~ /^(.*?)$/ ;
	        $d = $1;
		unlink("$upload_dir/$d") or ($message .= "<p>Could not remove file use another name, DO NOT use \"$d\"");
		}
	imexShowInitial($q, $message, $upload_dir);
	exit;
	}

	#now get the file/line format
	my $lineFormat = '';
	my %FileFormat = '';
	foreach $i (0..13)
	{
		my $myfield = $q->param("field$i");

		if ($myfield ne '--BLANK--')
		{
			if (exists($FileFormat{$myfield}))
			{
				$msg = 'Import: Each field can only be selected once.';
				imexShowInitial($q, $msg, $upload_dir);
			}
			else
			{
				$FileFormat{$myfield} = $myfield ;
				$lineFormat .= "$myfield:" unless ($myfield eq 'FullName');
			}
		}

	}
		
	if($FileFormat{'FName'} ne 'FName' or $FileFormat{'LName'} ne 'LName')
	{
		$msg = 'Import: Fields "FName" and "LName" must be selected.';
		imexShowInitial($q, $msg, $upload_dir);
	}
	
	if($FileFormat{'FullName'} eq 'FullName' and $lineFormat !~ m/\b(F|L)Name:(L|F)Name\b/ )
	{
		$msg = 'Import: If you choose "FullName" fields FName and LName 
			must be selected after "FullName" in the other that FullName is form.';
		imexShowInitial($q, $msg, $upload_dir);
	}
	
			
	#remove the last : we dont need it
	$lineFormat =~ s/:$//;

	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	print "<p><b>LineFormat(delimiter=\"$sep\"):</b><br>$lineFormat</p>\n";
	
	my @uploadData = ();
            
	    open(FILE,"<$upload_dir/$file_name") or die(&imexBODY($q, "Error opening file $file_name for reading, error $!", $upload_dir));
	    @uploadData = <FILE> ;
	    close(FILE);

	my $line;
	$line = @uploadData;
	print $q->p ("Total lines/users <b>$line</b>\n");
	
	my $p = 0;
	my $S = $separator;
	my $Ssep = $q->param('SaveSeparator');
	my $Smysep = $q->param('MySaveSeparator');
	
	if ($Ssep eq 'other' and $Smysep)
	{
	$SS = $Smysep;
	}
	elsif ($Ssep eq 'tab')
	{
	$SS = "\t"; 
	}
	elsif ($Ssep eq 'comma')
	{
	$SS = ',';
	}
	elsif ($Ssep eq 'space')
	{
	$SS = ' ';
	}
	elsif ($Ssep eq 'semicolon')
	{
	$SS = ';';
	}
	elsif ($Ssep eq 'colon')
	{
	$SS = ':';
	}
	else
	{
	$SS = $S;
	}
	
	my $txtAREA ;
	my $BadAREA ;
	my @LineFmT = split(/:/,$lineFormat);
	my %Fields ;
	my $k;
	my $l;
	my $m;
		
	foreach $i (@uploadData)
	{
	$p++;
	
	$Fields{"FullName"}=''; 
	$Fields{"FName"}=''; 
	$Fields{"LName"}=''; 
	$Fields{"User"}=''; 
	$Fields{"Pwd"}=''; 
	$Fields{"Dept"}=''; 
	$Fields{"Comp"}=''; 
	$Fields{"Addr"}=''; 
	$Fields{"City"}=''; 
	$Fields{"Phone"}=''; 
	$Fields{"Email"}=''; 
	$Fields{"FEmail"}=''; 
	$Fields{"Groups"}=''; 
			
	chomp($i);
	#This removes all the extra spaces. allowing only one space between characters
	$i =~ s/[ ]{2,999}//g;
	$i =~ s/\n//g;
	$i =~ s/\r//g;
	$i =~ s/\"//g;
	$i =~ s/\'//g;
	$i =~ s/\`//g;

		if ($i =~ m/\w*$S\w*/i or $lineFormat =~ m/^(F|L)Name:(L|F)Name$/)
		{
		my @tmpArray = split(/$S/,$i);
		$l = 0 ;
			foreach $k (0..$#LineFmT)
			{			
				if($FileFormat{'FullName'} eq 'FullName' and $LineFmT[$k] =~ m/\b(F|L)Name\b/)
				{
				$l = 1;				
					if($lineFormat =~ m/FName:LName/)
					{
					#print "Line $p) \$lineFormat =~ m/FName:LName/<br>\n" unless $LineFmT[$k] eq 'LName';
					#print "\$tmpArray[$k] = \"$tmpArray[$k]\"<br>\n";
						if ($tmpArray[$k] =~ m/,/ and $LineFmT[$k] eq 'FName')
						{			
						$tmpArray[$k] =~ s/^\s//g;
						$tmpArray[$k] =~ s/\s$//g;
						$tmpArray[$k] =~ s/\s?,\s?/,/g;
						$tmpArray[$k] =~ m/(\w+-*\s?\w+-*),(.*)/;
						$Fields{'FName'}=$1;
						$Fields{'LName'}=$2;
						#print "\$1 \"$1\"<br>\$2 \"$2\"<br>\n";
						}
						elsif($LineFmT[$k] eq 'FName')
						{						
						$tmpArray[$k] =~ s/^\s//;
						$tmpArray[$k] =~ s/\s$//;
						$tmpArray[$k] =~ m/(\b\w+-*\w+-*\b),(.*)/;						
						$Fields{'FName'}=$1;
						$Fields{'LName'}=$2;
						#print "\$1 \"$1\"<br>\$2 \"$2\"<br>\n";
						}
					}
					elsif($lineFormat =~ m/LName:FName/)
					{					
					#print "Line $p) \$lineFormat =~ m/LName:FName/<br>\n" unless $LineFmT[$k] eq 'FName';
					#print "\$tmpArray[$k] = \"$tmpArray[$k]\"<br>\n";
						if ($tmpArray[$k] =~ m/,/ and $LineFmT[$k] eq 'LName')
						{						
						$tmpArray[$k] =~ s/^\s//g;
						$tmpArray[$k] =~ s/\s$//g;
						$tmpArray[$k] =~ s/\s?,\s?/,/g;						
						$tmpArray[$k] =~ m/(\w*.*),(\w+-*\s?\w+-*)+/;
						$Fields{'FName'}=$2;                    
						$Fields{'LName'}=$1;
						#print "\$1 \"$1\"<br>\$2 \"$2\"<br>\n";
						}
						elsif($LineFmT[$k] eq 'LName')
						{						
						$tmpArray[$k] =~ s/^\s//g;
						$tmpArray[$k] =~ s/\s$//g;						
						$tmpArray[$k] =~ m/(\w*.*)\s(\w+-*\w+)+/;						
						$Fields{'FName'}=$2;
						$Fields{'LName'}=$1;
						#print "\$1 \"$1\"<br>\$2 \"$2\"<br>\n";
						}
					}
				}
				else
				{				
				$Fields{$LineFmT[$k]}=$tmpArray[$k - $l];
				}
			}
				
			$k = '';
			foreach $m ('FName','LName','User','Pwd','Dept','Comp','Addr','City','Phone','Email','FEmail','Groups')
			{
			$k .= "$Fields{$m}$SS";
			}		
		$k =~ s/$SS$//;	
		$txtAREA .= "$k\n";
		}
		else
		{
		$BadAREA .= "Bad line $p\n$i\n";		
		}
	}
	
	


print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Import Data</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$txtAREA</TEXTAREA>\n");
print endform;
	
if ($BadAREA)
{
print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Errors</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$BadAREA</TEXTAREA>\n");
print endform;
}

$file_name = "GenImportData-".&define_dates.".gIm";
	open(FILE,">$upload_dir/$file_name") or ($l = 'SaveError');
	        print FILE $txtAREA;		    
	close(FILE);
	
	if($l eq 'SaveError')
	{
	print "<p><b>Error saving generated Import Data:</b> $!</p>\n";
	}
	else
	{
	$message = $q->a ({href => $q->url (-absolute => 1) . "?TXTfile=$file_name&EorV=view&state=performView", -target=>'_new'}, $file_name);
	print "<p>Generated Import Data saved as: $message</p>\n";
	}


print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');
	


esmith::cgi::genFooter ($q);
exit;
}

#------------------------------------------------------
#
#------------------------------------------------------

#-----------------------------------------------
#
#-----------------------------------------------
sub performExport($$$)
{	
	my ($q, $msg, $upload_dir) = @_ ;

# First check the delimiter
my $sep = $q->param('SaveSeparator');
my $mysep = $q->param('MySaveSeparator');
my $Eb = $q->param('EncloseGen');
my ($i,$S,$Ee); 
my ($FirstName,
$LastName,
$acctName,
$Passwd,
$Department,
$Company,
$Street,
$City,
$Phone,
$Email,
$EmailAddress,
@Groups);

	if ($sep eq 'other' and $mysep)
	{
	$S = $mysep;
	}
	elsif ($sep eq 'tab')
	{
	$S = "\t";
	}
	elsif ($sep eq 'comma')
	{
	$S = ',';
	}
	elsif ($sep eq 'space')
	{
	$S = ' ';
	}
	elsif ($sep eq 'semicolon')
	{
	$S = ';';
	}
	elsif ($sep eq 'colon')
	{
	$S = ':';
	}
	else
	{
	my $message = "Export: Choose a delimiter for output file.";		
	imexShowInitial($q, $message, $upload_dir);
	exit;
	}
	
	if ($Eb eq 'Double')
	{
	$Ee = $Eb = '"';
	}
	elsif($Eb eq 'Single')
	{
	$Ee = $Eb = "'";
	}
	elsif($Eb eq 'other' and $q->param('MyEnclose1') ne '' and $q->param('MyEnclose2') ne '')
	{
	$Eb = $q->param('MyEnclose1');
	$Ee = $q->param('MyEnclose2');
	}
	elsif($Eb eq 'other')
	{
	my $message = "Export: If you choose 'Other' for a delimiter, you MUST also input 'Begin' and 'End'.";		
	imexShowInitial($q, $message, $upload_dir);
	exit;
	}	
	
	my $FC = '';
	if ($q->param('FbyC') eq '1')
	{
	$FC = ',';
	}

	#now get the file/line format
	my $lineFormat = '';
	my %FileFormat = '';
	foreach $i (0..13)
	{
		my $myfield = $q->param("field$i");

		if ($myfield ne '--BLANK--')
		{	
			$FileFormat{$myfield} = $myfield ;
			$lineFormat .= "$myfield:" unless ($myfield eq 'FullName');		
		}

	}
	
	if($FileFormat{'FullName'} eq 'FullName' and $lineFormat !~ m/\b(F|L)Name:(L|F)Name\b/ )
	{
		$msg = 'Export: If you choose "FullName" fields FName and LName 
			must be selected after "FullName" in the other that you want the Full name.';
		imexShowInitial($q, $msg, $upload_dir);
	}
	
			
	#remove the last : we dont need it
	$lineFormat =~ s/:$//;

	esmith::cgi::genHeaderNonCacheable($q, \%conf, 'Operation status report');
	print $q->p ($msg);
	print $q->hr;

	print "<p><b>LineFormat(delimiter=\"$sep\"):</b><br>$lineFormat</p>\n";
	
	my ($txtAREA,$l,$m,$n);
	my @LineFmT = split(/:/,$lineFormat);
	my %Fields ;
	my @AllUsers = '';
	my @AllGroups = '';	
	
	foreach $acctName (sort keys %accounts)	
    	{
    	my $Type = db_get_type(\%accounts, $acctName);
    		if ($Type eq "user")
		{
		push(@AllUsers,$acctName);
		}
		elsif ($Type eq "group")
		{
		push(@AllGroups,$acctName);
		}
    	}
		
	foreach $acctName (@AllUsers)	
    	{
    	   if ($acctName =~ m/\w/)
    	   {    	
		$Fields{"FName"}=''; 
		$Fields{"LName"}=''; 
		$Fields{"User"}='';
		$Fields{"Dept"}=''; 
		$Fields{"Comp"}=''; 
		$Fields{"Addr"}=''; 
		$Fields{"City"}=''; 
		$Fields{"Phone"}=''; 
		$Fields{"Email"}=''; 
		$Fields{"FEmail"}=''; 
		$Fields{"Groups"}=''; 
		
		$Fields{"User"} = $acctName;
		$Fields{"FName"} = $FirstName = db_get_prop(\%accounts, $acctName, 'FirstName');
    		$Fields{"LName"} = $LastName = db_get_prop(\%accounts, $acctName, 'LastName');
    		$Fields{"Phone"} = $Phone = db_get_prop(\%accounts, $acctName, 'Phone');
    		$Fields{"Comp"} = $Company = db_get_prop(\%accounts, $acctName, 'Company');
    		$Fields{"Dept"} = $Department = db_get_prop(\%accounts, $acctName, 'Dept');
    		$Fields{"City"} = $City = db_get_prop(\%accounts, $acctName, 'City');
    		$Fields{"Addr"} = $Street = db_get_prop(\%accounts, $acctName, 'Street');
    		$Fields{"Email"} = $Email = db_get_prop(\%accounts, $acctName, 'EmailForward');
    		$Fields{"FEmail"} = $EmailAddress = db_get_prop(\%accounts, $acctName, 'ForwardAddress');
    		
    		$n = '';
    		my $UserData = '';
    		
    		foreach $i (@LineFmT)
    		{    		
    		next if $i =~ m/(FName|LName)/ and $n eq 'Complete';    		
    			if($i =~ m/(FName|LName)/ and $n ne 'Complete' and $FileFormat{'FullName'} eq 'FullName')
			{	
				if($lineFormat =~ m/FName:LName/)
				{				
				$Fields{"FullName"} = "$Fields{'FName'}$FC $Fields{'LName'}"; 
				$n = 'Complete';
				}
				elsif($lineFormat =~ m/LName:FName/)
				{				
				$Fields{"FullName"} = "$Fields{'LName'}$FC $Fields{'FName'}"; 
				$n = 'Complete';
				}
			$UserData .= "$Eb$Fields{'FullName'}$Ee$S";			
			}    			
    			elsif ($i eq 'Groups')
    			{
    			my $Group = '';
    			my @selected = '';
    				foreach $Group (@AllGroups)
    				{
    				my @members = split (/,/, db_get_prop(\%accounts, $Group, "Members"));

					if (grep (/^$acctName$/, @members))
					{
					push(@selected, $Group);
					}	
				}			
			$m = "@selected"; 
			$m =~ s/^\s//;
			$m =~ s/\s$//;
			$Fields{"Groups"} = $m ;
			}
			
		next if ($i =~m /(FName|LName)/ and $n eq 'Complete');
    		$UserData .= "$Eb$Fields{$i}$Ee$S";
    		}
		$UserData =~ s/$S$//;
    		$txtAREA .= "$UserData\n";
    	   }
	}

print startform(-method => 'POST', -action => $q->url (-absolute => 1));
print $q->p ("<font color=red size=+1><b>Export Data</b></font>".
"\n<p><TEXTAREA NAME=\"noname\" COLS=55 ROWS=25 WRAP=OFF READONLY>$txtAREA</TEXTAREA>\n");
print endform;


my $file_name = "GenExportData-".&define_dates.".gEx";
	open(FILE,">$upload_dir/$file_name") or ($l = 'SaveError');
	        print FILE $txtAREA;		    
	close(FILE);
	
	if($l eq 'SaveError')
	{
	print "<p><b>Error saving generated Export Data:</b> $!</p>\n";
	}
	else
	{
	$message = $q->a ({href => $q->url (-absolute => 1) . "?TXTfile=$file_name&EorV=view&state=performView", -target=>'_new'}, $file_name);
	print "<p>Generated Export Data saved as: $message</p>\n";
	}


print $q->p ($q->a ({href => $q->url (-absolute => 1)},
			'Click here'),
		 'to go back to the menu.');
	


esmith::cgi::genFooter ($q);
exit;
	
}
#################################################################
###### Import/export ends.
#################################################################
#################################################################
###### Help begins
#################################################################
sub Help($)
{
my $about = $_[0];

my $BODY;
	
	if($about eq 'Index')
	{
	$BODY .= "This script will help you create/delete/modify many user accounts onn this
	server very easily. It will take a file with user information, process it and 
	create/delete/modify the accounts with the information found in it. This is very userful
	for an enviroment where you dont have time to work with one user at a time, for example
	in a school. If use in a school enviroment, you can get all the information needed from
	the attendance office, put in the correct <a href=\"#HELP\">format</a> with MS Excel or 
	<a href=\"http://www.sun.com/software/star/staroffice/get/get.html\" target=_new>
	StarOffice</a> (free), upload the file and create/delete/modify the user accounts.
	
	<ul>
	<li><b>upload and/or generate</b><br>
		Select this if you have a file containing user information on a 
		floppy/cdrom/other machine and you want to upload this file to the server. 
		Also if the file is already on the server and you want to use it. This file
		will need to have at least  First and Last names so that user accounts can be 
		generated. This will probably be your first step.</li>
	<li><b>create user accounts</b><br>
		Select this if you have already generated user information (done the above step) 
		or have all the information you need about the user/s. This will take the file
		and create the user accounts from the information found in it.</li>
	<li><b>set password</b><br>
		Select this if you did not set a password for the user account/s, this will only
		set the password. If a password is already set it will change it.
	<li><b>delete user accounts</b><br>
		Select this to delete all the users from the file, this will only use the
		username field.
	<li><b>modify users</b><br>
		Select this to modify existing users with their new information from the file. The
		username will remain the same, all other fields may change.
	<li><b>update user accounts</b><br>
		This will compare users from the file you provide, with users from the system to
		see if they still exist. If the user is found in both the file and the system the
		user is okay, but for all the users that are not found in the system it will
		create a list and give the option of adding these users.  If a system user is not
		found in the file then it will added them to a list of users that need to be 
		deleted and give you the option of deleting these users.
	<li><b>view/delete text file/s</b><br>
		This lets you view files in your upload directory, one file at a time, this is
		useful if you do not remember the delimiter/seperator of the file. This also
		lets you delete files in your upload directory, many at a time.
	</ul>
	\n";
	}
	
#this is for all	
$BODY .= "<a name=\"HELP\">
	<p><b><font size=+1>File Format</font></b></p>
	The file <B>MUST</B> be in the correct format for this to work. First it must have all 
	information about a single user per line, each field must be delimited/seperated by 
	some special character/s, you will always be ask for the delimiter/seperator. Each line 
	must have all these fields, if a field is to be blank, do not use a space use a 
	delimiter/seperator (look at example three below). If you plan to generate user 
	information, the only fields that are needed are First and Last name. Here are 
	three examples(the ones in <b>bold</b>) with different delimiter/seperator:
	<pre>
delimiter/seperator = |
<b>Firstname|Lastname</b>

delimiter/seperator = tab
<b>Firstname	Lastname</b>

delimiter/seperator = :
<b>Firstname:Lastname:::::::123-456:local::</b>
	</pre>
	
	<p>Each field and what the value should/could be.</p>
	<ol>
	<li><p><b>FName</b><br>
		First name, this is a require field.
	<li><b>LName</b><br>
		Last name, this is a require field.
	<li><b>User</b><br>
		Username for account, optional, can be generate. The account name should contain only lower-case letters,
		numbers, hyphens, periods, and underscores, and should start with a lower-case
		letter. For example \"betty\", \"hjohnson\", and \"john.smith\" are, all valid 
		account names, but \"3friends\", \"John Smith\", and \"Henry-Miller\" are not. 		
	<li><b>Pwd</b><br>
		Password, optional, can be generate.
	<li><b>Dept</b><br>
	       Department, optional, can be generate. The value of this field can be what ever
	       you want(e.g. ID number, Date of Birth, Year, Class room number...).
	<li><b>Comp</b><br>
		Company, optional, can be generate. The value of this field can be what ever
	       you want(e.g. ID number, Date of Birth, Year, Class room number...). 
	<li><b>Addr</b><br>
		Address, optional, can be generate. The value of this field can be what ever
	       you want(e.g. ID number, Date of Birth, Year, Class room number...). 
	<li><b>City</b><br>
		City, optional, can be generate.  The value of this field can be what ever
	       you want(e.g. ID number, Date of Birth, Year, Class room number...).
	<li><b>Phone</b><br>
		Phone number, optional, can be generate.  The value of this field can be what ever
	       you want(e.g. ID number, Date of Birth, Year, Class room number...).
	<li><b>Email</b><br>
		Email delivery, can only be one of these three options(in <b>bold</b>):<br>
		<b>local</b> to Deliver email locally<br>
		<b>forward</b> to Forward to address below<br>
		<b>both</b> to Both deliver locally and forward<br>
		
	<li><b>FEmail</b><br>
		If the above (Email/Email delivery) is set to <b>forward</b> or <b>both</b>,
		this is the email address of the user to forward any email. If it's set to 
		<b>local</b> leave this field blank.
	<li><b>Groups</b><br>
		List of group/s the user will be a member of, optional, can be generate. 
	</ol>	
	\n";
#---------------------------------------
print $q->PrintHeader;

print <<'endHTML';
<HTML>
<HEAD><TITLE>Help</TITLE>
endHTML

#<script language="JavaScript">
#
#name = 'navigation';
#
#//-- JavaScript code written by Alan Simpson - www.coolnerds.com
#//-- This function subtracts one from the current value in the form field,
#//-- and decides whether to keep going, or end the countdown.
#function subtractOne() {
#   //Subtract 1 from current value in form field.
#   var newValue = parseInt(document.myForm.numberShown.value)-1
#   //Replace the contents of form field with smaller number.
#   document.myForm.numberShown.value = newValue
#
#   //-- If countdown hasn't reached zero, pause then do it again.
#   if (newValue > 0) {
#        //-- From here on out, this function calls itself once every second.
#        myTimer=setTimeout("subtractOne()",1000)
#   //-- When countdown does reach zero, stop the timer and call reachedZero().
#   }else{
#     clearTimeout("myTimer")
#     reachedZero()
#   }
#}
#
#//-- This function is called by onload="getStarted()" in this page's 
#//-- body tag, and gets the ball rolling.
#function getStarted() {
#   //-- Loads the number 300 into the form field(5 mins).   
#   document.myForm.numberShown.value="300"
#   //-- Pauses one-second, then calles the subtractOne function.
#   myTimer=setTimeout("subtractOne()",1000)
#}
#
#function reachedZero() {
#   //-- This is the function that is executed when the countdown ends.
#   self.close();
#}
#
#</SCRIPT>
#
#</HEAD>                            
#<BODY onload="getStarted();self.focus();">
#<center>
#<form name="myForm">
#<b>Window will close in <input name="numberShown" type="text" size="3" align="center"></b>
#</form>
#</center>

print "<BODY>\n";
print "<center><br><A HREF=\"/common/navigation\">Return the navigation menu.</a></center><p>\n";
#	<font size=+3 color=red>HELP</font></center><p>\n";
print $BODY;
print <<'endHTML';

<center>
<p><A HREF="/common/navigation">Return the navigation menu.</a><p>
</center>    
</BODY>
</HTML>
endHTML

#<a href="javascript:self.close();">Close Window Now!</a>
#----------------------------------
}

#################################################################
###### Help ends.
#################################################################

###########################################################
sub hlplnk($)
{
my $about = $_[0];
my $URL = $q->url (-absolute => 1) . "?state=Help&about=$about" ; 		
#return ($q->p("<a href=\"javascript: window.open('$URL', 'navigation', 'width=225,height=500,toolbar=0,directories=0, menubar=0,status=0,resizable=0,location=0, scrollbars=1,copyhistory=0,left=0,top=0'); void('');\"> Click here</a> for some help about this page.\n"));

return ($q->p("<A HREF=\"$URL\" TARGET=\"navigation\"> Click here</a> for some help about this page.\n"));
}
############################################################
# print hlplnk('Index');
#############################################################
#############################################################
#############################################################
# To make things go faster the script is going to add/delete/modify all the users and then restart the daemons
# for this we need our own event, lets add "multi" to the event name
#
#system ("/sbin/e-smith/signal-event", "user-create", "$acctName")
#
#	will become...
#	
#	
#   if (-d "$EventDir/multi-user-create")
#    {
#    system ("/sbin/e-smith/signal-event", "multi-user-create", "$acctName") == 0 || $error++;
#    }
#    else
#    {                                                                          
#    system ("/sbin/e-smith/signal-event", "user-create", "$acctName") == 0 || $error++;
#    }
#+++++++++++++++++++++++++++++++++++++++++++++++++++
#cp -a /etc/e-smith/events/user-create /etc/e-smith/events/multi-user-create
#----remove---------
#S20conf-httpd-admin  ????
#S25reload-httpd-admin 
#S75reload-samba
#+++++++++++++++++++++++++++++++++++++++++++++++++++
#cp -a /etc/e-smith/events/group-modify /etc/e-smith/events/multi-group-modify
#----remove---------
#S20conf-httpd-admin  ????
#S25reload-httpd-admin 
#S75reload-samba
#+++++++++++++++++++++++++++++++++++++++++++++++++++
#cp -a /etc/e-smith/events/user-delete /etc/e-smith/events/multi-user-delete
#----remove---------
#S20conf-httpd-admin  ????
#S25reload-httpd-admin 
#S75reload-samba
#+++++++++++++++++++++++++++++++++++++++++++++++++++
#cp -a /etc/e-smith/events/user-modify /etc/e-smith/events/multi-user-modify
#----remove---------
#S20conf-httpd-admin  ????
#S25reload-httpd-admin 
#S75reload-samba
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++
