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:
M | src/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);
}