summaryrefslogtreecommitdiff
path: root/Build/source/texk/xdvipdfmx
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2011-03-09 05:32:47 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2011-03-09 05:32:47 +0000
commit6ccff4c232f2c867cef173c7bfc9ca79ea43a15d (patch)
tree883ba8cc1b7c7b03e0f34c38350c2a03ac03f1a1 /Build/source/texk/xdvipdfmx
parent9a2fa1807f38fb5152a81f80d49b1f06cc50d4fc (diff)
add a new special pdf:encrypt by Matthias Franz.
git-svn-id: svn://tug.org/texlive/trunk@21656 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/xdvipdfmx')
-rw-r--r--Build/source/texk/xdvipdfmx/ChangeLog.TL6
-rw-r--r--Build/source/texk/xdvipdfmx/src/dpxfile.c131
-rw-r--r--Build/source/texk/xdvipdfmx/src/dvi.c57
-rw-r--r--Build/source/texk/xdvipdfmx/src/dvi.h3
-rw-r--r--Build/source/texk/xdvipdfmx/src/dvipdfmx.c33
-rw-r--r--Build/source/texk/xdvipdfmx/src/pdfencrypt.c48
-rw-r--r--Build/source/texk/xdvipdfmx/src/pdfencrypt.h4
-rw-r--r--Build/source/texk/xdvipdfmx/src/spc_pdfm.c1
8 files changed, 235 insertions, 48 deletions
diff --git a/Build/source/texk/xdvipdfmx/ChangeLog.TL b/Build/source/texk/xdvipdfmx/ChangeLog.TL
index a688f921aa9..f083bfa8c17 100644
--- a/Build/source/texk/xdvipdfmx/ChangeLog.TL
+++ b/Build/source/texk/xdvipdfmx/ChangeLog.TL
@@ -1,6 +1,12 @@
ChangeLog.TL: TeX Live (TL) changes for xdvipdfmx
=================================================
+2011-03-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+ * src/dpxfile.c: Avoid to use system().
+ * src/dvi.c, src/dvi.h, src/dvipdfmx.c, src/pdfencript.c,
+ src/pdfencrypt.h, src/spc_pdfm.c: new special pdf:encrypt
+ by Matthias Franz.
+
2011-02-28 Peter Breitenlohner <peb@mppmu.mpg.de>
* src/pngimage.c (create_cspace_ICCBased): Avoid libpng-1.5.x
diff --git a/Build/source/texk/xdvipdfmx/src/dpxfile.c b/Build/source/texk/xdvipdfmx/src/dpxfile.c
index 8e89f207911..e7cbf85a54d 100644
--- a/Build/source/texk/xdvipdfmx/src/dpxfile.c
+++ b/Build/source/texk/xdvipdfmx/src/dpxfile.c
@@ -1,8 +1,8 @@
-/* $Header: /home/cvsroot/dvipdfmx/src/dpxfile.c,v 1.25 2009/03/12 19:29:48 matthias Exp $
+/* $Header: /home/cvsroot/dvipdfmx/src/dpxfile.c,v 1.27 2011/03/05 02:01:28 chofchof Exp $
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -35,6 +35,23 @@
#include "dpxfile.h"
+#include <kpathsea/lib.h>
+#include <string.h>
+#ifdef WIN32
+#include <io.h>
+#include <process.h>
+#else
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(val) ((unsigned)(val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(val) (((val) & 255) == 0)
+#endif
+#endif
+
static int verbose = 0;
void
@@ -135,6 +152,104 @@ miktex_find_psheader_file (const char *filename, char *buf)
static char _tmpbuf[_MAX_PATH+1];
#endif /* MIKTEX */
+static int exec_spawn (char *cmd)
+{
+ char **cmdv, **qv;
+ char *p, *pp;
+ char buf[512];
+ int i, ret;
+
+ if (!cmd || !*cmd)
+ return -1;
+ i = 0;
+ p = cmd;
+ while (*p) {
+ if (*p == ' ' || *p == '\t')
+ i++;
+ p++;
+ }
+ cmdv = (char **) xmalloc (sizeof (char *) * (i+2));
+ p = cmd;
+ qv = cmdv;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ while (*p) {
+ pp = buf;
+ if (*p == '"') {
+ p++;
+ while (*p != '"') {
+ if (*p == '\0') {
+ free (cmdv);
+ return -1;
+ }
+ *pp++ = *p++;
+ }
+ p++;
+ } else if (*p == '\'') {
+ p++;
+ while (*p != '\'') {
+ if (*p == '\0') {
+ free (cmdv);
+ return -1;
+ }
+ *pp++ = *p++;
+ }
+ p++;
+ } else {
+ while (*p != ' ' && *p != '\t' && *p)
+#ifdef WIN32
+ if (*p == '\'') {
+ *pp++ = '\"';
+ p++;
+ } else {
+ *pp++ = *p++;
+ }
+#else
+ *pp++ = *p++;
+#endif
+ }
+ *pp = '\0';
+ if ((pp = strchr (buf, ' ')) || (pp = strchr (buf, '\t'))) {
+#ifdef WIN32
+ *qv = concat3 ("\"", buf, "\"");
+#else
+ *qv = concat3 ("'", buf, "'");
+#endif
+ } else {
+ *qv = concat (buf, "");
+ }
+ while (*p == ' ' || *p == '\t')
+ p++;
+ qv++;
+ }
+ *qv = NULL;
+#ifdef WIN32
+ ret = spawnvp (_P_WAIT, *cmdv, (const char* const*) cmdv);
+#else
+ i = fork ();
+ if (i < 0)
+ ret = -1;
+ else if (i == 0) {
+ if (execvp (*cmdv, cmdv))
+ ret = -1;
+ } else {
+ if (wait (&ret) == i) {
+ ret = (WIFEXITED (ret) ? WEXITSTATUS (ret) : -1);
+ } else {
+ ret = -1;
+ }
+ }
+#endif
+ qv = cmdv;
+ if (qv) {
+ while (*qv) {
+ free (*qv);
+ qv++;
+ }
+ free (cmdv);
+ }
+ return ret;
+}
/* ensuresuffix() returns a copy of basename if sfx is "". */
static char *
@@ -695,7 +810,6 @@ dpx_delete_temp_file (char *tmp)
return;
}
-#ifdef HAVE_SYSTEM
/* dpx_file_apply_filter() is used for converting unsupported graphics
* format to one of the formats that dvipdfmx can natively handle.
* 'input' is the filename of the original file and 'output' is actually
@@ -703,6 +817,7 @@ dpx_delete_temp_file (char *tmp)
* This should be system dependent. (MiKTeX may want something different)
* Please modify as appropriate (see also pdfximage.c and dvipdfmx.c).
*/
+
int
dpx_file_apply_filter (const char *cmdtmpl,
const char *input, const char *output,
@@ -773,21 +888,13 @@ if ((l) + (n) >= (m)) { \
return -1;
}
- error = system(cmd);
+ error = exec_spawn(cmd);
if (error)
WARN("Filtering file via command -->%s<-- failed.", cmd);
RELEASE(cmd);
return error;
}
-#else
-int
-dpx_file_apply_filter (const char *cmdtmpl, const char *input, const char *output)
-{
- WARN("Your system does not have system().");
- return -1;
-}
-#endif /* HAVE_SYSTEM */
static char _sbuf[128];
/*
diff --git a/Build/source/texk/xdvipdfmx/src/dvi.c b/Build/source/texk/xdvipdfmx/src/dvi.c
index a0ab254d4f5..f6b4f8a92e7 100644
--- a/Build/source/texk/xdvipdfmx/src/dvi.c
+++ b/Build/source/texk/xdvipdfmx/src/dvi.c
@@ -45,6 +45,7 @@
#include "pdfdev.h"
#include "pdfdoc.h"
#include "pdfparse.h"
+#include "pdfencrypt.h"
#include "fontmap.h"
@@ -2490,7 +2491,10 @@ read_length (double *vp, double mag, const char **pp, const char *endptr)
static int
-scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, unsigned *minorversion, const char *buf, UNSIGNED_QUAD size)
+scan_special (double *wd, double *ht, double *xo, double *yo, char *lm,
+ unsigned *minorversion,
+ int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw,
+ const char *buf, UNSIGNED_QUAD size)
{
char *q;
const char *p = buf, *endptr;
@@ -2597,6 +2601,48 @@ scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, unsigned
*minorversion = (unsigned)strtol(kv, NULL, 10);
RELEASE(kv);
}
+ } else if (ns_pdf && !strcmp(q, "encrypt") && do_enc) {
+ *do_enc = 1;
+ *owner_pw = *user_pw = 0;
+ while (!error && p < endptr) {
+ char *kp = parse_c_ident(&p, endptr);
+ if (!kp)
+ break;
+ else {
+ pdf_obj *obj;
+ skip_white(&p, endptr);
+ if (!strcmp(kp, "ownerpw")) {
+ if ((obj = parse_pdf_string(&p, endptr))) {
+ strncpy(owner_pw, pdf_string_value(obj), MAX_PWD_LEN);
+ pdf_release_obj(obj);
+ } else
+ error = -1;
+ } else if (!strcmp(kp, "userpw")) {
+ if ((obj = parse_pdf_string(&p, endptr))) {
+ strncpy(user_pw, pdf_string_value(obj), MAX_PWD_LEN);
+ pdf_release_obj(obj);
+ } else
+ error = -1;
+ } else if (!strcmp(kp, "length")) {
+ if ((obj = parse_pdf_number(&p, endptr)) && PDF_OBJ_NUMBERTYPE(obj)) {
+ *key_bits = (unsigned) pdf_number_value(obj);
+ } else
+ error = -1;
+ if (obj)
+ pdf_release_obj(obj);
+ } else if (!strcmp(kp, "perm")) {
+ if ((obj = parse_pdf_number(&p, endptr)) && PDF_OBJ_NUMBERTYPE(obj)) {
+ *permission = (unsigned) pdf_number_value(obj);
+ } else
+ error = -1;
+ if (obj)
+ pdf_release_obj(obj);
+ } else
+ error = -1;
+ RELEASE(kp);
+ }
+ skip_white(&p, endptr);
+ }
}
RELEASE(q);
}
@@ -2609,7 +2655,8 @@ void
dvi_scan_specials (long page_no,
double *page_width, double *page_height,
double *x_offset, double *y_offset, char *landscape,
- unsigned *minorversion)
+ unsigned *minorversion,
+ int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw)
{
FILE *fp = dvi_file;
long offset;
@@ -2649,8 +2696,10 @@ dvi_scan_specials (long page_no,
}
if (fread(dvi_page_buffer + dvi_page_buf_index, sizeof(char), size, fp) != size)
ERROR("Reading DVI file failed!");
- scan_special(page_width, page_height, x_offset, y_offset, landscape, minorversion,
- (char*)dvi_page_buffer + dvi_page_buf_index, size);
+ if (scan_special(page_width, page_height, x_offset, y_offset, landscape, minorversion,
+ do_enc, key_bits, permission, owner_pw, user_pw,
+ (char*)dvi_page_buffer + dvi_page_buf_index, size))
+ WARN("Reading special command failed: \"%.*s\"", size, (char*)dvi_page_buffer + dvi_page_buf_index);
dvi_page_buf_index += size;
continue;
}
diff --git a/Build/source/texk/xdvipdfmx/src/dvi.h b/Build/source/texk/xdvipdfmx/src/dvi.h
index d4a87a2a79b..396d9b8f0f1 100644
--- a/Build/source/texk/xdvipdfmx/src/dvi.h
+++ b/Build/source/texk/xdvipdfmx/src/dvi.h
@@ -73,7 +73,8 @@ extern void dvi_do_page (long page_no,
extern void dvi_scan_specials (long page_no,
double *width, double *height,
double *x_offset, double *y_offset,
- char *landscape, unsigned *minorversion);
+ char *landscape, unsigned *minorversion,
+ int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw);
extern int dvi_locate_font (const char *name, spt_t ptsize);
/* link or nolink:
diff --git a/Build/source/texk/xdvipdfmx/src/dvipdfmx.c b/Build/source/texk/xdvipdfmx/src/dvipdfmx.c
index 5e7e8c8abaf..6e0431b7791 100644
--- a/Build/source/texk/xdvipdfmx/src/dvipdfmx.c
+++ b/Build/source/texk/xdvipdfmx/src/dvipdfmx.c
@@ -140,7 +140,7 @@ usage (int exit_code)
fprintf (stdout, "\nThis is %s-%s by Jonathan Kew and Jin-Hwan Cho,\n", PACKAGE, VERSION);
fprintf (stdout, "an extended version of DVIPDFMx, which in turn was\n");
fprintf (stdout, "an extended version of dvipdfm-0.13.2c developed by Mark A. Wicks.\n");
- fprintf (stdout, "\nCopyright (c) 2006-2008 SIL International and Jin-Hwan Cho.\n");
+ fprintf (stdout, "\nCopyright (c) 2006-2011 SIL International and Jin-Hwan Cho.\n");
fprintf (stdout, "\nThis is free software; you can redistribute it and/or modify\n");
fprintf (stdout, "it under the terms of the GNU General Public License as published by\n");
fprintf (stdout, "the Free Software Foundation; either version 2 of the License, or\n");
@@ -175,7 +175,7 @@ usage (int exit_code)
fprintf (stdout, "\t\tAnd negative values replace old values.\n");
fprintf (stdout, "-D template\tPS->PDF conversion command line template [none]\n");
fprintf (stdout, "-E \t\tAlways try to embed fonts, regardless of licensing flags.\n");
- fprintf (stdout, "-K number\tEncryption key bits [40]\n");
+ fprintf (stdout, "-K number\tEncryption key length [40]\n");
fprintf (stdout, "-O number\tSet maximum depth of open bookmark items [0]\n");
fprintf (stdout, "-P number\tSet permission flags for PDF encryption [0x003C]\n");
fprintf (stdout, "-S \t\tEnable PDF encryption\n");
@@ -511,10 +511,10 @@ do_args (int argc, char *argv[])
do_encryption = 1;
break;
case 'K':
- CHECK_ARG(1, "encryption key bits");
+ CHECK_ARG(1, "encryption key length");
key_bits = (unsigned) atoi(argv[1]);
- if (key_bits < 40 || key_bits > 128)
- ERROR("Invalid encryption key bits specified: %s", argv[1]);
+ if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7))
+ ERROR("Invalid encryption key length specified: %s", argv[1]);
POP_ARG();
break;
case 'P':
@@ -708,7 +708,7 @@ do_dvi_pages (void)
page_width = paper_width; page_height = paper_height;
w = page_width; h = page_height; lm = landscape_mode;
xo = x_offset; yo = y_offset;
- dvi_scan_specials(page_no, &w, &h, &xo, &yo, &lm, NULL);
+ dvi_scan_specials(page_no, &w, &h, &xo, &yo, &lm, NULL, NULL, NULL, NULL, NULL, NULL);
if (lm != landscape_mode) {
SWAP(w, h);
landscape_mode = lm;
@@ -859,7 +859,7 @@ main (int argc, char *argv[])
set_default_pdf_filename();
if (do_encryption) {
- pdf_enc_set_passwd(key_bits, permission, dvi_filename, pdf_filename);
+ pdf_enc_set_passwd(key_bits, permission, NULL, NULL);
if (key_bits > 40 && pdf_get_version() < 4)
pdf_set_version(4);
}
@@ -870,6 +870,7 @@ main (int argc, char *argv[])
dvi2pts = 0.01; /* dvi2pts controls accuracy. */
} else {
unsigned ver_minor = 0;
+ char owner_pw[MAX_PWD_LEN], user_pw[MAX_PWD_LEN];
/* Dependency between DVI and PDF side is rather complicated... */
dvi2pts = dvi_init(dvi_filename, mag);
if (dvi2pts == 0.0)
@@ -877,7 +878,23 @@ main (int argc, char *argv[])
pdf_doc_set_creator(dvi_comment());
- dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, &ver_minor);
+ if (do_encryption)
+ /* command line takes precedence */
+ dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode,
+ &ver_minor, NULL, NULL, NULL, NULL, NULL);
+ else {
+ dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode,
+ &ver_minor, &do_encryption, &key_bits, &permission, owner_pw, user_pw);
+ if (do_encryption) {
+ if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7))
+ ERROR("Invalid encryption key length specified: %u", key_bits);
+ else if (key_bits > 40 && pdf_get_version() < 4)
+ ERROR("Chosen key length requires at least PDF 1.4. "
+ "Use \"-V 4\" to change.");
+ do_encryption = 1;
+ pdf_enc_set_passwd(key_bits, permission, owner_pw, user_pw);
+ }
+ }
if (ver_minor >= PDF_VERSION_MIN && ver_minor <= PDF_VERSION_MAX) {
pdf_set_version(ver_minor);
}
diff --git a/Build/source/texk/xdvipdfmx/src/pdfencrypt.c b/Build/source/texk/xdvipdfmx/src/pdfencrypt.c
index d90c77c23e2..8edf21acb06 100644
--- a/Build/source/texk/xdvipdfmx/src/pdfencrypt.c
+++ b/Build/source/texk/xdvipdfmx/src/pdfencrypt.c
@@ -46,7 +46,6 @@
#define MAX_KEY_LEN 16
#define MAX_STR_LEN 32
-#define MAX_PWD_LEN 128
static unsigned char algorithm, revision, key_size;
static unsigned long permission;
@@ -365,27 +364,33 @@ static char *getpass (const char *prompt)
}
#endif
-void pdf_enc_set_passwd (unsigned bits, unsigned perm, char *dviname, char *pdfname)
+void pdf_enc_set_passwd (unsigned bits, unsigned perm, const char *owner_pw, const char *user_pw)
{
- register char *retry_passwd;
-
- while (1) {
- strcpy(owner_passwd, getpass("Owner password: "));
- retry_passwd = getpass("Re-enter owner password: ");
- if (!strcmp(owner_passwd, retry_passwd))
- break;
- fputs("Password is not identical.\nTry again.\n", stderr);
- fflush(stderr);
- }
-
- while (1) {
- strcpy(user_passwd, getpass("User password: "));
- retry_passwd = getpass("Re-enter user password: ");
- if (!strcmp(user_passwd, retry_passwd))
- break;
- fputs("Password is not identical.\nTry again.\n", stderr);
- fflush(stderr);
- }
+ char *retry_passwd;
+
+ if (owner_pw) {
+ strncpy(owner_passwd, owner_pw, MAX_PWD_LEN);
+ } else
+ while (1) {
+ strncpy(owner_passwd, getpass("Owner password: "), MAX_PWD_LEN);
+ retry_passwd = getpass("Re-enter owner password: ");
+ if (!strncmp(owner_passwd, retry_passwd, MAX_PWD_LEN))
+ break;
+ fputs("Password is not identical.\nTry again.\n", stderr);
+ fflush(stderr);
+ }
+
+ if (user_pw) {
+ strncpy(user_passwd, user_pw, MAX_PWD_LEN);
+ } else
+ while (1) {
+ strncpy(user_passwd, getpass("User password: "), MAX_PWD_LEN);
+ retry_passwd = getpass("Re-enter user password: ");
+ if (!strncmp(user_passwd, retry_passwd, MAX_PWD_LEN))
+ break;
+ fputs("Password is not identical.\nTry again.\n", stderr);
+ fflush(stderr);
+ }
key_size = (unsigned char)(bits / 8);
algorithm = (key_size == 5 ? 1 : 2);
@@ -394,7 +399,6 @@ void pdf_enc_set_passwd (unsigned bits, unsigned perm, char *dviname, char *pdfn
if (revision == 3)
permission |= 0xFFFFF000;
- compute_id_string(dviname, pdfname);
compute_owner_password();
compute_user_password();
}
diff --git a/Build/source/texk/xdvipdfmx/src/pdfencrypt.h b/Build/source/texk/xdvipdfmx/src/pdfencrypt.h
index 4735d89d976..8b4d536b323 100644
--- a/Build/source/texk/xdvipdfmx/src/pdfencrypt.h
+++ b/Build/source/texk/xdvipdfmx/src/pdfencrypt.h
@@ -25,11 +25,13 @@
#include "pdfobj.h"
+#define MAX_PWD_LEN 128
+
extern void pdf_enc_set_verbose (void);
extern pdf_obj *pdf_enc_id_array (void);
extern void pdf_enc_set_label (unsigned long label);
extern void pdf_enc_set_generation (unsigned generation);
-extern void pdf_enc_set_passwd (unsigned size, unsigned perm, char *dviname, char *pdfname);
+extern void pdf_enc_set_passwd (unsigned size, unsigned perm, const char *owner, const char *user);
extern void pdf_encrypt_data (unsigned char *data, unsigned long len);
extern pdf_obj *pdf_encrypt_obj (void);
diff --git a/Build/source/texk/xdvipdfmx/src/spc_pdfm.c b/Build/source/texk/xdvipdfmx/src/spc_pdfm.c
index fd337d8cf0c..2561d3ffcda 100644
--- a/Build/source/texk/xdvipdfmx/src/spc_pdfm.c
+++ b/Build/source/texk/xdvipdfmx/src/spc_pdfm.c
@@ -2054,6 +2054,7 @@ static struct spc_handler pdfm_handlers[] = {
{"code", spc_handler_pdfm_code},
{"minorversion", spc_handler_pdfm_do_nothing},
+ {"encrypt", spc_handler_pdfm_do_nothing},
};
int