prout.c (4100B)
1 /* 2 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 3 * Version 2, December 2004 4 * 5 * Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> 6 * 7 * Everyone is permitted to copy and distribute verbatim or modified 8 * copies of this license document, and changing it is allowed as long 9 * as the name is changed. 10 * 11 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 12 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 * 14 * 0. You just DO WHAT THE FUCK YOU WANT TO. 15 * 16 */ 17 18 #include <stdio.h> 19 #include <stdbool.h> 20 #include <cups/cups.h> 21 22 /* Usage function */ 23 static void 24 usage() 25 { 26 printf("usage: prout [-h] <file>\n"); 27 } 28 29 /* Return the file name if the file is opennable otherwise exit */ 30 static char* 31 check_file(char *file) 32 { 33 FILE *f; 34 35 /* Try to open given file */ 36 f = fopen(file, "r"); 37 38 if (!f) { 39 fprintf(stderr, "Cannot open the given file\n"); 40 exit(1); 41 } 42 43 /* Close file again */ 44 fclose(f); 45 46 return file; 47 } 48 49 /* Return a pointer to the destination if reachable otherwise exit */ 50 static 51 cups_dest_t* check_dest() 52 { 53 int num_dests; 54 cups_dest_t *dests, *dest; 55 56 /* Get the number of destination configured */ 57 num_dests = cupsGetDests(&dests); 58 59 /* Exit if there is no default printer configured */ 60 if (num_dests < 1) { 61 fprintf(stderr, "No default printer configured\n"); 62 exit(1); 63 } 64 65 /* Get the default destination from all destinations */ 66 dest = cupsGetDest(NULL, NULL, 1, dests); 67 68 /* No need to go on if we can't reach the printer */ 69 if (!dest) { 70 fprintf(stderr, "Cannot get a pointer to the default destination"); 71 exit(1); 72 } 73 74 return (dest); 75 } 76 77 /* Return the printed file's job ID */ 78 static int 79 print(const char* file, cups_dest_t *dest) 80 { 81 int job_id = -1; 82 83 /* Create a new job to print the document */ 84 job_id = cupsPrintFile (dest->name, file, "pp file", 0, NULL); 85 86 fprintf(stdout, "printing %s (%d) to %s.\n", file, job_id, dest->name); 87 88 return job_id; 89 } 90 91 /* Blocking function: Wait util the job is completed, or an error is thrown */ 92 static void 93 check_job(cups_dest_t *dest, int job_id) 94 { 95 int i, num_jobs; 96 97 cups_job_t *jobs; 98 99 ipp_jstate_t state = IPP_JOB_PENDING; 100 101 /* get total number of jobs */ 102 num_jobs = cupsGetJobs(&jobs, dest->name, 1, CUPS_WHICHJOBS_ALL); 103 104 /* Find my job ID */ 105 for (i = 0; i < num_jobs; i++) { 106 if (jobs[i].id == job_id) { 107 state = jobs[i].state; 108 break; 109 } 110 } 111 112 /* Free the job array */ 113 cupsFreeJobs(num_jobs, jobs); 114 115 switch (state) { 116 case IPP_JOB_PENDING : 117 printf("job %d pending.\n", job_id); 118 break; 119 case IPP_JOB_HELD : 120 printf("job %d held.\n", job_id); 121 break; 122 case IPP_JOB_PROCESSING : 123 printf("job %d processing.\n", job_id); 124 break; 125 case IPP_JOB_STOPPED : 126 printf("job %d stopped.\n", job_id); 127 break; 128 case IPP_JOB_CANCELED : 129 printf("job %d canceled.\n", job_id); 130 break; 131 case IPP_JOB_ABORTED : 132 printf("job %d aborted.\n", job_id); 133 break; 134 case IPP_JOB_COMPLETED : 135 printf("job %d completed.\n", job_id); 136 break; 137 } 138 } 139 140 int 141 main(int argc, char **argv) 142 { 143 int i = 0; 144 int job_id = -1; 145 146 char *file; 147 148 cups_dest_t *dest; 149 150 /* check given arguments */ 151 if (argc < 2) { 152 usage(); 153 exit(1); 154 } 155 156 for (i = 1; (i < argc) && (argv[i][0] == '-'); i++) { 157 switch (argv[i][1]) { 158 case 'h': 159 usage(); 160 exit(0); 161 default: 162 usage(); 163 exit(1); 164 } 165 } 166 167 /* check whether the file is correct */ 168 file = check_file(argv[1]); 169 170 /* is the default printer set up? Can we use it? */ 171 dest = check_dest(); 172 173 /* print the file */ 174 job_id = print(file, dest); 175 176 /* did it print successfully? */ 177 check_job(dest, job_id); 178 179 return 0; 180 }