prout

smaller "lp" command
git clone git://git.2f30.org/prout
Log | Files | Refs | README | LICENSE

commit b659be70acb5fba540b32585a5962215c711830f
parent b4ca05b74cf6942aa9371d53917c872d2b8b6d8c
Author: Willy Goiffon <w.goiffon@gmail.com>
Date:   Tue, 15 Oct 2013 10:51:53 +0200

Make basic checks, send a new job to the printer and block until it is completed

Diffstat:
Msrc/pp.c | 160++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 147 insertions(+), 13 deletions(-)

diff --git a/src/pp.c b/src/pp.c @@ -16,21 +16,155 @@ */ #include <stdio.h> +#include <stdbool.h> #include <cups/cups.h> +/* Return the file name if the file is opennable. exit instead */ +static char* check_file(char *file) +{ + + FILE *f; + + /* Try to open the given file */ + f = fopen(file, "r"); + + if (!f) { + fputs("Cannot open the given file", stderr); + exit (1); + } + + /* Don't let the file close longer */ + fclose(f); + + return file; +} + +/* Return a pointer to the destion if reachable. exit instead */ +static cups_dest_t* check_dest() +{ + int num_dests; + cups_dest_t *dests, *dest; + + /* Get the number of destionation configured */ + num_dests = cupsGetDests(&dests); + + /* Leave if there is no default printer configured */ + if (num_dests < 1) { + fputs("No default printer configured", stderr); + exit (1); + } + + /* Get the default destination from all dests */ + dest = cupsGetDest(NULL, NULL, 1, dests); + + /* No need to go on if we can't reach the printer */ + if (!dest) { + fputs("Cannot get a pointer to the default destination", stderr); + exit (1); + } + + return (dest); +} + +/* Return the job id of the printed file */ +static int print(const char* file, cups_dest_t *dest) +{ + int job_id = -1; + + /* Create a new job to print the document */ + job_id = cupsPrintFile (dest->name, file, "pp file", 0, NULL); + + fprintf(stdout, "printing %s (%d) to %s.\n", file, job_id, dest->name); + + return job_id; +} + +/* Blocking function. Wait util the job is completed, or an error is thrown */ +static void check_job (cups_dest_t *dest, int job_id) +{ + int i, num_jobs; + + cups_job_t *jobs; + + ipp_jstate_t state = IPP_JOB_PENDING; + + fputs("Current state of the job:\n", stdout); + + while (state < IPP_JOB_STOPPED) { + /* GET ALL THE JOBS "\_(°D°)/ */ + num_jobs = cupsGetJobs(&jobs, dest->name, 1, CUPS_WHICHJOBS_ALL); + + /* Find MY job id */ + for (i = 0; i < num_jobs; i++) { + if (jobs[i].id == job_id) { + state = jobs[i].state; + break; + } + } + + /* Free the job array */ + cupsFreeJobs(num_jobs, jobs); + + switch (state) { + case IPP_JOB_PENDING : + fprintf(stdout, "\rjob %d pending.", job_id); + break; + case IPP_JOB_HELD : + fprintf(stdout, "\rjob %d held.", job_id); + break; + case IPP_JOB_PROCESSING : + fprintf(stdout, "\rjob %d processing.", job_id); + break; + case IPP_JOB_STOPPED : + fprintf(stdout, "\rjob %d stopped.", job_id); + break; + case IPP_JOB_CANCELED : + fprintf(stdout, "\rjob %d canceled.", job_id); + break; + case IPP_JOB_ABORTED : + fprintf(stdout, "\rjob %d aborted.", job_id); + break; + case IPP_JOB_COMPLETED : + fprintf(stdout, "\rjob %d completed.\n", job_id); + break; + } + + /* Actually print text to stdout */ + fflush(stdout); + + /* Wait just a second if the job is not finished */ + if (state < IPP_JOB_STOPPED) { + sleep(1); + } + } + + return; +} + int main(int argc, char **argv) { - int i; - cups_dest_t *dests, *dest; - int num_dests = cupsGetDests(&dests); - - for (i = num_dests, dest = dests; i > 0; i --, dest ++) - { - if (dest->instance) - printf("%s/%s\n", dest->name, dest->instance); - else - puts(dest->name); - } - - return (0); + int job_id = -1; + + cups_dest_t *dest; + + char *file; + + /* check the input file */ + if (argc != 2 ) { + fputs("I can only handle one file at a time", stderr); + } + + /* check if the file is correct */ + file = check_file(argv[1]); + + /* Is the default printer set up ? Can we use it ? */ + dest = check_dest(); + + /* Well, let's print the file then */ + job_id = print(file, dest); + + /* How is the printing going ? */ + check_job(dest, job_id); + + return (0); }