root/source3/printing/tests/vlp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usage
  2. get_job_list
  3. set_job_list
  4. next_jobnum
  5. set_printer_status
  6. get_printer_status
  7. lpq_command
  8. lprm_command
  9. print_command
  10. queuepause_command
  11. queueresume_command
  12. lppause_command
  13. lpresume_command
  14. main

   1 /* 
   2    Unix SMB/Netbios implementation.
   3 
   4    Virtual lp system for printer testing
   5 
   6    Copyright (C) Tim Potter 2000
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 
  24 #define PRINT_FIRSTJOB "100"
  25 
  26 static TDB_CONTEXT *tdb;
  27 
  28 struct vlp_job {
  29         fstring owner;
  30         int jobid;
  31         fstring jobname;
  32         int size;
  33         int status;
  34         time_t submit_time;
  35         int deleted;
  36 };
  37 
  38 /* Print usage */
  39 
  40 static void usage(void)
     /* [<][>][^][v][top][bottom][index][help] */
  41 {
  42         printf("Usage: vlp tdbfile=/tmp/vlp.tdb lpq|lprm|print|queuepause|queueresume|"
  43                "lppause|lpresume [args]\n");
  44 }
  45 
  46 /* Return an array of vlp jobs that is the printer queue */
  47 
  48 static void get_job_list(char *printer, struct vlp_job **job_list, 
     /* [<][>][^][v][top][bottom][index][help] */
  49                          int *num_jobs)
  50 {
  51         fstring keystr;
  52         TDB_DATA data;
  53 
  54         slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
  55         data = tdb_fetch_bystring(tdb, keystr);
  56 
  57         *job_list = (struct vlp_job *)data.dptr;
  58         *num_jobs = data.dsize / sizeof(struct vlp_job);
  59 }
  60 
  61 /* Store an array of vl jobs for the queue */
  62 
  63 static void set_job_list(char *printer, struct vlp_job *job_list, 
     /* [<][>][^][v][top][bottom][index][help] */
  64                          int num_jobs)
  65 {
  66         fstring keystr;
  67         TDB_DATA data;
  68 
  69         slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
  70 
  71         data.dptr = (unsigned char *)job_list;
  72         data.dsize = num_jobs * sizeof(struct vlp_job);
  73         tdb_store_bystring(tdb, keystr, data, TDB_REPLACE);
  74 }
  75 
  76 /* Return the next job number for a printer */
  77 
  78 static int next_jobnum(char *printer)
     /* [<][>][^][v][top][bottom][index][help] */
  79 {
  80         fstring keystr;
  81         int jobnum;
  82 
  83         slprintf(keystr, sizeof(keystr) - 1, "JOBNUM/%s", printer);
  84 
  85         tdb_lock_bystring(tdb, keystr);
  86 
  87         jobnum = tdb_fetch_int32(tdb, keystr);
  88 
  89         /* Create next job index if none exists */
  90 
  91         if (jobnum == -1) {
  92                 jobnum = atoi(PRINT_FIRSTJOB);
  93         }
  94 
  95         jobnum++;
  96         tdb_store_int32(tdb, keystr, jobnum);
  97 
  98         tdb_unlock_bystring(tdb, keystr);
  99 
 100         return jobnum;
 101 }
 102 
 103 static void set_printer_status(char *printer, int status)
     /* [<][>][^][v][top][bottom][index][help] */
 104 {
 105         fstring keystr;
 106         int result;
 107 
 108         slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
 109         result = tdb_store_int32(tdb, keystr, status);
 110 }
 111 
 112 static int get_printer_status(char *printer)
     /* [<][>][^][v][top][bottom][index][help] */
 113 {
 114         fstring keystr;
 115         TDB_DATA data;
 116 
 117         slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
 118 
 119         data.dptr = (unsigned char *)keystr;
 120         data.dsize = strlen(keystr) + 1;
 121 
 122         if (!tdb_exists(tdb, data)) {
 123                 set_printer_status(printer, LPSTAT_OK);
 124                 return LPSTAT_OK;
 125         }
 126 
 127         return tdb_fetch_int32(tdb, keystr);
 128 }
 129 
 130 /* Display printer queue */
 131 
 132 static int lpq_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 133 {
 134         char *printer;
 135         struct vlp_job *job_list = NULL;
 136         int i, num_jobs, job_count = 0;
 137 
 138         if (argc != 2) {
 139                 printf("Usage: lpq <printername>\n");
 140                 return 1;
 141         }
 142 
 143         printer = argv[1];
 144 
 145         /* Display printer status */
 146 
 147         switch (get_printer_status(printer)) {
 148         case LPSTAT_OK:
 149                 printf("enabled\n");
 150                 break;
 151         case LPSTAT_STOPPED:
 152                 printf("disabled\n");
 153                 break;
 154         case LPSTAT_ERROR:
 155         default:
 156                 printf("error\n");
 157                 break;
 158         }
 159 
 160         /* Print queued documents */
 161 
 162         get_job_list(printer, &job_list, &num_jobs);
 163 
 164         for (i = 0; i < num_jobs; i++) {
 165                 if (job_list[i].deleted) continue;
 166                 printf("%d\t%d\t%d\t%ld\t%s\t%s\n", job_list[i].jobid,
 167                        job_list[i].size, 
 168                        (i == 0 && job_list[i].status == LPQ_QUEUED) ? 
 169                        LPQ_SPOOLING : job_list[i].status,
 170                        (long int)job_list[i].submit_time, job_list[i].owner, 
 171                        job_list[i].jobname);
 172                 job_count++;
 173         }
 174 
 175         free(job_list);
 176 
 177         return 0;
 178 }
 179 
 180 /* Remove a job */
 181 
 182 static int lprm_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 183 {
 184         char *printer;
 185         int jobid, num_jobs, i;
 186         struct vlp_job *job_list;
 187 
 188         if (argc < 3) {
 189                 printf("Usage: lprm <printername> <jobid>\n");
 190                 return 1;
 191         }
 192 
 193         printer = argv[1];
 194         jobid = atoi(argv[2]);
 195 
 196         get_job_list(printer, &job_list, &num_jobs);
 197 
 198         for (i = 0; i < num_jobs; i++) {
 199                 if (job_list[i].jobid == jobid) {
 200                         job_list[i].deleted = 1;
 201                         set_job_list(printer, job_list, num_jobs);
 202                         break;
 203                 }
 204         }
 205 
 206         return 0;
 207 }
 208 
 209 /* print command = print-test %p %s */
 210 
 211 static int print_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 212 {
 213         char *printer;
 214         fstring keystr;
 215         struct passwd *pw;
 216         TDB_DATA value, queue;
 217         struct vlp_job job;
 218         int i;
 219 
 220         if (argc < 3) {
 221                 printf("Usage: print <printername> <jobname>\n");
 222                 return 1;
 223         }
 224 
 225         printer = argv[1];
 226 
 227         ZERO_STRUCT(job);
 228 
 229         /* Create a job record */
 230 
 231         for (i = 2; i < argc; i++) {
 232                 fstrcat(job.jobname, argv[i]);
 233                 if (i < argc - 1) {
 234                         fstrcat(job.jobname, " ");
 235                 }
 236         }
 237 
 238         if (!(pw = getpwuid(getuid()))) {
 239                 return 1;
 240         }
 241 
 242         fstrcpy(job.owner, pw->pw_name);
 243 
 244         job.jobid = next_jobnum(printer);
 245         job.size = 666;
 246         job.submit_time = time(NULL);
 247 
 248         /* Store job entry in queue */
 249 
 250         slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
 251 
 252         value = tdb_fetch_bystring(tdb, keystr);
 253 
 254         if (value.dptr) {
 255 
 256                 /* Add job to end of queue */
 257 
 258                 queue.dptr = (unsigned char *)SMB_MALLOC(value.dsize +
 259                                                         sizeof(struct vlp_job));
 260                 if (!queue.dptr) return 1;
 261 
 262                 memcpy(queue.dptr, value.dptr, value.dsize);
 263                 memcpy(queue.dptr + value.dsize, &job, sizeof(struct vlp_job));
 264 
 265                 queue.dsize = value.dsize + sizeof(struct vlp_job);
 266 
 267                 tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
 268 
 269                 free(queue.dptr);
 270 
 271         } else {
 272 
 273                 /* Create new queue */
 274                 queue.dptr = (unsigned char *)&job;
 275                 queue.dsize = sizeof(struct vlp_job);
 276 
 277                 tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
 278         }
 279 
 280         return 0;
 281 }
 282 
 283 /* Pause the queue */
 284 
 285 static int queuepause_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 286 {
 287         char *printer;
 288 
 289         if (argc != 2) {
 290                 printf("Usage: queuepause <printername>\n");
 291                 return 1;
 292         }
 293 
 294         printer = argv[1];
 295         set_printer_status(printer, LPSTAT_STOPPED);
 296 
 297         return 0;
 298 }
 299 
 300 /* Resume the queue */
 301 
 302 static int queueresume_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 303 {
 304         char *printer;
 305 
 306         if (argc != 2) {
 307                 printf("Usage: queueresume <printername>\n");
 308                 return 1;
 309         }
 310 
 311         printer = argv[1];
 312         set_printer_status(printer, LPSTAT_OK);
 313 
 314         return 0;
 315 }
 316 
 317 /* Pause a job */
 318 
 319 static int lppause_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 320 {
 321         struct vlp_job *job_list;
 322         char *printer;
 323         int jobid, num_jobs, i;
 324 
 325         if (argc != 3) {
 326                 printf("Usage: lppause <printername> <jobid>\n");
 327                 return 1;
 328         }
 329 
 330         printer = argv[1];
 331         jobid = atoi(argv[2]);
 332 
 333         get_job_list(printer, &job_list, &num_jobs);
 334 
 335         for (i = 0; i < num_jobs; i++) {
 336                 if (job_list[i].jobid == jobid) {
 337                         job_list[i].status = LPQ_PAUSED;
 338                         set_job_list(printer, job_list, num_jobs);
 339                         return 0;
 340                 }
 341         }
 342 
 343         return 1;
 344 }
 345 
 346 /* Resume a job */
 347 
 348 static int lpresume_command(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 349 {
 350         struct vlp_job *job_list;
 351         char *printer;
 352         int jobid, num_jobs, i;
 353 
 354         if (argc != 3) {
 355                 printf("Usage: lpresume <printername> <jobid>\n");
 356                 return 1;
 357         }
 358 
 359         printer = argv[1];
 360         jobid = atoi(argv[2]);
 361 
 362         get_job_list(printer, &job_list, &num_jobs);
 363 
 364         for (i = 0; i < num_jobs; i++) {
 365                 if (job_list[i].jobid == jobid) {
 366                         job_list[i].status = LPQ_QUEUED;
 367                         set_job_list(printer, job_list, num_jobs);
 368                         return 0;
 369                 }
 370         }
 371 
 372         return 1;
 373 }
 374 
 375 int main(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 376 {
 377         /* Parameter check */
 378         const char *printdb_path = NULL;
 379 
 380         if (argc < 2) {
 381                 usage();
 382                 return 1;
 383         }
 384 
 385         if (!strnequal(argv[1], "tdbfile", strlen("tdbfile"))) {
 386                 usage();
 387                 return 1;
 388         }
 389 
 390         printdb_path = get_string_param(argv[1]);
 391         if (!printdb_path) {
 392                 return 1;
 393         }
 394 
 395         if (!(tdb = tdb_open(printdb_path, 0, 0, O_RDWR | O_CREAT,
 396                              0666))) {
 397                 printf("%s: unable to open %s\n", argv[0], printdb_path);
 398                 return 1;
 399         }
 400 
 401         /* Ensure we are modes 666 */
 402 
 403         chmod(printdb_path, 0666);
 404 
 405         /* Do commands */
 406 
 407         if (strcmp(argv[2], "lpq") == 0) {
 408                 return lpq_command(argc - 2, &argv[2]);
 409         }
 410 
 411         if (strcmp(argv[2], "lprm") == 0) {
 412                 return lprm_command(argc - 2, &argv[2]);
 413         }
 414 
 415         if (strcmp(argv[2], "print") == 0) {
 416                 return print_command(argc - 2, &argv[2]);
 417         }
 418 
 419         if (strcmp(argv[2], "queuepause") == 0) {
 420                 return queuepause_command(argc - 2, &argv[2]);
 421         }
 422 
 423         if (strcmp(argv[2], "queueresume") == 0) {
 424                 return queueresume_command(argc - 2, &argv[2]);
 425         }
 426 
 427         if (strcmp(argv[2], "lppause") == 0) {
 428                 return lppause_command(argc - 2, &argv[2]);
 429         }
 430 
 431         if (strcmp(argv[2], "lpresume") == 0) {
 432                 return lpresume_command(argc - 2, &argv[2]);
 433         }
 434 
 435         /* Unknown command */
 436 
 437         printf("%s: invalid command %s\n", argv[0], argv[1]);
 438         return 1;
 439 }

/* [<][>][^][v][top][bottom][index][help] */