int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ int copies; /* Number of copies */ char uri[1024], /* URI */ *sep, /* Pointer to separator */ *password; /* Password */ const char *username, /* Username */ *server, /* Server name */ *printer; /* Printer name */ const char *workgroup; /* Workgroup */ FILE *fp; /* File to print */ int status=0; /* Status of LPD job */ struct cli_state *cli; /* SMB interface */ /* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */ if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) { argv++; argc--; } if (argc == 1) { /* * NEW! In CUPS 1.1 the backends are run with no arguments to list the * available devices. These can be devices served by this backend * or any other backends (i.e. you can have an SNMP backend that * is only used to enumerate the available network printers... :) */ list_devices(); return (0); } if (argc < 6 || argc > 7) { fprintf(stderr, "Usage: %s [DEVICE_URI] job-id user title copies options [file]\n", argv[0]); fputs(" The DEVICE_URI environment variable can also contain the\n", stderr); fputs(" destination printer:\n", stderr); fputs("\n", stderr); fputs(" smb://[username:password@][workgroup/]server/printer\n", stderr); return (1); } /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, print data from stdin... */ if (argc == 6) { /* * Print from Copy stdin to a temporary file... */ fp = stdin; copies = 1; } else if ((fp = fopen(argv[6], "rb")) == NULL) { perror("ERROR: Unable to open print file"); return (1); } else copies = atoi(argv[4]); /* * Find the URI... */ if (strncmp(argv[0], "smb://", 6) == 0) strncpy(uri, argv[0], sizeof(uri) - 1); else if (getenv("DEVICE_URI") != NULL) strncpy(uri, getenv("DEVICE_URI"), sizeof(uri) - 1); else { fputs("ERROR: No device URI found in argv[0] or DEVICE_URI environment variable!\n", stderr); return (1); } uri[sizeof(uri) - 1] = '\0'; /* * Extract the destination from the URI... */ if ((sep = strrchr_m(uri, '@')) != NULL) { username = uri + 6; *sep++ = '\0'; server = sep; /* * Extract password as needed... */ if ((password = strchr_m(username, ':')) != NULL) *password++ = '\0'; else password = ""; } else { username = ""; password = ""; server = uri + 6; } if ((sep = strchr_m(server, '/')) == NULL) { fputs("ERROR: Bad URI - need printer name!\n", stderr); return (1); } *sep++ = '\0'; printer = sep; if ((sep = strchr_m(printer, '/')) != NULL) { /* * Convert to smb://[username:password@]workgroup/server/printer... */ *sep++ = '\0'; workgroup = server; server = printer; printer = sep; } else workgroup = NULL; /* * Setup the SAMBA server state... */ setup_logging("smbspool", True); in_client = True; /* Make sure that we tell lp_load we are */ if (!lp_load(dyn_CONFIGFILE, True, False, False)) { fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); return (1); } if (workgroup == NULL) workgroup = lp_workgroup(); load_interfaces(); do { if ((cli = smb_connect(workgroup, server, printer, username, password)) == NULL) { if (getenv("CLASS") == NULL) { fprintf(stderr, "ERROR: Unable to connect to SAMBA host, will retry in 60 seconds..."); sleep (60); } else { fprintf(stderr, "ERROR: Unable to connect to SAMBA host, trying next printer..."); return (1); } } } while (cli == NULL); /* * Now that we are connected to the server, ignore SIGTERM so that we * can finish out any page data the driver sends (e.g. to eject the * current page... Only ignore SIGTERM if we are printing data from * stdin (otherwise you can't cancel raw jobs...) */ if (argc < 7) CatchSignal(SIGTERM, SIG_IGN); /* * Queue the job... */ for (i = 0; i < copies; i ++) if ((status = smb_print(cli, argv[3] /* title */, fp)) != 0) break; cli_shutdown(cli); /* * Return the queue status... */ return (status); }
int main(int argc, const char **argv) { struct tevent_context *evt_ctx; struct messaging_context *msg_ctx; struct db_context *db; uint16_t count; const char *dbname; const char *opname; dbwrap_op op; const char *keyname = ""; const char *keytype = "int32"; dbwrap_type type; const char *valuestr = "0"; int32_t value = 0; TALLOC_CTX *mem_ctx = talloc_stackframe(); int ret = 1; struct poptOption popt_options[] = { POPT_AUTOHELP POPT_COMMON_SAMBA POPT_TABLEEND }; int opt; const char **extra_argv; int extra_argc = 0; poptContext pc; load_case_tables(); lp_set_cmdline("log level", "0"); setup_logging(argv[0], DEBUG_STDERR); pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "Invalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); goto done; } } /* setup the remaining options for the main program to use */ extra_argv = poptGetArgs(pc); if (extra_argv) { extra_argv++; while (extra_argv[extra_argc]) extra_argc++; } lp_load_global(get_dyn_CONFIGFILE()); if ((extra_argc < 2) || (extra_argc > 5)) { d_fprintf(stderr, "USAGE: %s <database> <op> [<key> [<type> [<value>]]]\n" " ops: fetch, store, delete, erase, listkeys\n" " types: int32, uint32\n", argv[0]); goto done; } dbname = extra_argv[0]; opname = extra_argv[1]; if (strcmp(opname, "store") == 0) { if (extra_argc != 5) { d_fprintf(stderr, "ERROR: operation 'store' requires " "value argument\n"); goto done; } valuestr = extra_argv[4]; keytype = extra_argv[3]; keyname = extra_argv[2]; op = OP_STORE; } else if (strcmp(opname, "fetch") == 0) { if (extra_argc != 4) { d_fprintf(stderr, "ERROR: operation 'fetch' requires " "type but not value argument\n"); goto done; } op = OP_FETCH; keytype = extra_argv[3]; keyname = extra_argv[2]; } else if (strcmp(opname, "delete") == 0) { if (extra_argc != 3) { d_fprintf(stderr, "ERROR: operation 'delete' does " "not allow type nor value argument\n"); goto done; } keyname = extra_argv[2]; op = OP_DELETE; } else if (strcmp(opname, "erase") == 0) { if (extra_argc != 2) { d_fprintf(stderr, "ERROR: operation 'erase' does " "not take a key argument\n"); goto done; } op = OP_ERASE; } else if (strcmp(opname, "listkeys") == 0) { if (extra_argc != 2) { d_fprintf(stderr, "ERROR: operation 'listkeys' does " "not take a key argument\n"); goto done; } op = OP_LISTKEYS; } else { d_fprintf(stderr, "ERROR: invalid op '%s' specified\n" " supported ops: fetch, store, delete\n", opname); goto done; } if (strcmp(keytype, "int32") == 0) { type = TYPE_INT32; value = (int32_t)strtol(valuestr, NULL, 10); } else if (strcmp(keytype, "uint32") == 0) { type = TYPE_UINT32; value = (int32_t)strtoul(valuestr, NULL, 10); } else { d_fprintf(stderr, "ERROR: invalid type '%s' specified.\n" " supported types: int32, uint32\n", keytype); goto done; } evt_ctx = tevent_context_init(mem_ctx); if (evt_ctx == NULL) { d_fprintf(stderr, "ERROR: could not init event context\n"); goto done; } msg_ctx = messaging_init(mem_ctx, procid_self(), evt_ctx); if (msg_ctx == NULL) { d_fprintf(stderr, "ERROR: could not init messaging context\n"); goto done; } db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644); if (db == NULL) { d_fprintf(stderr, "ERROR: could not open dbname\n"); goto done; } for (count = 0; dispatch_table[count].cmd != NULL; count++) { if ((op == dispatch_table[count].op) && (type == dispatch_table[count].type)) { ret = dispatch_table[count].cmd(db, keyname, &value); break; } } done: TALLOC_FREE(mem_ctx); return ret; }