[KLUG Members] Need C Help

members@kalamazoolinux.org members@kalamazoolinux.org
Thu, 1 Aug 2002 09:31:25 -0400


My ultimate need is to write a service provider whereby I can control an LPRng
print server via XML-RPC calls.  But initially I'm just trying to write a little
utility that can communicate with the lpd daemon on the local host.  According
to the specs, with lprng,  I can send a "\006{printername} {agentname}
{key/commands} {option}" string to the server and then get some kind of response
back.  But my little utility does -

[root@lnx01688 tmp]# ./xmllpcd actps adam stop
Printer Name: actps
Agent Name: adam
Printer Command:  stop

[root@lnx01688 tmp]#

And queue actps is not effected.  It should write to stdout and feedback it gets.

Maybe someone with better C skills than me could take a look and see if I am
gubbering up the communications somehow -


#include <stdio.h>
#include <string.h>
#include <time.h>
#define closesocket close
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define TBUF_LEN 1024

void main(argc, argv)
int argc;
char *argv[];
{
	int sockfd;
	int file_size;
	struct sockaddr_in lpdhost_addr, my_addr;
	int lpd_serv_tcp_port = 515;
	int my_addr_lpd_client_tcp_port = 721;
	unsigned long inaddr = 0;
	FILE *fp;

	struct hostent *hp;
	struct linger linger;

	struct timeval timeout;
	fd_set writefds, readfds;

	int i, slen, iarg;
	int daemon_command = -1;
	int job_subcommand = -1;
	char tbuf[TBUF_LEN], file_name[TBUF_LEN];
	char lpdhost[TBUF_LEN], printer_name[TBUF_LEN], agent_name[TBUF_LEN];
	void *printer_command;
	int totresplen = 0, resplen = 0;
	int time_out = 8;
	
	if (argc < 4) {
		fprintf(stderr, "Usage: {Printer Name} {Agent} {Command. . .}\n");
		exit(1);
 	}
    lpdhost[0] = '\0';
	strncpy(lpdhost, "127.0.0.1", sizeof(lpdhost));
    printer_name[0] = '\0';
	strncpy(printer_name, argv[1], sizeof(printer_name));
    agent_name[0] = '\0';
	strncpy(agent_name, argv[2], sizeof(agent_name));
    i = 3;
    printer_command = (void*) malloc(TBUF_LEN);
    while ( i < argc ) {
      sprintf(printer_command, "%s %s", printer_command, argv[i]);
      i++;
     }

    printf("Printer Name: %s\n", printer_name);
    printf("Agent Name: %s\n", agent_name);
    printf("Printer Command: %s\n", printer_command);
    
    memset((char *) &lpdhost_addr, 0, sizeof(lpdhost_addr));
    lpdhost_addr.sin_family      = AF_INET;
    lpdhost_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    lpdhost_addr.sin_port        = htons((u_short) lpd_serv_tcp_port);


    memcpy((char *) &lpdhost_addr.sin_addr, (char *) &inaddr, sizeof(inaddr));

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      fprintf(stderr, "%s: can't open stream socket\n", argv[0]);
      exit(1);
     }

    linger.l_onoff = 1;
    linger.l_linger = 0;
    if (setsockopt (sockfd, SOL_SOCKET, SO_LINGER, (char *) &linger,
sizeof(linger)) != 0)
      fprintf(stderr, "%s: failed to set socket option\n", argv[0]);

    memset((char *) &my_addr, 0, sizeof(my_addr));
    my_addr.sin_family      = AF_INET;
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    my_addr.sin_port        = htons((u_short) my_addr_lpd_client_tcp_port);
    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) {
      fprintf(stderr, "%s: can't bind local address\n", argv[0]);
      exit(1);
     }

    if (connect(sockfd, (struct sockaddr *) &lpdhost_addr, sizeof(lpdhost_addr))
< 0) {
      fprintf(stderr, "%s: can't connect to server\n", argv[0]);
      exit(1);
     }

    timeout.tv_sec = time_out;
    timeout.tv_usec = 0;


    FD_ZERO(&writefds);		
    FD_SET(sockfd, &writefds);
    FD_ZERO(&readfds);
    FD_SET(sockfd, &readfds);

    sprintf(tbuf, "\006%s %s%s", printer_name, agent_name, printer_command);
		
    /* Send a daemon command telegram */
    if (select(32, NULL, &writefds, NULL, &timeout) == 1)
    send(sockfd, tbuf, strlen(tbuf), 0);
		
    while (select(32, &readfds, NULL, NULL, &timeout) == 1 &&
      (resplen = recv(sockfd, tbuf, sizeof(tbuf)-1, 0)) > 0) {
      tbuf[resplen] = '\0';
      fprintf(stdout, "%s", tbuf);
     }
    fprintf(stdout, "\n");		

    closesocket(sockfd);

}