Last Updated on 13 Giugno 2021 by Roberto De Pedrini
Qualche tempo fa un cliente mi espresse la necessità di rimuovere la protezione dai file PDF provenienti dalla propria rete di vendita.
Mi disse che per ovviare al problema era costretto ad eliminare la protezione dai PDF manualmente usando il tool open source QPDF su Windows ma che questa non era la soluzione migliore dal momento che il suo applicativo era residente su un sistema IBM i. Mi chiese quindi se potessi verificare la fattibilità di un’installazione del tool sul sistema IBM i per automatizzare l’attività inserendola tra i lavori batch notturni.
Da subito tentai di risolvergli il problema scrivendo un piccolo programma Java che però, col tempo, scoprimmo non riuscire a sproteggere tutti i tipi di PDF. A questo punto, prima di rimettere le mani sul codice Java, decisi di verificare se era possibile compilare QPDF su IBM i.
Siccome su internet non trovai nulla, fui costretto a rimboccarmi le maniche…
Questo articolo sintetizza questa esperienza mostrando i passi necessari per installare QPDF su di un sistema IBM i.
QPDF è un programma da riga di comando gratuito in grado di eseguire una serie di trasformazioni come linearizzazione (visualizzazione web veloce), crittografia e decrittografia di file PDF. Include il supporto per apportare modifiche strutturali ai PDF, inclusa la riorganizzazione delle pagine, la creazione di filigrane, la rotazione, l’unione e la divisione di PDF tramite la possibilità di copiare oggetti da un file PDF a un altro e di manipolare l’elenco delle pagine in un file PDF. QPDF ha anche molte opzioni per l’ispezione o il controllo dei file PDF (utile principalmente per gli sviluppatori PDF).
Versioni QPDF testate: 10.3.1, 10.3.2.
Sistema operativo utilizzato: IBM i V7R2 (SF99720 livello 20296 e SF99717 livello 9).
Prerequisito: Gestione dei pacchetti YUM/RPM completamente funzionante (per l’installazione dei pacchetti RPM, step 3).
Step 1: avviare una sessione PASE
Avvia una sessione PASE interattiva da una sessione 5250:
CALL PGM(QP2TERM)
Nota. In alternativa, se il server SSH è configurato sul sistema IBM i, è possibile utilizzare un client SSH per accedere al sistema IBM i.
Step 2: aggiungere la directory di installazione open source alla variabile di ambiente PATH
Se non lo hai già fatto, dovrai modificare il tuo percorso aggiungendo la directory di installazione open source /QOpenSys/pkgs/bin
alla tua v
ariabile d’ambiente PATH
(ricorda che questa impostazione è temporanea solo per questa sessione):
# export PATH=/QOpenSys/pkgs/bin:$PATH
Inoltre, sarebbe necessario aggiungere la directory di installazione delle librerie condivise open source /QOpenSys/pkgs/lib
alla variabile di ambiente LIBPATH
:
# export LIBPATH=/QOpenSys/pkgs/lib:$LIBPATH
Nota. Utilizza LIBPATH
per specificare directory aggiuntive per la ricerca di librerie condivise oltre al percorso di ricerca integrato dell’applicazione. Queste directory vengono cercate prima delle directory nel percorso di ricerca dell’applicazione (PATH vs LIBPATH).
Step3: utilizzare yum
per installare i pacchetti RPM richiesti
Installare gli strumenti di sviluppo:
# yum -y group install "Development tools"
Installare i file di intestazione e le librerie per lo sviluppo Zlib:
# yum -y install zlib-devel.ppc64
Installare i file di intestazione e le librerie per la gestione del formato dei dati delle immagini JPEG:
# yum -y install libjpeg*
Step 4: scaricare QPDF sul PC
Per compilare il sorgente per Linux o per altri sistemi tipo UNIX/UNIX, è generalmente sufficiente scaricare solo il file qpdf-<versione>.tar.gz
: qpdf-10.3.2.tar.gz
.
Step 5: caricare il file qpdf-<version>.tar.gz
sul sistema IBM i (<qpdf_upload_dir>
)
È possibile utilizzare l’unità di rete Netserver, FTP o IBM Access Client Solutions (Generale -> Integrated File System -> Carica…).
Step 6: estrarre i file dall’archivio qpdf-<version>.tar.gz
Cambiare la directory corrente nella directory di caricamento di QPDF:
# cd <qpdf_upload_dir>
Impostare la variabile d’ambiente qpdfver
:
# export qpdfver=10.3.2
Estrai i file dall’archivio tar:
# tar -xvf qpdf-$qpdfver.tar.gz --no-same-owner
Nota. tar
prova a prendere le informazioni sulla proprietà dall’archivio quando viene eseguito come euid 0 (root). Se si utilizza un superutente (come il profilo utente QSECOFR), utilizzare l’opzione tar
--no-same-owner
per estrarre i file con i propri id e gid (proprietà del file impostata sull’utente corrente, impostazione predefinita per gli utenti ordinari).
Questa impostazione impedisce messaggi di avviso come il seguente:
tar: qpdf-x.x.x: Cannot change ownership to uid x, gid x: Una chiamata di sistema ha ricevuto un parametro che non è valido.
tar: Exiting with failure status due to previous errors
Nota. Il comando tar
QShell non riesce a estrarre i file dall’archivio.
Step 7: configurazione del pacchetto QPDF
Cambia la directory corrente nella directory QPDF:
# cd qpdf- $ qpdfver
Imposta la modalità di istruzione su PPC64:
# export OBJECT_MODE=64
Nota. In AIX, è fondamentale definire una variabile di ambiente che indichi se si stanno creando librerie a 64 o 32 bit. Quindi, se stai costruendo librerie a 64 bit e usi una shell derivata da bash, dovresti emettere export OBJECT_MODE=64
prima di iniziare la fase di configurazione.
Questa impostazione impedisce i messaggi di errore nel passo make
(comando ar
) come il seguente:
ar: 0707-126 [...] is not valid with the current object file mode.
Use the -X option to specify the desired object mode.
# ./configure --prefix=/QOpenSys/QIBM/UserData/qpdf
Nota. Per impostazione predefinita, make install
installa i comandi in /usr/local/bin
, gli include file in /usr/local/include
, le librerie locali in /usr/local/lib
ed i file indipendenti dall’architettura locale, come documentazione e manuali, in /usr/local/share
. È possibile specificare un prefisso di installazione diverso da /usr/local
passando al comando configure
l’opzione --prefix=PREFIX
. In questo articolo, useremo /QOpenSys/QIBM/UserData/qpdf
.
Step 8: modificare i file libtool e fuzz/build.mk per compatibilità con IBM i
# sed --in-place='_backup' 's/ECHO="print -r --"/ECHO="echo"/' libtool
Prima:
...
70 # An echo program that protects backslashes.
71 ECHO="print -r --"
...
Dopo:
...
70 # An echo program that protects backslashes.
71 ECHO="echo"
...
# sed --in-place='_backup' 's/tar xzf ..\/..\/original-corpus.tar.gz)/tar xzf ..\/..\/original-corpus.tar.gz --no-same-owner)/' fuzz/build.mk
Prima:
...
89 (cd $ (CORPUS_DIR); tar xzf ../../original-corpus.tar.gz)
...
Dopo:
...
89 (cd $ (CORPUS_DIR); tar xzf ../../original-corpus.tar.gz --no-same-owner)
...
Step 9: creazione del pacchetto QPDF
# make
Questo passaggio può richiedere diverse ore per il suo completamento.
Nota. Puoi ignorare i seguenti avvisi:
...: warning: visibility attribute not supported in this configuration; ignored [-Wattributes]
Step 10: installazione del pacchetto QPDF
# make install
Nota. make inst
all crea le directory che non esistono sul sistema.
Step 11: eseguire il comando qpdf
# export PATH=/QOpenSys/QIBM/UserData/qpdf/bin:$PATH
# export LIBPATH=/QOpenSys/QIBM/UserData/qpdf/lib:$LIBPATH
# qpdf --version
qpdf version 10.3.2
Run qpdf --copyright to see copyright and license information.
Step 12: distribuzione di QPDF su altri sistemi IBM i
a. Cercare le librerie condivise richieste da QPDF:
Il comando AIX/P
ASE dump
può fornire informazioni dettagliate sugli eseguibili, sulle librerie condivise e sui file oggetto. Qui stiamo usando il flag -X64
per dirgli che stiamo guardando un oggetto a 64 bit e il flag -H
per dirgli di scaricare l’intestazione dell’oggetto (LIBPATH… Come funziona?).
# dump -X64 -H /QOpenSys/QIBM/UserData/qpdf/bin/qpdf
/QOpenSys/QIBM/UserData/qpdf/bin/qpdf:
***Sezione loader***
Info intestazione loader
VERSIONE# #SYMtableENT #RELOCent LENidSTR
0x00000001 0x000000f0 0x0000102f 0x0000017c
#IMPfilID OFFidSTR LENstrTBL OFFstrTBL
0x00000006 0x000119a8 0x00001c3a 0x00011b24
***Importare stringa file***
INDICE PERCORSO BASE MEMBRO
0 libqpdf/build:/QOpenSys/pkgs/lib:/QOpenSys/pkgs/bin/../lib/gcc/powerpc-ibm-aix6.1.0.0/6.3.0/ppc64:/QOpenSys/pkgs/bin/../lib/gcc/powerpc-ibm-aix6.1.0.0/6.3.0:/QOpenSys/pkgs/bin/../lib/gcc:/QOpenSys/pkgs/bin/../lib/gcc/powerpc-ibm-aix6.1.0.0/6.3.0/../../..:/usr/lib:/lib
1 libz.so.1 shr_64.o
2 libjpeg.so.8 shr_64.o
3 libstdc++.so.6 shr_64.o
4 libgcc_s.so.1 shr_64.o
5 libc.a shr_64.o
Nota. libc.a
è la libreria runtime C situata in /QOpenSys/QIBM/ProdData/OS400/PASE/lib/
.
b. Salvare gli oggetti QPDF e le librerie condivise necessarie su file di salvataggio:
FILE CRTSAVF(<savflib>/QPDF)
SAV DEV('/QSYS.LIB/<savflib>.LIB/QPDF.FILE') OBJ(('/QOpenSys/QIBM/UserData/qpdf/*') ('/QOpenSys/pkgs/lib/libz.so.1') ('/QOpenSys/pkgs/lib/libjpeg.so.8') ('/QOpenSys/pkgs/lib/libstdc++.so.6') ('/QOpenSys/pkgs/lib/libgcc_s.so.1')) SUBTREE(*ALL)
c. Trasferire il file di salvataggio sul sistema IBM i di destinazione.
d. Ripristinare oggetti dal file di salvataggio:
– tutti gli oggetti nel percorso originale (/QOpenSys/QIBM/UserData/qpdf
):
QSH CMD('mkdir -m 0755 -p -- /QOpenSys/QIBM/UserData/qpdf')
RST DEV('/QSYS.LIB/<savflib>.LIB/QPDF.FILE') OBJ(('/QOpenSys/QIBM/UserData/qpdf') ('/QOpenSys/pkgs/lib')) SUBTREE(*ALL) ALWOBJDIF(*ALL)
– solo gli oggetti necessari (comando e librerie condivise) al nuovo percorso (/<newpath>/qpdf
):
QSH CMD('mkdir -m 0755 -p -- /<newpath>/qpdf')
RST DEV('/QSYS.LIB/<savflib>.LIB/QPDF.FILE') OBJ(('/QOpenSys/QIBM/UserData/qpdf/bin/qpdf' *INCLUDE '/<newpath>/qpdf/qpdf') ('/QOpenSys/pkgs/lib/libz.so.1' *INCLUDE '/<newpath>/qpdf/libz.so.1') ('/QOpenSys/pkgs/lib/libjpeg.so.8' *INCLUDE '/<newpath>/qpdf/libjpeg.so.8') ('/QOpenSys/pkgs/lib/libstdc++.so.6' *INCLUDE '/<newpath>/qpdf/libstdc++.so.6') ('/QOpenSys/pkgs/lib/libgcc_s.so.1' *INCLUDE '/<newpath>/qpdf/libgcc_s.so.1')) SUBTREE(*NONE) ALWOBJDIF(*ALL)
e. QPDF (distribuito) può essere eseguito anche da QShell:
QSH CMD('export PATH=/<newpath>/qpdf:$PATH; export LIBPATH=/<newpath>/qpdf:$LIBPATH; qpdf --version')