#include <stdio.h>
#include <stdlib.h>
#include <cups/cups.h>
#include <cups/string.h>
#include <errno.h>
int Verbosity = 0;
const char *SAMBAUser,
*SAMBAServer;
int do_samba_command(const char *, const char *);
int export_dest(const char *);
void usage();
int
main(int argc,
char *argv[])
{
int i, j;
int status;
int export_all;
int num_printers;
char **printers;
export_all = 0;
SAMBAUser = cupsUser();
SAMBAServer = NULL;
for (i = 1; i < argc; i ++)
if (strcmp(argv[i], "-a") == 0)
export_all = 1;
else if (strcmp(argv[i], "-U") == 0)
{
i ++;
if (i >= argc)
usage();
SAMBAUser = argv[i];
}
else if (strcmp(argv[i], "-H") == 0)
{
i ++;
if (i >= argc)
usage();
SAMBAServer = argv[i];
}
else if (strcmp(argv[i], "-h") == 0)
{
i ++;
if (i >= argc)
usage();
cupsSetServer(argv[i]);
}
else if (strcmp(argv[i], "-v") == 0)
Verbosity = 1;
else if (argv[i][0] != '-')
{
if (SAMBAServer == NULL)
SAMBAServer = cupsServer();
if ((status = export_dest(argv[i])) != 0)
return (status);
}
else
usage();
if (export_all)
{
if (SAMBAServer == NULL)
SAMBAServer = cupsServer();
num_printers = cupsGetPrinters(&printers);
for (j = 0, status = 0; j < num_printers; j ++)
if ((status = export_dest(printers[j])) != 0)
break;
for (j = 0; j < num_printers; j ++)
free(printers[j]);
if (num_printers)
free(printers);
if (status)
return (status);
}
return (0);
}
int
do_samba_command(const char *command,
const char *subcmd)
{
int status;
char temp[4096];
static const char *p = NULL;
for (status = 1;;)
{
if (p == NULL)
{
snprintf(temp, sizeof(temp),
"Password for %s required to access %s via SAMBA: ",
SAMBAUser, SAMBAServer);
if ((p = cupsGetPassword(temp)) == NULL)
break;
}
snprintf(temp, sizeof(temp), "%s -N -U\'%s%%%s\' -c \'%s\'",
command, SAMBAUser, p, subcmd);
if (Verbosity)
printf("Running command: %s\n", temp);
else
strlcat(temp, " </dev/null >/dev/null 2>/dev/null", sizeof(temp));
if ((status = system(temp)) != 0)
{
if (Verbosity)
puts("");
if (p[0])
p = NULL;
else
break;
}
else
{
if (Verbosity)
puts("");
break;
}
}
return (status);
}
int
export_dest(const char *dest)
{
int status;
const char *ppdfile;
char command[1024],
subcmd[1024];
const char *datadir;
if ((datadir = getenv("CUPS_DATADIR")) == NULL)
datadir = CUPS_DATADIR;
if ((ppdfile = cupsGetPPD(dest)) == NULL)
{
fprintf(stderr, "Warning: No PPD file for printer \"%s\"!\n", dest);
return (1);
}
snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
snprintf(subcmd, sizeof(subcmd),
"mkdir W32X86;"
"put %s W32X86/%s.PPD;"
"put %s/drivers/ADOBEPS5.DLL W32X86/ADOBEPS5.DLL;"
"put %s/drivers/ADOBEPSU.DLL W32X86/ADOBEPSU.DLL;"
"put %s/drivers/ADOBEPSU.HLP W32X86/ADOBEPSU.HLP",
ppdfile, dest, datadir, datadir, datadir);
if ((status = do_samba_command(command, subcmd)) != 0)
{
fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
status);
unlink(ppdfile);
return (3);
}
snprintf(subcmd, sizeof(subcmd),
"mkdir WIN40;"
"put %s WIN40/%s.PPD;"
"put %s/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;"
"put %s/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;"
"put %s/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;"
"put %s/drivers/DEFPRTR2.PPD WIN40/DEFPRTR2.PPD;"
"put %s/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;"
"put %s/drivers/PSMON.DLL WIN40/PSMON.DLL;",
ppdfile, dest, datadir, datadir, datadir,
datadir, datadir, datadir);
if ((status = do_samba_command(command, subcmd)) != 0)
{
fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
status);
unlink(ppdfile);
return (3);
}
unlink(ppdfile);
snprintf(subcmd, sizeof(subcmd),
"adddriver \"Windows NT x86\" \"%s:ADOBEPS5.DLL:%s.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL\"",
dest, dest);
snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
if ((status = do_samba_command(command, subcmd)) != 0)
{
fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
status);
return (5);
}
snprintf(subcmd, sizeof(subcmd),
"adddriver \"Windows 4.0\" \"%s:ADOBEPS4.DRV:%s.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL\"",
dest, dest);
if ((status = do_samba_command(command, subcmd)) != 0)
{
fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
status);
return (5);
}
snprintf(subcmd, sizeof(subcmd), "setdriver %s %s", dest, dest);
if ((status = do_samba_command(command, subcmd)) != 0)
{
fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
status);
return (5);
}
return (0);
}
void
usage()
{
puts("Usage: cupsaddsmb [options] printer1 ... printerN");
puts(" cupsaddsmb [options] -a");
puts("");
puts("Options:");
puts(" -H samba-server Use the named SAMBA server");
puts(" -U samba-user Authenticate using the named SAMBA user");
puts(" -a Export all printers");
puts(" -h cups-server Use the named CUPS server");
puts(" -v Be verbose (show commands)");
exit(1);
}