#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>

typedef int BOOLEAN;

struct t_type {
 char name[255];
 struct t_type *next;
}; /* end t_type */

struct t_type *tfirst=NULL;

struct t_type *get_files(),
              *find_job_number(int);
BOOLEAN read_and_transfer(char *, char *),
        is_file(char *);


main(int argc, char *argv[])

{

 if (argc != 3)
  fprintf(stderr,"lptran <job_number> <queue>\n");
 else {
  tfirst = get_files();
  tfirst = find_job_number(atoi(argv[1]));
  if (tfirst) {
   if (!read_and_transfer(tfirst->name,argv[2])) {
    fprintf(stderr,"Transfer unsuccessful\n");
    return(1);
   } /* end then */
  } /* end then */
  else  {
   fprintf(stderr,"Could not find job # %s\n",argv[1]);
   return(1);
  } /* end else */
 } /* end else */
 return(0);

} /* end main */



/* ***************************************************************** *
 *                                                                   *
 *  Procedure  : get_files                                           *
 *  Purpose    : This procedure builds a linked list of the print    *
 *               header files                                        *
 *                                                                   *
 * ***************************************************************** */
struct t_type *get_files()

{

 DIR *dir;
 struct dirent *entry;
 struct t_type *temp,
               *hold_first;

  
#ifdef AIX31
 if ((dir = opendir("/usr/lpd/qdir")) == NULL)
#endif
#ifdef AIX32
 if ((dir = opendir("/var/spool/lpd/qdir")) == NULL)
#endif
  exit(1);
 entry = readdir(dir);   /* . and .. will always be the first two listings */
 entry = readdir(dir);   /* so lets get rid of them here                   */
 temp = hold_first;
 while ((entry = readdir(dir)) != NULL) {
  if (!hold_first) {
   temp = (struct t_type *) malloc(sizeof(struct t_type));   
   hold_first = temp;
  } /* end then */
  else {
   temp->next = (struct t_type *) malloc(sizeof(struct t_type));   
   temp = temp->next;
  } /* end else */
  strcpy(temp->name,entry->d_name);  
 } /* end while */
 closedir(dir);
 return(hold_first);

} /* end get_files */



/* ***************************************************************** *
 *                                                                   *
 *  Procedure  : find_job_number                                     *
 *  Purpose    : This procedure finds the job number in the header   *
 *               files                                               *
 *                                                                   *
 * ***************************************************************** */
struct t_type *find_job_number(int job)

{

 char job_number[10],
      temp[255];
 struct t_type *info,
               *found=NULL;
 FILE *fp;

 info = tfirst;
 do {
#ifdef AIX31
  strcpy(temp,"/usr/lpd/qdir/");
#endif
#ifdef AIX32
  strcpy(temp,"/var/spool/lpd/qdir/");
#endif
  strcat(temp,info->name);
  if ((fp = fopen(temp,"r")) == NULL) {
   printf("cannot open file \n");
   printf("open = %s\n",temp);
  }  /* end then */
  else {
   fscanf(fp,"%s",job_number);
   if (job == atoi(job_number))
    found = info;
   fclose(fp);
  } /* end else */
  info = info->next;
 } while ((info) && (!found));
 return(found);

} /* end find_job_number */


/* ***************************************************************** *
 *                                                                   *
 *  Procedure  : read_and_transfer                                   *
 *  Purpose    : This procedure reads the header file and builds the *
 *               transfer string                                     *
 *                                                                   *
 * ***************************************************************** */

BOOLEAN read_and_transfer(char *file_name,char *queue_name)

{

 char temp[255],
      job_name[1024],
      transfer_string[4096];
 int remote = 18;
 FILE *in;

#ifdef AIX31
 strcpy(temp,"/usr/spool/lpd/qdir/");
#endif
#ifdef AIX32
 strcpy(temp,"/var/spool/lpd/qdir/");
#endif
 strcat(temp,file_name);
 strcpy(transfer_string,"lp -d");
 strcat(transfer_string,queue_name);
 if ((in = fopen(temp,"r")) != NULL) {
  do {
   fscanf(in,"%s",job_name);
  } while (remote-- > 0);
  while (!feof(in)) {
   if ((is_file(job_name)) && (strlen(job_name) < 255)) {
    if ((strlen(transfer_string) + strlen(job_name) + 1) > 4095)
     return FALSE;
    strcat(transfer_string," ");
    strcat(transfer_string,job_name);
   } /* end then */
   fscanf(in,"%s",job_name);
  } /* end while */
  if (system(transfer_string) != 0)
   return FALSE;
  fclose(in);
 } /* end then */
 return TRUE;

} /* end read_and_transfer */


/* ***************************************************************** *
 *                                                                   *
 *  Procedure  : is_file                                             *
 *  Purpose    : This procedure returns TRUE if the file passed is   *
 *               a regular file, otherwise it return FALSE.          *
 *                                                                   *
 * ***************************************************************** */

BOOLEAN is_file(file_name)

 char *file_name;

{

 struct stat buf;

 if (stat(file_name,&buf) == 0) {
  switch (buf.st_mode & S_IFMT) {
   case S_IFDIR : return FALSE;
   case S_IFBLK : return FALSE;
   case S_IFCHR : return FALSE;
   case S_IFIFO : return FALSE;
   case S_IFREG : return TRUE;
  } /* end switch */
 } /* end then */
 return FALSE;

} /* end is_file */


