This is the mail archive of the cygwin@sources.redhat.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Providing a working "lp" in cygwin?


FWIW, I've attached the "C" source to a very simple lpr filter I wrote a year
or more ago. I use it with Emacs, enscript, groff, et. al. Use it as you see
fit.

Rick
--
Rick Rankin
rick_rankin@yahoo.com


--- "David M. Karr" <dkarr@tcsi.com> wrote:
> Is there any implementation of a reasonably fully-functional "lp" in
> Cygwin?  I can write a script wrapper on "print", but that apparently
> doesn't deal with acting as a filter, at least not without more
> unobvious work.
> 
> -- 
>
===============================================================================
> David M. Karr     ; dkarr@tcsi.com  ; w:(425)487-8312 ; TCSI & Best
> Consulting
> Software Engineer ; Unix/Java/C++/X ; BrainBench CJ12P (6/12/2000)
> 
> 
> --
> Want to unsubscribe from this list?
> Send a message to cygwin-unsubscribe@sourceware.cygnus.com
> 


__________________________________________________
Do You Yahoo!?
Get Yahoo! Mail – Free email you can access from anywhere!
http://mail.yahoo.com/
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "getopt.h"

char *        programName     = "lpr";
char          deviceName[256] = "prn";
HANDLE        deviceHandle;
unsigned char buffer[1024];
int           bufferIndex;

int error(int sys, const char *control, ...)
{
  va_list ap;

  fprintf(stderr, "%s: ", programName);
    
  va_start(ap, control);
  vfprintf(stderr, control, ap);
  va_end(ap);

  fputc('\n', stderr);
  
  if (sys)
  {
    LPVOID msgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                  NULL, GetLastError(),
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (LPTSTR) &msgBuf, 0, NULL);
    fprintf(stderr, "%s: %s\n", programName, (char *) msgBuf);
    /* Free the buffer. */
    LocalFree(msgBuf);
  }

  return 1;
}

int flushBuf(void)
{
  int exitCode = 0;

  if (bufferIndex > 0)
  {
    DWORD written;
    if (!WritePrinter(deviceHandle, buffer, bufferIndex, &written))
      exitCode = error(1, "error writing to %s", deviceName);
    bufferIndex = 0;
  }

  return exitCode;
}

void initBuf(void)
{
  bufferIndex = 0;
}

int putBuf(unsigned char ch)
{
  int exitCode = 0;
  
  if (bufferIndex == sizeof(buffer))
    exitCode = flushBuf();
  buffer[bufferIndex++] = ch;
  
  return exitCode;
}

int lpr(FILE *inFile, LPTSTR docName)
{
  int           exitCode = 0;
  unsigned char ch;
  unsigned char lastCh = '\0';
  DOC_INFO_1    di1;

  di1.pDocName = docName;
  di1.pOutputFile = "";
  di1.pDatatype = "raw";

  if (StartDocPrinter(deviceHandle, 1, (LPBYTE) &di1) == 0)
    exitCode = error(1, "StartDocPrinter error");
  else
  {
    initBuf();
    while (exitCode == 0 && !feof(inFile))
    {
      ch = fgetc(inFile);
      if (ch == '\n' && lastCh != '\r')
        exitCode = putBuf('\r');
      exitCode = putBuf(ch);
      lastCh = ch;
    }
    flushBuf();
    if (!EndDocPrinter(deviceHandle))
      exitCode = error(1, "EndDocPrinter error");
  }
  
  return exitCode;
}

int main(int argc, char *argv[])
{
  int     optionChar;
  char *  envPtr;
  FILE *  inputFile;
  int     i;
  int     exitCode = 0;

  if ((envPtr = getenv("PRINTER")) != NULL)
  {
    strncpy(deviceName, envPtr, sizeof(deviceName));
    deviceName[sizeof(deviceName)-1] = '\0';
  }
    
  while ((optionChar = getopt(argc, argv, "hP:")) != EOF)
  {
    switch (optionChar)
    {
    case 'h':
      /* accept for compatibility */
      break;
    case 'P':
      strncpy(deviceName, optarg, sizeof(deviceName));
      deviceName[sizeof(deviceName)-1] = '\0';
      break;
    default:
      return error(0, "unknown option: '%c'", optionChar);
    }
  }

  if (!OpenPrinter(deviceName, &deviceHandle, NULL))
    exitCode = error(1, "can't open '%s' for writing", deviceName);
  else
  {
    if (optind >= argc)
      exitCode = lpr(stdin, "stdin");
    else
    {
      for (i = optind; i < argc && exitCode == 0; ++i)
      {
        if ((inputFile = fopen(argv[i], "r")) == NULL)
          exitCode = error(1, "can't open '%s' for input",argv[i]);
        else
        {
          exitCode = lpr(inputFile, argv[i]);
          fclose(inputFile);
        }
      }
    }
    if (!ClosePrinter(deviceHandle))
      exitCode = error(1, "error closing printer");
  }

  return exitCode;
}
DEBUG		=-g
CFLAGS		=$(DEBUG) -Wall
LDFLAGS		=$(DEBUG)
LDLIBS		=-lwinspool

INSTDIR		=/usr/local/bin

SRCS		=lpr.c
OBJS		=$(SRCS:.c=.o)

lpr.exe:	$(OBJS)
		$(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@

clean:
		rm -f lpr.exe *.o *~ *.bak \#*\#

install:
		cp lpr.exe $(INSTDIR)

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]