2
* Copyright (c) 1998, 1999 peter memishian (meem), meem@gnu.org
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2, or (at your option)
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* $Id: rlpq.c,v 1.8 1999/05/04 01:45:24 meem Exp $
17
#include <sys/types.h>
28
#include "component.h"
36
static struct component *components[] =
45
const char *program_name;
46
const char *bsd_program_name = "lpq";
48
static struct rlpr_rlpq *rlpr_rlpq;
50
static const char *make_queue_request(const char *, char * const *);
53
main(int argc, char *argv[])
56
struct component *comp;
57
char *user_argv[] = { 0, 0 };
58
char * const *user_list = user_argv;
60
int retval = EXIT_SUCCESS;
62
program_name = argv[0];
65
setlocale(LC_ALL, "");
66
bindtextdomain(PACKAGE, LOCALEDIR);
69
if ((comp = component_init(components, argc, argv)) != 0)
70
msg(R_FATAL, 0, "component `%s': init() failed!", comp->name);
73
* if --mine is specified, then use a two-element argv[] that
74
* has the first element set to the current user
77
if (rlpr_rlpq->mine_only)
78
user_argv[0] = rlpr_rlpq->user;
80
user_list = &argv[optind];
83
* make the queue request message (which we need to make as
84
* one message because some lpd's are broken and require that
85
* they reap the message in one read(2)). then connect to
86
* the lpd, send the request and read the reply.
89
req = make_queue_request(client_get_printer(), user_list);
91
sock_fd = client_open(rlpr_rlpq->timeout);
93
msg(R_FATAL, 0, "client_open(): cannot connect to lpd");
95
if (client_command_noack(sock_fd, req, rlpr_rlpq->timeout, "queue request")
97
msg(R_FATAL, 0, "unable to send queue request to lpd");
106
* we'd like to see if there's a "no entries\n" string
107
* returned or not from the lpd. however, we want to respect
108
* timeouts retrieving this information -- ideally, we'd use
109
* copy_file() since it knows about timeouts. what to do?
110
* pipes to the rescue. we're so friggin' clever sometimes.
113
if (pipe(pipe_fd) == -1)
114
msg(R_FATAL, errno, "pipe");
116
if (copy_file(sock_fd, pipe_fd[1], rlpr_rlpq->timeout, 0, "pipe") == 0)
117
msg(R_FATAL, 0, "unable to get queue output from lpd");
119
if ((n_read = read(pipe_fd[0], buffer, sizeof buffer - 1)) == -1)
120
msg(R_FATAL, errno, "read of piped data from lpd");
122
buffer[n_read] = '\0';
123
if (strcasecmp("no entries\n", buffer) == 0)
124
retval = EXIT_FAILURE;
128
if (copy_file(sock_fd, STDOUT_FILENO, rlpr_rlpq->timeout, 0, "stdout")
130
msg(R_FATAL, 0, "unable to get queue output from lpd");
135
if ((comp = component_fini(components)) != 0)
136
msg(R_FATAL, 0, "component `%s': fini() failed!", comp->name);
142
make_queue_request(const char *printer, char * const *user_list)
144
unsigned int request_size = 3; /* "\003\n" */
148
request_size += strlen(printer);
149
for (i = 0; user_list[i] != 0; i++)
150
request_size += strlen(user_list[i]) + 1;
152
request = xmalloc(request_size);
153
sprintf(request, "%c%s", rlpr_rlpq->long_output ? SENDQL : SENDQS, printer);
155
for (i = 0; user_list[i] != 0; i++) {
156
strcat(request, " ");
157
strcat(request, user_list[i]);
160
strcat(request, "\n");
167
struct rlpr_rlpq rlpr_rlpq_tmpl = { 0 };
171
* we perform a structure copy on a zero-initialized structure
172
* instead of using memset() since memset is a raw bit-oriented
173
* function, which means that it will generate potentially
174
* incorrect results with non-integer types.
177
rlpr_rlpq = xmalloc(sizeof (struct rlpr_rlpq));
178
*rlpr_rlpq = rlpr_rlpq_tmpl;
179
pwd = getpwuid(getuid());
181
if (pwd == 0 || pwd->pw_name == 0) {
182
msg(R_ERROR, errno, "unable to resolve your username");
186
rlpr_rlpq->timeout = R_TIMEOUT_DEFAULT;
187
rlpr_rlpq->user = xstrdup(pwd->pw_name);
192
rlpq_parse_args(int opt)
197
rlpr_rlpq->long_output++;
201
rlpr_rlpq->mine_only++;
205
msg(R_STDOUT, 0, "usage: %s [-Hprinthost] [-Pprinter] [-Xproxy]"
206
" [OPTIONS]\nplease see the manpage for detailed help",
212
rlpr_rlpq->timeout = strtol(optarg, 0, 0);
216
msg(R_STDOUT, 0, "version "VERSION" from " __DATE__" "__TIME__
228
static struct option rlpq_opts[] = {
229
{ "help", 0, 0, -500 },
230
{ "long", 0, 0, 'l' },
231
{ "mine", 0, 0, 'm' },
232
{ "timeout", 1, 0, -501 },
233
{ "version", 0, 0, 'V' },
237
static const char rlpq_opt_list[] = "lmV";
239
struct component comp_rlpq = {
240
"rlpq", rlpq_init, 0,
241
{ { rlpq_opts, rlpq_opt_list, rlpq_parse_args } }