#include <stdio.h>
#include <pwd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>

char *progname;

#ifdef NO_RE_COMP
#define INIT        register char *sp=instring;
#define GETC()      (*sp++)
#define PEEKC()     (*sp)
#define UNGETC(c)   (--sp)
#define RETURN(c)   return;
#define ERROR(c)    \
        fprintf( stderr,"\n%s: regerr %d, please contact Cadence\n",progname,c );

#define ESIZE       128
#include <regexp.h>
char    expbuf[ESIZE];
#endif

/* Bitwise functions made readable */
#define AND_		&
#define OR_             |
#define SHR_		>>
#define SHL_		<<

/* ON=YES OFF-NO */
#define ON              1
#define OFF             0

/* Assorted character constants */
#define SPACE		    ' '

#define DEC( c )	( ( ( c ) - SPACE ) AND_ 077 )

#define RET_SUCCESS                        0
#define RET_CANT_OPEN_EMAIL_FILE           2
#define RET_CANT_OPEN_DECOD_FILE           4
#define RET_CANT_OPEN_TARGT_FILE           6
#define RET_MISMATCHED_BEGIN_END           8
#define RET_USAGE_NO_INPUT_FILE           10
#define RET_FSTAT_SYSCALL_FAILED          12
#define RET_INPUT_FILE_ZERO_LEN           14
#define RET_NOT_REGULAR_FILE	          16 
#define RET_NO_BEGIN_END		  18
#define RET_FULLCHECKSUM_FAILED		  20
#define RET_CHECKSUM_FAILED		  22
#define RET_NOT_RIGHT_FILE		  24

#define CALC_SUM_WHILE_LOOP while (--count >= 0) sum += sum + sum + *(ptr++);

#ifdef DEBUG

char tmp_ptr[161];

#define DEBUG1 \
       strncpy( tmp_ptr,cptr,161 ); \
       fprintf( stderr,"\n==========\n%s\n============\n",tmp_ptr );

#define DEBUG2 \
       strncpy( tmp_ptr,cptr,10 ); \
       fprintf( stderr,"\n==========\n%s\n============\n",tmp_ptr );

#define DEBUG3 \
       strncpy( tmp_ptr,cptr,62 ); \
       fprintf( stderr,"\n==========\n%s\n============\n",tmp_ptr );
#endif


/* Buffer Size for each read operation */
#define BUFSIZE        256 

/* The maximum string length a work order number string can have */
#define WO_SIZE         32

/* The number of bytes we should back off current file pointer when needed */
#define THRESHOLD       256

/* The maximum number of e-mail parts this program can handle */
#define MAX_EMAIL_PART  128

/* The uuencode length per line, which is fixed at 62 */
#define UUENC_LPL       62

/* Macro to skip space and new-line char to get to the next string */
#define SKIP_TO_NEXT_TOKEN \
        while ( *cptr != ' ' && *cptr != '\n' ) cptr++; \
        while ( *cptr == ' ' || *cptr == '\n' ) cptr++


#define FULLCHKSUM_KEY 	"C_Begin Fullchecksum"
#define CHKSUM_KEY	"C_Begin Checksum"
#define CADENCE_BEGIN_KEY	"C_Begin Cadence_Begin"
#define UUENCODE_BEGIN_KEY	"C_Begin begin"
#define CADENCE_END_KEY		"C_Begin Cadence_End"
#define BEGIN_KEY	"C_Begin "
#define END_KEY		" C_End"
#define DUM_CADENCE_END_KEY "C_End"
#define JUST_UUENCODE_END_KEY "end"
#define JUST_UUENCODE_BEGIN_KEY "begin"

#define BEGIN_KEY_LENGTH 8


FILE          *out;
char          *fn, *cptr, offset;
FILE	      *fd;
int           debug=OFF, mode, part_no, total_parts, eof_reached=OFF;
unsigned int  fullsum, currentsum;
off_t         total_file_size, save_floc=0, cur_floc=0;

char          next_5char[6];
extern char   *sys_errlist[];


/* The input buffer when reading from file */
char      buf[BUFSIZE+1];

/* The filename arrary */
char      fname[ MAXPATHLEN ];

/* the array for the file offset (from BOF) for each e-mail part */
long     pos[MAX_EMAIL_PART+1];

/* the array for check sum for each e-mail part */
unsigned  cksum[MAX_EMAIL_PART+1];

/* won = Work Order Number */
char  current_won[WO_SIZE];


/*
Hariraj: Added the workorder to help in exiting whenever more than
one workorders have been saved in the same file
*/
char  workorder[WO_SIZE];



/*
 * output a group of 3 bytes (4 input characters).
 * the input chars are pointed to by p, they are to
 * be output to file f.  n is used to tell us not to
 * output all of them at the end of the file.
 */
outdec( p, n )
char *p;
int n;
{
    int c1, c2, c3;
  
  	c1 = DEC( *p ) SHL_ 2 OR_ DEC( p[ 1 ] ) SHR_ 4;
  	c2 = DEC( p[ 1 ] ) SHL_ 4 OR_ DEC( p[ 2 ] ) SHR_ 2;
  	c3 = DEC( p[ 2 ] ) SHL_ 6 OR_ DEC( p[ 3 ] );
  	if ( n >= 1 ) 
	    putc( c1, out );
  	if ( n >= 2 ) 
	    putc( c2, out );
  	if ( n >= 3 ) 
	    putc( c3, out );
}

/*
 * copy from in to out, decoding as you go along.
 */
doaline( s )
char s[];
{
    char *bp;
    int n;
  
	if ( ( n = DEC( s[ 0 ] ) ) > 0 )
    	{
      	    bp = &s[ 1 ];
      	    while ( n > 0)
	    {
		outdec( bp, n );
		bp += 4;
		n -= 3;
	    };
    	}
}


/*
 * XXchecksumSeg --
 *
 * compute a checksum for a segment.  The checksum is used to
 * verify that the disk version isn't corrupted.
 *
 *TODO  This assumes that a character is signed.  Is this a problem?
 *TODO  It is late to change this...
 */  

cds_checksum( bufptr,count,sum )
char *bufptr;
int count;
unsigned int *sum;
{

unsigned int local_sum;

   local_sum=*sum;
   while (--count >= 0) {
      local_sum += local_sum + local_sum + *(bufptr++);
   }  
   *sum = local_sum;
}

/*
 *  Pass One
 *
 *  Problem to solve:
 *
 *  Say user received 7 parts e-mail from Cadence and the user did not save
 *  these 7 parts in the default order (1,2,3,4,5,6,7).  So the "Pass One"
 *  will scan through the whole file and identify how many parts are in the
 *  file and save the file-offset (from BOF) into array pos[]
 *
 *  Result from Pass One
 *
 *  The array pos[] is updated with the file-offsets for all e-mail parts
 *  presented in the e-mail file.
 *
 *  Special Note:
 *
 *  Due to avoid line-by-line reading which is very slow, a input buffer is
 *  used to read in from file.  The problem created by using a buffer is
 *  that we can not determine how many parts are actually in a buffer.
 *
 *  So, the program will try to identify at maximum 2 "BEGIN" (2 e-mail parts)
 *  in each buffer read.  If it so happens that each piece of e-mail is so
 *  small that there is actually 3 pieces of e-mail in a buffer, this program
 *  will report missing the last piece of e-mail (the last BEGIN).
 *
 *  Solution?  Loop through to identify all BEGIN, OR, reduce the input buffer
 *  size.  But remember, the smaller the buffer is, the LESS efficiency the
 *  program is going to perform.
 *
 *  Currently the buffer size is set to 512 bytes due to bug report.  The 
 *  original design size is 8K (8 * 1024).
 *
 */


int uuread_pass1( infile )
FILE *infile;
{

   char dum[THRESHOLD];
   char chksum_name[WO_SIZE], begin_name[WO_SIZE], end_name[WO_SIZE];
   int begin_cur_part_no,begin_tot_part_no,end_cur_part_no,end_tot_part_no; 
   int fullchecksum_found_flag = 0;
   int current_sum;
   int end_found_flag;
   if (debug==ON) fprintf( stderr,"Entering Pass One ...\n" );

   while(fgets(buf,BUFSIZE,infile))
   {
     
     char *tmp; /* used to store the pointer returned by strstr */

     if(tmp=(char *)strstr(buf,FULLCHKSUM_KEY))
     {
	/*
	Found FULLCHECKSUM:
	Read the name of the workorder.
	*/	
	
        if ( sscanf(tmp,"%s%s%s%u%s",dum,dum,current_won,&fullsum,dum) != 5)
	{
	   (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	    my_exit(RET_NOT_RIGHT_FILE);
	}
        
	if ( strcmp(dum,DUM_CADENCE_END_KEY) != 0)
	{
	   (void)fprintf(stderr,"\n%s:Corrupted E-mail File: %s\n",progname,fn);
	    my_exit(RET_NOT_RIGHT_FILE);
	}
        fullchecksum_found_flag = 1;	

     } /*If FULLCHECKSUM found */

     if(tmp=(char *)strstr(buf,CHKSUM_KEY))
     {
	/*
	 Read till END for that block is found
	*/
   
        if ( sscanf(tmp,"%s%s%s%u%s",dum,dum,chksum_name,&current_sum,dum) != 5)
	{
	   (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	    my_exit(RET_NOT_RIGHT_FILE);
	}

	if ( strcmp(dum,DUM_CADENCE_END_KEY) != 0)
	{
	   (void)fprintf(stderr,"\n%s:Corrupted E-mail File: %s\n",progname,fn);
	    my_exit(RET_NOT_RIGHT_FILE);
	}
	if ( strlen ( current_won ) != 0)
        {
	  if(strcmp(current_won,chksum_name) != 0)
	  {
   	     (void)fprintf(stderr,"\n%s:More than one workorders saved in file %s\n",progname,fn);
       	     my_exit(RET_NOT_RIGHT_FILE);
	  }
	}

	if ( fgets(buf,BUFSIZE,infile) ) /*Read the begin line*/
	{
	   if( tmp = strstr(buf,CADENCE_BEGIN_KEY) )
	   {
		if(sscanf(tmp,"%s%s%s%d%s%d%s",dum,dum,begin_name,&begin_cur_part_no,dum,&begin_tot_part_no,dum) != 7)
		{
	          (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	    	  my_exit(RET_NOT_RIGHT_FILE);
	 	}
	
		if ( strcmp(dum,DUM_CADENCE_END_KEY) != 0)
		{
		   (void)fprintf(stderr,"\n%s:Corrupted E-mail File: %s\n",progname,fn);
		    my_exit(RET_NOT_RIGHT_FILE);
		}

	        if ( 0 == total_parts )
			total_parts = begin_tot_part_no;	
			
		if(strcmp(chksum_name,begin_name) != 0)
		{
	   	   (void)fprintf(stderr,"\n%s:More than one workorders saved in file %s\n",progname,fn);
            	   my_exit(RET_NOT_RIGHT_FILE);
		}

		if(begin_tot_part_no != total_parts)
		{
	   	   (void)fprintf(stderr,"\n%s:More than one workorders saved in file %s\n",progname,fn);
            	   my_exit(RET_NOT_RIGHT_FILE);
		}

	        /*
		Save the location of the file pointer after the BEGIN Line has been read
	        */

		pos[begin_cur_part_no] = (long) ftell (infile);


		/*
		Read the next line, If it had begin in it then get the name of the output file
		*/

		if (fgets(buf,BUFSIZE,infile))
		{
		  if( tmp = strstr(buf,UUENCODE_BEGIN_KEY))
		  {
        	    if ( sscanf(tmp,"%s%s%o%s%s",dum,dum,&mode,fname,dum) != 5)
		    {
	  	      (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	 	      my_exit(RET_NOT_RIGHT_FILE);
		    }

		    if ( strcmp(dum,DUM_CADENCE_END_KEY) != 0)
		    {
		       (void)fprintf(stderr,"\n%s:Corrupted E-mail File: %s\n",progname,fn);
		        my_exit(RET_NOT_RIGHT_FILE);
		    }

		  } /*If UUENCODE_BEGIN_KEY is found */
		}
		else
		{
           	  (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	          my_exit(RET_NOT_RIGHT_FILE);
    	        }
		 
		end_found_flag = 0; /*if END is not found then an error */

		while( fgets(buf,BUFSIZE,infile) )
		{
		   if ( tmp = strstr(buf,CADENCE_END_KEY) )
		   {
		   	if(sscanf(tmp,"%s%s%s%d%s%d%s",dum,dum,end_name,&end_cur_part_no,dum,&end_tot_part_no,dum) != 7)
		   	{
	             	  (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	    	     	  my_exit(RET_NOT_RIGHT_FILE);
	 	   	}
		        if(strcmp(begin_name,end_name) != 0)
			{
	   		   (void)fprintf(stderr,"\n%s:More than one workorders saved in file %s\n",progname,fn);
            		   my_exit(RET_NOT_RIGHT_FILE);
		        }

		        if ( end_cur_part_no != begin_cur_part_no )
			{
           		  fprintf( stderr, "\n%s: Unexpected EOF, check BEGIN END pair in file %s\n",progname,fn);
           		  fprintf( stderr,"%s: %s\n",progname,sys_errlist[errno] );
           		  my_exit( RET_MISMATCHED_BEGIN_END );
			}

		        if ( end_tot_part_no != begin_tot_part_no )
			{
	             	  (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	    	     	  my_exit(RET_NOT_RIGHT_FILE);
			}

			end_found_flag = 1;

			/*
			Put the checksum value of the part in the array
			*/
		
			cksum[begin_cur_part_no] = current_sum ;

			break;
		    } /*If END found */
		} /*While loop that reads after the begin line till the END line*/

		if ( end_found_flag != 1)
	        {
           	  fprintf( stderr, "\n%s: Unexpected EOF, check BEGIN END pair in file %s\n",progname,fn);
           	  fprintf( stderr,"%s: %s\n",progname,sys_errlist[errno] );
           	  my_exit( RET_MISMATCHED_BEGIN_END );
		}
	   }
	   else /*if BEGIN line not after CHECKSUM LINE Error*/
	   {
		(void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
		my_exit(RET_NOT_RIGHT_FILE);
    	   }
	} /*if read of begin line successful*/
	else
	{
           (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
	   my_exit(RET_NOT_RIGHT_FILE);
    	}
     } /*If CHECKSUM found*/	
  } /*End of the while loop */

  if ( strlen (fname) == 0 || mode == 0 )
  {
     (void)fprintf(stderr,"\n%s:The file %s is not a legitimate Cadence E-mail file\n",progname,fn);
     my_exit(RET_NOT_RIGHT_FILE);
  }


  /*
   Added after the code review. If fullchecksum not found then flag
   an error
  */

  if (0 == fullchecksum_found_flag)
  {
	(void)fprintf(stderr,"\n%s:fullchecksum not found in E-mail file %s\n",progname,fn);
	my_exit(RET_NOT_RIGHT_FILE);
   }


}/*End of function pass1*/


/*
 * Some basic checking to see if all parts are present, and report aay
 * discrepency if any.
 */

int sanity_check()
{
int cnt, cont=0;

   if (debug==ON) fprintf( stderr,"Total %d parts\n",total_parts );
   for ( cnt=1; cnt <= total_parts ; cnt++ )
     if ( cksum[cnt] == 0 )
       fprintf( stderr,"Part %3d is missing ....\n",cnt );
     else
       fprintf(stderr,"part %3d: cksum = %u\n",cnt,cksum[cnt]);
}


/*
 *  Pass Two
 *
 *  Problem to solve:
 *
 *  Now we know WHERE in file all parts started, we can just reset the file
 *  pointer and starting reading each part, pass each line readed (UUENC_LPL)
 *  to our checksum routine and pass them to "uudecode" engine within this
 *  program.
 *
 *  Report any discrepency if any, say the checksum for any specific part
 *  is not correct.
 *
 *  Last, check to see if the final file which is produced after the "uudecode"
 *  process has the correct checksum, which we refer as the FULLCHECKSUM.
 *  If not, report that, too.
 *
 *  That's it, easy, ah?
 *
 */


int uuread_pass2( infile )
FILE *infile;
{

int             cnt, print_flag=1;
long 	floc;
char            *tmp,*tmp1,*tmp2;
unsigned int    cur_calc_sum;

   if ( debug==ON ) {
     fprintf( stderr,"Entering Pass Two ...\n" );
     sanity_check();
   };

/*
Open the file in which we have to write the decoded 
information
*/

   if ( (out=fopen( fname, "w" )) == NULL ) {
       fprintf( stderr,"\n%s: Can't open file %s\n",progname,fname );
       fprintf( stderr,"\n%s: %s\n",progname,sys_errlist[errno] );
       my_exit( RET_CANT_OPEN_DECOD_FILE );
   };
/* accessing the 1st part, get the final filename */

   for ( cnt=1 ; cnt <= total_parts ; cnt++ ) 
   {

     cur_calc_sum=0;
     print_flag = 1;

     if (debug==ON) 
	fprintf( stderr,"part %d pos = %d\n",cnt,pos[cnt] );

     /*
	Seek to the beginning of the email part
     */

     floc=fseek( infile,(long)pos[cnt],0 );

     if (debug==ON) 
	fprintf( stderr,"floc = %ld\n",floc );

     

     while ( fgets(buf,BUFSIZE,infile) ) 
     {
     	/*
	 Break out of the while loop if cadence
	 end is reached
	*/

	if ( tmp = strstr(buf,CADENCE_END_KEY) )
		break;
	
	if ( tmp1 = strstr(buf,BEGIN_KEY) )
		tmp1 += BEGIN_KEY_LENGTH;

	if ( tmp2 = strstr(buf,END_KEY) )
		tmp2[0] = '\n';

	if ( ON == debug )
	{
		if ( 1 == print_flag )
			fprintf(stderr,"%s length = %d\n",tmp1,tmp2-tmp1+1);

		print_flag = 0 ;
	}

        /* Pass buffer to run checksum */


        if ( tmp1 != 0 && tmp2 != 0 )
        {
          cds_checksum( tmp1,(tmp2-tmp1+1),&cur_calc_sum );


	/*
	 Decode the line
	*/

	  if ( strstr(tmp1,JUST_UUENCODE_END_KEY) || 
		strstr(tmp1,JUST_UUENCODE_BEGIN_KEY))
	  ;
	  else
            doaline( tmp1 );
        }

     } /* End of the while loop */

     if ( cur_calc_sum != cksum[cnt] ) {
       fprintf( stderr,
         "\n%s:CHECKSUM verify of Mail #%3d of %-3d in file %s FAILED\n",
         progname,cnt,total_parts,fn );

       if ( debug==ON )
     		fprintf( stderr,"%s: Mail #%3d of %-3d has %u, calculation returns %u\n",
              progname,cnt,total_parts,cksum[cnt],cur_calc_sum );

	my_exit(RET_CHECKSUM_FAILED);
     };
     if ( debug==ON)
     {
       fprintf( stderr,"%s: Processed Part %3d ...\n",progname,cnt );
       fprintf(stderr, "%s: CHECKSUM of the part is  %u\n",progname,cur_calc_sum);
     }
   }

   fclose( out );

   /* Change file mode using the mode we read from the begin line */

   chmod( fname, mode );
}

checksum_uudecoded_file()
{
int fd;
unsigned char  *ptr;
int            nr, count;
unsigned int   sum=0;


   if ((fd = open(fname, O_RDONLY, 0)) < 0) {
fprintf( stderr,"\n%s: Can't open file %s,Check Permissions \n",progname,fname );
     fprintf( stderr,"%s: %s\n",progname,sys_errlist[errno] );
     my_exit( RET_CANT_OPEN_TARGT_FILE );
   };

   while ((nr = read(fd, buf, sizeof(buf))) > 0) {
     count = nr;
     ptr   = (unsigned char *)&buf[0];
     CALC_SUM_WHILE_LOOP;
   }
   if ( sum != fullsum ) {
     fprintf( stderr, "\n%s:FULLCHECKSUM verify of file %s FAILED\n",
                      progname,fname );
     if (debug == ON)
       fprintf( stderr,"%s: Mail has %u but destination file has %u\n",
                       progname, fullsum, sum );


     my_exit( RET_FULLCHECKSUM_FAILED );

   };
   close( fd );

}




/* ARGSUSED */
/*
 * Expand the UNIX environment variable.
 */
int
expandEnv(path, expandFile)
    char *path;
    char *expandFile;
{
    static char	*env;
    static char	*envEnd;

    if (*path != '$') {
	return(0);
    }

    /* Find the next / */
    envEnd = strchr(path, '/');
    if (envEnd != (char *) NULL) {
	*envEnd = '\0';
    }
    if ((env = (char*)getenv(path+1)) == (char *) NULL) {
	(void)fprintf(stderr, "\n%s:Cannot get the %s enviroment variable. \n",progname, path);
	if (envEnd != (char *) NULL) *envEnd = '/';
	return(-1);
    }
    (void)strcpy(expandFile, env);
    if (envEnd != (char *) NULL) {
	*envEnd = '/';
	(void)strcat(expandFile, envEnd);
    }

    return(0);
}

/* ARGSUSED */
/*
 * Copied from voExpandTilde:
 *	path:		pathname with (possibly) leading tilde
 *
 * voExpandTilde will expand any leading tildes, replacing "~" with the
 * current user's home directory and "~user" with the home directory
 * for user "user".  The 'path' buffer passed is expected to be large
 * enough to hold the entire string after expansion.
 */
int
expandTilde(path, expandFile)
    char			*path;
    char			*expandFile;
{
    static char			*myHome = (char *) NULL;
    static struct passwd	*pw;
    char			*ep;
    char			saveChar;
    char			*userHome;

    /* Find the end of the ~ component */

    ep = strchr(path, '/');
    if (ep == (char *) NULL) {
	ep = path + strlen(path);
    }

    if (ep == path + 1) {
	/* Home of current user */
	if (myHome == (char *) NULL) {
	    if ((myHome = (char *)getenv("HOME")) == (char *) NULL) {
		if ((myHome = (char *)getenv("home")) == (char *) NULL) {
		    if ((pw = (struct passwd *)getpwuid(geteuid())) != (struct passwd *) NULL) {
			myHome = pw->pw_dir;
		    } else {
			(void)fprintf(stderr, "\n%s:Cannot get user's home directory\n",progname);
			return(-1);
		    }
		}
	    }
	}
	userHome = myHome;
    } else {
	/* Home of specified user */
	saveChar = *ep;
	*ep = '\0';
	if ((pw = (struct passwd *)getpwnam(path + 1)) != (struct passwd *) NULL) {
	    userHome = pw->pw_dir;
	} else {
	    fprintf(stderr, "\n%s:Cannot get home directory of user '%s'\n",progname, path + 1);
	    *ep = saveChar;
	    return(-1);
	}
	*ep = saveChar;
    }

    if ((*userHome == '/') && (*(userHome + 1) == '\0') && (*ep != '\0')) {
	/* userHome was just "/".  Avoid creating "//foo". */
	userHome = "";
    }

    strcpy(expandFile+strlen(userHome), ep);
    strncpy(expandFile, userHome, strlen(userHome));
    return(0);
}




main( argc, argv )
int argc;
char *argv[];
{
struct stat stat_buf;
   char exp_buffer[MAXPATHLEN];
   FILE *fopen();

   progname = "    cdsudp";
   fn       = argv[1];

   if ( argc != 2 ) {
     (void)fprintf(stderr,"\n%s:Usage: %s input_filename\n",progname,progname );
     my_exit( RET_USAGE_NO_INPUT_FILE );
   }

   if( fn[0] == '$' )
   {
	if(expandEnv(fn,exp_buffer))
        {
	   (void)fprintf(stderr,"\n%s:Could not expand the filename %s",progname,fn);
	   (void)fprintf(stderr,"\n%s:Please type the absolute path of the E-mail file\n ",progname);
	    my_exit(RET_CANT_OPEN_EMAIL_FILE);
	}
	else
	   fn = exp_buffer;
   }
   else
   {
	if( fn[0] == '~')
	{
	    if(expandTilde(fn,exp_buffer))
	    {
	   	(void)fprintf(stderr,"\n%s:Could not expand the filename %s",progname,fn);
	   	(void)fprintf(stderr,"\n%s:Please type the absolute path of the E-mail file\n ",progname);
	    	my_exit(RET_CANT_OPEN_EMAIL_FILE);
	    }
            else
              fn = exp_buffer;
	}
    }



      

   if ((fd = fopen(fn,"r"))==NULL) {
     fprintf( stderr,"\n%s: Can't open file %s\n",progname,fn );
     fprintf( stderr,"\n%s: %s\n",progname,sys_errlist[errno] );
     my_exit( RET_CANT_OPEN_EMAIL_FILE );
   };

   if ( stat(fn, &stat_buf ) == -1 ) {
     fprintf( stderr,"\n%s: stat system call failed!\n",progname );
     fprintf( stderr,"\n%s: %s\n",progname,sys_errlist[errno] );
     my_exit( RET_FSTAT_SYSCALL_FAILED );
   }
   else {
     if( (stat_buf.st_mode & S_IFMT) != S_IFREG)
     {
        fprintf( stderr,"\n%s: Not a regular file %s\n",progname,fn );
        fprintf( stderr,"\n%s: %s\n",progname,sys_errlist[errno] );
        my_exit( RET_NOT_REGULAR_FILE );
     }
     else
     {
        total_file_size=stat_buf.st_size;
        if (debug == ON) fprintf( stderr,"File size = %d\n",total_file_size );
     }
   };

   if ( getenv("CDSUDP") != NULL ) debug=ON;
   else debug=OFF;


   if ( total_file_size == 0 ) {
     fprintf( stderr,"\n%s: %s can not be an empty file\n\n",progname,fn );
     my_exit( RET_INPUT_FILE_ZERO_LEN );
   };

   uuread_pass1( fd );
   uuread_pass2( fd );
   checksum_uudecoded_file();

   if (debug==ON)
   {
	int i;
	printf("Workorder is %s\n",current_won);
	printf("FULLCHECKSUM is %u\n",fullsum);
	printf("The Part numbers and checksums are\n");
	for(i=1;i<=total_parts;i++)
	{
		printf("%d -> %u Location = %ld\n",i,cksum[i],(long)pos[i]);
	}
   }

   close( (int)fd );
   printf( "%s\n",fname );
   my_exit( RET_SUCCESS );
}


my_exit(errcode)
int errcode;
{
	if (fd)
		close((int)fd);

	exit(errcode);
}
