/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:ldfnt.c 12.3$ */
/* $ACIS:ldfnt.c 12.3$ */
/* $Source: /ibm/acis/usr/src/ibm/lpfilter/pp4216/RCS/ldfnt.c,v $ */

#ifndef lint
static char *rcsid = "$Header:ldfnt.c 12.3$";
#endif


/*
 *
 *   ldfnt -- download a font to a 4216 Personal Pageprinter 
 *
 *     usage:
 *            ldfnt [-fprinterdev] [-p] fontname ... 
 */ 

#include <stdio.h>
#include <fcntl.h>
#include <sys/psioctl.h>


static int DEBUG = 0;

char msgbuff[128];
long int password = 0;

main(int argc, char *argv[])
    
{  int ps;
   char *devname;
   int thisfile = 1;

    if (argc < 2) {
        fprintf(stderr,"usage: ldfnt [-fprinterdev] [-p] fontfile ...\n"); 
        exit(2);
    }
    else {
        devname = "/dev/ps0";
        while ((thisfile < argc - 1) && (*argv[thisfile] == '-') ) {
            if ( (argv[thisfile])[1] == 'f' ) {
                devname = (argv[thisfile])+2;
            }
            else if ( (argv[thisfile])[1] == 'p' ) {
                password = atol(getpass("Enter the password: "));
            }
            else {
                fprintf(stderr, "usage: ldfnt [-fprinterdev] [-p] fontfile ...\n"); 
                exit(2);
            }
        thisfile++;
        }

        for (; thisfile < argc; thisfile++) { 
            ps = open(devname, O_RDWR, 0);
            if (ps < 0) {
                sprintf(msgbuff, "ldfnt: can't open printer %s\n", devname);
                perror(msgbuff);
                exit(2);
            }

            loadfnt(ps, argv[thisfile]);
            close(ps);
        }
    }
    exit(0);
}


loadfnt(ps, fname)
     int ps, fname;


{ int stat, writestat, f;
  char buf[1040];
  char initcmd[128];
  unsigned short packetlen;
  

   f = open(fname, O_RDONLY, 0);
   if (f < 0) {
       fprintf(stderr, "ldfnt: file %s not found.\n", fname);
   }
   else {
       printf("ldfnt: loading %s\n",fname);
       if (DEBUG) {
           fprintf(stderr, "opened  %s\n", fname);
       }
   }

   stat = 0;
   sprintf(initcmd, " serverdict begin %d exitserver \n", password);
   writestat = write(ps, initcmd, strlen(initcmd));
   if (writestat < 0) {
       sprintf(msgbuff,   
              "ldfnt: ps write failed.  stat = %x.\n", writestat);
       perror(msgbuff);
       exit(2);
   }
   do {
        stat = xferfontpacket(ps, f, buf);
        if (stat == -2)
            fprintf(stderr, "ldfnt: %s file not a vaild font file\n", fname); 
        while ((packetlen = read(ps, buf, 1024)) > 0){
            write(1, buf, packetlen);
        }
         
   } while (stat > 0 );
   close(f);
   sleep(4);  /* wait for the printer to return from reading the font file. 
                 IT will break if we start writing to it too soon. */
}






buildpacket(len, type, data, pktbuff)
        short len, type;
        char *data, *pktbuff;
        

{ short *pb;

    pb = (short *)pktbuff;

    pb[0] = len;
    pb[1] = type; 
    bcopy(data, pktbuff+4, len);
}





#define swapbytes(x) (((x&0xff00) >> 8) | ((x&0xff) << 8))

#define swapwords(x) (((x&0xffff0000) >> 16) | ((x&0xffff) << 16))

long getlong(f)
     int f;

{  short *d;
   long l;
   int stat;


   d = (short *)(&l);
   
   stat = read(f, d, 4);
   if (stat < 4) return 0;
   d[1] = swapbytes(d[1]);
   d[0] = swapbytes(d[0]);
   
   l = swapwords(l);
   return l;
}
#define FONTPACKETLEN 128

#define min(x,y) ((x > y)? (y) : (x))



int xferfontpacket(ps, f, pktbuff)
        int ps, f;
        char *pktbuff;
        
{
  char recog = 0;
  char type = 0;
  long len  = 0L;
  long togo = 0L;
  int stat = -1;
  int i;
  char *data = NULL;
  char *dp   = NULL;
  char hexdata[FONTPACKETLEN*2];
  char *hp = hexdata;

     
    stat = ioctl(ps, PSWRITEPACKET, 0);
    if (stat < 0) {
        fprintf(stderr, "ldfnt: could not ioctl ps device\n");
        exit(2);
    }
    stat = read(f, &recog, 1);
    if (stat < 0) {
        fprintf(stderr, "ldfnt: problem reading font file\n");
        exit(2);
    }
    if (recog != 0x80) {
        return -2;
    }

    stat = read(f, &type, 1);
    if (stat < 0) {
        fprintf(stderr, "ldfnt: problem reading font file\n");
        exit(2);
    }
    if (type == 3) {
        return 0;
    }
    len  = getlong(f);
    if (DEBUG) {
        fprintf(stderr, "len =%x, %d\n", len, len);
    }
    if (len > 65536) {
        fprintf(stderr, "ldfnt: silly packet length = %d\n", len);
        exit(2);
    }
    data = (char *)malloc(len);
    stat = read(f, data, len);
    if (stat < 0) {
        fprintf(stderr, "ldfnt: problem reading font packet\n");
        exit(2);
    }


    if (type == 1) {
        if (DEBUG) {
            printf("type 1\n");
        }
        for (dp = data, togo = len;
                 togo > 0;
                 dp += min(togo, FONTPACKETLEN),
                 togo -= min(togo, FONTPACKETLEN)) {
            buildpacket(min(togo, FONTPACKETLEN), 0, dp, pktbuff);
            write(ps, pktbuff, (min(togo, FONTPACKETLEN))+4); 
        }
    }
    else if (type == 2) {  char c1,c2;
        if (DEBUG) {
            printf("type 2\n");
        }
        for( dp = data, togo = len;
             togo > 0;
             togo -= min(togo, FONTPACKETLEN)) {
            for (hp = hexdata, i = 0; i < min(togo,FONTPACKETLEN); i+=2, hp+=4){
                c1 = *dp++;
                c2 = *dp++;
                sprintf(hp, "%02x%02x", c1, c2);
            }

            buildpacket(min(togo*2,FONTPACKETLEN*2), 0, hexdata, pktbuff);
            write(ps, pktbuff, min((togo*2)+4,(FONTPACKETLEN*2)+4));
        }
    }
    else if (type == 3) {
        if (DEBUG) {
            printf("type 3\n");
        }
      /*
        buildpacket(0, 1, hexdata, pktbuff);
        write(ps, pktbuff, 4); 
       */
    }

    return stat;
}





