home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IBM Presents OS/2 Software Hits 1995
/
OS-2_SW_HITS_2ND_EDITION_1995.ISO
/
i17
/
lwp42n.exe
/
UNIXLPR.C
< prev
Wrap
C/C++ Source or Header
|
1994-10-05
|
4KB
|
222 lines
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/stat.h>
#include <netdb.h>
#include <netinet/in.h>
/*
A Sample LPR program for UNIX systems which currently don't support
the LPR protocol. Mainly for SYS V systems.
This is an unsupported program.
*/
char line[132];
int pfd;
#ifdef BUFSIZ
#undef BUFSIZ
#endif
#define BUFSIZ 512
/*
* Send a data file to the remote machine and spool it.
* Return positive if we should try resending.
*/
sendfile( file)
char *file;
{
register int f, i, amt;
struct stat stb;
char buf[BUFSIZ];
int sizerr, resp;
if (stat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0)
{
perror("hello");
return(-1);
}
/*
* Check to see if data file is a symbolic link. If so, it should
* still point to the same file or someone is trying to print something
* he shouldn't.
*/
(void) sprintf(buf, "\3%ld %s\n", stb.st_size, file);
amt = strlen(buf);
for (i = 0; ; i++) {
if (write(pfd, buf, amt) != amt ||
(resp = response()) < 0 || resp == '\1') {
(void) close(f);
return(-2);
} else if (resp == '\0')
break;
if (i == 0)
printf("no space on remote; waiting for queue to drain");
if (i == 10)
printf("Can't send; queue full\n");
sleep(5 * 60);
}
sizerr = 0;
for (i = 0; i < stb.st_size; i += BUFSIZ) {
amt = BUFSIZ;
if (i + amt > stb.st_size)
amt = stb.st_size - i;
if (sizerr == 0 && read(f, buf, amt) != amt)
sizerr = 1;
if (write(pfd, buf, amt) != amt) {
(void) close(f);
return(-2);
}
}
(void) close(f);
if (sizerr) {
printf("%s: changed size\n", file);
/* tell recvjob to ignore this file */
(void) write(pfd, "\1", 1);
return(-1);
}
if (write(pfd, "\0", 1) != 1 || response())
return(-2);
return(0);
}
/*
* Check to make sure there have been no errors and that both programs
* are in sync with eachother.
* Return non-zero if the connection was lost.
*/
response()
{
char resp;
if (read(pfd, &resp, 1) != 1) {
fprintf(stderr,"Connection lost to queue\n");
return(-1);
}
return(resp);
}
/*
* Create a connection to the remote printer server.
* Most of this code comes from rcmd.c.
*/
getport(rhost)
char *rhost;
{
struct hostent *hp;
struct servent *sp;
struct sockaddr_in sin;
int s, timo = 1, lport = IPPORT_RESERVED - 1;
int err;
/*
* Get the host address and port number to connect to.
*/
hp = gethostbyname(rhost);
if (hp == NULL)
{
fprintf(stderr,"unknown host %s\n", rhost);
exit(1);
}
bzero((char *)&sin, sizeof(sin));
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
sin.sin_family = hp->h_addrtype;
sin.sin_port = htons(515);
/*
* Try connecting to the server.
*/
retry:
s = socket(AF_INET,SOCK_STREAM,0);
if (s < 0)
return(-1);
if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) {
err = errno;
(void) close(s);
errno = err;
if (errno == EADDRINUSE) {
lport--;
goto retry;
}
if (errno == ECONNREFUSED && timo <= 16) {
sleep(timo);
timo *= 2;
goto retry;
}
return(-1);
}
return(s);
}
/*
* Acquire line printer or remote connection.
*/
openpr(RM,RP)
char *RM,*RP;
{
register int i, n;
int resp;
for (i = 1; ; i = i < 256 ? i << 1 : i) {
resp = -1;
pfd = getport(RM);
if (pfd >= 0) {
(void) sprintf(line, "\2%s\n", RP);
n = strlen(line);
if (write(pfd, line, n) == n &&
(resp = response()) == '\0')
break;
(void) close(pfd);
}
if (i == 1) {
if (resp < 0)
printf("waiting for %s to come up\n", RM);
else {
printf("waiting for queue to be enabled on %s\n", RM);
i = 256;
}
}
sleep(i);
}
}
main(argc,argv)
int argc;
char *argv[];
{
int i,resp;
if ( argc != 5)
{
fprintf(stderr,"Usage: unixlpr host printer username file\n");
exit(1);
}
again:
openpr(argv[1],argv[2]);
reprint:
i=sendfile(argv[4]);
switch(i)
{
case 0:
sprintf(line,"\2%d cf\n",strlen(argv[3])+strlen(argv[1])+4);
if (write(pfd, line, strlen(line)) != strlen(line) ||
(resp = response()) < 0 || resp == '\1') {
goto reprint;
} else if (resp == '\0')
{
sprintf(line,"P%s\nf%s\n\0",argv[3],argv[1]);
write(pfd,line,strlen(line)+1);
resp = response();
}
close(pfd);
exit(0);
case -1:
close(pfd);
fprintf(stderr,"Error sending file.\n");
exit(1);
case -2:
goto reprint;
}
}