#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#define kUsage "Usage:\n\t%s dialerPath device number speed\n\
%s dialer -h device speed\n"
#define kExitErrFlag 0x80
#define kErrorMask 0x0f
#define RCE_NULL 0
#define RCE_INUSE 1
#define RCE_SIG 2
#define RCE_ARGS 3
#define RCE_PHNO 4
#define RCE_SPEED 5
#define RCE_OPEN 6
#define RCE_IOCTL 7
#define RCE_TIMOUT 8
#define RCE_NOTONE 9
#define RCE_BUSY 13
#define RCE_NOCARR 14
#define RCE_ANSWER 15
typedef struct
{
int errNum;
char *errString;
} errTable;
const errTable errors[]=
{
{ RCE_NULL, "Unknown Error" },
{ RCE_INUSE, "Line is being used" },
{ RCE_SIG, "Recieved fatal signal" },
{ RCE_ARGS, "Bad arguments" },
{ RCE_PHNO, "Invalid phone number" },
{ RCE_SPEED, "Invalid baud rate or bad connection" },
{ RCE_OPEN, "Unable to open line" },
{ RCE_IOCTL, "ioctl error" },
{ RCE_TIMOUT, "Timed out" },
{ RCE_NOTONE, "No dialtone" },
{ RCE_BUSY, "Phone number is busy" },
{ RCE_NOCARR, "No carrier" },
{ RCE_ANSWER, "No answer" },
{ 0,NULL}
};
int figureStat(int stat);
char *findInTable(int error);
void badExec(void);
char *dialerName;
char *dialerPath;
main(int argc,char *argv[])
{
int parent;
int child;
int stat;
char *temp;
if(argc!=5)
{
fprintf(stderr,kUsage,argv[0],argv[0]);
exit(1);
}
dialerPath=argv[1];
dialerName= (temp=strrchr(argv[1],'/'))!=NULL ? temp+1 : argv[1];
parent=getpid();
signal(SIGUSR1,badExec);
if((child=fork())<0)
{
perror("fork");
exit(2);
}
if(child>0)
{
signal(SIGHUP,SIG_IGN);
signal(SIGINT,SIG_IGN);
signal(SIGTERM,SIG_IGN);
wait(&stat);
exit(figureStat(stat));
}
else
{
close(0);
close(1);
dup2(2,1);
if(execvp(argv[1],argv+1)<0)
{
kill(parent,SIGUSR1);
exit(0);
}
}
exit(0);
}
int figureStat(int stat)
{
int exit;
int errFlag;
int error;
if(WIFSIGNALED(stat))
{
fprintf(stderr,"Error: Dialer %s recieved signal %d.\n",dialerName,
WTERMSIG(stat));
return(1);
}
if(WIFSTOPPED(stat))
{
fprintf(stderr,"Error: Dialer %s recieved signal %d.\n",dialerName,
WSTOPSIG(stat));
return(1);
}
exit=WEXITSTATUS(stat);
errFlag=exit&kExitErrFlag;
if(errFlag)
{
char *errString;
error=exit&kErrorMask;
errString=findInTable(error);
fprintf(stderr,"Error: %s - %s.\n",dialerName,errString);
return(1);
}
return(0);
}
char *findInTable(int error)
{
int i=0;
for(i=0;errors[i].errString!=NULL;i++)
{
if(errors[i].errNum==error)
return(errors[i].errString);
}
return(errors[0].errString);
}
void badExec(void)
{
fprintf(stderr,"Error: %s - Execution problem.\n",dialerPath);
exit(1);
}