Linux ns8.secondary29.go.th 2.6.32-754.28.1.el6.x86_64 #1 SMP Wed Mar 11 18:38:45 UTC 2020 x86_64
Apache/2.2.15 (CentOS)
: 122.154.134.11 | : 122.154.134.9
Cant Read [ /etc/named.conf ]
5.6.40
apache
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
bin /
[ HOME SHELL ]
Name
Size
Permission
Action
.fipscheck.hmac
65
B
-rw-r--r--
.ssh.hmac
65
B
-rw-r--r--
411toppm
11.26
KB
-rwxr-xr-x
5250keys
876
B
-rwxr-xr-x
GET
14.18
KB
-rwxr-xr-x
HEAD
14.18
KB
-rwxr-xr-x
Mail
381.95
KB
-rwxr-xr-x
POST
14.18
KB
-rwxr-xr-x
[
36.13
KB
-rwxr-xr-x
a2p
109.27
KB
-rwxr-xr-x
a2ping
91.65
KB
-rwxr-xr-x
ab
49.54
KB
-rwxr-xr-x
abrt-action-analyze-backtrace
21.81
KB
-rwxr-xr-x
abrt-action-analyze-c
20.66
KB
-rwxr-xr-x
abrt-action-analyze-ccpp-local
1.28
KB
-rwxr-xr-x
abrt-action-analyze-core
6.52
KB
-rwxr-xr-x
abrt-action-analyze-oops
21.26
KB
-rwxr-xr-x
abrt-action-analyze-python
19.73
KB
-rwxr-xr-x
abrt-action-generate-backtrace
21.13
KB
-rwxr-xr-x
abrt-action-generate-core-back...
19.93
KB
-rwxr-xr-x
abrt-action-install-debuginfo
7.02
KB
-rwxr-xr-x
abrt-action-list-dsos
2.69
KB
-rwxr-xr-x
abrt-action-notify
8.66
KB
-rwxr-xr-x
abrt-action-save-kernel-data
1.26
KB
-rwxr-xr-x
abrt-action-save-package-data
29.41
KB
-rwxr-xr-x
abrt-action-trim-files
24.56
KB
-rwxr-xr-x
abrt-cli
31.16
KB
-rwxr-xr-x
abrt-cli-root
8.67
KB
-rwxr-xr-x
abrt-dedup-client
36.2
KB
-rwxr-xr-x
abrt-dump-oops
28.66
KB
-rwxr-xr-x
abrt-handle-upload
8.79
KB
-rwxr-xr-x
ac
24.23
KB
-rwxr-xr-x
aclocal
30.45
KB
-rwxr-xr-x
aclocal-1.11
30.45
KB
-rwxr-xr-x
aconnect
22.37
KB
-rwxr-xr-x
acpi_listen
14.63
KB
-rwxr-xr-x
addftinfo
25.52
KB
-rwxr-xr-x
addr2line
29.16
KB
-rwxr-xr-x
afs5log
76.61
KB
-rwxr-xr-x
aleph
458.53
KB
-rwxr-xr-x
allcm
3.3
KB
-rwxr-xr-x
allec
3.3
KB
-rwxr-xr-x
allneeded
903
B
-rwxr-xr-x
alsa-info
27.22
KB
-rwxr-xr-x
alsa-info.sh
27.22
KB
-rwxr-xr-x
alsaloop
1.49
MB
-rwxr-xr-x
alsamixer
74.68
KB
-rwxr-xr-x
amidi
22.94
KB
-rwxr-xr-x
amixer
54.85
KB
-rwxr-xr-x
amstex
650.74
KB
-rwxr-xr-x
anytopnm
11.11
KB
-rwxr-xr-x
aplay
76.96
KB
-rwxr-xr-x
aplaymidi
25.51
KB
-rwxr-xr-x
apropos
1.74
KB
-rwxr-xr-x
ar
59.55
KB
-rwxr-xr-x
arecord
76.96
KB
-rwxr-xr-x
arecordmidi
28.36
KB
-rwxr-xr-x
as
529.23
KB
-rwxr-xr-x
asciitopgm
10.2
KB
-rwxr-xr-x
aseqdump
20.84
KB
-rwxr-xr-x
aseqnet
21.88
KB
-rwxr-xr-x
aserver
32.12
KB
-rwxr-xr-x
assistant-qt4
947.75
KB
-rwxr-xr-x
assistant_adp
603.22
KB
-rwxr-xr-x
at
53.19
KB
-rwsr-xr-x
atktopbm
11.36
KB
-rwxr-xr-x
atq
53.19
KB
-rwsr-xr-x
atrm
53.19
KB
-rwsr-xr-x
attr
13.52
KB
-rwxr-xr-x
aulast
18.31
KB
-rwxr-xr-x
aulastlog
12.88
KB
-rwxr-xr-x
ausyscall
11.02
KB
-rwxr-xr-x
autoconf
14.29
KB
-rwxr-xr-x
autoheader
8.29
KB
-rwxr-xr-x
autom4te
31.04
KB
-rwxr-xr-x
automake
251.04
KB
-rwxr-xr-x
automake-1.11
251.04
KB
-rwxr-xr-x
autopoint
18.32
KB
-rwxr-xr-x
autoreconf
19.76
KB
-rwxr-xr-x
autoscan
16.67
KB
-rwxr-xr-x
autoupdate
32.97
KB
-rwxr-xr-x
auvirt
34.01
KB
-rwxr-xr-x
awk
373.78
KB
-rwxr-xr-x
b2m
10.87
KB
-rwxr-xr-x
b43-fwcutter
26.95
KB
-rwxr-xr-x
base64
32.08
KB
-rwxr-xr-x
bashbug-64
6.77
KB
-rwxr-xr-x
batch
137
B
-rwxr-xr-x
bc
85.78
KB
-rwxr-xr-x
bdftopcf
10.91
KB
-rwxr-xr-x
bdftops
292
B
-rwxr-xr-x
berkeley_db_svc
74.05
KB
-rwxr-xr-x
bibtex
100.58
KB
-rwxr-xr-x
bibtex8
126.81
KB
-rwxr-xr-x
bioradtopgm
10.41
KB
-rwxr-xr-x
bison
296.2
KB
-rwxr-xr-x
blkiomon
24.82
KB
-rwxr-xr-x
blkparse
46.11
KB
-rwxr-xr-x
blkrawverify
15.17
KB
-rwxr-xr-x
blktrace
38.83
KB
-rwxr-xr-x
bmp2tiff
17.5
KB
-rwxr-xr-x
bmptopnm
22.91
KB
-rwxr-xr-x
bmptoppm
22.91
KB
-rwxr-xr-x
bno_plot.py
3.38
KB
-rwxr-xr-x
brushtopbm
9.32
KB
-rwxr-xr-x
btrace
891
B
-rwxr-xr-x
btrecord
16.55
KB
-rwxr-xr-x
btreplay
26.84
KB
-rwxr-xr-x
btt
72.35
KB
-rwxr-xr-x
build-classpath
1.5
KB
-rwxr-xr-x
build-classpath-directory
383
B
-rwxr-xr-x
build-jar-repository
1.54
KB
-rwxr-xr-x
bunzip2
35.48
KB
-rwxr-xr-x
byacc
76.46
KB
-rwxr-xr-x
bzcat
35.48
KB
-rwxr-xr-x
bzcmp
2.08
KB
-rwxr-xr-x
bzdiff
2.08
KB
-rwxr-xr-x
bzgrep
1.64
KB
-rwxr-xr-x
bzip2
35.48
KB
-rwxr-xr-x
bzip2recover
13.14
KB
-rwxr-xr-x
bzless
1.23
KB
-rwxr-xr-x
bzmore
1.23
KB
-rwxr-xr-x
c++
264.98
KB
-rwxr-xr-x
c++filt
28.54
KB
-rwxr-xr-x
c2ph
35.74
KB
-rwxr-xr-x
c89
224
B
-rwxr-xr-x
c99
215
B
-rwxr-xr-x
ca-legacy
1.61
KB
-rwxr-xr-x
cal
21.09
KB
-rwxr-xr-x
callgrind_annotate
39.92
KB
-rwxr-xr-x
callgrind_control
11.25
KB
-rwxr-xr-x
cameratopam
110.96
KB
-rwxr-xr-x
cancel
14.33
KB
-rwxr-xr-x
cancel.cups
14.33
KB
-rwxr-xr-x
captoinfo
52.52
KB
-rwxr-xr-x
cas
17.01
KB
-rwxr-xr-x
cas-admin
9.84
KB
-rwxr-xr-x
catchsegv
3.3
KB
-rwxr-xr-x
cc
265.34
KB
-rwxr-xr-x
ccache-swig
49.04
KB
-rwxr-xr-x
certmaster-getcert
130.03
KB
-rwxr-xr-x
certutil
172.66
KB
-rwxr-xr-x
certwatch
18.33
KB
-rwxr-xr-x
cg_annotate
31.42
KB
-rwxr-xr-x
cg_diff
10.17
KB
-rwxr-xr-x
cg_merge
68.01
KB
-rwxr-xr-x
chacl
16.82
KB
-rwxr-xr-x
chage
68.83
KB
-rwsr-xr-x
chainsaw
693
B
-rwxr-xr-x
chattr
13.8
KB
-rwxr-xr-x
chcon
58.28
KB
-rwxr-xr-x
check-binary-files
3.25
KB
-rwxr-xr-x
checkmodule
274.53
KB
-rwxr-xr-x
checkpolicy
282.53
KB
-rwxr-xr-x
checksctp
7.75
KB
-rwxr-xr-x
cheetah
73
B
-rwxr-xr-x
cheetah-analyze
114
B
-rwxr-xr-x
cheetah-compile
89
B
-rwxr-xr-x
chfn
19.71
KB
-rws--x--x
chrt
12.77
KB
-rwxr-xr-x
chsh
19.59
KB
-rws--x--x
chvt
9.82
KB
-rwxr-xr-x
ci
90.02
KB
-rwxr-xr-x
cifsiostat
55.98
KB
-rwxr-xr-x
cjpeg
31.84
KB
-rwxr-xr-x
ck-history
27.01
KB
-rwxr-xr-x
ck-launch-session
11.2
KB
-rwxr-xr-x
ck-list-sessions
15.39
KB
-rwxr-xr-x
cksum
28.14
KB
-rwxr-xr-x
clean-binary-files
12.91
KB
-rwxr-xr-x
clear
8.16
KB
-rwxr-xr-x
cloog
14.98
KB
-rwxr-xr-x
clusterdb
57.98
KB
-rwxr-xr-x
cmp
23.09
KB
-rwxr-xr-x
cmsutil
103.77
KB
-rwxr-xr-x
cmuwmtopbm
9.7
KB
-rwxr-xr-x
co
85.62
KB
-rwxr-xr-x
col
14.21
KB
-rwxr-xr-x
colcrt
11.04
KB
-rwxr-xr-x
colrm
8.64
KB
-rwxr-xr-x
column
13.16
KB
-rwxr-xr-x
combinediff
48.13
KB
-rwxr-xr-x
comm
31.3
KB
-rwxr-xr-x
config_data
7.07
KB
-rwxr-xr-x
consolehelper
8.67
KB
-rwxr-xr-x
corelist
6.36
KB
-rwxr-xr-x
cpan
11.56
KB
-rwxr-xr-x
cpan2dist
21.88
KB
-rwxr-xr-x
cpanp
3.32
KB
-rwxr-xr-x
cpanp-run-perl
536
B
-rwxr-xr-x
cpp
264.98
KB
-rwxr-xr-x
crash
7.07
MB
-rwxr-xr-x
create-jar-links
4.55
KB
-rwxr-xr-x
createdb
59.52
KB
-rwxr-xr-x
createlang
61.05
KB
-rwxr-xr-x
createuser
59.81
KB
-rwxr-xr-x
crlutil
115.62
KB
-rwxr-xr-x
crontab
50.57
KB
-rwsr-xr-x
cscope
327.81
KB
-rwxr-xr-x
cscope-indexer
3.77
KB
-rwxr-xr-x
cslatex
650.74
KB
-rwxr-xr-x
csplain
650.74
KB
-rwxr-xr-x
csplit
106.16
KB
-rwxr-xr-x
csslint-0.6
22.67
KB
-rwxr-xr-x
ctags
230.13
KB
-rwxr-xr-x
ctangle
43.22
KB
-rwxr-xr-x
ctie
18.92
KB
-rwxr-xr-x
cupstestdsc
14.23
KB
-rwxr-xr-x
cupstestppd
62.62
KB
-rwxr-xr-x
curl
131.35
KB
-rwxr-xr-x
cut
44.47
KB
-rwxr-xr-x
cvs
626.08
KB
-rwxr-xr-x
cvsbug
13.7
KB
-rwxr-xr-x
cweave
80.28
KB
-rwxr-xr-x
db_archive
11.8
KB
-rwxr-xr-x
db_checkpoint
13.79
KB
-rwxr-xr-x
db_codegen
25.59
KB
-rwxr-xr-x
db_deadlock
14.16
KB
-rwxr-xr-x
db_dump
15.8
KB
-rwxr-xr-x
db_dump185
63.81
KB
-rwxr-xr-x
db_hotbackup
20.88
KB
-rwxr-xr-x
db_load
26.78
KB
-rwxr-xr-x
db_printlog
69.6
KB
-rwxr-xr-x
db_recover
13.48
KB
-rwxr-xr-x
db_stat
14.5
KB
-rwxr-xr-x
db_upgrade
12.31
KB
-rwxr-xr-x
db_verify
12.9
KB
-rwxr-xr-x
dbilogstrip
1.43
KB
-rwxr-xr-x
dbiprof
6.15
KB
-rwxr-xr-x
dbiproxy
5.35
KB
-rwxr-xr-x
dbus-binding-tool
87.89
KB
-rwxr-xr-x
dc
48.65
KB
-rwxr-xr-x
ddate
13.68
KB
-rwxr-xr-x
ddbugtopbm
10.95
KB
-rwxr-xr-x
deallocvt
10.28
KB
-rwxr-xr-x
debuginfo-install
7.46
KB
-rwxr-xr-x
dehtmldiff
1.32
KB
-rwxr-xr-x
desktop-file-install
51.77
KB
-rwxr-xr-x
desktop-file-validate
43.81
KB
-rwxr-xr-x
dialog
35.69
KB
-rwxr-xr-x
diff
84.34
KB
-rwxr-xr-x
diff-jars
1.2
KB
-rwxr-xr-x
diff3
26.94
KB
-rwxr-xr-x
diffstat
34.27
KB
-rwxr-xr-x
dig
150.51
KB
-rwxr-xr-x
dir
114.3
KB
-rwxr-xr-x
dircolors
35.74
KB
-rwxr-xr-x
dirname
25.65
KB
-rwxr-xr-x
djpeg
32.17
KB
-rwxr-xr-x
dltest
10.8
KB
-rwxr-xr-x
dmp
37.08
KB
-rwxr-xr-x
doxygen
5.47
MB
-rwxr-xr-x
doxytag
285.77
KB
-rwxr-xr-x
dprofpp
23.52
KB
-rwxr-xr-x
drill
63.46
KB
-rwxr-xr-x
dropdb
55.79
KB
-rwxr-xr-x
droplang
63.36
KB
-rwxr-xr-x
dropuser
55.79
KB
-rwxr-xr-x
dstat
81.42
KB
-rwxr-xr-x
du
96.88
KB
-rwxr-xr-x
dumphint
554
B
-rwxr-xr-x
dvi2fax
1.07
KB
-rwxr-xr-x
dvipdf
1.03
KB
-rwxr-xr-x
dvips
203.13
KB
-rwxr-xr-x
dvired
3.01
KB
-rwxr-xr-x
dvitomp
38.8
KB
-rwxr-xr-x
e2pall
2.66
KB
-rwxr-xr-x
easy_install
323
B
-rwxr-xr-x
easy_install-2.6
331
B
-rwxr-xr-x
ebrowse
46.57
KB
-rwxr-xr-x
ecj
117
B
-rwxr-xr-x
editdiff
1.91
KB
-rwxr-xr-x
eject
8.67
KB
-rwxr-xr-x
elinks
1.2
MB
-rwxr-xr-x
emacs
10.51
MB
-rwxr-xr-t
emacs-23.1
10.51
MB
-rwxr-xr-t
emacsclient
24.71
KB
-rwxr-xr-x
enc2xs
38.23
KB
-rwxr-xr-x
env
25.75
KB
-rwxr-xr-x
envsubst
32.77
KB
-rwxr-xr-x
eplain
650.74
KB
-rwxr-xr-x
eps2eps
632
B
-rwxr-xr-x
epsffit
13.96
KB
-rwxr-xr-x
epstopdf
12.02
KB
-rwxr-xr-x
eqn
140.8
KB
-rwxr-xr-x
eqn2graph
2.19
KB
-rwxr-xr-x
escp2topbm
9.98
KB
-rwxr-xr-x
espdiff
1.53
KB
-rwxr-xr-x
etags
100.07
KB
-rwxr-xr-x
etags.emacs
100.07
KB
-rwxr-xr-x
etex
650.74
KB
-rwxr-xr-x
eu-addr2line
25.46
KB
-rwxr-xr-x
eu-ar
36.27
KB
-rwxr-xr-x
eu-elfcmp
33.06
KB
-rwxr-xr-x
eu-elflint
101.55
KB
-rwxr-xr-x
eu-findtextrel
19.51
KB
-rwxr-xr-x
eu-make-debug-archive
2.84
KB
-rwxr-xr-x
eu-nm
46.32
KB
-rwxr-xr-x
eu-objdump
33.37
KB
-rwxr-xr-x
eu-ranlib
20.49
KB
-rwxr-xr-x
eu-readelf
174.43
KB
-rwxr-xr-x
eu-size
18.76
KB
-rwxr-xr-x
eu-stack
29.21
KB
-rwxr-xr-x
eu-strings
19.82
KB
-rwxr-xr-x
eu-strip
50.24
KB
-rwxr-xr-x
eu-unstrip
48.64
KB
-rwxr-xr-x
execstack
180.27
KB
-rwxr-xr-x
expand
29.79
KB
-rwxr-xr-x
expr
97.88
KB
-rwxr-xr-x
extconv
8
KB
-rwxr-xr-x
eyuvtoppm
11.86
KB
-rwxr-xr-x
f95
277.73
KB
-rwxr-xr-x
factor
47.84
KB
-rwxr-xr-x
fallocate
11.33
KB
-rwxr-xr-x
fastjar
47.43
KB
-rwxr-xr-x
fax2ps
19.02
KB
-rwxr-xr-x
fax2tiff
17.92
KB
-rwxr-xr-x
fc-cache
17.02
KB
-rwxr-xr-x
fc-cat
15.1
KB
-rwxr-xr-x
fc-list
12.71
KB
-rwxr-xr-x
fc-match
13.98
KB
-rwxr-xr-x
fc-query
11.38
KB
-rwxr-xr-x
fc-scan
11.74
KB
-rwxr-xr-x
fgconsole
10.38
KB
-rwxr-xr-x
fiascotopnm
92.72
KB
-rwxr-xr-x
file
19.32
KB
-rwxr-xr-x
filterdiff
44.24
KB
-rwxr-xr-x
find
233.4
KB
-rwxr-xr-x
find-jar
749
B
-rwxr-xr-x
find-repos-of-install
4.27
KB
-rwxr-xr-x
find2perl
23.06
KB
-rwxr-xr-x
findsmb
4.5
KB
-rwxr-xr-x
fipscheck
14.57
KB
-rwxr-xr-x
fipshmac
13.9
KB
-rwxr-xr-x
fitstopnm
16.29
KB
-rwxr-xr-x
fixcvsdiff
1.83
KB
-rwxr-xr-x
flac
191.95
KB
-rwxr-xr-x
flex
329.84
KB
-rwxr-xr-x
flex++
329.84
KB
-rwxr-xr-x
flipdiff
48.13
KB
-rwxr-xr-x
flock
14.15
KB
-rwxr-xr-x
floppy
27.98
KB
-rwxr-xr-x
fmt
33.23
KB
-rwxr-xr-x
fmtutil
28.47
KB
-rwxr-xr-x
fmtutil-sys
831
B
-rwxr-xr-x
fold
30.95
KB
-rwxr-xr-x
font2c
300
B
-rwxr-xr-x
fontinst
552
B
-rwxr-xr-x
fonttosfnt
36.59
KB
-rwxr-xr-x
foomatic-combo-xml
45.17
KB
-rwxr-xr-x
foomatic-compiledb
4.52
KB
-rwxr-xr-x
foomatic-configure
133.59
KB
-rwxr-xr-x
foomatic-datafile
9.45
KB
-rwxr-xr-x
foomatic-perl-data
81.95
KB
-rwxr-xr-x
foomatic-ppd-options
3.91
KB
-rwxr-xr-x
foomatic-ppd-to-xml
8.79
KB
-rwxr-xr-x
foomatic-ppdfile
9.45
KB
-rwxr-xr-x
foomatic-printjob
34.27
KB
-rwxr-xr-x
foomatic-rip
108.56
KB
-rwxr-xr-x
foomatic-searchprinter
2.43
KB
-rwxr-xr-x
fprintd-delete
12.99
KB
-rwxr-xr-x
fprintd-enroll
12.7
KB
-rwxr-xr-x
fprintd-list
13.45
KB
-rwxr-xr-x
fprintd-verify
14.66
KB
-rwxr-xr-x
free
14.02
KB
-rwxr-xr-x
fstopgm
10.46
KB
-rwxr-xr-x
funzip
24.84
KB
-rwxr-xr-x
g++
264.98
KB
-rwxr-xr-x
g3topbm
15.47
KB
-rwxr-xr-x
gawk
373.78
KB
-rwxr-xr-x
gcc
265.34
KB
-rwxr-xr-x
gcj-dbtool
36.13
KB
-rwxr-xr-x
gconf-merge-tree
60.98
KB
-rwxr-xr-x
gconftool-2
70.29
KB
-rwxr-xr-x
gcore
1.99
KB
-rwxr-xr-x
gcov
43.09
KB
-rwxr-xr-x
gctags
101.78
KB
-rwxr-xr-x
gdb
4.3
MB
-rwxr-xr-x
gdb-add-index
1.07
KB
-rwxr-xr-x
gdbtui
4.3
MB
-rwxr-xr-x
gdbus
37.91
KB
-rwxr-xr-x
gdk-pixbuf-query-loaders-64
16.42
KB
-rwxr-xr-x
gemtopbm
12.04
KB
-rwxr-xr-x
gemtopnm
12.04
KB
-rwxr-xr-x
gencat
25.18
KB
-rwxr-xr-x
gendiff
586
B
-rwxr-xr-x
genkey
43.96
KB
-rwxr-xr-x
geqn
140.8
KB
-rwxr-xr-x
getafm
5.98
KB
-rwxr-xr-x
getcert
134.02
KB
-rwxr-xr-x
getcifsacl
10.2
KB
-rwxr-xr-x
getconf
24.93
KB
-rwxr-xr-x
getent
29.79
KB
-rwxr-xr-x
getfacl
25.63
KB
-rwxr-xr-x
getfattr
21.46
KB
-rwxr-xr-x
getkeycodes
10.54
KB
-rwxr-xr-x
getopt
15.27
KB
-rwxr-xr-x
gettext
32.7
KB
-rwxr-xr-x
gettext.sh
4.54
KB
-rwxr-xr-x
gettextize
40.92
KB
-rwxr-xr-x
gfortran
277.73
KB
-rwxr-xr-x
gftodvi
45.33
KB
-rwxr-xr-x
gftopk
26.82
KB
-rwxr-xr-x
gftype
26.74
KB
-rwxr-xr-x
ghostscript
18.68
KB
-rwxr-xr-x
gif2tiff
17.47
KB
-rwxr-xr-x
giftopnm
23.99
KB
-rwxr-xr-x
gij
9.55
KB
-rwxr-xr-x
gindxbib
31.53
KB
-rwxr-xr-x
gio-querymodules-64
14.03
KB
-rwxr-xr-x
git
1.09
MB
-rwxr-xr-x
git-receive-pack
1.09
MB
-rwxr-xr-x
git-shell
450.64
KB
-rwxr-xr-x
git-upload-archive
1.09
MB
-rwxr-xr-x
git-upload-pack
460.71
KB
-rwxr-xr-x
gjar
10.21
KB
-rwxr-xr-x
gjarsigner
10.23
KB
-rwxr-xr-x
gkeytool
10.22
KB
-rwxr-xr-x
glib-compile-schemas
42.34
KB
-rwxr-xr-x
glookbib
39.98
KB
-rwxr-xr-x
gmake
169.15
KB
-rwxr-xr-x
gneqn
255
B
-rwxr-xr-x
gnroff
2.34
KB
-rwxr-xr-x
gorbd
10.21
KB
-rwxr-xr-x
gouldtoppm
10.08
KB
-rwxr-xr-x
gpasswd
73.87
KB
-rwsr-xr-x
gpg
750.44
KB
-rwxr-xr-x
gpg-agent
298.02
KB
-rwxr-xr-x
gpg-connect-agent
175.2
KB
-rwxr-xr-x
gpg-error
21.33
KB
-rwxr-xr-x
gpg-zip
3.23
KB
-rwxr-xr-x
gpg2
750.44
KB
-rwxr-xr-x
gpgconf
132.59
KB
-rwxr-xr-x
gpgkey2ssh
39.55
KB
-rwxr-xr-x
gpgparsemail
26.02
KB
-rwxr-xr-x
gpgsplit
51.38
KB
-rwxr-xr-x
gpgv
334.27
KB
-rwxr-xr-x
gpgv2
334.27
KB
-rwxr-xr-x
gpic
216.12
KB
-rwxr-xr-x
gprof
97.09
KB
-rwxr-xr-x
grefer
125.91
KB
-rwxr-xr-x
grep-changelog
7.12
KB
-rwxr-xr-x
grepdiff
44.24
KB
-rwxr-xr-x
grepjar
88.31
KB
-rwxr-xr-x
grmic
10.21
KB
-rwxr-xr-x
grmid
10.21
KB
-rwxr-xr-x
grmiregistry
10.23
KB
-rwxr-xr-x
grn
71.27
KB
-rwxr-xr-x
grodvi
86.23
KB
-rwxr-xr-x
groff
71.95
KB
-rwxr-xr-x
groffer
7.59
KB
-rwxr-xr-x
grog
2.41
KB
-rwxr-xr-x
grolbp
93.49
KB
-rwxr-xr-x
grolj4
83.24
KB
-rwxr-xr-x
grops
121.94
KB
-rwxr-xr-x
grotty
82.23
KB
-rwxr-xr-x
groups
27.34
KB
-rwxr-xr-x
gs
18.68
KB
-rwxr-xr-x
gsbj
337
B
-rwxr-xr-x
gsdj
339
B
-rwxr-xr-x
gsdj500
342
B
-rwxr-xr-x
gserialver
10.23
KB
-rwxr-xr-x
gsftopk
36.88
KB
-rwxr-xr-x
gslj
340
B
-rwxr-xr-x
gslp
337
B
-rwxr-xr-x
gsnd
264
B
-rwxr-xr-x
gsoelim
25.58
KB
-rwxr-xr-x
gst-feedback
15.76
KB
-rwxr-xr-x
gst-feedback-0.10
3.1
KB
-rwxr-xr-x
gst-inspect
15.76
KB
-rwxr-xr-x
gst-inspect-0.10
49.73
KB
-rwxr-xr-x
gst-launch
15.76
KB
-rwxr-xr-x
gst-launch-0.10
33.39
KB
-rwxr-xr-x
gst-typefind
15.76
KB
-rwxr-xr-x
gst-typefind-0.10
18.37
KB
-rwxr-xr-x
gst-xmlinspect
15.77
KB
-rwxr-xr-x
gst-xmlinspect-0.10
27.16
KB
-rwxr-xr-x
gst-xmllaunch
15.76
KB
-rwxr-xr-x
gst-xmllaunch-0.10
33.39
KB
-rwxr-xr-x
gstack
1.1
KB
-rwxr-xr-x
gtbl
103.23
KB
-rwxr-xr-x
gtk-query-immodules-2.0-64
22.66
KB
-rwxr-xr-x
gtk-update-icon-cache
36.45
KB
-rwxr-xr-x
gtnameserv
10.23
KB
-rwxr-xr-x
gtroff
355.09
KB
-rwxr-xr-x
gunzip
61
B
-rwxr-xr-x
gzexe
5.73
KB
-rwxr-xr-x
gzip
67.09
KB
-rwxr-xr-x
h2ph
27.38
KB
-rwxr-xr-x
h2xs
58.97
KB
-rwxr-xr-x
hal-device
21.75
KB
-rwxr-xr-x
hal-disable-polling
16.43
KB
-rwxr-xr-x
hal-find-by-capability
12.21
KB
-rwxr-xr-x
hal-find-by-property
12.34
KB
-rwxr-xr-x
hal-get-property
14.42
KB
-rwxr-xr-x
hal-is-caller-locked-out
12.16
KB
-rwxr-xr-x
hal-lock
17.05
KB
-rwxr-xr-x
hal-set-property
16.27
KB
-rwxr-xr-x
halt
8.67
KB
-rwxr-xr-x
hdifftopam
10.26
KB
-rwxr-xr-x
head
35.29
KB
-rwxr-xr-x
hexdump
24.87
KB
-rwxr-xr-x
hipstopgm
10.04
KB
-rwxr-xr-x
host
133.74
KB
-rwxr-xr-x
hostid
25
KB
-rwxr-xr-x
hpcdtoppm
764
B
-rwxr-xr-x
hpftodit
24.09
KB
-rwxr-xr-x
htdbm
15.04
KB
-rwxr-xr-x
htdigest
10.98
KB
-rwxr-xr-x
htpasswd
13.66
KB
-rwxr-xr-x
huge_page_setup_helper.py
12.05
KB
-rwxr-xr-x
hugeadm
68.96
KB
-rwxr-xr-x
hugectl
16.04
KB
-rwxr-xr-x
hugeedit
11.42
KB
-rwxr-xr-x
hunspell
58.84
KB
-rwxr-xr-x
hwloc-assembler
13.23
KB
-rwxr-xr-x
hwloc-assembler-remote
2.28
KB
-rwxr-xr-x
hwloc-bind
29.23
KB
-rwxr-xr-x
hwloc-calc
34.36
KB
-rwxr-xr-x
hwloc-distances
17.3
KB
-rwxr-xr-x
hwloc-distrib
21.11
KB
-rwxr-xr-x
hwloc-gather-topology
3.87
KB
-rwxr-xr-x
hwloc-info
94.2
KB
-rwxr-xr-x
hwloc-ls
94.2
KB
-rwxr-xr-x
hwloc-ps
16.11
KB
-rwxr-xr-x
i386
13.59
KB
-rwxr-xr-x
icontopbm
10.55
KB
-rwxr-xr-x
iconv
61.55
KB
-rwxr-xr-x
id
31.95
KB
-rwxr-xr-x
ident
11.88
KB
-rwxr-xr-x
idn
35.38
KB
-rwxr-xr-x
iecset
21.05
KB
-rwxr-xr-x
ifnames
3.95
KB
-rwxr-xr-x
igawk
3.02
KB
-rwxr-xr-x
ilbmtoppm
39.33
KB
-rwxr-xr-x
imgtoppm
10.82
KB
-rwxr-xr-x
indent
75.13
KB
-rwxr-xr-x
indxbib
31.53
KB
-rwxr-xr-x
info
181.73
KB
-rwxr-xr-x
infocmp
54.41
KB
-rwxr-xr-x
infokey
25.06
KB
-rwxr-xr-x
infotocap
52.52
KB
-rwxr-xr-x
infotopam
14.23
KB
-rwxr-xr-x
innochecksum
14.46
KB
-rwxr-xr-x
install
110.7
KB
-rwxr-xr-x
install-catalog
4.27
KB
-rwxr-xr-x
instmodsh
4.15
KB
-rwxr-xr-x
interdiff
48.13
KB
-rwxr-xr-x
intltool-extract
27.32
KB
-rwxr-xr-x
intltool-merge
39
KB
-rwxr-xr-x
intltool-prepare
8.4
KB
-rwxr-xr-x
intltool-update
33.74
KB
-rwxr-xr-x
intltoolize
6.98
KB
-rwxr-xr-x
ionice
18.35
KB
-rwxr-xr-x
iostat
69.9
KB
-rwxr-xr-x
ipa-getcert
126.02
KB
-rwxr-xr-x
ipcmk
17.87
KB
-rwxr-xr-x
ipcrm
12.27
KB
-rwxr-xr-x
ipcs
22.58
KB
-rwxr-xr-x
isosize
10.55
KB
-rwxr-xr-x
isql
32.02
KB
-rwxr-xr-x
iusql
27.16
KB
-rwxr-xr-x
java
9.7
KB
-rwxr-xr-x
jbigtopnm
58.69
KB
-rwxr-xr-x
join
41.89
KB
-rwxr-xr-x
jpeg2ktopam
15.01
KB
-rwxr-xr-x
jpegtopnm
31.75
KB
-rwxr-xr-x
jpegtran
30.98
KB
-rwxr-xr-x
jv-convert
10.16
KB
-rwxr-xr-x
jvmjar
1.72
KB
-rwxr-xr-x
k5srvutil
1.87
KB
-rwxr-xr-x
kadmin
74.09
KB
-rwxr-xr-x
kbdrate
11.38
KB
-rwxr-xr-x
kdestroy
10.02
KB
-rwxr-xr-x
keyrand
12.51
KB
-rwxr-xr-x
keytool
9.82
KB
-rwxr-xr-x
keyutil
66.44
KB
-rwxr-xr-x
kill
14.88
KB
-rwxr-xr-x
killall
23.89
KB
-rwxr-xr-x
kinit
26.02
KB
-rwxr-xr-x
klist
26.02
KB
-rwxr-xr-x
koi8rxterm
3.67
KB
-rwxr-xr-x
kpasswd
10.02
KB
-rwxr-xr-x
kpseaccess
8.76
KB
-rwxr-xr-x
kpsepath
3.38
KB
-rwxr-xr-x
kpsereadlink
8.87
KB
-rwxr-xr-x
kpsestat
9.57
KB
-rwxr-xr-x
kpsetool
3.38
KB
-rwxr-xr-x
kpsewhere
1.41
KB
-rwxr-xr-x
kpsewhich
24.09
KB
-rwxr-xr-x
kpsexpand
3.38
KB
-rwxr-xr-x
kswitch
10.02
KB
-rwxr-xr-x
ktutil
22.02
KB
-rwxr-xr-x
kvno
14.02
KB
-rwxr-xr-x
lacheck
63.24
KB
-rwxr-xr-x
lambda
467.72
KB
-rwxr-xr-x
lamed
458.53
KB
-rwxr-xr-x
last
19.88
KB
-rwxr-xr-x
lastb
19.88
KB
-rwxr-xr-x
lastcomm
22.88
KB
-rwxr-xr-x
lastlog
14.02
KB
-rwxr-xr-x
latex
650.74
KB
-rwxr-xr-x
latrace
95.79
KB
-rwxr-xr-x
latrace-ctl
95.79
KB
-rwxr-xr-x
lchfn
32.63
KB
-rwxr-xr-x
lchsh
30.1
KB
-rwxr-xr-x
ld
581.21
KB
-rwxr-xr-x
ldapadd
81.48
KB
-rwxr-xr-x
ldapcompare
69.19
KB
-rwxr-xr-x
ldapdelete
73.35
KB
-rwxr-xr-x
ldapexop
70.83
KB
-rwxr-xr-x
ldapmodify
81.48
KB
-rwxr-xr-x
ldapmodrdn
70.8
KB
-rwxr-xr-x
ldappasswd
70.89
KB
-rwxr-xr-x
ldapsearch
94.31
KB
-rwxr-xr-x
ldapurl
25.02
KB
-rwxr-xr-x
ldapwhoami
69.17
KB
-rwxr-xr-x
ldd
5.2
KB
-rwxr-xr-x
ldns-chaos
12.18
KB
-rwxr-xr-x
ldns-compare-zones
14.42
KB
-rwxr-xr-x
ldns-dane
45.55
KB
-rwxr-xr-x
ldns-dpa
45.02
KB
-rwxr-xr-x
ldns-gen-zone
17.96
KB
-rwxr-xr-x
ldns-key2ds
13.14
KB
-rwxr-xr-x
ldns-keyfetcher
25.82
KB
-rwxr-xr-x
ldns-keygen
16.36
KB
-rwxr-xr-x
ldns-mx
10.63
KB
-rwxr-xr-x
ldns-notify
17.13
KB
-rwxr-xr-x
ldns-nsec3-hash
11.91
KB
-rwxr-xr-x
ldns-read-zone
16.35
KB
-rwxr-xr-x
ldns-resolver
10.08
KB
-rwxr-xr-x
ldns-revoke
11.26
KB
-rwxr-xr-x
ldns-rrsig
14.67
KB
-rwxr-xr-x
ldns-signzone
29.58
KB
-rwxr-xr-x
ldns-test-edns
13.66
KB
-rwxr-xr-x
ldns-testns
35.64
KB
-rwxr-xr-x
ldns-update
17.1
KB
-rwxr-xr-x
ldns-verify-zone
26.68
KB
-rwxr-xr-x
ldns-version
8.54
KB
-rwxr-xr-x
ldns-walk
22.44
KB
-rwxr-xr-x
ldns-zcat
12.53
KB
-rwxr-xr-x
ldns-zsplit
15.55
KB
-rwxr-xr-x
ldnsd
15.63
KB
-rwxr-xr-x
leaftoppm
11.69
KB
-rwxr-xr-x
less
150.8
KB
-rwxr-xr-x
lessecho
10.41
KB
-rwxr-xr-x
lesskey
18.4
KB
-rwxr-xr-x
lesspipe.sh
2.74
KB
-rwxr-xr-x
lex
329.84
KB
-rwxr-xr-x
libnetcfg
15.36
KB
-rwxr-xr-x
libtar
14.68
KB
-rwxr-xr-x
libtool
276.69
KB
-rwxr-xr-x
libtoolize
66.56
KB
-rwxr-xr-x
linc-cleanup-sockets
13.09
KB
-rwxr-xr-x
links
1.2
MB
-rwxr-xr-x
linux32
13.59
KB
-rwxr-xr-x
linux64
13.59
KB
-rwxr-xr-x
lispmtopgm
10.19
KB
-rwxr-xr-x
lkbib
40.11
KB
-rwxr-xr-x
loadunimap
25.52
KB
-rwxr-xr-x
local-getcert
130.02
KB
-rwxr-xr-x
locale
40.4
KB
-rwxr-xr-x
localedef
321.91
KB
-rwxr-xr-x
locate
37.56
KB
-rwx--s--x
logfactor5
593
B
-rwxr-xr-x
logger
14.7
KB
-rwxr-xr-x
logname
25.09
KB
-rwxr-xr-x
logresolve
10.94
KB
-rwxr-xr-x
look
11.46
KB
-rwxr-xr-x
lookbib
39.98
KB
-rwxr-xr-x
lp
18.38
KB
-rwxr-xr-x
lp.cups
18.38
KB
-rwxr-xr-x
lp5250d
17.86
KB
-rwxr-xr-x
lpoptions
14.36
KB
-rwxr-xr-x
lppasswd
14.38
KB
-rwxr-xr-x
lpq
14.38
KB
-rwxr-xr-x
lpq.cups
14.38
KB
-rwxr-xr-x
lpr
14.35
KB
-rwxr-xr-x
lpr.cups
14.35
KB
-rwxr-xr-x
lprm
10.21
KB
-rwxr-xr-x
lprm.cups
10.21
KB
-rwxr-xr-x
lprsetup.sh
4.55
KB
-rwxr-xr-x
lpstat
26.71
KB
-rwxr-xr-x
lpstat.cups
26.71
KB
-rwxr-xr-x
lsattr
12.77
KB
-rwxr-xr-x
lsb_release
15.56
KB
-rwxr-xr-x
lscpu
53.92
KB
-rwxr-xr-x
lsdiff
44.24
KB
-rwxr-xr-x
lshal
27.89
KB
-rwxr-xr-x
lslogins
50.78
KB
-rwxr-xr-x
lstopo
105.62
KB
-rwxr-xr-x
lstopo-no-graphics
94.2
KB
-rwxr-xr-x
lsusb
105.49
KB
-rwxr-xr-x
lsusb.py
13.09
KB
-rwxr-xr-x
ltrace
111.55
KB
-rwxr-xr-x
lua
17.45
KB
-rwxr-xr-x
luac
113.37
KB
-rwxr-xr-x
lwp-download
7.89
KB
-rwxr-xr-x
lwp-dump
2.55
KB
-rwxr-xr-x
lwp-mirror
2.33
KB
-rwxr-xr-x
lwp-request
14.18
KB
-rwxr-xr-x
lwp-rget
14.71
KB
-rwxr-xr-x
lzcat
50.63
KB
-rwxr-xr-x
lzcmp
5.1
KB
-rwxr-xr-x
lzdiff
5.1
KB
-rwxr-xr-x
lzegrep
5.36
KB
-rwxr-xr-x
lzfgrep
5.36
KB
-rwxr-xr-x
lzgrep
5.36
KB
-rwxr-xr-x
lzless
1.76
KB
-rwxr-xr-x
lzma
50.63
KB
-rwxr-xr-x
lzmadec
15.11
KB
-rwxr-xr-x
lzmainfo
12.56
KB
-rwxr-xr-x
lzmore
2.12
KB
-rwxr-xr-x
m4
207.46
KB
-rwxr-xr-x
macptopbm
9.7
KB
-rwxr-xr-x
mag
10.13
KB
-rwxr-xr-x
mailq
208.61
KB
-rwxr-xr-x
mailq.postfix
208.61
KB
-rwxr-xr-x
make
169.15
KB
-rwxr-xr-x
makeindex
83.06
KB
-rwxr-xr-x
makempx
21.23
KB
-rwxr-xr-x
mako-render
893
B
-rwxr-xr-x
man
54.8
KB
-rwxr-xr-x
man2html
60.84
KB
-rwxr-xr-x
manpath
54.8
KB
-rwxr-xr-x
manweb
12.19
KB
-rwxr-xr-x
mapscrn
20.55
KB
-rwxr-xr-x
markdown
1.24
KB
-rwxr-xr-x
mbchk
607.3
KB
-rwxr-xr-x
mc
963.14
KB
-rwxr-xr-x
mcedit
963.14
KB
-rwxr-xr-x
mcmfmt
8.4
KB
-rwxr-xr-x
mcookie
13.93
KB
-rwxr-xr-x
mcview
963.14
KB
-rwxr-xr-x
md5sum
35.27
KB
-rwxr-xr-x
mdatopbm
11.94
KB
-rwxr-xr-x
memhog
13.24
KB
-rwxr-xr-x
merge
63.04
KB
-rwxr-xr-x
mesg
9.57
KB
-rwxr-xr-x
metaflac
111.89
KB
-rwxr-xr-x
mf
270.67
KB
-rwxr-xr-x
mf-nowin
254.84
KB
-rwxr-xr-x
mft
53.45
KB
-rwxr-xr-x
mgrtopbm
10.01
KB
-rwxr-xr-x
migratepages
12.41
KB
-rwxr-xr-x
migspeed
15.16
KB
-rwxr-xr-x
mkfifo
29.09
KB
-rwxr-xr-x
mkfontdir
131
B
-rwxr-xr-x
mkfontscale
34.02
KB
-rwxr-xr-x
mkindex
947
B
-rwxr-xr-x
mkocp
171
B
-rwxr-xr-x
mkofm
83
B
-rwxr-xr-x
mktexfmt
28.47
KB
-rwxr-xr-x
mktexlsr
5.66
KB
-rwxr-xr-x
mktexmf
3.76
KB
-rwxr-xr-x
mktexpk
8.91
KB
-rwxr-xr-x
mktextfm
4.72
KB
-rwxr-xr-x
mllatex
650.74
KB
-rwxr-xr-x
mltex
650.74
KB
-rwxr-xr-x
modutil
157.41
KB
-rwxr-xr-x
mp2bug
1.24
KB
-rwxr-xr-x
mpost
365.57
KB
-rwxr-xr-x
mpstat
59.74
KB
-rwxr-xr-x
mpto
13.21
KB
-rwxr-xr-x
mrftopbm
10.52
KB
-rwxr-xr-x
ms_print
23.64
KB
-rwxr-xr-x
msgattrib
23.53
KB
-rwxr-xr-x
msgcat
23.8
KB
-rwxr-xr-x
msgcmp
17.73
KB
-rwxr-xr-x
msgcomm
22.2
KB
-rwxr-xr-x
msgconv
19.56
KB
-rwxr-xr-x
msgen
19.47
KB
-rwxr-xr-x
msgexec
16.27
KB
-rwxr-xr-x
msgfilter
25.75
KB
-rwxr-xr-x
msgfmt
67.73
KB
-rwxr-xr-x
msggrep
103.15
KB
-rwxr-xr-x
msghack
12.51
KB
-rwxr-xr-x
msginit
44.45
KB
-rwxr-xr-x
msgmerge
44.63
KB
-rwxr-xr-x
msgunfmt
31.2
KB
-rwxr-xr-x
msguniq
21.26
KB
-rwxr-xr-x
msql2mysql
1.38
KB
-rwxr-xr-x
mtvtoppm
9.73
KB
-rwxr-xr-x
musixflx
20.3
KB
-rwxr-xr-x
my_print_defaults
1.34
MB
-rwxr-xr-x
myisam_ftdump
1.59
MB
-rwxr-xr-x
myisamchk
1.7
MB
-rwxr-xr-x
myisamlog
1.59
MB
-rwxr-xr-x
myisampack
1.62
MB
-rwxr-xr-x
mysql
348.62
KB
-rwxr-xr-x
mysql_client_test
408.45
KB
-rwxr-xr-x
mysql_config
7.77
KB
-rwxr-xr-x
mysql_convert_table_format
4.15
KB
-rwxr-xr-x
mysql_find_rows
3.24
KB
-rwxr-xr-x
mysql_fix_extensions
1.23
KB
-rwxr-xr-x
mysql_fix_privilege_tables
5.7
KB
-rwxr-xr-x
mysql_install_db
14.3
KB
-rwxr-xr-x
mysql_secure_installation
8.01
KB
-rwxr-xr-x
mysql_setpermission
17.06
KB
-rwxr-xr-x
mysql_tzinfo_to_sql
1.31
MB
-rwxr-xr-x
mysql_upgrade
77.36
KB
-rwxr-xr-x
mysql_waitpid
174.54
KB
-rwxr-xr-x
mysql_zap
3.8
KB
-rwxr-xr-x
mysqlaccess
108.95
KB
-rwxr-xr-x
mysqladmin
42.6
KB
-rwxr-xr-x
mysqlbinlog
160.74
KB
-rwxr-xr-x
mysqlbug
7.77
KB
-rwxr-xr-x
mysqlcheck
39.13
KB
-rwxr-xr-x
mysqld_multi
23.92
KB
-rwxr-xr-x
mysqldump
95.73
KB
-rwxr-xr-x
mysqldumpslow
7.23
KB
-rwxr-xr-x
mysqlhotcopy
31.72
KB
-rwxr-xr-x
mysqlimport
34.39
KB
-rwxr-xr-x
mysqlshow
33.69
KB
-rwxr-xr-x
mysqlslap
52.3
KB
-rwxr-xr-x
mysqltest
194.11
KB
-rwxr-xr-x
nail
381.95
KB
-rwxr-xr-x
namei
15.99
KB
-rwxr-xr-x
nano
174.7
KB
-rwxr-xr-x
nc
25.76
KB
-rwxr-xr-x
needs-restarting
5.61
KB
-rwxr-xr-x
neotoppm
9.7
KB
-rwxr-xr-x
neqn
255
B
-rwxr-xr-x
net
8.33
MB
-rwxr-xr-x
netaddr
920
B
-rwxr-xr-x
newaliases
208.61
KB
-rwxr-xr-x
newaliases.postfix
208.61
KB
-rwxr-xr-x
newer
9.74
KB
-rwxr-xr-x
newgrp
39.3
KB
-rwsr-xr-x
nfs4_editfacl
28.38
KB
-rwxr-xr-x
nfs4_getfacl
16.55
KB
-rwxr-xr-x
nfs4_setfacl
28.38
KB
-rwxr-xr-x
ngettext
32.16
KB
-rwxr-xr-x
nl
98.3
KB
-rwxr-xr-x
nm
43.29
KB
-rwxr-xr-x
nmblookup
1.65
MB
-rwxr-xr-x
nohup
29.07
KB
-rwxr-xr-x
nosetests
299
B
-rwxr-xr-x
nproc
27.22
KB
-rwxr-xr-x
nroff
2.34
KB
-rwxr-xr-x
nsenter
22.3
KB
-rwxr-xr-x
nslookup
133.68
KB
-rwxr-xr-x
nss-policy-check
10.2
KB
-rwxr-xr-x
nsupdate
75.52
KB
-rwxr-xr-x
ntpstat
10.02
KB
-rwxr-xr-x
numactl
30.48
KB
-rwxr-xr-x
numademo
45.19
KB
-rwxr-xr-x
numastat
28
KB
-rwxr-xr-x
objcopy
213.91
KB
-rwxr-xr-x
objdump
281.38
KB
-rwxr-xr-x
ocount
157.13
KB
-rwxr-xr-x
ocs
7.1
KB
-rwxr-xr-x
od
60.72
KB
-rwxr-xr-x
odbc_config
9.98
KB
-rwxr-xr-x
odbcinst
27.28
KB
-rwxr-xr-x
oddjob_request
35.52
KB
-rwxr-xr-x
odvips
203.13
KB
-rwxr-xr-x
ofm2opl
117.45
KB
-rwxr-xr-x
oldfind
230.81
KB
-rwxr-xr-x
omega
467.72
KB
-rwxr-xr-x
omfonts
117.45
KB
-rwxr-xr-x
omshell
442.43
KB
-rwxr-xr-x
on_ac_power
1.57
KB
-rwxr-xr-x
op-check-perfevents
8.98
KB
-rwxr-xr-x
opannotate
1.22
MB
-rwxr-xr-x
oparchive
1.11
MB
-rwxr-xr-x
opcontrol
55.85
KB
-rwxr-xr-x
open
16.2
KB
-rwxr-xr-x
openssl
535.34
KB
-rwxr-xr-x
openvt
16.2
KB
-rwxr-xr-x
operf
265.8
KB
-rwxr-xr-x
opgprof
1.14
MB
-rwxr-xr-x
ophelp
65.3
KB
-rwxr-xr-x
opimport
71.67
KB
-rwxr-xr-x
opjitconv
776.27
KB
-rwxr-xr-x
opl2ofm
117.45
KB
-rwxr-xr-x
opreport
1.32
MB
-rwxr-xr-x
oprof_start
249.99
KB
-rwxr-xr-x
oprofiled
102.55
KB
-rwxr-xr-x
orbd
10
KB
-rwxr-xr-x
oscap
102.66
KB
-rwxr-xr-x
otangle
43.39
KB
-rwxr-xr-x
otfdump
31.47
KB
-rwxr-xr-x
otflist
11.98
KB
-rwxr-xr-x
otftobdf
11.78
KB
-rwxr-xr-x
otfview
70.52
KB
-rwxr-xr-x
otp2ocp
37.27
KB
-rwxr-xr-x
outocp
12.59
KB
-rwxr-xr-x
ovf2ovp
117.45
KB
-rwxr-xr-x
ovp2ovf
117.45
KB
-rwxr-xr-x
p11-kit
120.36
KB
-rwxr-xr-x
pack200
9.85
KB
-rwxr-xr-x
package-cleanup
18.16
KB
-rwxr-xr-x
pagesize
34.27
KB
-rwxr-xr-x
pal2rgb
15.1
KB
-rwxr-xr-x
palmtopnm
22.54
KB
-rwxr-xr-x
pamaddnoise
15
KB
-rwxr-xr-x
pamarith
16.05
KB
-rwxr-xr-x
pambackground
12.89
KB
-rwxr-xr-x
pambayer
10.98
KB
-rwxr-xr-x
pamchannel
10.95
KB
-rwxr-xr-x
pamcomp
17.52
KB
-rwxr-xr-x
pamcut
16.66
KB
-rwxr-xr-x
pamdeinterlace
10.09
KB
-rwxr-xr-x
pamdepth
10.6
KB
-rwxr-xr-x
pamdice
13.05
KB
-rwxr-xr-x
pamditherbw
21.15
KB
-rwxr-xr-x
pamedge
10.46
KB
-rwxr-xr-x
pamendian
8.87
KB
-rwxr-xr-x
pamenlarge
11.59
KB
-rwxr-xr-x
pamfile
11.27
KB
-rwxr-xr-x
pamfixtrunc
10.57
KB
-rwxr-xr-x
pamflip
18.86
KB
-rwxr-xr-x
pamfunc
13.11
KB
-rwxr-xr-x
pamgauss
11.16
KB
-rwxr-xr-x
pamgradient
11.14
KB
-rwxr-xr-x
pamlookup
12.38
KB
-rwxr-xr-x
pammasksharpen
11.25
KB
-rwxr-xr-x
pammixinterlace
11.98
KB
-rwxr-xr-x
pamoil
10.32
KB
-rwxr-xr-x
pamperspective
24.88
KB
-rwxr-xr-x
pampick
10.97
KB
-rwxr-xr-x
pampop9
9.86
KB
-rwxr-xr-x
pamrgbatopng
10.95
KB
-rwxr-xr-x
pamscale
27.3
KB
-rwxr-xr-x
pamseq
11.04
KB
-rwxr-xr-x
pamsharpmap
10.38
KB
-rwxr-xr-x
pamsharpness
9.7
KB
-rwxr-xr-x
pamsistoaglyph
12.36
KB
-rwxr-xr-x
pamslice
10.39
KB
-rwxr-xr-x
pamsplit
10.94
KB
-rwxr-xr-x
pamstack
11.32
KB
-rwxr-xr-x
pamstereogram
18.3
KB
-rwxr-xr-x
pamstretch
12.76
KB
-rwxr-xr-x
pamstretch-gen
2.13
KB
-rwxr-xr-x
pamsumm
10.62
KB
-rwxr-xr-x
pamsummcol
11.23
KB
-rwxr-xr-x
pamthreshold
15.34
KB
-rwxr-xr-x
pamtilt
16.16
KB
-rwxr-xr-x
pamtodjvurle
11.66
KB
-rwxr-xr-x
pamtofits
11.49
KB
-rwxr-xr-x
pamtogif
20.45
KB
-rwxr-xr-x
pamtohdiff
9.73
KB
-rwxr-xr-x
pamtohtmltbl
11.88
KB
-rwxr-xr-x
pamtojpeg2k
17.98
KB
-rwxr-xr-x
pamtompfont
10.1
KB
-rwxr-xr-x
pamtooctaveimg
11.53
KB
-rwxr-xr-x
pamtopam
9.2
KB
-rwxr-xr-x
pamtopfm
10.88
KB
-rwxr-xr-x
pamtopnm
10.14
KB
-rwxr-xr-x
pamtosvg
77.25
KB
-rwxr-xr-x
pamtotga
16.26
KB
-rwxr-xr-x
pamtotiff
32.83
KB
-rwxr-xr-x
pamtouil
13.08
KB
-rwxr-xr-x
pamtoxvmini
10.9
KB
-rwxr-xr-x
pamundice
14.63
KB
-rwxr-xr-x
pamx
37.57
KB
-rwxr-xr-x
pango-querymodules-64
18.2
KB
-rwxr-xr-x
pango-view
60.86
KB
-rwxr-xr-x
passwd
30.05
KB
-rwsr-xr-x
paste
28.45
KB
-rwxr-xr-x
patch
117.9
KB
-rwxr-xr-x
patgen
33.33
KB
-rwxr-xr-x
pathchk
27.23
KB
-rwxr-xr-x
pax
110.9
KB
-rwxr-xr-x
pbmclean
10.73
KB
-rwxr-xr-x
pbmlife
9.25
KB
-rwxr-xr-x
pbmmake
10.03
KB
-rwxr-xr-x
pbmmask
11.26
KB
-rwxr-xr-x
pbmminkowski
9.69
KB
-rwxr-xr-x
pbmpage
11.35
KB
-rwxr-xr-x
pbmpscale
11.49
KB
-rwxr-xr-x
pbmreduce
11.67
KB
-rwxr-xr-x
pbmtext
15.73
KB
-rwxr-xr-x
pbmtextps
14.95
KB
-rwxr-xr-x
pbmto10x
10.77
KB
-rwxr-xr-x
pbmto4425
9.75
KB
-rwxr-xr-x
pbmtoascii
10.34
KB
-rwxr-xr-x
pbmtoatk
10.58
KB
-rwxr-xr-x
pbmtobbnbg
9.71
KB
-rwxr-xr-x
pbmtocmuwm
9.38
KB
-rwxr-xr-x
pbmtodjvurle
10.05
KB
-rwxr-xr-x
pbmtoepsi
10.23
KB
-rwxr-xr-x
pbmtoepson
11.17
KB
-rwxr-xr-x
pbmtoescp2
10.68
KB
-rwxr-xr-x
pbmtog3
14.6
KB
-rwxr-xr-x
pbmtogem
10.66
KB
-rwxr-xr-x
pbmtogo
11.13
KB
-rwxr-xr-x
pbmtoibm23xx
11.29
KB
-rwxr-xr-x
pbmtoicon
10.13
KB
-rwxr-xr-x
pbmtolj
13.32
KB
-rwxr-xr-x
pbmtoln03
11.26
KB
-rwxr-xr-x
pbmtolps
10.62
KB
-rwxr-xr-x
pbmtomacp
10.97
KB
-rwxr-xr-x
pbmtomatrixorbital
9
KB
-rwxr-xr-x
pbmtomda
11.16
KB
-rwxr-xr-x
pbmtomgr
9.08
KB
-rwxr-xr-x
pbmtomrf
10.66
KB
-rwxr-xr-x
pbmtonokia
13.44
KB
-rwxr-xr-x
pbmtopgm
10.01
KB
-rwxr-xr-x
pbmtopi3
9.73
KB
-rwxr-xr-x
pbmtopk
21.49
KB
-rwxr-xr-x
pbmtoplot
8.88
KB
-rwxr-xr-x
pbmtoppa
28.51
KB
-rwxr-xr-x
pbmtopsg3
13.45
KB
-rwxr-xr-x
pbmtoptx
9.06
KB
-rwxr-xr-x
pbmtowbmp
9.16
KB
-rwxr-xr-x
pbmtox10bm
1.35
KB
-rwxr-xr-x
pbmtoxbm
13.47
KB
-rwxr-xr-x
pbmtoybm
9.31
KB
-rwxr-xr-x
pbmtozinc
10.57
KB
-rwxr-xr-x
pbmupc
17.69
KB
-rwxr-xr-x
pc1toppm
9.97
KB
-rwxr-xr-x
pcdovtoppm
5.43
KB
-rwxr-xr-x
pcregrep
31.66
KB
-rwxr-xr-x
pcretest
48.23
KB
-rwxr-xr-x
pcxtoppm
15.05
KB
-rwxr-xr-x
pdbedit
2.04
MB
-rwxr-xr-x
pdf2dsc
696
B
-rwxr-xr-x
pdf2ps
901
B
-rwxr-xr-x
pdfcrop
8.29
KB
-rwxr-xr-x
pdfcslatex
650.74
KB
-rwxr-xr-x
pdfcsplain
650.74
KB
-rwxr-xr-x
pdfetex
650.74
KB
-rwxr-xr-x
pdffonts
22.33
KB
-rwxr-xr-x
pdfimages
48.73
KB
-rwxr-xr-x
pdfinfo
28.02
KB
-rwxr-xr-x
pdflatex
650.74
KB
-rwxr-xr-x
pdfopt
547
B
-rwxr-xr-x
pdftex
650.74
KB
-rwxr-xr-x
pdftohtml
91.53
KB
-rwxr-xr-x
pdftoppm
23.75
KB
-rwxr-xr-x
pdftops
23.7
KB
-rwxr-xr-x
pdftosrc
14.99
KB
-rwxr-xr-x
pdftotext
25.67
KB
-rwxr-xr-x
peekfd
12.7
KB
-rwxr-xr-x
perf
2.1
MB
-rwxr-xr-x
perl
12.97
KB
-rwxr-xr-x
perl5.10.1
12.97
KB
-rwxr-xr-x
perlbug
43.68
KB
-rwxr-xr-x
perldoc
224
B
-rwxr-xr-x
perlivp
12.01
KB
-rwxr-xr-x
perltex
14.46
KB
-rwxr-xr-x
perlthanks
43.68
KB
-rwxr-xr-x
perror
1.32
MB
-rwxr-xr-x
pf2afm
495
B
-rwxr-xr-x
pfb2pfa
12.09
KB
-rwxr-xr-x
pfbtopfa
511
B
-rwxr-xr-x
pfbtops
10.05
KB
-rwxr-xr-x
pfmtopam
12.52
KB
-rwxr-xr-x
pg_dump
273.87
KB
-rwxr-xr-x
pg_dumpall
79.73
KB
-rwxr-xr-x
pg_restore
125.13
KB
-rwxr-xr-x
pgawk
374.73
KB
-rwxr-xr-x
pgmabel
14.17
KB
-rwxr-xr-x
pgmbentley
8.88
KB
-rwxr-xr-x
pgmcrater
14.16
KB
-rwxr-xr-x
pgmdeshadow
10.02
KB
-rwxr-xr-x
pgmedge
10.46
KB
-rwxr-xr-x
pgmenhance
10.03
KB
-rwxr-xr-x
pgmhist
10.02
KB
-rwxr-xr-x
pgmkernel
9.95
KB
-rwxr-xr-x
pgmmake
10.03
KB
-rwxr-xr-x
pgmmedian
13.79
KB
-rwxr-xr-x
pgmminkowski
10.55
KB
-rwxr-xr-x
pgmmorphconv
11.44
KB
-rwxr-xr-x
pgmnoise
9.73
KB
-rwxr-xr-x
pgmnorm
14.18
KB
-rwxr-xr-x
pgmoil
10.32
KB
-rwxr-xr-x
pgmramp
10.58
KB
-rwxr-xr-x
pgmslice
10.39
KB
-rwxr-xr-x
pgmtexture
24.82
KB
-rwxr-xr-x
pgmtofs
10.15
KB
-rwxr-xr-x
pgmtolispm
10.11
KB
-rwxr-xr-x
pgmtopbm
37
B
-rwxr-xr-x
pgmtopgm
8.91
KB
-rwxr-xr-x
pgmtoppm
11.15
KB
-rwxr-xr-x
pgrep
20.08
KB
-rwxr-xr-x
phar
14.48
KB
-rwxr-xr-x
phar.phar
14.48
KB
-rwxr-xr-x
php
3.88
MB
-rwxr-xr-x
php-cgi
3.86
MB
-rwxr-xr-x
phpize
4.64
KB
-rwxr-xr-x
physe
650.74
KB
-rwxr-xr-x
phyzzx
650.74
KB
-rwxr-xr-x
pi1toppm
9.7
KB
-rwxr-xr-x
pi3topbm
9.73
KB
-rwxr-xr-x
pic
216.12
KB
-rwxr-xr-x
pic2graph
2.5
KB
-rwxr-xr-x
piconv
7.17
KB
-rwxr-xr-x
pidstat
70.03
KB
-rwxr-xr-x
pinentry
2.54
KB
-rwxr-xr-x
pinentry-curses
52.58
KB
-rwxr-xr-x
pinfo
101.66
KB
-rwxr-xr-x
pinky
32.73
KB
-rwxr-xr-x
pjtoppm
12.7
KB
-rwxr-xr-x
pk12util
92.2
KB
-rwxr-xr-x
pk2bm
15.48
KB
-rwxr-xr-x
pkaction
14.02
KB
-rwxr-xr-x
pkcheck
14.02
KB
-rwxr-xr-x
pkexec
22.02
KB
-rwsr-xr-x
pkg-config
108.06
KB
-rwxr-xr-x
pkill
20.08
KB
-rwxr-xr-x
pktogf
25.36
KB
-rwxr-xr-x
pktopbm
16.7
KB
-rwxr-xr-x
pktype
18.84
KB
-rwxr-xr-x
pl2pm
4.42
KB
-rwxr-xr-x
pltotf
61.48
KB
-rwxr-xr-x
plymouth
35.95
KB
-rwxr-xr-x
pm-is-supported
983
B
-rwxr-xr-x
pm-utils-bugreport-info.sh
816
B
-rwxr-xr-x
pmap
15.91
KB
-rwxr-xr-x
png2theora
29.38
KB
-rwxr-xr-x
pngtopam
23.31
KB
-rwxr-xr-x
pngtopnm
22.4
KB
-rwxr-xr-x
pnmalias
13.29
KB
-rwxr-xr-x
pnmarith
16.05
KB
-rwxr-xr-x
pnmcat
16.55
KB
-rwxr-xr-x
pnmcolormap
16.7
KB
-rwxr-xr-x
pnmcomp
17.52
KB
-rwxr-xr-x
pnmconvol
34.2
KB
-rwxr-xr-x
pnmcrop
18.7
KB
-rwxr-xr-x
pnmcut
16.66
KB
-rwxr-xr-x
pnmdepth
10.6
KB
-rwxr-xr-x
pnmenlarge
11.59
KB
-rwxr-xr-x
pnmfile
11.27
KB
-rwxr-xr-x
pnmflip
2.43
KB
-rwxr-xr-x
pnmgamma
17.46
KB
-rwxr-xr-x
pnmhisteq
12.72
KB
-rwxr-xr-x
pnmhistmap
14.3
KB
-rwxr-xr-x
pnmindex
14.94
KB
-rwxr-xr-x
pnminterp
12.76
KB
-rwxr-xr-x
pnminvert
10.1
KB
-rwxr-xr-x
pnmmargin
2.32
KB
-rwxr-xr-x
pnmmontage
15.05
KB
-rwxr-xr-x
pnmnlfilt
22.36
KB
-rwxr-xr-x
pnmnoraw
31
B
-rwxr-xr-x
pnmnorm
14.18
KB
-rwxr-xr-x
pnmpad
17.08
KB
-rwxr-xr-x
pnmpaste
13.45
KB
-rwxr-xr-x
pnmpsnr
11.73
KB
-rwxr-xr-x
pnmquant
7.67
KB
-rwxr-xr-x
pnmremap
19.03
KB
-rwxr-xr-x
pnmrotate
16.13
KB
-rwxr-xr-x
pnmscale
27.3
KB
-rwxr-xr-x
pnmscalefixed
16.26
KB
-rwxr-xr-x
pnmshear
11.89
KB
-rwxr-xr-x
pnmsmooth
11.3
KB
-rwxr-xr-x
pnmsplit
10.94
KB
-rwxr-xr-x
pnmstitch
27.35
KB
-rwxr-xr-x
pnmtile
9.73
KB
-rwxr-xr-x
pnmtoddif
16.73
KB
-rwxr-xr-x
pnmtofiasco
157.32
KB
-rwxr-xr-x
pnmtofits
11.49
KB
-rwxr-xr-x
pnmtojbig
60.86
KB
-rwxr-xr-x
pnmtojpeg
21.91
KB
-rwxr-xr-x
pnmtopalm
23.91
KB
-rwxr-xr-x
pnmtopclxl
17.68
KB
-rwxr-xr-x
pnmtoplainpnm
31
B
-rwxr-xr-x
pnmtopng
40.81
KB
-rwxr-xr-x
pnmtopnm
10.14
KB
-rwxr-xr-x
pnmtops
27.6
KB
-rwxr-xr-x
pnmtorast
16.2
KB
-rwxr-xr-x
pnmtorle
34.88
KB
-rwxr-xr-x
pnmtosgi
13.11
KB
-rwxr-xr-x
pnmtosir
9.96
KB
-rwxr-xr-x
pnmtotiff
32.83
KB
-rwxr-xr-x
pnmtotiffcmyk
29.99
KB
-rwxr-xr-x
pnmtoxwd
12.95
KB
-rwxr-xr-x
pod2html
2.28
KB
-rwxr-xr-x
pod2latex
10.01
KB
-rwxr-xr-x
pod2man
20.68
KB
-rwxr-xr-x
pod2text
8.87
KB
-rwxr-xr-x
pod2usage
3.26
KB
-rwxr-xr-x
podchecker
3.61
KB
-rwxr-xr-x
podselect
2.47
KB
-rwxr-xr-x
pooltype
15.72
KB
-rwxr-xr-x
post-grohtml
136.2
KB
-rwxr-xr-x
poweroff
8.67
KB
-rwxr-xr-x
ppdc
14.51
KB
-rwxr-xr-x
ppdhtml
10.36
KB
-rwxr-xr-x
ppdi
10.3
KB
-rwxr-xr-x
ppdmerge
14.41
KB
-rwxr-xr-x
ppdpo
10.36
KB
-rwxr-xr-x
ppl-config
104.6
KB
-rwxr-xr-x
ppm2tiff
14.86
KB
-rwxr-xr-x
ppm3d
14.56
KB
-rwxr-xr-x
ppmbrighten
12.41
KB
-rwxr-xr-x
ppmchange
10.33
KB
-rwxr-xr-x
ppmcie
25.87
KB
-rwxr-xr-x
ppmcolormask
11.52
KB
-rwxr-xr-x
ppmcolors
8.84
KB
-rwxr-xr-x
ppmdcfont
10.39
KB
-rwxr-xr-x
ppmddumpfont
8.63
KB
-rwxr-xr-x
ppmdim
9.73
KB
-rwxr-xr-x
ppmdist
10.2
KB
-rwxr-xr-x
ppmdither
11.88
KB
-rwxr-xr-x
ppmdmkfont
13.53
KB
-rwxr-xr-x
ppmdraw
18.56
KB
-rwxr-xr-x
ppmfade
10.97
KB
-rwxr-xr-x
ppmflash
9.73
KB
-rwxr-xr-x
ppmforge
22.62
KB
-rwxr-xr-x
ppmglobe
10.16
KB
-rwxr-xr-x
ppmhist
12.13
KB
-rwxr-xr-x
ppmlabel
12.95
KB
-rwxr-xr-x
ppmmake
9.72
KB
-rwxr-xr-x
ppmmix
10.05
KB
-rwxr-xr-x
ppmnorm
14.18
KB
-rwxr-xr-x
ppmntsc
12.65
KB
-rwxr-xr-x
ppmpat
23.12
KB
-rwxr-xr-x
ppmquant
926
B
-rwxr-xr-x
ppmquantall
2.33
KB
-rwxr-xr-x
ppmrainbow
1.79
KB
-rwxr-xr-x
ppmrelief
9.72
KB
-rwxr-xr-x
ppmrough
13.77
KB
-rwxr-xr-x
ppmshadow
8.64
KB
-rwxr-xr-x
ppmshift
10.17
KB
-rwxr-xr-x
ppmspread
10.09
KB
-rwxr-xr-x
ppmtoacad
14.69
KB
-rwxr-xr-x
ppmtoarbtxt
14.73
KB
-rwxr-xr-x
ppmtobmp
18.45
KB
-rwxr-xr-x
ppmtoeyuv
14.1
KB
-rwxr-xr-x
ppmtogif
13.23
KB
-rwxr-xr-x
ppmtoicr
12.45
KB
-rwxr-xr-x
ppmtoilbm
40.15
KB
-rwxr-xr-x
ppmtojpeg
21.91
KB
-rwxr-xr-x
ppmtoleaf
13.05
KB
-rwxr-xr-x
ppmtolj
11.71
KB
-rwxr-xr-x
ppmtomap
82
B
-rwxr-xr-x
ppmtomitsu
19.99
KB
-rwxr-xr-x
ppmtompeg
508.71
KB
-rwxr-xr-x
ppmtoneo
13.06
KB
-rwxr-xr-x
ppmtopcx
17.05
KB
-rwxr-xr-x
ppmtopgm
12.62
KB
-rwxr-xr-x
ppmtopi1
10.05
KB
-rwxr-xr-x
ppmtopict
11.93
KB
-rwxr-xr-x
ppmtopj
12.01
KB
-rwxr-xr-x
ppmtopjxl
15.91
KB
-rwxr-xr-x
ppmtoppm
8.97
KB
-rwxr-xr-x
ppmtopuzz
10.09
KB
-rwxr-xr-x
ppmtorgb3
10.11
KB
-rwxr-xr-x
ppmtosixel
10.87
KB
-rwxr-xr-x
ppmtoterm
9.7
KB
-rwxr-xr-x
ppmtouil
13.08
KB
-rwxr-xr-x
ppmtowinicon
17.41
KB
-rwxr-xr-x
ppmtoxpm
14.53
KB
-rwxr-xr-x
ppmtoyuv
9.71
KB
-rwxr-xr-x
ppmtoyuvsplit
10.9
KB
-rwxr-xr-x
ppmtv
9.73
KB
-rwxr-xr-x
ppmwheel
10.43
KB
-rwxr-xr-x
pr
62.8
KB
-rwxr-xr-x
pre-grohtml
76.61
KB
-rwxr-xr-x
printafm
386
B
-rwxr-xr-x
printenv
25.66
KB
-rwxr-xr-x
printf
48.91
KB
-rwxr-xr-x
profiles
1.59
MB
-rwxr-xr-x
protoize
70.42
KB
-rwxr-xr-x
prove
9.15
KB
-rwxr-xr-x
proxy
10.72
KB
-rwxr-xr-x
ps2ascii
786
B
-rwxr-xr-x
ps2epsi
2.71
KB
-rwxr-xr-x
ps2frag
229
B
-rwxr-xr-x
ps2pdf
315
B
-rwxr-xr-x
ps2pdf12
260
B
-rwxr-xr-x
ps2pdf13
260
B
-rwxr-xr-x
ps2pdf14
260
B
-rwxr-xr-x
ps2pdfwr
1.06
KB
-rwxr-xr-x
ps2pk
135.38
KB
-rwxr-xr-x
ps2ps
634
B
-rwxr-xr-x
ps2ps2
704
B
-rwxr-xr-x
ps4pdf
4.19
KB
-rwxr-xr-x
psbook
18.52
KB
-rwxr-xr-x
psed
52.08
KB
-rwxr-xr-x
psfaddtable
20.52
KB
-rwxr-xr-x
psfgettable
20.52
KB
-rwxr-xr-x
psfstriptable
20.52
KB
-rwxr-xr-x
psfxtable
20.52
KB
-rwxr-xr-x
psidtopgm
10.18
KB
-rwxr-xr-x
pslatex
1.41
KB
-rwxr-xr-x
psnup
26.8
KB
-rwxr-xr-x
psql
334.97
KB
-rwxr-xr-x
psresize
24.37
KB
-rwxr-xr-x
psselect
19.83
KB
-rwxr-xr-x
pstack
1.1
KB
-rwxr-xr-x
pstopnm
19.6
KB
-rwxr-xr-x
pstops
25.27
KB
-rwxr-xr-x
pstree
24.66
KB
-rwxr-xr-x
pstree.x11
24.66
KB
-rwxr-xr-x
pstruct
35.74
KB
-rwxr-xr-x
ptar
2.72
KB
-rwxr-xr-x
ptardiff
2.46
KB
-rwxr-xr-x
ptx
126.56
KB
-rwxr-xr-x
pv.sh
1.39
KB
-rwxr-xr-x
pwdx
9.91
KB
-rwxr-xr-x
pydoc
78
B
-rwxr-xr-x
pygmentize
141
B
-rwxr-xr-x
python
8.82
KB
-rwxr-xr-x
python2
8.82
KB
-rwxr-xr-x
python2.6
8.82
KB
-rwxr-xr-x
qdbus
63.64
KB
-rwxr-xr-x
qdbusviewer
182.99
KB
-rwxr-xr-x
qrttoppm
9.73
KB
-rwxr-xr-x
qtconfig-qt4
342.75
KB
-rwxr-xr-x
quota
80.81
KB
-rwxr-xr-x
quotasync
64.69
KB
-rwxr-xr-x
ranlib
59.55
KB
-rwxr-xr-x
ras2tiff
14.33
KB
-rwxr-xr-x
rasttopnm
15.35
KB
-rwxr-xr-x
raw2tiff
19.59
KB
-rwxr-xr-x
rawtopgm
12.34
KB
-rwxr-xr-x
rawtoppm
11.77
KB
-rwxr-xr-x
rcs
90.95
KB
-rwxr-xr-x
rcs-checkin
3.88
KB
-rwxr-xr-x
rcs2log
19.12
KB
-rwxr-xr-x
rcsclean
85.66
KB
-rwxr-xr-x
rcsdiff
65.53
KB
-rwxr-xr-x
rcsfreeze
3.15
KB
-rwxr-xr-x
rcsmerge
65.53
KB
-rwxr-xr-x
rdate
13.24
KB
-rwxr-xr-x
rdjpgcom
12.19
KB
-rwxr-xr-x
readelf
296.33
KB
-rwxr-xr-x
readlink
39.12
KB
-rwxr-xr-x
reboot
8.67
KB
-rwxr-xr-x
rebuild-gcj-db
441
B
-rwxr-xr-x
rebuild-jar-repository
1.76
KB
-rwxr-xr-x
recode-sr-latin
15.16
KB
-rwxr-xr-x
recountdiff
3.36
KB
-rwxr-xr-x
rediff
36.25
KB
-rwxr-xr-x
refer
125.91
KB
-rwxr-xr-x
reindexdb
59.5
KB
-rwxr-xr-x
rename
9.66
KB
-rwxr-xr-x
renice
10.38
KB
-rwxr-xr-x
replace
1.32
MB
-rwxr-xr-x
repo-graph
4.1
KB
-rwxr-xr-x
repo-rss
9.99
KB
-rwxr-xr-x
repoclosure
11.35
KB
-rwxr-xr-x
repodiff
11.63
KB
-rwxr-xr-x
repomanage
6.88
KB
-rwxr-xr-x
repoquery
45.03
KB
-rwxr-xr-x
report
19.87
KB
-rwxr-xr-x
report-cli
39.41
KB
-rwxr-xr-x
reporter-kerneloops
28.23
KB
-rwxr-xr-x
reporter-mailx
23.69
KB
-rwxr-xr-x
reporter-print
22.07
KB
-rwxr-xr-x
reporter-rhtsupport
55.41
KB
-rwxr-xr-x
reporter-upload
29.73
KB
-rwxr-xr-x
reporter-ureport
34.34
KB
-rwxr-xr-x
reposync
14.74
KB
-rwxr-xr-x
repotrack
8.54
KB
-rwxr-xr-x
reset
21.91
KB
-rwxr-xr-x
resize
17.88
KB
-rwxr-xr-x
resizecons
19.06
KB
-rwxr-xr-x
resolve_stack_dump
1.32
MB
-rwxr-xr-x
resolveip
1.32
MB
-rwxr-xr-x
rev
9.93
KB
-rwxr-xr-x
rgb2ycbcr
15.7
KB
-rwxr-xr-x
rgb3toppm
9.72
KB
-rwxr-xr-x
rhgb-client
35.95
KB
-rwxr-xr-x
rlatopam
13.01
KB
-rwxr-xr-x
rletopnm
31.41
KB
-rwxr-xr-x
rlog
70.2
KB
-rwxr-xr-x
rmail
262
B
-rwxr-xr-x
rmail.postfix
262
B
-rwxr-xr-x
rmid
9.81
KB
-rwxr-xr-x
rmiregistry
9.82
KB
-rwxr-xr-x
rnano
174.7
KB
-rwxr-xr-x
rngtest
16.45
KB
-rwxr-xr-x
rpcclient
7.41
MB
-rwxr-xr-x
rpcgen
93.46
KB
-rwxr-xr-x
rpm2cpio
15.73
KB
-rwxr-xr-x
rpmbuild
34.41
KB
-rwxr-xr-x
rpmdb
29.98
KB
-rwxr-xr-x
rpmquery
29.98
KB
-rwxr-xr-x
rpmsign
29.98
KB
-rwxr-xr-x
rpmverify
29.98
KB
-rwxr-xr-x
rsvg
2.44
KB
-rwxr-xr-x
rsvg-convert
27.82
KB
-rwxr-xr-x
rsvg-view
42.67
KB
-rwxr-xr-x
rsync
405.24
KB
-rwxr-xr-x
rubibtex
2.52
KB
-rwxr-xr-x
rumakeindex
1.75
KB
-rwxr-xr-x
run-parts
1.38
KB
-rwxr-xr-x
runcon
31.16
KB
-rwxr-xr-x
rvim
2.22
MB
-rwxr-xr-x
s2p
52.08
KB
-rwxr-xr-x
sadf
111.99
KB
-rwxr-xr-x
sar
82.96
KB
-rwxr-xr-x
satyr
22.85
KB
-rwxr-xr-x
sbigtopgm
11.43
KB
-rwxr-xr-x
scl
21.48
KB
-rwxr-xr-x
scl_enabled
258
B
-rwxr-xr-x
scl_source
1.83
KB
-rwxr-xr-x
scp
66.06
KB
-rwxr-xr-x
script
16.24
KB
-rwxr-xr-x
scriptreplay
10.91
KB
-rwxr-xr-x
scs2ascii
13.52
KB
-rwxr-xr-x
scs2pdf
26.78
KB
-rwxr-xr-x
scs2ps
15.09
KB
-rwxr-xr-x
sctp_darn
42.79
KB
-rwxr-xr-x
sctp_status
22.45
KB
-rwxr-xr-x
sctp_test
31.59
KB
-rwxr-xr-x
sdiff
28.32
KB
-rwxr-xr-x
secon
18.39
KB
-rwxr-xr-x
sedismod
169.45
KB
-rwxr-xr-x
sedispol
142.02
KB
-rwxr-xr-x
seekwatcher
32.28
KB
-rwxr-xr-x
selfsign-getcert
130.03
KB
-rwxr-xr-x
semodule_deps
194.95
KB
-rwxr-xr-x
semodule_expand
10.34
KB
-rwxr-xr-x
semodule_link
10.27
KB
-rwxr-xr-x
semodule_package
14.59
KB
-rwxr-xr-x
seq
42.91
KB
-rwxr-xr-x
servertool
9.84
KB
-rwxr-xr-x
setarch
13.59
KB
-rwxr-xr-x
setcifsacl
18.29
KB
-rwxr-xr-x
setfacl
36.15
KB
-rwxr-xr-x
setfattr
18.02
KB
-rwxr-xr-x
setkeycodes
10.23
KB
-rwxr-xr-x
setleds
11.98
KB
-rwxr-xr-x
setmetamode
9.74
KB
-rwxr-xr-x
setsid
8.59
KB
-rwxr-xr-x
setterm
25.1
KB
-rwxr-xr-x
setup
8.67
KB
-rwxr-xr-x
setup-nsssysinit.sh
1.5
KB
-rwxr-xr-x
sftp
102.07
KB
-rwxr-xr-x
sg
39.3
KB
-rwsr-xr-x
sgitopnm
14.65
KB
-rwxr-xr-x
sgmlwhich
265
B
-rwxr-xr-x
sha1sum
38.98
KB
-rwxr-xr-x
sha224sum
44.7
KB
-rwxr-xr-x
sha256sum
44.7
KB
-rwxr-xr-x
sha384sum
49.91
KB
-rwxr-xr-x
sha512sum
49.91
KB
-rwxr-xr-x
sharesec
1.57
MB
-rwxr-xr-x
shasum
7.48
KB
-rwxr-xr-x
show-changed-rco
10.11
KB
-rwxr-xr-x
show-installed
16.18
KB
-rwxr-xr-x
showchar
2.51
KB
-rwxr-xr-x
showconsolefont
17.26
KB
-rwxr-xr-x
showkey
13.78
KB
-rwxr-xr-x
shred
50.23
KB
-rwxr-xr-x
shuf
38.03
KB
-rwxr-xr-x
signtool
168.09
KB
-rwxr-xr-x
signver
91.64
KB
-rwxr-xr-x
sinjdoc
132
B
-rw-r-xr-x
sirtopnm
10.22
KB
-rwxr-xr-x
size
32.95
KB
-rwxr-xr-x
skill
18.31
KB
-rwxr-xr-x
slabtop
17.16
KB
-rwxr-xr-x
sldtoppm
17.45
KB
-rwxr-xr-x
slogin
440.16
KB
-rwxr-xr-x
smbcacls
6.1
MB
-rwxr-xr-x
smbclient
6.14
MB
-rwxr-xr-x
smbcontrol
1.6
MB
-rwxr-xr-x
smbcquotas
6.09
MB
-rwxr-xr-x
smbget
6.33
MB
-rwxr-xr-x
smbpasswd
6.12
MB
-rwxr-xr-x
smbprint
2.24
KB
-rwxr-xr-x
smbspool
3.31
MB
-rwxr-xr-x
smbta-util
1.56
MB
-rwxr-xr-x
smbtar
4.78
KB
-rwxr-xr-x
smbtree
6.03
MB
-rwxr-xr-x
sndfile-cmp
10.42
KB
-rwxr-xr-x
sndfile-convert
18.83
KB
-rwxr-xr-x
sndfile-info
14.2
KB
-rwxr-xr-x
sndfile-metadata-get
12.62
KB
-rwxr-xr-x
sndfile-metadata-set
18.17
KB
-rwxr-xr-x
sndfile-play
17.83
KB
-rwxr-xr-x
sndfile-regtest
19.54
KB
-rwxr-xr-x
snice
18.31
KB
-rwxr-xr-x
soelim
25.58
KB
-rwxr-xr-x
spctoppm
10.02
KB
-rwxr-xr-x
speaker-test
34.23
KB
-rwxr-xr-x
splain
17.04
KB
-rwxr-xr-x
split
54.06
KB
-rwxr-xr-x
splitdiff
2.96
KB
-rwxr-xr-x
spottopgm
10.99
KB
-rwxr-xr-x
sprof
26.2
KB
-rwxr-xr-x
sputoppm
9.19
KB
-rwxr-xr-x
sqlite3
58
KB
-rwxr-xr-x
ssh
440.16
KB
-rwxr-xr-x
ssh-add
155.2
KB
-rwxr-xr-x
ssh-agent
138.07
KB
-rwxr-sr-x
ssh-copy-id
1.39
KB
-rwxr-xr-x
ssh-keygen
195.2
KB
-rwxr-xr-x
ssh-keyscan
247.8
KB
-rwxr-xr-x
ssltap
115.44
KB
-rwxr-xr-x
sss_ssh_authorizedkeys
33.24
KB
-rwxr-xr-x
sss_ssh_knownhostsproxy
35.95
KB
-rwxr-xr-x
stap
2.92
MB
-rwxr-xr-x
stap-merge
10.02
KB
-rwxr-xr-x
stap-prep
3.79
KB
-rwxr-xr-x
stap-report
4.41
KB
-rwxr-xr-x
staprun
178.78
KB
---s--x---
stapsh
26.09
KB
-rwxr-xr-x
stat
49.79
KB
-rwxr-xr-x
stdbuf
61.98
KB
-rwxr-xr-x
strace
425.97
KB
-rwxr-xr-x
strace-log-merge
944
B
-rwxr-xr-x
strings
31.7
KB
-rwxr-xr-x
strip
213.94
KB
-rwxr-xr-x
sudo
120.93
KB
---s--x--x
sudoedit
120.93
KB
---s--x--x
sudoreplay
62.34
KB
---x--x--x
sum
33.82
KB
-rwxr-xr-x
svn
195.63
KB
-rwxr-xr-x
svnadmin
61.46
KB
-rwxr-xr-x
svndumpfilter
33.09
KB
-rwxr-xr-x
svnlook
61.07
KB
-rwxr-xr-x
svnsync
43.66
KB
-rwxr-xr-x
svnversion
11.28
KB
-rwxr-xr-x
swig
1.09
MB
-rwxr-xr-x
system-config-firewall-tui
1.13
KB
-rwxr-xr-x
system-config-network
8.67
KB
-rwxr-xr-x
system-config-network-cmd
8.67
KB
-rwxr-xr-x
tabs
14.14
KB
-rwxr-xr-x
tac
94
KB
-rwxr-xr-x
tail
60.05
KB
-rwxr-xr-x
tailf
11.66
KB
-rwxr-xr-x
tangle
46.31
KB
-rwxr-xr-x
tbl
103.23
KB
-rwxr-xr-x
tcpdf_addfont
7.28
KB
-rwxr-xr-x
tee
27.1
KB
-rwxr-xr-x
test
33.02
KB
-rwxr-xr-x
testparm
1.57
MB
-rwxr-xr-x
tex
281.8
KB
-rwxr-xr-x
texconfig
43.33
KB
-rwxr-xr-x
texconfig-dialog
12.75
KB
-rwxr-xr-x
texconfig-sys
838
B
-rwxr-xr-x
texhash
5.66
KB
-rwxr-xr-x
texlinks
8.66
KB
-rwxr-xr-x
texsis
650.74
KB
-rwxr-xr-x
tfmtodit
30.16
KB
-rwxr-xr-x
tftopl
46.8
KB
-rwxr-xr-x
tgatoppm
13.73
KB
-rwxr-xr-x
theora_dump_video
17.2
KB
-rwxr-xr-x
theora_encode
45.05
KB
-rwxr-xr-x
theora_player
266
B
-rwxr-xr-x
theora_player.bin
26.41
KB
-rwxr-xr-x
thinkjettopbm
22.05
KB
-rwxr-xr-x
thumbnail
19.32
KB
-rwxr-xr-x
thumbpdf
40.59
KB
-rwxr-xr-x
tic
52.52
KB
-rwxr-xr-x
tie
14.8
KB
-rwxr-xr-x
tiff2bw
16.05
KB
-rwxr-xr-x
tiff2pdf
67.74
KB
-rwxr-xr-x
tiff2ps
45.01
KB
-rwxr-xr-x
tiff2rgba
15.59
KB
-rwxr-xr-x
tiffcmp
18.64
KB
-rwxr-xr-x
tiffcp
35.16
KB
-rwxr-xr-x
tiffcrop
101.85
KB
-rwxr-xr-x
tiffdither
14.37
KB
-rwxr-xr-x
tiffdump
20.45
KB
-rwxr-xr-x
tiffinfo
17.95
KB
-rwxr-xr-x
tiffmedian
18.83
KB
-rwxr-xr-x
tiffset
12.77
KB
-rwxr-xr-x
tiffsplit
14.85
KB
-rwxr-xr-x
tifftopnm
36.16
KB
-rwxr-xr-x
time
17.51
KB
-rwxr-xr-x
timeout
49
KB
-rwxr-xr-x
tload
11.53
KB
-rwxr-xr-x
tmpwatch
21.15
KB
-rwxr-xr-x
tn5250
36.44
KB
-rwxr-xr-x
tnameserv
10.04
KB
-rwxr-xr-x
toe
15.13
KB
-rwxr-xr-x
tomcat6-digest
1.06
KB
-rwxr-xr-x
tomcat6-tool-wrapper
1.02
KB
-rwxr-xr-x
top
66.77
KB
-rwxr-xr-x
tput
14.91
KB
-rwxr-xr-x
tr
40.48
KB
-rwxr-xr-x
trace-cmd
269.22
KB
-rwxr-xr-x
troff
355.09
KB
-rwxr-xr-x
truncate
49.96
KB
-rwxr-xr-x
tset
21.91
KB
-rwxr-xr-x
tsort
35.02
KB
-rwxr-xr-x
ttmkfdir
107.1
KB
-rwxr-xr-x
tty
24.87
KB
-rwxr-xr-x
tzselect
6.96
KB
-rwxr-xr-x
ucs2any
21.34
KB
-rwxr-xr-x
ul
17.12
KB
-rwxr-xr-x
unexpand
31.01
KB
-rwxr-xr-x
uniq
38.09
KB
-rwxr-xr-x
unix-lpr.sh
4.11
KB
-rwxr-xr-x
unlzma
50.63
KB
-rwxr-xr-x
unpack200
89.75
KB
-rwxr-xr-x
unprotoize
60.15
KB
-rwxr-xr-x
unshare
12.9
KB
-rwxr-xr-x
unwrapdiff
5.8
KB
-rwxr-xr-x
unxz
50.63
KB
-rwxr-xr-x
unzip
165.79
KB
-rwxr-xr-x
unzipsfx
79.17
KB
-rwxr-xr-x
update-ca-trust
8.54
KB
-rwxr-xr-x
update-desktop-database
18.18
KB
-rwxr-xr-x
update-gdk-pixbuf-loaders
484
B
-rwxr-xr-x
update-gio-modules
319
B
-rw-r--r--
update-gtk-immodules
313
B
-rwxr-xr-x
update-mime-database
49.73
KB
-rwxr-xr-x
updatedb
39.77
KB
-rwxr-xr-x
updmap
46.06
KB
-rwxr-xr-x
updmap-sys
829
B
-rwxr-xr-x
uptime
8.16
KB
-rwxr-xr-x
urlgrabber
12.15
KB
-rwxr-xr-x
usb-devices
4.1
KB
-rwxr-xr-x
usbhid-dump
23.39
KB
-rwxr-xr-x
users
27.06
KB
-rwxr-xr-x
utmpdump
13.86
KB
-rwxr-xr-x
uuidgen
9.14
KB
-rwxr-xr-x
uxterm
3.59
KB
-rwxr-xr-x
vacuumdb
37.89
KB
-rwxr-xr-x
valgrind
45.66
KB
-rwxr-xr-x
valgrind-listener
27.78
KB
-rwxr-xr-x
vdir
114.3
KB
-rwxr-xr-x
verify_blkparse
9.63
KB
-rwxr-xr-x
verifytree
9.19
KB
-rwxr-xr-x
vftovp
51.98
KB
-rwxr-xr-x
vgdb
95.42
KB
-rwxr-xr-x
vim
2.22
MB
-rwxr-xr-x
vimdiff
2.22
MB
-rwxr-xr-x
vimtutor
2.04
KB
-rwxr-xr-x
vmstat
24.3
KB
-rwxr-xr-x
vnstat
94.77
KB
-rwxr-xr-x
vnstati
83.65
KB
-rwxr-xr-x
volname
8.7
KB
-rwxr-xr-x
vptovf
60.27
KB
-rwxr-xr-x
w
16.22
KB
-rwxr-xr-x
wall
14.87
KB
-r-xr-sr-x
watch
16.46
KB
-rwxr-xr-x
watchgnupg
13.84
KB
-rwxr-xr-x
wbinfo
1.64
MB
-rwxr-xr-x
wbmptopbm
9.71
KB
-rwxr-xr-x
wc
35.55
KB
-rwxr-xr-x
wcmgr
25.78
KB
-rwxr-xr-x
weave
67.33
KB
-rwxr-xr-x
webalizer
172.85
KB
-rwxr-xr-x
webazolver
172.85
KB
-rwxr-xr-x
wftopfa
284
B
-rwxr-xr-x
wget
358.25
KB
-rwxr-xr-x
whatis
1.74
KB
-rwxr-xr-x
whereis
14.27
KB
-rwxr-xr-x
which
24.93
KB
-rwxr-xr-x
whiptail
29.59
KB
-rwxr-xr-x
who
47.8
KB
-rwxr-xr-x
whoami
25.66
KB
-rwxr-xr-x
winicontoppm
16.57
KB
-rwxr-xr-x
withsctp
227
B
-rwxr-xr-x
write
11.73
KB
-rwxr-sr-x
wrjpgcom
12.89
KB
-rwxr-xr-x
x3270
1.26
MB
-rwxr-xr-x
x3270if
19.76
KB
-rwxr-xr-x
x86_64
13.59
KB
-rwxr-xr-x
x86_64-redhat-linux-c++
264.98
KB
-rwxr-xr-x
x86_64-redhat-linux-g++
264.98
KB
-rwxr-xr-x
x86_64-redhat-linux-gcc
265.34
KB
-rwxr-xr-x
xargs
45.55
KB
-rwxr-xr-x
xbmtopbm
13.3
KB
-rwxr-xr-x
xdg-desktop-icon
14.7
KB
-rwxr-xr-x
xdg-desktop-menu
37.06
KB
-rwxr-xr-x
xdg-email
18.61
KB
-rwxr-xr-x
xdg-icon-resource
23.89
KB
-rwxr-xr-x
xdg-mime
28.88
KB
-rwxr-xr-x
xdg-open
10.94
KB
-rwxr-xr-x
xdg-screensaver
20.57
KB
-rwxr-xr-x
xdg-settings
24.47
KB
-rwxr-xr-x
xgettext
219.69
KB
-rwxr-xr-x
ximtoppm
14.28
KB
-rwxr-xr-x
xml-resolver
514
B
-rwxr-xr-x
xml-xparse
508
B
-rwxr-xr-x
xml-xread
505
B
-rwxr-xr-x
xml_grep
12.88
KB
-rwxr-xr-x
xml_merge
3.98
KB
-rwxr-xr-x
xml_pp
7.57
KB
-rwxr-xr-x
xml_spellcheck
6.44
KB
-rwxr-xr-x
xml_split
21.13
KB
-rwxr-xr-x
xmlcatalog
19.09
KB
-rwxr-xr-x
xmllint
63.34
KB
-rwxr-xr-x
xmlwf
25.47
KB
-rwxr-xr-x
xpmtoppm
18.11
KB
-rwxr-xr-x
xsltproc
28.88
KB
-rwxr-xr-x
xsubpp
4
KB
-rwxr-xr-x
xt5250
2.71
KB
-rwxr-xr-x
xterm
414.13
KB
-rwxr-xr-x
xvminitoppm
10.64
KB
-rwxr-xr-x
xwdtopnm
21.57
KB
-rwxr-xr-x
xxd
18.24
KB
-rwxr-xr-x
xz
50.63
KB
-rwxr-xr-x
xzcat
50.63
KB
-rwxr-xr-x
xzcmp
5.1
KB
-rwxr-xr-x
xzdec
15.07
KB
-rwxr-xr-x
xzdiff
5.1
KB
-rwxr-xr-x
xzegrep
5.36
KB
-rwxr-xr-x
xzfgrep
5.36
KB
-rwxr-xr-x
xzgrep
5.36
KB
-rwxr-xr-x
xzless
1.76
KB
-rwxr-xr-x
xzmore
2.12
KB
-rwxr-xr-x
yacc
76.46
KB
-rwxr-xr-x
ybmtopbm
9.74
KB
-rwxr-xr-x
yes
25.06
KB
-rwxr-xr-x
ypcat
15.79
KB
-rwxr-xr-x
ypchfn
25.41
KB
-rwxr-xr-x
ypchsh
25.41
KB
-rwxr-xr-x
ypmatch
13.66
KB
-rwxr-xr-x
yppasswd
25.41
KB
-rwxr-xr-x
ypwhich
17.14
KB
-rwxr-xr-x
yum
801
B
-rwxr-xr-x
yum-builddep
8.34
KB
-rwxr-xr-x
yum-config-manager
8.32
KB
-rwxr-xr-x
yum-debug-dump
7.42
KB
-rwxr-xr-x
yum-debug-restore
7.75
KB
-rwxr-xr-x
yum-groups-manager
10.77
KB
-rwxr-xr-x
yumdownloader
12
KB
-rwxr-xr-x
yuvsplittoppm
11.7
KB
-rwxr-xr-x
yuvtoppm
10.13
KB
-rwxr-xr-x
zcmp
67
B
-rwxr-xr-x
zdiff
4.34
KB
-rwxr-xr-x
zegrep
62
B
-rwxr-xr-x
zeisstopnm
10.47
KB
-rwxr-xr-x
zfgrep
62
B
-rwxr-xr-x
zforce
1.98
KB
-rwxr-xr-x
zgrep
4.86
KB
-rwxr-xr-x
zip
210.51
KB
-rwxr-xr-x
zipcloak
107.13
KB
-rwxr-xr-x
zipgrep
2.88
KB
-rwxr-xr-x
zipinfo
165.79
KB
-rwxr-xr-x
zipnote
99.47
KB
-rwxr-xr-x
zipsplit
102.81
KB
-rwxr-xr-x
zless
1.69
KB
-rwxr-xr-x
zmore
2.54
KB
-rwxr-xr-x
znew
5.12
KB
-rwxr-xr-x
zsoelim
25.58
KB
-rwxr-xr-x
zts-php
4.09
MB
-rwxr-xr-x
Delete
Unzip
Zip
${this.title}
Close
Code Editor : foomatic-configure
#!/usr/bin/perl -w use strict; # -*- perl -*- # This is foomatic-configure, a program to establish and configure # print queues, drivers, spoolers, etc using the foomatic database and # companion filters. # It also comprises half of a programatic API for user tools: you can # learn and control everything about the static properties of print # queues here. With the sister program foomatic-printjob, you can do # everything related to print queue dynamic state: submit jobs, and # query, cancel, reorder, and redirect them. use Foomatic::Defaults; use Foomatic::DB; use Data::Dumper; # Connect syntax: # # This differs a tad from CUPS's, partly because everything is # supposed to be a file, and CUPS doesn't entirely reflect that. # But I'm not really very particular... # # If a certain URI is not supported by all the spoolers, the spoolers # which support it are listed in parantheses, "direct" means direct, # spooler-less printing. # # usb:/path/device # Local USB printer # usb://make/model?serial=xxx # Printer-bound USB connection (CUPS) # parallel:/path/device # Local parallel printer # serial:/path/device # Local serial printer # file:/path/file # includes usb, lp, named pipes, other # hp:/bus/model?serial=xxx # HPLIP print queue (hpinkjet.sf.net) # hpfax:/bus/model?serial=xxx # HPLIP fax queue (hpinkjet.sf.net) # ptal:/provider:bus:name # HPOJ MLC protocol (hpoj.sf.net,obsolete) # mtink:/path/device # Epson inkjet through mtink daemon # # (for ink level monitoring when printing, # # http://xwtools.automatix.de/) # lpd://host/queue # LPD protocol # lpd://host # LPD protocol (default queue, CUPS only) # socket://host:port # TCP aka appsocket # socket://host # TCP aka appsocket (port 9100) # ncp://user:pass@host/queue # Netware (LPD, LPRng, direct) # smb://user:pass@wgrp/host/queue # Windows (CUPS, PPR, LPD, LPRng, direct) # stdout # Standard output (direct) # postpipe:"<command line>" # Free-formed backend command line # # (LPD, LPRng, direct) # # Read out the program name with which we were called, but discard the path $0 =~ m!/([^/]+)\s*$!; my $progname = ($1 || $0); my $debug = 0; # We use the library Getopt::Long here, so that we can have more than # one "-o" option on one command line. my($opt_q, $opt_f, $opt_w, $opt_n, $opt_N, $opt_L, $opt_ppd, $opt_d, $opt_p, $opt_s, $opt_C, $opt_R, $opt_D, $opt_Q, $opt_P, $opt_O, $opt_X, $opt_c, @opt_o, $opt_r, $opt_dd, $opt_nodd, $opt_att, $opt_delay, $opt_h); use Getopt::Long; Getopt::Long::Configure("no_ignore_case"); GetOptions("q" => \$opt_q, # Quiet, non-interactive operation "f" => \$opt_f, # Force rebuild of PPD from database "w" => \$opt_w, # Cut GUI strings in the PPD to 39 # characters (for CUPS Windows driver) "n=s" => \$opt_n, # queue Name "N=s" => \$opt_N, # human-readable Name (Model, # Description) "L=s" => \$opt_L, # Location "ppd=s" => \$opt_ppd, # PPD file "d=s" => \$opt_d, # Driver "p=s" => \$opt_p, # Printer "s=s" => \$opt_s, # Spooler "C" => \$opt_C, # Copy queue "R" => \$opt_R, # Remove queue "D" => \$opt_D, # set Default queue "Q" => \$opt_Q, # Query queue info "P" => \$opt_P, # Perl queue/printer/driver info output "O" => \$opt_O, # get printer support Overview "X" => \$opt_X, # query XML printer/driver/combo info "c=s" => \$opt_c, # printer Connection type "o=s" => \@opt_o, # default printing Options "r" => \$opt_r, # list Remote queues "backend-dont-disable=s" => \$opt_dd, # Do not disable CUPS # backends "backend-attempts=s" => \$opt_att, # Try that often when backend # fails "backend-delay=s" => \$opt_delay, # Delay in seconds between # retries of failed backend "h" => \$opt_h, # Help! "help"=> \$opt_h) || help(); help() if $opt_h; my $db = new Foomatic::DB; overview() if $opt_O; get_xml() if $opt_X; my $force = ($opt_f ? 1 : 0); my $shortgui = ($opt_w ? 1 : 0); my $in_config = {'queue' => $opt_n, 'desc' => $opt_N, 'loc' => $opt_L, 'ppdfile' => $opt_ppd, 'driver' => $opt_d, 'printer' => $opt_p, 'spooler' => $opt_s, 'connect' => $opt_c, 'options' => \@opt_o, 'force' => $force, 'shortgui' => $shortgui, 'dd' => $opt_dd, 'att' => $opt_att, 'delay' => $opt_delay, 'foomatic' => 1}; # If description and location contain only whitespace, use an empty string # instead if ((defined($in_config->{'desc'})) && ($in_config->{'desc'} =~ m!^\s*$!)) { $in_config->{'desc'} = ""; } if ((defined($in_config->{'loc'})) && ($in_config->{'loc'} =~ m!^\s*$!)) { $in_config->{'loc'} = ""; } my $action = ($opt_R ? 'delete' : 'configure'); $action = ($opt_D ? 'default' : $action); $action = ($opt_Q ? 'query' : $action); $action = ($opt_P ? 'query' : $action); my $procs = { 'lpd' => { 'delete' => \&delete_lpd, 'configure' => \&setup_lpd, 'default' => \&default_lpd, 'query' => \&query_lpd }, 'lprng'=>{ 'delete' => \&delete_lpd, 'query' => \&query_lpd, 'default' => \&default_lprng, 'configure' => \&setup_lpd }, 'cups' =>{ 'delete' => \&delete_cups, 'query' => \&query_cups, 'default' => \&default_cups, 'configure' => \&setup_cups }, 'pdq' =>{ 'delete' => \&delete_pdq, 'query' => \&query_pdq, 'default' => \&default_pdq, 'configure' => \&setup_pdq }, 'ppr' =>{ 'delete' => \&delete_ppr, 'query' => \&query_ppr, 'default' => \&default_ppr, 'configure' => \&setup_ppr }, 'direct'=>{'delete' => \&delete_direct, 'query' => \&query_direct, 'default' => \&default_direct, 'configure' => \&setup_direct } }; if (!($opt_Q or $opt_P or defined($in_config->{'queue'}))) { # No queue manipulation without knowing the name of the queue print STDERR "You must specify a queue name with -n!\n"; help(); exit 1; } if (!defined($in_config->{'spooler'})) { my $takenfromconfigfile = 0; # Personal default spooler my $s; if (($> != 0) && (-f "$ENV{'HOME'}/.defaultspooler")) { $s = `cat $ENV{'HOME'}/.defaultspooler`; chomp $s; $takenfromconfigfile = 1; } # System default spooler if ((!defined($s)) && (-f "$sysdeps->{'foo-etc'}/defaultspooler")) { $s = `cat $sysdeps->{'foo-etc'}/defaultspooler`; chomp $s; $takenfromconfigfile = 1; } if (!defined($s)) { $s = detect_spooler(); } die "Unable to identify spooler, please specify with -s\n" unless $s; if ((!$opt_q) && (!$takenfromconfigfile)) { print STDERR "You appear to be using $s. Correct? "; my $yn = <STDIN>; die "\n" if ($yn !~ m!^y!i); } $in_config->{'spooler'} = $s; } if ($in_config->{'printer'}) { # If the user supplies an old numerical printer ID, translate it to # a new clear-text ID $in_config->{'printer'} = Foomatic::DB::translate_printer_id($in_config->{'printer'}); } # Call proper proc &{$procs->{$in_config->{'spooler'}}{$action}}($in_config); exit(0); # Common parts for queue creation/modification functions sub getoldqueuedata { my ($config, $reconf) = @_; my ($sourcespooler, $sourcequeue, $olddatablob, $beh); # Copy a queue if ($opt_C) { if ($#ARGV == 0) { # 1 argument -> queue from same spooler $sourcespooler = $config->{'spooler'}; $sourcequeue = $ARGV[0]; } elsif ($#ARGV == 1) { # 2 arguments -> queue from given spooler $sourcespooler = $ARGV[0]; $sourcequeue = $ARGV[1]; } else { die "Unsufficient options to copy a queue, " . "try \"$progname -h\"!\n"; } # Read data from source queue if (!($olddatablob = load_datablob($sourcespooler, $sourcequeue))) { # It is not possible to copy the given source queue die "The source queue $sourcequeue does not exist " . "or is corrupted!\n"; } # PPD file of the source queue, if it exists, and if the user # does not insist on using another PPD file, we must copy it my $sourceppd = $olddatablob->{'ppdfile'}; if ((-r $sourceppd) && (!$config->{'ppdfile'})) { $config->{'ppdfile'} = $sourceppd; } # Stuff data into the $config structure, all items must be defined, # so that an old queue gets overwritten if ($olddatablob->{'queuedata'}) { my $i; for $i (('desc', 'loc', 'printer', 'driver', 'connect', 'ppdfile', 'dd', 'att', 'delay')) { if (!defined($config->{$i})) { if ($olddatablob->{'queuedata'}{$i}){ $config->{$i} = $olddatablob->{'queuedata'}{$i}; } elsif ($i eq 'dd') { $config->{$i} = 0; } elsif ($i eq 'att') { $config->{$i} = 1; } elsif ($i eq 'delay') { $config->{$i} = 30; } else { $config->{$i} = ""; } } } # Check consistency of the printer/driver settings if ((($config->{'driver'} eq "") || ($config->{'driver'} eq "raw") || # No new driver, printer, ($config->{'printer'} eq "")) && # PPD file ($config->{'ppdfile'} eq "") && ((!defined($olddatablob->{'args'})) || # No existing options ($#{$olddatablob->{'args'}} < 0))) { # -> source queue raw $config->{'driver'} = "raw"; $config->{'printer'} = undef; } # We do not need the queue data block any more delete($olddatablob->{'queuedata'}); } else { # No Foomatic/PPD data $olddatablob = undef; } } else { # Load the datablob of the former configuration if ($reconf) { if ($olddatablob = load_datablob($config->{'spooler'}, $config->{'queue'})) { # If the user has supplied only a printer or only a driver # fill in the second of the two fields in $config if ((!$config->{'ppdfile'}) && ($olddatablob->{'queuedata'}{'foomatic'})) { if ((!$config->{'driver'}) && ($config->{'printer'})) { $config->{'driver'} = $olddatablob->{'driver'}; } if ((!$config->{'printer'}) && ($config->{'driver'})) { $config->{'printer'} = $olddatablob->{'id'}; } } # Extract URI and backend error handling data if ($config->{'spooler'} eq "cups") { $beh->{'uri'} = $olddatablob->{'queuedata'}{'connect'}; $beh->{'dd'} = $olddatablob->{'queuedata'}{'dd'}; $beh->{'att'} = $olddatablob->{'queuedata'}{'att'}; $beh->{'delay'} = $olddatablob->{'queuedata'}{'delay'}; } # We do not need the queue data block here delete($olddatablob->{'queuedata'}); } else { $olddatablob = undef; } } } # If the user does not supply info about his printer and/or driver # and the queue did not exist before we assume that he wants to set up a # raw queue. To make a raw queue out of a formerly filtered one, one # has to use the driver name "raw". $config->{'driver'} = "" if not defined $config->{'driver'}; $config->{'printer'} = "" if not defined $config->{'printer'}; $config->{'ppdfile'} = "" if not defined $config->{'ppdfile'}; my $nodriver = (((!$config->{'driver'}) && (!$config->{'printer'}) && (!$config->{'ppdfile'})) || ($config->{'driver'} eq "raw")); # Set to 1 when we retrieve a data set from the Foomatic database my $newfoomaticdata = 0; if ($nodriver) { if ($olddatablob) { if ($config->{'driver'} ne "raw") { # We couldn't determine a certain driver, probably we had a # native PostScript PPD file $db->{'dat'} = $olddatablob; } else { # For a raw queue overtake at least the $postpipe if (defined($olddatablob->{'postpipe'})) { $db->{'dat'}{'postpipe'} = $olddatablob->{'postpipe'}; } } } } elsif ($config->{'ppdfile'}) { if (! -r $config->{'ppdfile'}) { die "The PPD file \'$config->{'ppdfile'}\' does not exist or is " . "readable.\n"; } # Load the data from the PPD file $db->getdatfromppd($config->{'ppdfile'}); # Overtake the former default settings if ($olddatablob) {overtake_defaults($olddatablob)}; # Overtake the former $postpipe if (defined($olddatablob->{'postpipe'})) { $db->{'dat'}{'postpipe'} = $olddatablob->{'postpipe'}; } } else { if (($olddatablob) && ($olddatablob->{'driver'} eq $config->{'driver'}) && ($olddatablob->{'id'} eq $config->{'printer'}) && (!$config->{'force'})) { # Overtake data from the former configuration $db->{'dat'} = $olddatablob; } else { # Retrieve data from the Foomatic database if (!$config->{'driver'}) { die "You also need to specify a driver with \"-d\"!\n"; } if (!$config->{'printer'}) { die "You also need to specify a printer with \"-p\"!\n"; } # The printer is supported by the chosen driver? If yes, load # its data my $possible = $db->getdat($config->{'driver'}, $config->{'printer'}); die "That printer and driver combination is not possible.\n" if (!$possible); die "There is neither a custom PPD file nor the driver database entry contains sufficient data to build a PPD file.\n" if (!$db->{'dat'}{'cmd'}) && (!$db->{'dat'}{'ppdfile'}); $newfoomaticdata = 1; # Overtake the former default settings if ($olddatablob) {overtake_defaults($olddatablob)}; # Overtake the former $postpipe if (defined($olddatablob->{'postpipe'})) { $db->{'dat'}{'postpipe'} = $olddatablob->{'postpipe'}; } } } # When we have no arguments in the current configuration, we must have # a raw queue my $rawqueue = ((!defined($db->{'dat'}{'args'})) || ($#{$db->{'dat'}{'args'}} < 0)); # Set the default printing options supplied on the command line if (!$rawqueue) { set_default_options($config, $db->{'dat'}); } # Printer model name (for comment field of the queue configuration) my ($make, $model, $makemodel); if (defined($db->{'dat'})) { $make = $db->{'dat'}{'make'}; $model = $db->{'dat'}{'model'}; $makemodel = $db->{'dat'}{'makemodel'}; if (($make) && ($model)) { $makemodel = "$make $model"; } } return ($rawqueue, $newfoomaticdata, $makemodel, ($config->{'spooler'} eq "cups" ? $beh : ())); } #fix to work on Ubuntu, where cupd runs not as root, but as cupsys user #like system ("chown cupsys $ppdfile"), but #changeowner function changes owner only if user exists on system sub changeowner { my ($username, $file) = @_; my ($uid,$gid) = (-1, -1); my $l; $l = getpwnam($username); $uid = $l if defined($l); $l = getgrnam($username); $gid = $l if defined($l); chown $uid, $gid, $file; } sub writeppdfile { my ($config, $ppdfile, $rawqueue, $newfoomaticdata) = @_; # Save old $ppdfile, if any system("cp -f \'$ppdfile\' \'$ppdfile.old\'") if (-f $ppdfile); if ($rawqueue) { # Raw queue with $postpipe, use a "PPD" only containing the # $postpipe (LPRng, LPD, and no spooler only) if (((defined $db->{'dat'}{'postpipe'} && $db->{'dat'}{'postpipe'} ne "") && (($config->{'spooler'} eq 'lprng') || ($config->{'spooler'} eq 'lpd'))) || ($config->{'spooler'} eq 'direct')) { open PPDFILE, "> $ppdfile" or die "Cannot write \'$ppdfile\'!\n"; print PPDFILE "*PPD-Adobe: \"4.3\"\n*%\n"; print PPDFILE "*% This is a raw (driverless/unfiltered) " . "queue, this PPD file only carries\n" . "*% the postpipe.\n*%\n"; close PPDFILE; $db->ppdsetdefaults($ppdfile); chmod 0644, $ppdfile; #fix to work on Ubuntu, where cupd runs not as root, but as cupsys user #system ("chown cupsys $ppdfile"); #changeowner function changes owner only if user exists on system changeowner("cupsys", $ppdfile); } else { if (-f $ppdfile) { unlink "$ppdfile" or die "Cannot delete \'$ppdfile\'!\n"; } } } else { if ($config->{'ppdfile'}) { # Copy in the PPD file specified on the command line if ($config->{'ppdfile'} !~ /\.gz$/i) { # Uncompressed PPD file system("cp -f \'$config->{'ppdfile'}\' \'$ppdfile\'") and die "Cannot copy \'$config->{'ppdfile'}\' to \'$ppdfile\'!\n"; } else { # Compressed PPD file system("$sysdeps->{'gzip'} -dc " . "\'$config->{'ppdfile'}\' > " . "\'$ppdfile\'") and die "Cannot copy \'$config->{'ppdfile'}\' to \'$ppdfile\'!\n"; } # Set default option settings and $postpipe $db->ppdsetdefaults($ppdfile); } elsif ($newfoomaticdata) { # Generate the PPD file from the Foomatic database open PPDFILE, "> $ppdfile" or die "Cannot write \'$ppdfile\'!\n"; print PPDFILE $db->getppd($config->{'shortgui'}); close PPDFILE; } else { # Keep the previous PPD file, only set the options and the # $postpipe $db->ppdsetdefaults($ppdfile); } # Correct the permissions of the PPD file chmod 0644, $ppdfile; #fix to work on Ubuntu, where cupd runs not as root, but as cupsys user #system ("chown cupsys $ppdfile"); #changeowner function changes owner only if user exists on system changeowner("cupsys", $ppdfile); } } ### Queue manipulation functions for both LPD and LPRng sub setup_lpd { my ($config) = $_[0]; # Read the previous /etc/printcap my $pcap = load_lpd_printcap(); my ($ppdfile, $entry, $reconf, $p); for $p (@{$pcap}) { if ($p->{'names'}[0] eq $config->{'queue'}) { $entry = $p; $reconf = 1; print "Reconfigure of ", Dumper($p) if $debug; last; } } # PPD file name $ppdfile = sprintf('%s/lpd/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}) if !$ppdfile; # Get the data from the former queue if we reconfigure or copy a queue # do also some checking of the user-supplied parameters my ($rawqueue, $newfoomaticdata, $makemodel) = getoldqueuedata($config, $reconf); # Set the printer queue name line in /etc/printcap if (!$reconf) { if (!$rawqueue) { $entry->{'names'}[0] = $config->{'queue'}; $entry->{'names'}[1] = $config->{'desc'}; $entry->{'names'}[2] = "$makemodel"; $entry->{'names'}[3] = $config->{'loc'}; } else { $entry->{'names'}[0] = $config->{'queue'}; $entry->{'names'}[1] = $config->{'desc'}; $entry->{'names'}[2] = "Raw queue"; $entry->{'names'}[3] = $config->{'loc'}; } } else { if (!$rawqueue) { $entry->{'names'}[2] = "$makemodel"; } else { if (($entry->{'names'}[2] eq "Raw queue") || ($config->{'driver'} eq "raw")) { $rawqueue = 1; $entry->{'names'}[2] = "Raw queue"; } } if (defined($config->{'desc'})) { $entry->{'names'}[1] = $config->{'desc'}; } if (defined($config->{'loc'})) { $entry->{'names'}[3] = $config->{'loc'}; } } # These lines are always in /etc/printcap $entry->{'str'}{'sd'} = sprintf('%s/%s', $sysdeps->{'lpd-dir'}, $config->{'queue'}); $entry->{'str'}{'lf'} = $sysdeps->{'lpd-log'}; $entry->{'num'}{'mx'} = '0'; $entry->{'bool'}{'sh'} = 1; # Lines depending on the printer/spooler if (!$rawqueue) { if ($config->{'spooler'} eq "lpd") { $entry->{'str'}{'ppdfile'} = $ppdfile; # For the GPR printing GUI delete $entry->{'str'}{'ppd'}; $entry->{'str'}{'if'} = $sysdeps->{'foomatic-rip'}; $entry->{'str'}{'af'} = $ppdfile; delete $entry->{'bool'}{'force_localhost'}; delete $entry->{'str'}{'filter_options'}; } elsif ($config->{'spooler'} eq "lprng") { $entry->{'str'}{'ppd'} = $ppdfile; # for LPRng PPD support $entry->{'str'}{'if'} = $sysdeps->{'foomatic-rip'}; $entry->{'bool'}{'force_localhost'} = 1; delete $entry->{'str'}{'ppdfile'}; delete $entry->{'str'}{'af'}; delete $entry->{'str'}{'filter_options'}; } else { die "The spooler $config->{'spooler'} is not supported " . "by this function!\n"; } } else { delete $entry->{'str'}{'if'}; delete $entry->{'str'}{'af'}; delete $entry->{'str'}{'filter_options'}; delete $entry->{'str'}{'ppd'}; if ($config->{'spooler'} eq "lpd") { delete $entry->{'bool'}{'force_localhost'}; } elsif ($config->{'spooler'} eq "lprng") { $entry->{'bool'}{'force_localhost'} = 1; } else { die "The spooler $config->{'spooler'} is not supported " . "by this function!\n"; } } # If printing job has to be passed through a special program, put the # command line into $postpipe (for example for Socket, Samba, ...) my $postpipe = ""; if ((!$reconf) or ($config->{'connect'})) { # Set up connection type # Remove "rm" and "rp" tags to avoid problems when overwriting a # raw queue delete $entry->{'str'}{'rm'}; delete $entry->{'str'}{'rp'}; # All URIs ("-c" option) have the same syntax as URIs in CUPS ("-v" # option of "lpadmin"). my $file; if ($config->{'connect'} =~ m!^(file|usb|parallel|serial):(.*)!) { # Local printer or printing to a file $file = $2; if ($config->{'connect'} =~ m!^usb://!) { # Queue with printer-bound USB URI transferred from CUPS, # as LPD/LPRng does not support these URIs, translate it # back to a standard USB device URI $file = cups_usb_printer_uri_to_device_uri($file); } if (! -e $file) { warn "The device or file $file doesn't exist? " . "Working anyway.\n"; } if (($file =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($file =~ m!^/dev/ptal-printd/(.+)$!) || ($file =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate URI for ptal-printd to postpipe using the # "ptal-connect" command my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $postpipe = "$sysdeps->{'ptal-connect'} $devname -print"; $entry->{'str'}{'lp'} = "/dev/null"; } else { $entry->{'str'}{'lp'} = $file; } } elsif ($config->{'connect'} =~ m!^ptal://?([^/].*)$!) { # HPOJ MLC protocol my $devname = $1; $postpipe = "$sysdeps->{'ptal-connect'} $devname -print"; $entry->{'str'}{'lp'} = "/dev/null"; } elsif ($config->{'connect'} =~ m!^mtink:/(.+)$!) { # Printing through "mtinkd" $entry->{'str'}{'lp'} = "$sysdeps->{'mtink-pipes'}/$1"; } elsif ($config->{'connect'} =~ m!^lpd://([^/]+)/([^/]+)$!) { # Remote LPD my $remhost = $1; my $remqueue = $2; if (($rawqueue) && ($config->{'spooler'} eq "lpd")) { $entry->{'str'}{'rm'} = $remhost; $entry->{'str'}{'rp'} = $remqueue; delete $entry->{'str'}{'lp'}; } elsif( ($config->{'spooler'} eq "lprng")) { delete $entry->{'str'}{'rm'}; delete $entry->{'str'}{'rp'}; $entry->{'str'}{'lp'} = "$remqueue\@$remhost"; } else { # classic LPD does not support sending jobs to a server with the # "rm" and "rp" tags in /etc/printcap and filtering it # before ("if" tag). So when we do not set up a raw queue, # we do not # # $entry->{'str'}{'rm'} = $remhost; # $entry->{'str'}{'rp'} = $remqueue; # # but use "rlpr" in a $postpipe. Note that "rlpr" prints a # banner page by default, "-h" suppresses it. "rlpr" must # be SUID "root". $postpipe = "$sysdeps->{'rlpr'} -q -h -P " . "$remqueue\@$remhost"; $entry->{'str'}{'lp'} = "/dev/null"; } } elsif ($config->{'connect'} =~ m!^socket://([^/:]+):([0-9]+)/?$!) { # Socket (AppSocket/HP JetDirect) my $remhost = $1; my $remport = $2; if( ($config->{'spooler'} eq "lprng")) { $entry->{'str'}{'lp'} = "$remhost\%$remport"; } else { $postpipe = "$sysdeps->{'nc'} -w 1 $remhost $remport"; $entry->{'str'}{'lp'} = "/dev/null"; } } elsif ($config->{'connect'} =~ m!^smb://(.*)$!) { # SMB (Printer on Windows server) my $parameters = $1; # Get the user's login and password from the URI my $smbuser = ""; my $smbpassword = ""; if ($parameters =~ m!([^@]*)@([^@]+)!) { my $login = $1; $parameters = $2; if ($login =~ m!([^:]*):([^:]*)!) { $smbuser = $1; $smbpassword = $2; } else { $smbuser = $login; $smbpassword = ""; } } else { $smbuser = "GUEST"; $smbpassword = ""; } # Get the workgroup, server, and share name my $workgroup = ""; my $smbserver = ""; my $smbshare = ""; if ($parameters =~ m!([^/]*)/([^/]+)/([^/]+)$!) { $workgroup = $1; $smbserver = $2; $smbshare = $3; } elsif ($parameters =~ m!([^/]+)/([^/]+)$!) { $workgroup = ""; $smbserver = $1; $smbshare = $2; } else { die "The \"smb://\" URI must at least contain the " . "server name and the share name!\n"; } # Set up the command line for printing on the SMB server $postpipe = "$sysdeps->{'smbclient'} '//$smbserver/$smbshare'"; if ($smbpassword ne "") { warn("WARNING: smbclient password is visible in PPD file\n"); $postpipe .= " '$smbpassword'"; } if ($smbuser ne "") {$postpipe .= " -U '$smbuser'";} if ($workgroup ne "") {$postpipe .= " -W '$workgroup'";} $postpipe .= " -N -P -c 'print -' "; $entry->{'str'}{'lp'} = "/dev/null"; } elsif ($config->{'connect'} =~ m!^ncp://(.*)$!) { my $parameters = $1; # Get the user's login and password from the URI my $ncpuser = ""; my $ncppassword = ""; if ($parameters =~ m!([^@]*)@([^@]+)!) { my $login = $1; $parameters = $2; if ($login =~ m!([^:]*):([^:]*)!) { $ncpuser = $1; $ncppassword = $2; } else { $ncpuser = $login; $ncppassword = ""; } } else { $ncpuser = ""; $ncppassword = ""; } # Get the server and share name my $ncpserver = ""; my $ncpqueue = ""; if ($parameters =~ m!([^/]+)/([^/]+)$!) { $ncpserver = $1; $ncpqueue = $2; } else { die "The \"ncp://\" URI must at least contain the " . "server name and the queue name!\n"; } # Set up the command line for printing on the Netware server $postpipe = "$sysdeps->{'nprint'} -S $ncpserver"; if ($ncpuser ne "") { $postpipe .= " -U $ncpuser"; if ($ncppassword ne "") { warn("WARNING: ncp password is visible in PPD file\n"); $postpipe .= " -P $ncppassword"; } else { $postpipe .= " -n"; } } $postpipe .= " -q $ncpqueue -N - 2>/dev/null"; $entry->{'str'}{'lp'} = "/dev/null"; } elsif ($config->{'connect'} =~ m!^postpipe:(.*)$!) { # Pipe output into a command $postpipe = $1; $entry->{'str'}{'lp'} = "/dev/null"; } elsif ($config->{'connect'}) { $entry->{'str'}{'lp'} = '/dev/null'; die ("The URI \"$config->{'connect'}\" is not supported " . "for LPD/LPRng or you have\nmistyped.\n"); } else { print STDERR "You must specify a connection with -c.\n"; help(); exit(1); } # Put $postpipe into the data structure, so that it will be # inserted into the PPD file if ($postpipe ne "") { $postpipe = "| $postpipe"; $db->{'dat'}{'postpipe'} = $postpipe; } else { undef $db->{'dat'}{'postpipe'}; } } else { # Keep previous connection type # Use previous $postpipe if (defined($db->{'dat'}{'postpipe'})) { $postpipe = $db->{'dat'}{'postpipe'}; } } # When we have a $postpipe we never write to a device if ($postpipe ne "") { $entry->{'str'}{'lp'} = '/dev/null'; if ($config->{'spooler'} eq "lpd") { $entry->{'str'}{'if'} = $sysdeps->{'foomatic-rip'}; $entry->{'str'}{'af'} = $ppdfile; } elsif ($config->{'spooler'} eq "lprng") { $entry->{'str'}{'if'} = $sysdeps->{'foomatic-rip'}; $entry->{'str'}{'ppd'} = $ppdfile; $entry->{'bool'}{'force_localhost'} = 1; } else { die "The spooler $config->{'spooler'} is not supported " . "by this function!\n"; } } # Various file setup mkdir $sysdeps->{'foo-etc'}, 0755; mkdir "$sysdeps->{'foo-etc'}/lpd", 0755; mkdir $entry->{'str'}{'sd'}, 0755; # Lead with a blank line for new entries push (@{$entry->{'comments'}}, "\n") if (!$reconf); # Put in a useful comment for both new and old entries push (@{$entry->{'comments'}}, sprintf ("\# Entry edited %s by $progname.", scalar(localtime(time))), "\# Additional configuration atop $ppdfile"); # Add to the printcap if a new entry if (!$reconf) { push(@{$pcap}, $entry); } # Generate/write te PPD file writeppdfile($config, $ppdfile, $rawqueue, $newfoomaticdata); # Make sure that /var/spool/lp-errs exists system "touch $sysdeps->{'lpd-log'}"; chmod 0600, $sysdeps->{'lpd-log'}; my ($lpuid, $lpgid) = (-1, -1); my $l; $l = getpwnam("lp"); $lpuid = $l if defined($l); $l = getgrnam("lp"); $lpgid = $l if defined($l); chown $lpuid, $lpgid, $sysdeps->{'lpd-log'}; # Write back /etc/printcap my $printcap = $sysdeps->{'lpd-pcap'}; rename $printcap, "$printcap.old" or die "Cannot backup $printcap!\n"; open PRINTCAP, "> $printcap" or die "Cannot write $printcap!\n"; print PRINTCAP dump_lpd_printcap($config, $pcap); close PRINTCAP; chmod 0644, $printcap; # In case of LPRng, give SIGHUP to the daemon, LPRng needs this to # recognize a new queue if ($config->{'spooler'} eq "lprng") { # first check configuration system("$sysdeps->{'lprng-checkpc'} -f > /dev/null 2>&1"); # now signal to use it system("$sysdeps->{'lpd-lpc'} reread > /dev/null 2>&1"); } return 1; } sub default_lpd { my ($config) = $_[0]; my $name = $config->{'queue'}; my $pcap = load_lpd_printcap(); # Add the alias "lp" to the /etc/printcap entry to make LPD considering # the chosen printer as default printer # Some stuff for renaming a queue named "lp" my $nppdfile = undef; my $newname = undef; my $rawqueue = 0; my @newcap; for (@{$pcap}) { my $p = $_; if ($p->{'names'}[0] eq $name) { $p->{'names'}[4] = 'lp'; } else { # Rename a printer whose first name is 'lp' if ($p->{'names'}[0] eq 'lp') { # Do we have a raw queue? if ((!defined($p->{'str'}{'if'})) || ($p->{'str'}{'if'} ne $sysdeps->{'foomatic-rip'})) { $rawqueue = 1; } # Search for a free name my $i = 0; my $namefound = 0; while(!$namefound) { my $pp; my $nameinuse = 0; for $pp (@{$pcap}) { if (defined($pp->{'names'})) { my $n; for $n (@{$pp->{'names'}}) { if ($n eq "lp$i") { $nameinuse = 1; last; } } if ($nameinuse) { $i++; last; } } } $namefound = 1 - $nameinuse; } $newname = "lp$i"; # Old PPD file name my $ppdfile = sprintf('%s/lpd/lp.ppd', $sysdeps->{'foo-etc'}); # New PPD file name my $nppdfile = sprintf('%s/lpd/%s.ppd', $sysdeps->{'foo-etc'}, $newname); # Rename the printer $p->{'names'}[0] = $newname; my $oldspooldir = $p->{'str'}{'sd'}; $p->{'str'}{'sd'} = sprintf('%s/%s', $sysdeps->{'lpd-dir'}, $newname); if ($p->{'str'}{'af'} =~ /\.ppd$/) { $p->{'str'}{'af'} = $nppdfile; } # Rename old $ppdfile, if any rename $ppdfile, $nppdfile if (-f $ppdfile); # Rename the spool directory rename $oldspooldir, $p->{'str'}{'sd'} if (-d $oldspooldir); # Put out warning warn("WARNING: Printer \"lp\" renamed to \"$newname\".\n"); } # Remove 'lp' as alias name my $n; for $n (@{$p->{'names'}}) { if ($n eq 'lp') { $n = ''; } } } push (@newcap, $p); } my @newprintcap = dump_lpd_printcap($config, \@newcap); my $printcap = $sysdeps->{'lpd-pcap'}; rename $printcap, "$printcap.old" or die "Cannot backup $printcap!\n"; open PRINTCAP, "> $printcap" or die "Cannot write $printcap!\n"; print PRINTCAP @newprintcap; close PRINTCAP; chmod 0644, $printcap; return 1; } sub default_lprng { my ($config) = $_[0]; my $name = $config->{'queue'}; my $pcap = load_lpd_printcap(); # Move the /etc/printcap entry for the chosen printer to the first place # so that LPRng considers it as the default printer my @newcap; for (@{$pcap}) { push (@newcap, $_) if ($_->{'names'}[0] eq $name); } for (@{$pcap}) { push (@newcap, $_) unless ($_->{'names'}[0] eq $name); } my @newprintcap = dump_lpd_printcap($config, \@newcap); my $printcap = $sysdeps->{'lpd-pcap'}; rename $printcap, "$printcap.old" or die "Cannot backup $printcap!\n"; open PRINTCAP, "> $printcap" or die "Cannot write $printcap!\n"; print PRINTCAP @newprintcap; close PRINTCAP; chmod 0644, $printcap; # In case of LPRng, give SIGHUP to the daemon, LPRng needs this to # recognize the changes if ($config->{'spooler'} eq "lprng") { system("$sysdeps->{'lpd-lpc'} reread > /dev/null 2>&1"); system("$sysdeps->{'lprng-checkpc'} -f > /dev/null 2>&1"); } return 1; } sub delete_lpd { my ($config) = $_[0]; my $name = $config->{'queue'}; my $pcap = load_lpd_printcap(); my @newcap; for (@{$pcap}) { push (@newcap, $_) unless ($_->{'names'}[0] eq $name); } my @newprintcap = dump_lpd_printcap($config, \@newcap); my $printcap = $sysdeps->{'lpd-pcap'}; rename $printcap, "$printcap.old" or die "Cannot backup $printcap!\n"; open PRINTCAP, "> $printcap" or die "Cannot write $printcap!\n"; print PRINTCAP @newprintcap; close PRINTCAP; chmod 0644, $printcap; # PPD file name my $ppdfile = sprintf('%s/lpd/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Rename old $ppdfile, if any rename $ppdfile, "$ppdfile.old" if (-f $ppdfile); # In case of LPRng, give SIGHUP to the daemon, LPRng needs this to # recognize the changes if ($config->{'spooler'} eq "lprng") { system("$sysdeps->{'lpd-lpc'} reread > /dev/null 2>&1"); system("$sysdeps->{'lprng-checkpc'} -f > /dev/null 2>&1"); } return 1; } sub query_lpd { my ($config) = @_; # User requests data of a printer/driver combo to see the options before # installing a queue if (($opt_P) && ((($config->{'driver'}) && ($config->{'printer'}) && ($config->{'driver'} ne "raw")) || ($config->{'ppdfile'}))) { if ($opt_n) { my $olddatablob = load_lpd_datablob($opt_n); print_perl_combo_data($config, $olddatablob); } else { print_perl_combo_data($config); } return; } my $i = $ARGV[0]; if (!defined($i)) {$i = 0;} my $pcap = load_lpd_printcap(); my $p; if (!$opt_P) { print "<queues>\n"; } # Query the default printer my $default; if (!defined($config->{'queue'})) { if ($config->{'spooler'} eq "lpd") { # Under LPD the default printer is the printer which has # "lp" as its name or as an alias name my $def_firstname = undef; for $p (@{$pcap}) { if (defined($p->{'names'})) { my $n; for $n (@{$p->{'names'}}) { if ($n eq 'lp') { $def_firstname = $p->{'names'}[0]; last; } } if (defined($def_firstname)) { last; } } } if (defined($def_firstname)) { $default = $def_firstname; if (!$opt_P) { print "<defaultqueue>$def_firstname</defaultqueue>\n"; } } } else { # Under LPRng the default printer is the first entry in # /etc/printcap for $p (@{$pcap}) { if (defined($p->{'names'})) { $default = $p->{'names'}[0]; if (!$opt_P) { print "<defaultqueue>$p->{'names'}[0]" . "</defaultqueue>\n"; } last; } } } } for $p (@{$pcap}) { # enpty end entry for trailing comments next if !defined($p->{'names'}); # were we invoked for only one queue? next if (defined($config->{'queue'}) and $config->{'queue'} ne $p->{'names'}[0]); # load the queue data $db->{'dat'} = load_lpd_datablob($p->{'names'}[0]); # extract the queue data block my $c = $db->{'dat'}{'queuedata'}; if ($opt_P) { if ($p->{'names'}[0] eq $default) { $db->{'dat'}{'queuedata'}{'default'} = 1; } else { $db->{'dat'}{'queuedata'}{'default'} = 0; } $db->{'dat'}{'queuedata'}{'remote'} = 0; my $asciidata = $db->getascii(); $asciidata =~ s/\$VAR1/\$QUEUES[$i]/g; print $asciidata; $i ++; } else { # and get it to standard output dump_config($c); } } if (!$opt_P) { print "</queues>\n"; } return; } ### Queue manipulation functions for CUPS sub setup_cups { my ($config) = $_[0]; # PPD file name # (/etc/foomatic/cups/ will be a link to /etc/cups/ppd/) my $ppdfile = sprintf('%s/ppd/%s.ppd', $sysdeps->{'cups-etc'}, $config->{'queue'}); # Get the data from the former queue if we reconfigure or copy a queue # do also some checking of the user-supplied parameters my ($rawqueue, $newfoomaticdata, $makemodel, $beh) = getoldqueuedata($config, 1); # Here we set up the command line for the "lpadmin" command my $lpadminline = "$sysdeps->{'cups-admin'} -p \"$config->{'queue'}\" -E"; # Use manufacturer and model as description when no description is # provided if (defined($config->{'desc'})) { $lpadminline .= " -D \"$config->{'desc'}\""; } else { # Before we overwrite the description field with manufacturer # and model, check if there is some old contents my $pconf = load_cups_printersconf(); my $p; my $olddesc; for $p (@{$pconf}) { next if (defined($config->{'queue'}) and $config->{'queue'} ne $p->{'name'}); $olddesc = $p->{'Info'}; } if (!$olddesc) { if (!$rawqueue) { $lpadminline .= " -D \"$makemodel\""; } else { $lpadminline .= " -D \"Raw queue\""; } } } # Fill in the "location" field if something for it is provided. if (defined($config->{'loc'})) { $lpadminline .= " -L \"$config->{'loc'}\""; } # PPD file argument for the printer if (!$rawqueue) { $lpadminline .= " -P \'$ppdfile\'"; } # All URIs ("-c" option) have the same syntax as URIs in CUPS # ("-v" option of "lpadmin"). Here the old "file:/" URIs are # translated to the form which CUPS needs. All other URIs are # simply passed to lpadmin. my $cupsuri = ""; if (defined($config->{'connect'})) { if ($config->{'connect'} =~ m!^(file|usb|parallel|serial):(.*)$!) { # Translate "file:/" into the prefix needed by CUPS, if # necessary $cupsuri = $2; if ((($cupsuri =~ m!$sysdeps->{'ptal-pipes'}/(.+)$!) || ($cupsuri =~ m!/dev/ptal-printd/(.+)$!) || ($cupsuri =~ m!/var/run/ptal-printd/(.+)$!)) && (-x "$sysdeps->{'cups-backends'}/ptal")) { # Translate URI for ptal-printd (does not work with CUPS # 1.1.12 and newer) to URI for the "ptal" CUPS backend # script (if the script is there) my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $cupsuri = "ptal:/$devname"; } elsif ((($cupsuri =~ m!^$sysdeps->{'mtink-pipes'}/(.+)$!) || ($cupsuri =~ m!^/var/mtink/(.+)$!)) && (-x "$sysdeps->{'cups-backends'}/mtink")) { # Translate URI for mtinkd (does not work with CUPS # 1.1.12 and newer) to URI for the "mtink" CUPS backend # script (if the script is there) $cupsuri = "mtink:/$1"; } elsif ($config->{'connect'} =~ m!usb!i) { $cupsuri = cups_usb_device_uri_to_printer_uri($cupsuri); $cupsuri = "usb:$cupsuri"; } elsif (($cupsuri =~ m!lp[0-9]!) || ($cupsuri =~ m!LP[0-9]!)|| ($cupsuri =~ m!parallel!)) { $cupsuri = "parallel:$cupsuri"; } elsif (($cupsuri =~ m!tty!) || ($cupsuri =~ m!TTY!) || ($cupsuri =~ m!serial!)) { $cupsuri = "serial:$cupsuri"; } else { $cupsuri = "file:$cupsuri"; } } elsif (($config->{'connect'} =~ m!^ptal://?([^/].*)$!) && (!-x "$sysdeps->{'cups-backends'}/ptal")) { # If there is no "ptal" backend script for CUPS, use an URI # pointing to the pipe set up by ptal-printd. my $devname = $1; $devname =~ tr/:/_/; $cupsuri = "file:$sysdeps->{'ptal-pipes'}/$devname"; } elsif (($config->{'connect'} =~ m!^mtink:/(.*)$!) && (!-x "$sysdeps->{'cups-backends'}/mtink")) { # If there is no "mtink" backend script for CUPS, use an URI # pointing to the pipe set up by mtinkd. $cupsuri = "file:$sysdeps->{'mtink-pipes'}/$1"; } else { $cupsuri=$config->{'connect'}; } # Correct PTAL URIs: "ptal:/..." for HPOJ 0.9, "ptal://..." for newer # HPOJ if ($cupsuri =~ m!^ptal:/!) { $cupsuri = cups_correct_ptal_uri($cupsuri); } } # Are there changes in the error handling of the backend? if (((defined($config->{'dd'})) && (((defined($beh->{'dd'})) && ($config->{'dd'} ne $beh->{'dd'})) || ($config->{'dd'} != 0))) || ((defined($config->{'att'})) && (((defined($beh->{'att'})) && ($config->{'att'} ne $beh->{'att'})) || ($config->{'att'} != 1))) || ((defined($config->{'delay'})) && (((defined($beh->{'delay'})) && ($config->{'delay'} ne $beh->{'delay'})) || ($config->{'delay'} != 30)))) { if (!defined($config->{'dd'})) { $config->{'dd'} = (defined($beh->{'dd'}) ? $beh->{'dd'} : 0); } if (!defined($config->{'att'})) { $config->{'att'} = (defined($beh->{'att'}) ? $beh->{'att'} : 1); } if (!defined($config->{'delay'})) { $config->{'delay'} = (defined($beh->{'delay'}) ? $beh->{'delay'} : 30); } $cupsuri = $beh->{'uri'} if !$cupsuri; # Do only add the "beh" wrapper backend when it is really needed # (More than one retry and/or no disabling) and if the queue is not # using the HPLIP ("hp") backend, as otherwise the "hp-toolbox" # will not list the printer any more. HPLIP does infinite retries # in 30-sec intervals anyway. if (($cupsuri) && ($cupsuri !~ m!^hp(fax|):/!) && (($config->{'dd'} != 0) || ($config->{'att'} != 1))) { $cupsuri = sprintf("beh:/%d/%d/%d/%s", $config->{'dd'}, $config->{'att'}, $config->{'delay'}, $cupsuri); } } if ($cupsuri) { $lpadminline .= " -v \"$cupsuri\""; } # Directory setup, let the Foomatic PPD directory for CUPS be the same # as /etc/cups/ppd/ (where CUPS stores the PPDs of the installed queues) mkdir $sysdeps->{'foo-etc'}, 0755; symlink "$sysdeps->{'cups-etc'}/ppd/", "$sysdeps->{'foo-etc'}/cups"; # In CUPS we never have a $postpipe # (when we get a $postpipe from a source PPD file from another # spooler, we don't need to remove it really, because it will be # ignored by foomatic-rip, uncomment this to remove it) #$db->{'dat'}{'postpipe'} = ""; # Generate/write te PPD file writeppdfile($config, $ppdfile, $rawqueue, $newfoomaticdata); # Execute the lpadmin command to set up the new queue if (system $lpadminline) { # Remove the config files unlink "$ppdfile" if (-f "$ppdfile"); # Revert changed config files rename "$ppdfile.old", "$ppdfile" if (-f "$ppdfile.old"); die "Could not set up/change the queue \"$config->{'queue'}\"!\n"; } return 1; } sub default_cups { my ($config) = $_[0]; if ($< == 0) { # (/etc/cups/printers.conf can only be manipulated by root) # This line sets the default printer in /etc/cups/printers.conf my $command = "$sysdeps->{'cups-admin'} -d " . "\"$config->{'queue'}\" > /dev/null"; # Do it! (Ignore errors silently) system $command; } # This line sets the default printer in /etc/cups/lpoptions # (required for setting a remote queue as default) my $command = "$sysdeps->{'cups-lpoptions'} -d " . "\"$config->{'queue'}\" > /dev/null"; # Do it! system $command and die "Unable to set queue \"$config->{'queue'}\" as default!\n"; } sub delete_cups { my ($config) = $_[0]; # This line deletes the old printer queue my $queuedeleteline = "$sysdeps->{'cups-admin'} -x \"$config->{'queue'}\""; # Do it! system $queuedeleteline and die "Unable to delete queue \"$config->{'queue'}\"!\n"; return 1; } sub query_cups { my ($config) = @_; # User requests data of a printer/driver combo to see the options before # installing a queue if (($opt_P) && ((($config->{'driver'}) && ($config->{'printer'}) && ($config->{'driver'} ne "raw")) || ($config->{'ppdfile'}))) { if ($opt_n) { my $olddatablob = load_cups_datablob($opt_n); print_perl_combo_data($config, $olddatablob); } else { print_perl_combo_data($config); } return; } my $i = $ARGV[0]; if (!defined($i)) {$i = 0;} my $pconf = load_cups_printersconf(); if (defined($opt_r)) {$opt_r = undef;} my $p; if (!$opt_P) { print "<queues>\n"; } # Query the default printer my $default = ''; if (!defined($config->{'queue'})) { open DEFAULT, "$sysdeps->{'cups-lpstat'} -d |" or die "Could not run $sysdeps->{'cups-lpstat'}!\n"; my $defaultstr = <DEFAULT>; close DEFAULT; if ($defaultstr =~ m!\S+:\s+(\S+)$!) { $default = $1; if (!$opt_P) { print "<defaultqueue>$default</defaultqueue>\n"; } } } for $p (@{$pconf}) { # were we invoked for only one queue? next if (defined($config->{'queue'}) and $config->{'queue'} ne $p->{'name'}); # load the queue data $db->{'dat'} = load_cups_datablob($p->{'name'}); # Enter info for remote queue if ($p->{'remote'}) { $db->{'dat'}{'queuedata'}{'foomatic'} = 0; $db->{'dat'}{'queuedata'}{'spooler'} = 'cups'; $db->{'dat'}{'queuedata'}{'queue'} = $p->{'name'}; $db->{'dat'}{'queuedata'}{'connect'} = $p->{'DeviceURI'}; $db->{'dat'}{'queuedata'}{'description'} = $p->{'Info'}; $db->{'dat'}{'queuedata'}{'loc'} = $p->{'Location'}; $db->{'dat'}{'queuedata'}{'remote'} = 1; } else { $db->{'dat'}{'queuedata'}{'remote'} = 0; } # extract the queue data block my $c = $db->{'dat'}{'queuedata'}; if ($opt_P) { if ($p->{'name'} eq $default) { $db->{'dat'}{'queuedata'}{'default'} = 1; } else { $db->{'dat'}{'queuedata'}{'default'} = 0; } my $asciidata = $db->getascii(); $asciidata =~ s/\$VAR1/\$QUEUES[$i]/g; print $asciidata; $i ++; } else { # and get it to standard output dump_config($c); } } if (!$opt_P) { print "</queues>\n"; } return; } ### Queue manipulation functions for PDQ sub setup_pdq { my ($config) = $_[0]; # Read the previous /usr/lib/pdq/printrc my $printrc = load_pdq_printrc(); my ($ppdfile, $driverfile, $entry, $reconf, $p); $reconf = 0; for $p (@{$printrc}) { if ((defined($p->{'name'})) && ($p->{'name'} eq $config->{'queue'})) { $entry = $p; $reconf = 1; last; use Data::Dumper; print "Reconfigure of ", Dumper($p); } } # Config file names $ppdfile = sprintf('%s/pdq/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); $driverfile = sprintf('%s/pdq/driverdescr/%s.pdq', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Get the data from the former queue if we reconfigure or copy a queue # do also some checking of the user-supplied parameters my ($rawqueue, $newfoomaticdata, $makemodel) = getoldqueuedata($config, $reconf); # Set the initial line of the "printer" block in /usr/lib/pdq/printrc $entry->{'name'} = $config->{'queue'}; # Location field if ((defined($config->{'loc'})) || (!$reconf)) { $entry->{'location'} = "\"$config->{'loc'}\""; } # Model/Description field if (defined($config->{'desc'})) { $entry->{'model'} = "\"$config->{'desc'}\""; } elsif (!$entry->{'model'}) { if (!$rawqueue) { $entry->{'model'} = "\"$makemodel\""; } else { $entry->{'model'} = "\"Raw printer\""; } } # Create directories mkdir $sysdeps->{'foo-etc'}, 0755; mkdir $sysdeps->{'foo-etc'} . '/pdq', 0755; mkdir $sysdeps->{'foo-etc'} . '/pdq/driverdescr', 0755; # Make the printer driver descriptions in /etc/foomatic/pdq visible # for PDQ # symlink $sysdeps->{'foo-etc'} . '/pdq', $sysdeps->{'pdq-foomatic'}; # Save old driver file, use the "~" to make it appear an editor # backup so that PDQ does not parse it. # Save old $driverfile, if any rename $driverfile, "$driverfile.old~" if (-f $driverfile); # Generate/write the PPD file writeppdfile($config, $ppdfile, $rawqueue, $newfoomaticdata); # Create driver description file if ($rawqueue) { system("$sysdeps->{'foomatic-rip'} --genrawpdq $driverfile") and die "Cannot create $driverfile!\n"; } else { system("$sysdeps->{'foomatic-rip'} --ppd \'$ppdfile\' --genpdq " . "$driverfile") and die "Cannot create $driverfile!\n"; } # PDQ configuration file # Driver fields # Extract driver name my $driverdesc = `cat $driverfile`; $driverdesc =~ m!^\s*driver\s*(\"\S*\-\d+\")!m; # Driver-specific entries $entry->{'driver'} = $1; $entry->{'driver_opts'} = "\{ \}"; $entry->{'driver_args'} = "\{ \}"; # Interface fields # All URIs ("-c" option) have the same syntax as URIs in CUPS ("-v" # option of "lpadmin"). if ($config->{'connect'} =~ m!^(file|usb|parallel|serial):(.*)!) { # Local printer or printing to a file my $file = $2; if ($config->{'connect'} =~ m!^usb://!) { # Queue with printer-bound USB URI transferred from CUPS, # as PDQ does not support these URIs, translate it # back to a standard USB device URI $file = cups_usb_printer_uri_to_device_uri($file); } if (! -e $file) { warn "The device or file $file doesn't exist? " . "Working anyway.\n"; } $entry->{'interface'} = "\"local-port\""; $entry->{'interface_opts'} = "\{ \}"; $entry->{'interface_args'} = "\{ \"PORT\" = \"$file\" \}"; } elsif ($config->{'connect'} =~ m!^ptal://?([^/].*)$!) { # HPOJ MLC protocol my $devname = $1; $devname =~ tr/:/_/; $entry->{'interface'} = "\"local-port\""; $entry->{'interface_opts'} = "\{ \}"; $entry->{'interface_args'} = "\{ \"PORT\" = " . "\"$sysdeps->{'ptal-pipes'}/$devname\" \}"; } elsif ($config->{'connect'} =~ m!^mtink:/(.+)$!) { # Printing through "mtinkd" $entry->{'interface'} = "\"local-port\""; $entry->{'interface_opts'} = "\{ \}"; $entry->{'interface_args'} = "\{ \"PORT\" = " . "\"$sysdeps->{'mtink-pipes'}/$1\" \}"; } elsif ($config->{'connect'} =~ m!^lpd://([^/]+)/([^/]+)$!) { # Remote LPD my $remhost = $1; my $remqueue = $2; $entry->{'interface'} = "\"bsd-lpd\""; $entry->{'interface_opts'} = "\{ \}"; $entry->{'interface_args'} = "\{ \"QUEUE\" = \"$remqueue\", \"REMOTE_HOST\" = " . "\"$remhost\" \}"; } elsif ($config->{'connect'} =~ m!^socket://([^/:]+):([0-9]+)/?$!) { # Socket (AppSocket/HP JetDirect) my $remhost = $1; my $remport = $2; $entry->{'interface'} = "\"tcp-port\""; $entry->{'interface_opts'} = "\{ \}"; $entry->{'interface_args'} = "\{ \"REMOTE_PORT\" = \"$remport\", \"REMOTE_HOST\" = " . "\"$remhost\" \}"; } elsif ($config->{'connect'}) { die ("The URI \"$config->{'connect'}\" is not supported " . "for PDQ or you have\nmistyped.\n"); } elsif (!$reconf) { die "You must specify a connection with -c.\n"; } # Add to the printrc if it is a new entry if (!$reconf) { push(@{$printrc}, $entry); } # Write back the modified printrc file my $printrcname = $sysdeps->{'pdq-printrc'}; rename $printrcname, "$printrcname.old" or die "Cannot backup $printrcname!\n"; open PRINTRC, "> $printrcname" or die "Cannot write $printrcname!\n"; print PRINTRC dump_pdq_printrc($printrc); close PRINTRC; chmod 0644, $printrcname; return 1; } sub default_pdq { my ($config) = $_[0]; # Determine the name of the config file to modify my $printrcname = ""; if ($< == 0) { $printrcname = "$sysdeps->{'pdq-printrc'}"; if (!(-f $printrcname)) {die "No file $printrcname!"}; } else { $printrcname = "$ENV{HOME}/.printrc"; if (!(-f $printrcname)) {system "touch $printrcname"}; } # Read the config file open PRINTRC, "$printrcname" or die "Cannot open $printrcname!"; my @printrc = <PRINTRC>; close PRINTRC; # Remove all valid "default_printer" lines ($_ =~ /^\s*default_printer/ and $_="") foreach @printrc; # Insert the new "default_printer" line push @printrc, "default_printer $config->{'queue'}\n"; # Write back the modified config file open PRINTRC, "> $printrcname" or die "Cannot open $printrcname!"; print PRINTRC @printrc; close PRINTRC; } sub delete_pdq { my ($config) = $_[0]; my $name = $config->{'queue'}; my $printrc = load_pdq_printrc(); my @newrc; for (@{$printrc}) { push (@newrc, $_) unless (defined($_->{'name'}) && ($_->{'name'} eq $name)); } my @newprintrc = dump_pdq_printrc(\@newrc); my $printrcname = $sysdeps->{'pdq-printrc'}; rename $printrcname, "$printrcname.old" or die "Cannot backup $printrcname!\n"; open PRINTRC, "> $printrcname" or die "Cannot write $printrcname!\n"; print PRINTRC @newprintrc; close PRINTRC; chmod 0644, $printrcname; # Config file names my $ppdfile = sprintf('%s/pdq/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); my $driverfile = sprintf('%s/pdq/driverdescr/%s.pdq', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Rename old $ppdfile, if any rename $ppdfile, "$ppdfile.old" if (-f $ppdfile); # Rename old driverfile, if any, use the "~" to make it appear an # editor backup so that PDQ does not parse it. # Rename old $driverfile, if any rename $driverfile, "$driverfile.old~" if (-f $driverfile); return 1; } sub query_pdq { my ($config) = @_; # User requests data of a printer/driver combo to see the options before # installing a queue if (($opt_P) && ((($config->{'driver'}) && ($config->{'printer'}) && ($config->{'driver'} ne "raw")) || ($config->{'ppdfile'}))) { if ($opt_n) { my $olddatablob = load_pdq_datablob($opt_n); print_perl_combo_data($config, $olddatablob); } else { print_perl_combo_data($config); } return; } my $i = $ARGV[0]; if (!defined($i)) {$i = 0;} my $printrc = load_pdq_printrc(); my $p; if (!$opt_P) { print "<queues>\n"; } # Query the default printer my $default; if (!defined($config->{'queue'})) { open DEFAULT, "$sysdeps->{'pdq-print'} -h 2>&1 |" or die "Could not run $sysdeps->{'pdq-print'}!\n"; my $defaultstr = join('', <DEFAULT>); close DEFAULT; if ($defaultstr =~ m!The\s+default\s+printer\s+is\s+(\S+)$!m) { $default = $1; if (!$opt_P) { print "<defaultqueue>$default</defaultqueue>\n"; } } } for $p (@{$printrc}) { # Omit non-printer-block items next if (!(defined($p->{'name'}))); # were we invoked for only one queue? next if (defined($config->{'queue'}) and $config->{'queue'} ne $p->{'name'}); # load the queue data $db->{'dat'} = load_pdq_datablob($p->{'name'}); # extract the queue data block my $c = $db->{'dat'}{'queuedata'}; if ($opt_P) { if ($p->{'name'} eq $default) { $db->{'dat'}{'queuedata'}{'default'} = 1; } else { $db->{'dat'}{'queuedata'}{'default'} = 0; } $db->{'dat'}{'queuedata'}{'remote'} = 0; my $asciidata = $db->getascii(); $asciidata =~ s/\$VAR1/\$QUEUES[$i]/g; print $asciidata; $i ++; } else { # and get it to standard output dump_config($c); } } if (!$opt_P) { print "</queues>\n"; } return; } ### Queue manipulation functions for PPR sub setup_ppr { my ($config) = $_[0]; # Read the previous configuration my $printrc = load_ppr_printers_conf(); my ($ppdfile, $entry, $reconf, $p); $reconf = 0; for $p (@{$printrc}) { if ((defined($p->{'name'})) && ($p->{'name'} eq $config->{'queue'})) { $entry = $p; $reconf = 1; last; use Data::Dumper; print "Reconfigure of ", Dumper($p); } } # PPD file name $ppdfile = sprintf('%s/ppr/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Determine the PPR version in use my $pprversion; if (open VER, "$sysdeps->{'ppr-pprd'} --version |") { my $ver = <VER>; close VER; $ver =~ /^\D*(\d+)\.(\d+)(\.(\d+)|)((a|alpha|b|beta|r|rc)(\d+|)|)/; $pprversion = (1e8 * $1 + 1e6 * $2 + 1e4 * $4 + ($5 ? 100 * (ord(uc($6)) - 64) + $7 : 9999)) / 1e8; } else { # Could not determine version, so we set it to 0 (oldest possible) $pprversion = 0; } # Get the data from the former queue if we reconfigure or copy a queue # do also some checking of the user-supplied parameters my ($rawqueue, $newfoomaticdata, $makemodel) = getoldqueuedata($config, $reconf); # Read out previous interface settings my $interface = ""; my $address = ""; my $options = ""; my $interface_options = ""; if ($reconf) { $interface = $entry->{'Interface'}; $address = $entry->{'Address'}; $interface_options = $entry->{'Options'}; if (($interface eq "foomatic-rip") || ($interface eq "ppromatic")) { if ($interface_options =~ /backend=(\S+)/) { $interface = $1; $interface_options =~ s/backend=(\S+)//; if ($interface_options =~ /^\s*$/) { $interface_options = ""; } } else { $interface = ""; } } } # All URIs ("-c" option) have the same syntax as URIs in CUPS ("-v" # option of "lpadmin"). if (defined($config->{'connect'})) { $interface_options =~ s/smbuser=(\S+)//; $interface_options =~ s/smbpassword=(\S+)//; if ($config->{'connect'} =~ m!^(file|usb|parallel|serial):(.*)!) { # Local printer or printing to a file $address = $2; if ($config->{'connect'} =~ m!^usb://!) { # Queue with printer-bound USB URI transferred from CUPS, # as PPR does not support these URIs, translate it # back to a standard USB device URI $address = cups_usb_printer_uri_to_device_uri($address); } if (! -e $address) { warn "The device or file $address doesn't exist? " . "Working anyway.\n"; } if (($address =~ m!usb!) || ($address =~ m!USB!) || ($address =~ m!$sysdeps->{'ptal-pipes'}!) || ($address =~ m!/dev/ptal-printd!) || ($address =~ m!/var/run/ptal-printd!) || ($address =~ m!$sysdeps->{'mtink-pipes'}!) || ($address =~ m!/var/mtink!)) { $interface = "simple"; } elsif (($address =~ m!lp[0-9]!) || ($address =~ m!LP[0-9]!) || ($address =~ m!parallel!)) { $interface = "parallel"; } elsif (($address =~ m!tty!) || ($address =~ m!TTY!) || ($address =~ m!serial!)) { $interface = "serial"; } else { $interface = "dummy"; } $options = ""; } elsif ($config->{'connect'} =~ m!^ptal://?([^/].*)$!) { # HPOJ MLC protocol my $devname = $1; $devname =~ tr/:/_/; $address = "$sysdeps->{'ptal-pipes'}/$devname"; $interface = "simple"; $options = ""; } elsif ($config->{'connect'} =~ m!^mtink:/(.+)$!) { # Printing through "mtinkd" $address = "$sysdeps->{'mtink-pipes'}/$1"; $interface = "simple"; $options = ""; } elsif ($config->{'connect'} =~ m!^lpd://([^/]+)/([^/]+)$!) { # Remote LPD my $remhost = $1; my $remqueue = $2; $address = "${remqueue}\@${remhost}"; $interface = "lpr"; $options = ""; } elsif ($config->{'connect'} =~ m!^socket://([^/:]+):([0-9]+)/?$!) { # Socket (AppSocket/HP JetDirect) my $remhost = $1; my $remport = $2; $address = "$remhost:$remport"; $interface = "tcpip"; $options = ""; } elsif ($config->{'connect'} =~ m!^smb://(.*)$!) { # SMB (Printer on Windows server) my $parameters = $1; # Get the user's login and password from the URI my $smbuser = ""; my $smbpassword = ""; if ($parameters =~ m!([^@]*)@([^@]+)!) { my $login = $1; $parameters = $2; if ($login =~ m!([^:]*):([^:]*)!) { $smbuser = $1; $smbpassword = $2; } else { $smbuser = $login; $smbpassword = ""; } } else { $smbuser = "GUEST"; $smbpassword = ""; } # When a password is given, a user name should be given, too. if (($smbpassword ne "") && ($smbuser eq "")) { $smbuser = "GUEST"; } # The "smb" interface of PPR uses "ppr" as the SMB user when no # user name is given. Usually one does not have such a user name # under Windows. So use "GUEST" if no user name is given. if ($smbuser eq "") { $smbuser = "GUEST"; } # Set the options for PPR's "smb" interface $options = ""; if ($smbuser ne "") { $options = "smbuser=\"$smbuser\""; if ($smbpassword ne "") { $options .= " smbpassword=\"$smbpassword\""; } } # Get the workgroup, server, and share name my $workgroup = ""; my $smbserver = ""; my $smbshare = ""; if ($parameters =~ m!([^/]*)/([^/]+)/([^/]+)$!) { $workgroup = $1; $smbserver = $2; $smbshare = $3; } elsif ($parameters =~ m!([^/]+)/([^/]+)$!) { $workgroup = ""; $smbserver = $1; $smbshare = $2; } else { die "The \"smb://\" URI must at least contain the " . "server name and the share name!\n"; } $address = "//$smbserver/$smbshare"; $interface = "smb"; } else { die ("The URI \"$config->{'connect'}\" is not supported for " . "PPR or you have\nmistyped.\n"); } } elsif (!$reconf) { die "You must specify a connection with -c.\n"; } # Here we set up the command line for the "ppad interface" and the # "ppad options" commands my $ppad_interface = ""; my $ppad_options = ""; my $ppad_rip = ""; if ($rawqueue) { $ppad_interface = "$sysdeps->{'ppr-ppad'} interface " . "\"$config->{'queue'}\" $interface \"$address\""; $ppad_options = "$sysdeps->{'ppr-ppad'} options " . "\"$config->{'queue'}\" $options $interface_options"; $ppad_rip = "$sysdeps->{'ppr-ppad'} " . "rip \"$config->{'queue'}\""; } else { if ($pprversion >= 1.50000102 ) { #1.50a2 $ppad_interface = "$sysdeps->{'ppr-ppad'} interface " . "\"$config->{'queue'}\" $interface \"$address\""; $ppad_options = "$sysdeps->{'ppr-ppad'} options " . "\"$config->{'queue'}\" $options $interface_options"; if ($db->{'dat'}{'id'}) { $ppad_rip = "$sysdeps->{'ppr-ppad'} " . "rip \"$config->{'queue'}\" foomatic-rip x" . # PPR 1.50a2 has a bug and needs at least one option for # the command line of the PPR RIP, therefore we add the # "0" in this case. The number is very likely not the # name of any boolean option, so it will be ignored by # foomatic-rip (($pprversion < 1.50000103 ) ? " 0" : ""); } else { $ppad_rip = "$sysdeps->{'ppr-ppad'} " . "rip \"$config->{'queue'}\""; } } else { $ppad_interface = "$sysdeps->{'ppr-ppad'} interface " . "\"$config->{'queue'}\" foomatic-rip \"$address\""; $ppad_options = "$sysdeps->{'ppr-ppad'} options " . "\"$config->{'queue'}\" backend=\"$interface\" " . "$options $interface_options"; $ppad_rip = "$sysdeps->{'ppr-ppad'} " . "rip \"$config->{'queue'}\""; } } # Execute the ppad commands to set up the new queue if ((system $ppad_interface) || (system $ppad_options) || (system $ppad_rip)) { die "Could not set up/change the queue \"$config->{'queue'}\"!\n"; } # Use manufacturer and model as description when no description is # provided my($comment, $olddesc); if (defined($config->{'desc'})) { $comment = $config->{'desc'}; } else { # Before we overwrite the description field with manufacturer # and model, check if there is some old contents if (($reconf) && ($entry->{'Comment'})) { $olddesc = $entry->{'Comment'}; } if (!$olddesc) { if (!$rawqueue) { $comment = "$makemodel"; } else { $comment = "Raw queue"; } } } if ($comment) { my $ppad_comment = "$sysdeps->{'ppr-ppad'} comment " . "\"$config->{'queue'}\" \"$comment\""; if (system $ppad_comment) { warn "Could not set description for the queue " . "\"$config->{'queue'}\"!\n"; } } # Fill in the "location" field if something for it is provided. if (defined($config->{'loc'})) { my $ppad_location = "$sysdeps->{'ppr-ppad'} location " . "\"$config->{'queue'}\" \"$config->{'loc'}\""; if (system $ppad_location) { warn "Could not set location for the queue " . "\"$config->{'queue'}\"!\n"; } } # Various file setup mkdir $sysdeps->{'foo-etc'}, 0755; mkdir $sysdeps->{'foo-etc'} . '/ppr', 0755; # Generate/write the PPD file writeppdfile($config, $ppdfile, $rawqueue, $newfoomaticdata); if ($rawqueue) { my $ppad_ppd = "$sysdeps->{'ppr-ppad'} ppd " . "\"$config->{'queue'}\" \"\" 2> /dev/null"; if (!system $ppad_ppd) { # Automatic input tray selection not activated by default, # because the feature requires manual choice of the paper types # in the trays and other spoolers than PPR do not have automatic # paper tray selection. In addition "ppop media <queue>" is # broken for printers with a high number of input trays in their # PPD files. #my $ppad_bins = "$sysdeps->{'ppr-ppad'} bins delete " . #"\"$config->{'queue'}\" \"" . #join ('" "', @{$entry->{'Bins'}}) . "\""; #if (system $ppad_bins) { #warn "Could not set paper input trays for the " . #"queue \"$config->{'queue'}\"!\n"; #} my $ppad_deffiltopts = "$sysdeps->{'ppr-ppad'} " . "deffiltopts \"$config->{'queue'}\" 2> /dev/null"; if (system $ppad_deffiltopts) { warn "Could not set \"DefFiltOpts\" entry for " . "the queue \"$config->{'queue'}\"!\n"; } } else { die "Could not set PPD for the queue \"$config->{'queue'}\"!\n"; } } else { my $ppad_ppd = "$sysdeps->{'ppr-ppad'} ppd " . "\"$config->{'queue'}\" \"$ppdfile\" 2> /dev/null"; if (!system $ppad_ppd) { # Automatic input tray selection not activated by default, # because the feature requires manual choice of the paper types # in the trays and other spoolers than PPR do not have automatic # paper tray selection. In addition "ppop media <queue>" is # broken for printers with a high number of input trays in their # PPD files. #my $ppad_bins = "$sysdeps->{'ppr-ppad'} bins ppd " . #"\"$config->{'queue'}\""; #if (system $ppad_bins) { #warn "Could not set paper input trays for the " . #"queue \"$config->{'queue'}\"!\n"; #} my $ppad_deffiltopts = "$sysdeps->{'ppr-ppad'} " . "deffiltopts \"$config->{'queue'}\" 2> /dev/null"; if (system $ppad_deffiltopts) { warn "Could not set \"DefFiltOpts\" entry for the " . "queue \"$config->{'queue'}\"!\n"; } } else { die "Could not set PPD for the queue \"$config->{'queue'}\"!\n"; } } if ($rawqueue) { # If we have a raw queue, delete the PPD file if there is still # one from a former queue. unlink "$ppdfile" if (-f "$ppdfile"); } else { # Clean up "Switchset" entry my @switchset = split('|', $entry->{'Switchset'}); my @newswitchset = (); for my $option (@switchset) { if (!(($option =~ /^F\s*\*([^\*\s=:]+)\s+([^\*\s=:]+)\s*$/) || ($option =~ /^F\s*([^\*\s=:]+)\s*=\s*([^\*\s=:]+)\s*$/) || ($option =~ /^F\s*\*([^\*\s=:]+)\s*$/) || ($option =~ /^F\s*([^\*\s=:]+)\s*$/))) { # The option is not a PPD option, keep it. # PPD options are incorporated in the PPD file now and so # they can be dropped in the "Switchset". if ($option =~ /^\s*(\S)(.*)$/) { push (@newswitchset, "-$1 \"$2\""); } } } my $ppad_switchset = "$sysdeps->{'ppr-ppad'} switchset " . "\"$config->{'queue'}\" " . join (' ', @newswitchset); if (system $ppad_switchset) { warn "Could not set switchset for the queue " . "\"$config->{'queue'}\"!\n"; } # Check, if there is a PJL option and set the "Jobbreak" to "none" # because otherwise there is a Ctrl+D between the PJL frame added # by foomatic-rip and the PostScript job. This breaks printing of # certain PS files as the CUPS test page. my $pjloption = 0; for my $arg (@{$db->{'dat'}->{'args'}}) { if ($arg->{'style'} eq "J") { $pjloption = 1; last; } } if ($pjloption) { my $ppad_jobbreak = "$sysdeps->{'ppr-ppad'} jobbreak " . "\"$config->{'queue'}\" none"; if (system $ppad_jobbreak) { warn "Could not set \"Jobbreak\" entry for the " . "queue \"$config->{'queue'}\"!\n"; } } } return 1; } sub default_ppr { my ($config) = $_[0]; # The default printer under PPR is the printer named "default". To be # able to easily switch the default printer we set up a printer group # named "default" containing the chosen default printer as its only # member. If there is already a printer called "default", we rename it. my $name = $config->{'queue'}; my $printrc = load_ppr_printers_conf(); my $printerfound = 0; for my $p (@{$printrc}) { if ($p->{'name'} eq $name) { $printerfound = 1; } # Rename a printer whose name is 'default' if ($p->{'name'} eq 'default') { # Search for a free name my $i = 0; my $namefound = 0; my $newname = ""; while(!$namefound) { my $pp; my $nameinuse = 0; for $pp (@{$printrc}) { if (defined($pp->{'name'})) { if ($pp->{'name'} eq "default$i") { $nameinuse = 1; $i++; last; } } } $namefound = 1 - $nameinuse; } $newname = "default$i"; # If the printer we want to use as default printer has the # name "default", we must use the new name as the member name # in the default group. if ($name eq "default") { $name = $newname; } # Do the renaming # Copy the queue ... if (system("foomatic-configure -s ppr -n $newname -C default")){ die "Could not copy the queue \"default\" into the " . "queue \"$newname\"!\n"; } # ... and remove the original one if (system("foomatic-configure -s ppr -n default -R")) { die "Could not remove the queue \"default\"!\n"; } warn "Renamed the printer\"default\" to \"$newname\"!\n"; } } # The desired default printer exists? Then make it the default if ($printerfound) { # Create a group named "default" with only this printer as member my $ppad_group = "$sysdeps->{'ppr-ppad'} group members " . "default \"$name\""; if (system $ppad_group) { warn "Could not create a group to make the queue \"$name\" " . "the default!\n"; } } } sub delete_ppr { my ($config) = $_[0]; # This line deletes the old printer queue my $queuedeleteline = "$sysdeps->{'ppr-ppad'} delete " . "\"$config->{'queue'}\""; # Do it! system $queuedeleteline and die "Unable to delete queue \"$config->{'queue'}\"!\n"; # Rename the PPD file # PPD file name my $ppdfile = sprintf('%s/ppr/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Rename old $ppdfile, if any rename "$ppdfile", "$ppdfile.old" if (-f "$ppdfile"); return 1; } sub query_ppr { my ($config) = @_; # User requests data of a printer/driver combo to see the options before # installing a queue if (($opt_P) && ((($config->{'driver'}) && ($config->{'printer'}) && ($config->{'driver'} ne "raw")) || ($config->{'ppdfile'}))) { if ($opt_n) { my $olddatablob = load_ppr_datablob($opt_n); print_perl_combo_data($config, $olddatablob); } else { print_perl_combo_data($config); } return; } my $i = $ARGV[0]; if (!defined($i)) {$i = 0;} my $pconf = load_ppr_printers_conf(); if (defined($opt_r)) {$opt_r = undef;} my $p; if (!$opt_P) { print "<queues>\n"; } # Query the default printer my $default; if (!defined($config->{'queue'})) { for $p (@{$pconf}) { if ($p->{'default'}) { $default = $p->{'name'}; if (!$opt_P) { print "<defaultqueue>$p->{'name'}</defaultqueue>\n"; } last; } } } for $p (@{$pconf}) { # were we invoked for only one queue? next if (defined($config->{'queue'}) and $config->{'queue'} ne $p->{'name'}); # load the queue data $db->{'dat'} = load_ppr_datablob($p->{'name'}); # extract the queue data block my $c = $db->{'dat'}{'queuedata'}; if ($opt_P) { if ($p->{'name'} eq $default) { $db->{'dat'}{'queuedata'}{'default'} = 1; } else { $db->{'dat'}{'queuedata'}{'default'} = 0; } $db->{'dat'}{'queuedata'}{'remote'} = 0; my $asciidata = $db->getascii(); $asciidata =~ s/\$VAR1/\$QUEUES[$i]/g; print $asciidata; $i ++; } else { # and get it to standard output dump_config($c); } } if (!$opt_P) { print "</queues>\n"; } return; } ### Queue manipulation functions for direct, spooler-less printing sub setup_direct { my ($config) = $_[0]; # Read the previous config file my $pconfig = load_direct_config(); my ($entry, $reconf, $p); for $p (@{$pconfig}) { if ($p->{'name'} eq $config->{'queue'}) { $entry = $p; $reconf = 1; last; use Data::Dumper; print "Reconfigure of ", Dumper($p); } } # PPD file name my $ppdfile = sprintf('%s/direct/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Get the data from the former queue if we reconfigure or copy a queue # do also some checking of the user-supplied parameters my ($rawqueue, $newfoomaticdata, $makemodel) = getoldqueuedata($config, $reconf); # Set the printer queue name $entry->{'name'} = $config->{'queue'}; # Use manufacturer and model as description when no description is # provided if (defined($config->{'desc'})) { $entry->{'desc'} = $config->{'desc'}; } else { # Before we overwrite the description field with manufacturer # and model, check if there is some old contents my( $olddesc ); if (($reconf) && ($entry->{'desc'})) { $olddesc = $entry->{'desc'}; } if (!$olddesc) { $entry->{'desc'} = "$makemodel"; } } # Fill in the "location" field if something for it is provided. if (defined($config->{'loc'})) { $entry->{'loc'} = $config->{'loc'}; } # If the printing jobs should not be passed to standard output, put the # command line into $postpipe (for example for Socket, Samba, parallel # port ...) my $postpipe = ""; if ((!$reconf) or ($config->{'connect'})) { # Set up connection type # All URIs ("-c" option) have the same syntax as URIs in CUPS ("-v" # option of "lpadmin"). if ($config->{'connect'} =~ m!^(file|usb|parallel|serial):(.*)!) { # Local printer or printing to a file my $file = $2; if ($config->{'connect'} =~ m!^usb://!) { # Queue with printer-bound USB URI transferred from CUPS, # as spooler-less printing does not support these URIs, # translate it back to a standard USB device URI $file = cups_usb_printer_uri_to_device_uri($file); } if (! -e $file) { warn "The device or file $file doesn't exist? " . "Working anyway.\n"; } if (($file =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($file =~ m!^/dev/ptal-printd/(.+)$!) || ($file =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate URI for ptal-printd to postpipe using the # "ptal-connect" command my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $postpipe = "$sysdeps->{'ptal-connect'} $devname -print"; } else { $postpipe = "$sysdeps->{'cat'} > $file"; } } elsif ($config->{'connect'} =~ m!^ptal://?([^/].*)$!) { # HPOJ MLC protocol my $devname = $1; $postpipe = "$sysdeps->{'ptal-connect'} $devname -print"; } elsif ($config->{'connect'} =~ m!^mtink:/(.+)$!) { # Printing through "mtinkd" $postpipe = "$sysdeps->{'cat'} > $sysdeps->{'mtink-pipes'}/$1"; } elsif ($config->{'connect'} =~ m!^lpd://([^/]+)/([^/]+)$!) { # Remote LPD my $remhost = $1; my $remqueue = $2; $postpipe = "$sysdeps->{'rlpr'} -q -h -P $remqueue\@$remhost"; } elsif ($config->{'connect'} =~ m!^socket://([^/:]+):([0-9]+)/?$!){ # Socket (AppSocket/HP JetDirect) my $remhost = $1; my $remport = $2; $postpipe = "$sysdeps->{'nc'} -w 1 $remhost $remport"; } elsif ($config->{'connect'} =~ m!^smb://(.*)$!) { # SMB (Printer on Windows server) my $parameters = $1; # Get the user's login and password from the URI my $smbuser = ""; my $smbpassword = ""; if ($parameters =~ m!([^@]*)@([^@]+)!) { my $login = $1; $parameters = $2; if ($login =~ m!([^:]*):([^:]*)!) { $smbuser = $1; $smbpassword = $2; } else { $smbuser = $login; $smbpassword = ""; } } else { $smbuser = "GUEST"; $smbpassword = ""; } # Get the workgroup, server, and share name my $workgroup = ""; my $smbserver = ""; my $smbshare = ""; if ($parameters =~ m!([^/]*)/([^/]+)/([^/]+)$!) { $workgroup = $1; $smbserver = $2; $smbshare = $3; } elsif ($parameters =~ m!([^/]+)/([^/]+)$!) { $workgroup = ""; $smbserver = $1; $smbshare = $2; } else { die "The \"smb://\" URI must at least contain the " . "server name and the share name!\n"; } # Set up the command line for printing on the SMB server $postpipe = "$sysdeps->{'smbclient'} \"//$smbserver/$smbshare\""; if ($smbpassword ne "") { warn("WARNING: smbclient password is visible in PPD file\n"); $postpipe .= " $smbpassword"; } if ($smbuser ne "") {$postpipe .= " -U $smbuser";} if ($workgroup ne "") {$postpipe .= " -W $workgroup";} $postpipe .= " -N -P -c 'print -' "; } elsif ($config->{'connect'} =~ m!^ncp://(.*)$!) { my $parameters = $1; # Get the user's login and password from the URI my $ncpuser = ""; my $ncppassword = ""; if ($parameters =~ m!([^@]*)@([^@]+)!) { my $login = $1; $parameters = $2; if ($login =~ m!([^:]*):([^:]*)!) { $ncpuser = $1; $ncppassword = $2; } else { $ncpuser = $login; $ncppassword = ""; } } else { $ncpuser = ""; $ncppassword = ""; } # Get the server and share name my $ncpserver = ""; my $ncpqueue = ""; if ($parameters =~ m!([^/]+)/([^/]+)$!) { $ncpserver = $1; $ncpqueue = $2; } else { die "The \"ncp://\" URI must at least contain the server " . "name and the queue name!\n"; } # Set up the command line for printing on the Netware server $postpipe = "$sysdeps->{'nprint'} -S $ncpserver"; if ($ncpuser ne "") { $postpipe .= " -U $ncpuser"; if ($ncppassword ne "") { warn("WARNING: ncp password is visible in PPD file\n"); $postpipe .= " -P $ncppassword"; } else { $postpipe .= " -n"; } } $postpipe .= " -q $ncpqueue -N - 2>/dev/null"; } elsif ($config->{'connect'} =~ m!^postpipe:(.*)$!) { # Pipe output into a command $postpipe = $1; } elsif ($config->{'connect'} =~ m!^stdout!) { $postpipe = ""; } elsif ($config->{'connect'}) { die ("The URI \"$config->{'connect'}\" is not supported for " . "spooler-less printing or you have\nmistyped.\n"); } else { die "You must specify a connection with -c.\n"; } # Put $postpipe into the data structure, so that it will be # inserted into the PPD file if ($postpipe ne "") { $postpipe = "| $postpipe"; $db->{'dat'}{'postpipe'} = $postpipe; } else { undef $db->{'dat'}{'postpipe'}; } } else { # Keep previous connection type # Use previous $postpipe if (defined($db->{'dat'}{'postpipe'})) { $postpipe = $db->{'dat'}{'postpipe'}; } } # Various file setup mkdir $sysdeps->{'foo-etc'}, 0755; mkdir $sysdeps->{'foo-etc'} . "/direct", 0755; # Add to the config file if a new entry if (!$reconf) { push(@{$pconfig}, $entry); } # Generate/write the PPD file writeppdfile($config, $ppdfile, $rawqueue, $newfoomaticdata); # Write back /etc/foomatic/direct/.config my $pconfigname = $sysdeps->{'direct-config'}; rename $pconfigname, "$pconfigname.old"; open PCONFIG, "> $pconfigname" or die "Cannot write $pconfigname!\n"; print PCONFIG dump_direct_config($pconfig); close PCONFIG; chmod 0644, $pconfigname; return 1; } sub default_direct { my ($config) = $_[0]; my $name = $config->{'queue'}; my $pconfig = load_direct_config(); # Modify the "default" fields of the printers appropriately for (@{$pconfig}) { $_->{'default'} = ($_->{'name'} eq $name); } my @newpconfig = dump_direct_config($pconfig); my $pconfigname = $sysdeps->{'direct-config'}; rename $pconfigname, "$pconfigname.old"; open PCONFIG, "> $pconfigname" or die "Cannot write $pconfigname!\n"; print PCONFIG @newpconfig; close PCONFIG; chmod 0644, $pconfigname; return 1; } sub delete_direct { my ($config) = $_[0]; my $name = $config->{'queue'}; my $pconfig = load_direct_config(); # Overtake all entries except the one of the deleted printer to the # new config file my @newconf; for (@{$pconfig}) { push (@newconf, $_) unless ($_->{'name'} eq $name); } my @newpconfig = dump_direct_config(\@newconf); my $pconfigname = $sysdeps->{'direct-config'}; rename $pconfigname, "$pconfigname.old"; open PCONFIG, "> $pconfigname" or die "Cannot write $pconfigname!\n"; print PCONFIG @newpconfig; close PCONFIG; chmod 0644, $pconfigname; # PPD file name my $ppdfile = sprintf('%s/direct/%s.ppd', $sysdeps->{'foo-etc'}, $config->{'queue'}); # Rename old $ppdfile, if any rename $ppdfile, "$ppdfile.old" if (-f $ppdfile); return 1; } sub query_direct { my ($config) = @_; # User requests data of a printer/driver combo to see the options before # installing a queue if (($opt_P) && ((($config->{'driver'}) && ($config->{'printer'}) && ($config->{'driver'} ne "raw")) || ($config->{'ppdfile'}))) { if ($opt_n) { my $olddatablob = load_direct_datablob($opt_n); print_perl_combo_data($config, $olddatablob); } else { print_perl_combo_data($config); } return; } my $i = $ARGV[0]; if (!defined($i)) {$i = 0;} my $pconf = load_direct_config(); if (defined($opt_r)) {$opt_r = undef;} my $p; if (!$opt_P) { print "<queues>\n"; } # Query the default printer my $default; if (!defined($config->{'queue'})) { for $p (@{$pconf}) { if ($p->{'default'}) { $default = $p->{'name'}; if (!$opt_P) { print "<defaultqueue>$p->{'name'}</defaultqueue>\n"; } last; } } } for $p (@{$pconf}) { # were we invoked for only one queue? next if (defined($config->{'queue'}) and $config->{'queue'} ne $p->{'name'}); # load the queue data $db->{'dat'} = load_direct_datablob($p->{'name'}); # extract the queue data block my $c = $db->{'dat'}{'queuedata'}; if ($opt_P) { if ($p->{'name'} eq $default) { $db->{'dat'}{'queuedata'}{'default'} = 1; } else { $db->{'dat'}{'queuedata'}{'default'} = 0; } $db->{'dat'}{'queuedata'}{'remote'} = 0; my $asciidata = $db->getascii(); $asciidata =~ s/\$VAR1/\$QUEUES[$i]/g; print $asciidata; $i ++; } else { # and get it to standard output dump_config($c); } } if (!$opt_P) { print "</queues>\n"; } return; } ### Functions used by the queue manipulation functions from above sub dump_config { my $c = $_[0]; print sprintf("<queue foomatic=\"%d\" spooler=\"%s\">\n", ($c->{'foomatic'} ? 1 : 0), $c->{'spooler'}), _tag('name',$c->{'queue'}), _tag('printer',$c->{'printer'}), _tag('driver',$c->{'driver'}), _tag('connect',$c->{'connect'}), _tag('location',$c->{'loc'}), _tag('description',$c->{'desc'}), ($c->{'spooler'} eq "cups" ? (_tag('dontdisable',$c->{'dd'}), _tag('attempts',$c->{'att'}), _tag('delay',$c->{'delay'}), (defined($c->{'quotaperiod'}) ? _tag('quotaperiod',$c->{'quotaperiod'}) : ()), (defined($c->{'pagelimit'}) ? _tag('pagelimit',$c->{'pagelimit'}) : ()), (defined($c->{'klimit'}) ? _tag('klimit',$c->{'klimit'}) : ()), (defined($c->{'laststatechange'}) ? _tag('laststatechange',$c->{'laststatechange'}) : ()), (defined($c->{'shared'}) ? _tag('shared',$c->{'shared'}) : ()), (defined($c->{'operationpolicy'}) ? _tag('operationpolicy',$c->{'operationpolicy'}) : ()), (defined($c->{'errorpolicy'}) ? _tag('errorpolicy',$c->{'errorpolicy'}) : ())) : ()), "</queue>\n"; return; } sub _tag { my ($t, $v) = @_; return '' if !defined($v); $v =~ s!\&!\&\;!g; $v =~ s!\<!\<\;!g; return " <$t>$v</$t>\n"; } sub dump_lpd_printcap { my ($config, $pcap )= @_; my @retval; my $item; my $backslash = "\\"; $backslash = "" if $config->{'spooler'} eq 'lprng'; for $item (@{$pcap}) { for (@{$item->{'comments'}}) { push (@retval, "$_\n"); } if (defined($item->{'names'})) { map { $_ = '' if not defined $_; } @{$item->{'names'}}; push (@retval, (join('|', @{$item->{'names'}}) . ":${backslash}\n")); } for (keys(%{$item->{'str'}})) { # special case of 'tc' items, as there can be more than one if ($_ =~ /^tc\d+$/) { push (@retval, sprintf(" :tc=%s:${backslash}\n", $item->{'str'}{$_})); } else { push (@retval, sprintf(" :$_=%s:${backslash}\n", $item->{'str'}{$_})); } } for (keys(%{$item->{'bool'}})) { if ($item->{'bool'}{$_}) { push (@retval, " :$_:${backslash}\n"); } } for (keys(%{$item->{'num'}})) { push (@retval, sprintf(" :$_#%s:${backslash}\n", $item->{'num'}{$_})); } if( $backslash ){ my $lastline = pop(@retval); $lastline =~ s!:\\!:!; push (@retval, $lastline); } } print "PRINTCAP (spooler '" . $config->{'spooler'} . "') " . Dumper(\@retval) . "\n" if $debug; return @retval; } sub load_lpd_printcap { # list-o-printers, each with comments open PCAP, $sysdeps->{'lpd-pcap'} or die "Cannot read printcap file!\n"; my $pcap = join('', <PCAP>); close PCAP; print "PC '$pcap'\n" if $debug; # die( "Cannot currently parse lprng style printcaps created by " . # "lprngtool!\n" . # "See the BUGS section in the manpage for details.\n") # if $pcap =~ m/\n\s*(:.*[^\\]\n\s*:)/m; # watch out for comments with \ at end of line - ignore \ $pcap =~ s!^(\s*\#.*\\)$!${1}MEMEMEM!gm; # now we join lines with \ at end $pcap =~ s!\\\n!!gms; # remove \ in comment lines $pcap =~ s!\\MEMEMEM!\\!g; print "AFTER '$pcap'\n" if $debug; my (@comment, @items, @comments_in_pc_entry); my ($pline, $pcentry); $pcentry = ""; for $pline (split('\n',$pcap)) { $pline =~ s/^\s+//; print "LINE '$pline', pcentry '$pcentry'\n" if $debug; next if $pline eq ""; if ($pline =~ m!^\#!) { if( $pcentry ){ push (@comments_in_pc_entry, $pline); } else { push (@comment, $pline); } } elsif ($pline =~ m!^:!) { push( @comment, @comments_in_pc_entry ); @comments_in_pc_entry = (); if( $pcentry ne "" ){ $pcentry .= $pline; } else { die( "bad printcap entry at '$pline'" ); } } elsif( $pcentry ne "" ){ push (@items, { 'itemstr' => $pcentry, 'comments' => [ @comment ] }); @comment = @comments_in_pc_entry; @comments_in_pc_entry = (); $pcentry = $pline; } else { $pcentry = $pline; } } if( $pcentry ){ push( @comment, @comments_in_pc_entry ); @comments_in_pc_entry = (); push (@items, { 'itemstr' => $pcentry, 'comments' => [ @comment ] }); @comment = (); } # Trailing comments get stuck on as empty item later... print "Printcap:\n" . Dumper(\@items ) if $debug; my $p; for $p (@items) { my $item; my $first = 1; my $tci = 0; for $item (split(/:\s*/, $p->{'itemstr'})) { next if $item =~ m!^\s*$!; if ($first) { my $name; for $name (split('\|',$item)) { $name =~ s!\s*(.+)\s*!$1!; push (@{$p->{'names'}}, $name); } $first = 0; } else { if ($item =~ m!^([^=]*)=(.+)!) { # special case of 'tc' items, as there can be more # than one if ($1 eq 'tc') { $p->{'str'}{"tc$tci"} = $2; $tci++; } else { $p->{'str'}{$1} = $2; } } elsif ($item =~ m!^([^\#]*)\#(.+)!) { $p->{'num'}{$1} = $2; } elsif ($item =~ m!^([^\@]*)\@?!) { $p->{'bool'}{$1} = 1; } } } } # Trailing comments from way above... if (scalar(@comment)) { push (@items, {'comments' => [ @comment ]}); } return \@items; } sub load_cups_printersconf { # list-o-printers my @items = (); my $itemshash = {}; if ($< == 0) { # Get info from /etc/cups/printers.conf, works only as "root" and # with locally defined printers my @pconf = (); if (open PCONF, $sysdeps->{'cups-pconf'}) { @pconf = <PCONF>; close PCONF; } my $line; my $p = {}; my $linecount = 0; for $line (@pconf) { $linecount ++; if (!($line =~ m!^\s*\#!) && (!($line =~ m!^\s*$!))) { if ($line =~ m!^\s*<(.*)Printer\s+([^\s>]+)>\s*$!) { # Beginning of new <Printer ...> block $p->{'name'} = $2; $p->{'default'} = ($1 eq "Default"); } elsif ($line =~ m!^\s*</Printer>\s*$!) { # End of <Printer ...> block push (@items, $p); $itemshash->{$p->{name}} = $#items; $p = {}; } elsif (defined($p->{'name'})) { # Inside <Printer ...> block if (($line =~ m!^\s*(\S+)\s+(\S.*)$!) and ($1 ne '')) {$p->{$1} = $2}; } else { # Outside <Printer ...> block die "Line $linecount in $sysdeps->{'cups-pconf'} " . "invalid!\n"; } } } } if (($< != 0) || (($opt_r) && (($opt_Q) || ($opt_P)))) { # Get info with the "lpstat" command, works for normal users and for # remote printers. open LPSTAT, "$sysdeps->{'cups-lpstat'} -l -d -p -v |" or die "Cannot execute \"lpstat\".\n"; my @lpstat = <LPSTAT>; close LPSTAT; my $line; my $linecount = 0; my $defaultprinter = ''; my $currentitem = -1; for $line (@lpstat) { chomp ($line); $linecount ++; if (!($line =~ m!^\s*$!)) { if ($line =~ m!^\s*system\s+default\s+destination:\s+(\S+)\s*$!) { # Default printer $defaultprinter = $1; } elsif ($line =~ m!^printer\s+(\S+)\s+(\S.*)$!) { # Beginning of new printer's entry my $name = $1; my $state = $2; $state =~ s/\s+-$//; if (!defined($itemshash->{$name})) { push(@items, {}); $itemshash->{$name} = $#items; # If we are root and didn't see this entry # in /etc/cups/printers.conf, this printer # is remotely defined if ($< == 0) { $items[$itemshash->{$name}]{'remote'} = 1; } } $currentitem = $itemshash->{$name}; $items[$currentitem]{'name'} ||= $name; $items[$currentitem]{'State'} ||= $state; $items[$currentitem]{'default'} = ($name eq $defaultprinter); } elsif ($line =~ m!^\s+Description:\s+(\S.*)$!) { # Description field if ($currentitem != -1) { $items[$currentitem]{'Info'} ||= $1; } } elsif ($line =~ m!^\s+Location:\s+(\S.*)$!) { # Location field if ($currentitem != -1) { $items[$currentitem]{'Location'} ||= $1; } } elsif ($line =~ m!^\s+Connection:\s+remote!) { # Remote printer, only keep it when the "-r" option is # given if (!$opt_r) { # "delete" does not work on arrays with Perl 5.0.x # Thanks to Olaf Till (i7tiol@t-online.de) who # contributed this fix splice(@items, $currentitem, 1); #delete($items[$currentitem]); $currentitem = -1; } else { if ($currentitem != -1) { $items[$currentitem]{'remote'} = 1; } } } elsif ($line =~ m!^device\s+for\s+(\S+):\s+(\S.*)$!) { # "device for ..." line, extract URI my $name = $1; my $uri = $2; if (defined($itemshash->{$name})) { if ($uri !~ /:/) {$uri = "file:" . $uri}; $currentitem = $itemshash->{$name}; if (($currentitem <= $#items) && ($items[$currentitem]{'name'} eq $name)) { $items[$currentitem]{'DeviceURI'} ||= $uri; } } } } } } return \@items; } sub dump_pdq_printrc { my $printrc = $_[0]; my @retval; my $item; for $item (@{$printrc}) { if (defined($item->{'name'})) { # $item is a "printer" block push (@retval, "printer \"$item->{'name'}\" \{\n"); for my $key (keys(%{$item})) { if (($key ne 'name') && ($key ne 'others')) { push (@retval, "\t$key $item->{$key}\n"); } } push (@retval, "\}\n"); } elsif (defined($item->{'others'})) { # $item is not a "printer" block push (@retval, $item->{'others'}); } } # Check whether there is a already a 'try_include "/etc/foomatic/pdq/*"' # line in the config file if (!(join("", @retval) =~ m!^\s*try_include\s*\"$sysdeps->{'foo-etc'}/pdq/driverdescr/\*\"\s*$!m)) { splice(@retval,0,0,"# Line inserted by $progname\ntry_include " . "\"$sysdeps->{'foo-etc'}/pdq/driverdescr/*\"\n\n"); } # De-activate old line from Foomatic 2.0.x ($_ =~ s!^\s*try_include\s*\"$sysdeps->{'foo-etc'}/pdq/\*\"\s*$!\#$&!m) foreach @retval; return @retval; } sub load_pdq_printrc { # list-o-printers, with storage of non-printer-specific lines open PRINTRC, $sysdeps->{'pdq-printrc'} or die "Cannot read printrc file!\n"; my @printrc = <PRINTRC>; close PRINTRC; my @items; my @others; my $line; my $p; my $linecount = 0; my $inprinterblock = 0; my $nonprinterlines = 0; for $line (@printrc) { $linecount ++; if ($line =~ m!^\s*printer\s+\"(.+)\"\s*{\s*$!) { if ($inprinterblock == 1) { die "New printer block started without previous one " . "being closed!\nLine $linecount in " . "$sysdeps->{'pdq-printrc'}.\n"; } # Beginning of new "printer" block # Store all non-printer-block stuff at first if ($nonprinterlines == 1) { push (@items, {'others' => join ("", @others )}); $nonprinterlines = 0; @others = (); } # Read printer block name $inprinterblock = 1; $p->{'name'} = $1; } elsif ($inprinterblock == 1) { # Inside "printer" block if ($line =~ m!^\s*}\s*$!) { # End of "printer" block $inprinterblock = 0; push (@items, $p); $p = {}; } elsif ($line =~ m!^\s*(\S+)\s*(\S+.*)$!) { $p->{$1} = $2; } elsif ((!($line =~ m!^\s*\#!)) && (!($line =~ m!^\s*$!))) { die "Line $linecount in $sysdeps->{'pdq-printrc'} " . "invalid!\n"; } } else { # Outside "printer" block push(@others, $line); $nonprinterlines = 1; } } # Trailing non-printer lines get stuck on as empty item if ($nonprinterlines == 1) { my $lines = join ("", @others); # Make sure that the last line line ends with a newline character if (!($lines =~ m!\n$!s)) {$lines .= "\n";} push (@items, {'others' => $lines}); } return \@items; } sub load_ppr_printers_conf { # Check whether there is a group named "default" to see what is the # default printer. my $defaultfromgroup = " "; if (open SHOWDEFAULTGROUP, "$sysdeps->{'ppr-ppad'} group show default 2>/dev/null |"){ for my $line (<SHOWDEFAULTGROUP>) { chomp $line; if ($line =~ /\s*Members:\s*([^\s,]+)\s*$/) { $defaultfromgroup = $1; last; } } close SHOWDEFAULTGROUP; } # list-o-printers my @items = (); my $itemshash = {}; if ($< == 0) { # Get info from /etc/ppr/printers/<queue name>, works only as # "root" opendir PCONFDIR, "$sysdeps->{'ppr-etc'}/printers" or die "Cannot read $sysdeps->{'ppr-etc'}/printers directory!\n"; my $name; while ($name = readdir(PCONFDIR)) { # Do not consider "." and ".." as a printer queue next if ($name =~ /^\./); my $line; my $p = {}; $p->{'name'} = $name; $p->{'default'} = (($name eq "default") || ($name eq $defaultfromgroup)); @{$p->{'Bins'}} = (); my $linecount = 0; open PCONFFILE, "$sysdeps->{'ppr-etc'}/printers/$name" or die "Cannot read $sysdeps->{'ppr-etc'}/printers/$name!\n"; for my $line (<PCONFFILE>) { chomp $line; $linecount ++; if (!($line =~ m!^\s*\#!) && (!($line =~ m!^\s*$!))) { if (($line =~ m!^\s*([^\s:]+)\s*:\s*(\S.*)$!) || ($line =~ m!^\s*([^\s:]+)\s*:\s*()$!)) { # <keyword>: <value1> <value2> ... my $keyword = $1; my $values = $2; if (($values) && ($values ne "")) { # If the value is enclosed in double quotes, # remove the quotes $values =~ s/^\"(.*)\"$/$1/; if ($keyword eq "Bin") { push (@{$p->{'Bins'}}, $values); } else { $p->{$keyword} = $values; } } } else { warn "Line $linecount in " . "$sysdeps->{'ppr-etc'}/printers/$name " . "corrupted:\n $line\n"; } } } close PCONFFILE; push (@items, $p); $itemshash->{$p->{'name'}} = $#items; } } if ($< != 0) { # Get info with the "ppop"/"ppad" commands, works for normal users, # but needs installed and running PPR printing system open PPOP_DEST, "$sysdeps->{'ppr-ppop'} destination all |" or die "Cannot execute \"ppop\".\n"; my @ppop_dest = <PPOP_DEST>; close PPOP_DEST; my $line; my $linecount = 0; my $currentitem = -1; for $line (@ppop_dest) { chomp ($line); $linecount ++; if (($line !~ m!^\s*-+\s*$!) && ($line !~ m!^\s*Destination\s+Type\s+Status\s+Charge\s*$!)){ if ($line =~ m!^\s*(\S+)\s+printer!) { my $name = $1; open PPAD_SHOW,"$sysdeps->{'ppr-ppad'} show $name |" or die "Cannot execute \"ppad\".\n"; my $lcount = 0; if (!defined($itemshash->{$name})) { push(@items, {}); $itemshash->{$name} = $#items; #print Dumper($itemshash); } $currentitem = $itemshash->{$name}; $items[$currentitem]{'name'} ||= $name; $items[$currentitem]{'default'} = (($name eq "default") || ($name eq $defaultfromgroup)); for my $line (<PPAD_SHOW>) { chomp $line; $lcount ++; if ((!($line =~ m!^\s*\#!)) && (!($line =~ m!^\s*$!))) { if ($line =~ m!^\s*([^\s:][^:]*)\s*:\s*(.*)$!) { # <keyword>: <value1> <value2> ... my $keyword = $1; my $values = $2; if (($values) && ($values ne "")) { # If the value is enclosed in double # quotes, remove the quotes $values =~ s/^\"(.*)\"$/$1/; if ($keyword eq "Bins") { @{$items[$currentitem]{'Bins'}} = split(", ", $values); } else { if ($keyword eq "Switchset") { $values =~ s/ -(\S) /\|$1/g; $values =~ s/-(\S) /$1/g; $values =~ s/\'//g; $values =~ s/^|//g; } $items[$currentitem]{$keyword} = $values; } } } else { warn "Line $lcount in \"ppad show " . "$name\" corrupted:\n $line\n"; } } } close PPAD_SHOW; } } } } return \@items; } sub dump_direct_config { my $config = $_[0]; my @retval; my $defaultprinter = undef; my $item; for $item (@{$config}) { if (defined($item->{'name'})) { if (defined($item->{'desc'})) { push (@retval, "$item->{'name'} desc:$item->{'desc'}\n"); } if (defined($item->{'loc'})) { push (@retval, "$item->{'name'} loc:$item->{'loc'}\n"); } if ($item->{'default'}) { $defaultprinter = $item->{'name'}; } } } if (defined($defaultprinter)) { unshift(@retval, "default: $defaultprinter\n"); } return @retval; } sub load_direct_config { # list-o-printers my @items = (); my $itemshash = {}; # Configured printers are represented by PPD files in /etc/foomatic/ opendir PCONFDIR, "$sysdeps->{'foo-etc'}/direct" or die "Cannot read $sysdeps->{'foo-etc'}/direct directory!\n"; my $name; while ($name = readdir(PCONFDIR)) { # Files beginning with a dot or ending with a tilde are never # printers next if (($name =~ /^\./) || ($name =~ /~$/)); # Only ".ppd" files are printer descriptions. next unless ($name =~ /\.ppd$/i); $name =~ s/\.ppd$//i; # Do not make two entries when there is both a ".ppd" AND ".PPD" # file for the same printer name. next if (defined($itemshash->{$name})); my $p = {}; $p->{'name'} = $name; push (@items, $p); $itemshash->{$p->{'name'}} = $#items; } # Get additional info from /etc/foomatic/direct/.config (default # printer, description, location if (open CONFIG, "< $sysdeps->{'direct-config'}") { while (my $line = <CONFIG>) { chomp $line; if ($line =~ /^default\s*:\s*([^:\s]+)\s*$/) { my $currentitem = $itemshash->{$1}; $items[$currentitem]{'default'} = 1; } elsif ($line =~ /^\s*([^:\s]+)\s+([^:\s]+)\s*:(.*)$/) { my $currentitem = $itemshash->{$1}; $items[$currentitem]{$2} = $3; } } close CONFIG; } return \@items; } sub cups_correct_ptal_uri { # HPOJ 0.9 uses "ptal:..." URIs with one slash # ("ptal:/mlc:usb:dj450") and the current CVS of HPOJ uses two # slashes ("ptal://mlc:usb:dj450"). Correct the user-supplied URI # according to what "lpinfo -v" reports. my ($uri) = @_; $uri =~ m!^ptal://?([^/].*)$!; my $device = $1; # PTAL URIs listed by "lpinfo -v" open F, "$sysdeps->{'cups-lpinfo'} -v |" or return (@_); while (my $line = <F>) { chomp($line); my $d = quotemeta($device); if ($line =~ m!(ptal://?$d)$!) { my $realdevice = $1; close F; return $realdevice; } } close F; # Nothing found, do not correct the input return @_; } sub cups_generate_usb_device_lists { # Generate two lists: One of the actual USB device files in the # file system, another of the USB URIs listed by CUPS' "lpinfo -v" # Actual devices my @usbdevices; for my $pattern ("/dev/usb/lp*", "/dev/usb/usblp*") { open F, "ls -1 $pattern 2>/dev/null |" or next; @usbdevices = sort { Foomatic::DB::normalizename($a) cmp Foomatic::DB::normalizename($b) } grep { chomp } <F>; close F; last if $#usbdevices >= 0; } return ([], []) if $#usbdevices < 0; # USB URIs listed by "lpinfo -v" open F, "$sysdeps->{'cups-lpinfo'} -v |" or return ([], []); my @usburis = grep { s!^direct usb:!! and chomp } <F>; close F; return ([], []) if $#usburis < 0; # Results return (\@usbdevices, \@usburis); } sub cups_usb_device_uri_to_printer_uri { # Transfer a device file name into a printer-bound CUPS URI for # the printer currently connected my ($device) = @_; return $device if $device =~ m!^//!; my @devicelists = cups_generate_usb_device_lists(); return $device if (($#{$devicelists[0]} < 0) || ($#{$devicelists[1]} < 0)); for (my $i = 0; $i <= $#{$devicelists[0]}; $i ++) { last if !$devicelists[1][$i]; if ($device eq $devicelists[0][$i]) { return $devicelists[1][$i]; } } return $device; } sub cups_usb_printer_uri_to_device_uri { # Transfer a device file name into a printer-bound CUPS URI for # the printer currently connected my ($device) = @_; return $device if $device =~ m!^/[^/]!; $device =~ s/ /\%20/g; my @devicelists = cups_generate_usb_device_lists(); return $device if (($#{$devicelists[0]} < 0) || ($#{$devicelists[1]} < 0)); for (my $i = 0; $i <= $#{$devicelists[1]}; $i ++) { last if !$devicelists[0][$i]; if ($device eq $devicelists[1][$i]) { return $devicelists[0][$i]; } } return $device; } sub load_datablob { my ($spooler, $queue) = @_; my $spoolersubdir; my $datablob; if (($spooler eq "lpd") || ($spooler eq "lprng")) { $datablob = load_lpd_datablob($queue); $spoolersubdir = 'lpd'; } elsif ($spooler eq "cups") { $datablob = load_cups_datablob($queue); $spoolersubdir = 'cups'; } elsif ($spooler eq "pdq") { $datablob = load_pdq_datablob($queue); $spoolersubdir = 'pdq'; } elsif ($spooler eq "ppr") { $datablob = load_ppr_datablob($queue); $spoolersubdir = 'ppr'; } elsif ($spooler eq "direct") { $datablob = load_direct_datablob($queue); $spoolersubdir = 'direct'; } else { die "Unsupported spooler: $spooler\n"; } # Is the given queue a valid queue? if (!$datablob) { return undef; } return ($datablob); } sub load_lpd_datablob { my ($queue) = $_[0]; # Load the PPD file my $ppdfile = sprintf('%s/lpd/%s.ppd', $sysdeps->{'foo-etc'}, $queue); my $dat = ppdtoperl($ppdfile); if (defined($dat)) { $dat->{'ppdfile'} = $ppdfile; } my $postpipe = (defined($dat) ? $dat->{'postpipe'} : ""); # Get additional info from /etc/printcap my $pcap = load_lpd_printcap(); my $p; for $p (@{$pcap}) { # enpty end entry for trailing comments next if !defined($p->{'names'}); # Search for the correct queue next if ($queue ne $p->{'names'}[0]); # Collect values my $c = {}; my $name = $c->{'queue'} = $p->{'names'}[0]; $c->{'desc'} = $p->{'names'}[1] if $p->{'names'}[1]; $c->{'loc'} = $p->{'names'}[3] if $p->{'names'}[3]; $c->{'foomatic'} = 0; my $if = ($p->{'str'}{'if'} || ""); if ($if =~ m!foomatic-rip$!) { $c->{'foomatic'} = 1; $c->{'printer'} = $dat->{'id'}; $c->{'driver'} = $dat->{'driver'}; } if (!$p->{'bool'}{'force_localhost'}) { # LPD $c->{'spooler'} = 'lpd'; } else { # LPRng $c->{'spooler'} = 'lprng'; } # TODO Raw queue for LPD # if (0 and $p->{'str'}{'if'} eq $file) { # Raw queue with $postpipe # if (open FILE, "$file") { # # The first line is #!/bin/sh # $line = <FILE>; # # The second line is a comment # $line = <FILE>; # # The remaining line(s) are the $postpipe # $line = join('', <FILE>); # chomp $line; # $postpipe = "| $line"; # close FILE; # } # } if (defined($postpipe)) { if ($postpipe =~ m!^\s*\|\s*($sysdeps->{'cat'}|cat)\s+-?\s*>\s*([^\s]+)\s*$!) { my $file = $2; if (($file =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($file =~ m!^/dev/ptal-printd/(.+)$!) || ($file =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate device for ptal-printd to ptal URI my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $c->{'connect'} = "ptal:/$devname"; } elsif (($file =~ m!^$sysdeps->{'mtink-pipes'}/(.+)$!) || ($file =~ m!^/var/mtink/(.+)$!)) { # Translate device for mtinkd to mtink URI $c->{'connect'} = "mtink:/$1"; } elsif ($file =~ m!usb!i) { $c->{'connect'} = "usb:$file"; } elsif ($file =~ m!(tty|serial)!i) { $c->{'connect'} = "serial:$file"; } elsif ($file =~ m!(lp[0-9]|parallel)!i) { $c->{'connect'} = "parallel:$file"; } else { $c->{'connect'} = "file:$file"; } } elsif ($postpipe =~ m!^\s*\|\s*($sysdeps->{'ptal-connect'}|ptal-connect|ptal-print)\s+(-print\s+|)([^\s]+)(\s+-print|)\s*$!){ $c->{'connect'} = "ptal:/$3"; } elsif ($postpipe =~ m!^\s*\|\s*($sysdeps->{'nc'}|netcat|nc)\s+(-w\s*1\s+|)([^\s]+)\s+([^\s]+)\s*$!){ $c->{'connect'} = "socket://$3:$4"; } elsif ($postpipe =~ m!^\s*\|\s*$sysdeps->{'rlpr'}\s.*-P\s*([^\s\\\@]+)\@([^\s\\\@]+)\s*$!) { $c->{'connect'} = "lpd://$2/$1"; } elsif ($postpipe =~ m!^.*\|\s*$sysdeps->{'smbclient'}\s+\"//([^/\s]+)/([^/\s]+)\"\s+(\S.*)$!s) { my $servershare = "$1/$2"; my $parameters = $3; my $password = ""; if ($parameters =~ m!^([^-]\S*)\s+(\S.*)$!) { $password = $1; $parameters = $2; } my $username = ""; if ($parameters =~ m!^-U\s+(\S*)\s+(\S.*)$!) { $username = $1; $parameters = $2; } my $workgroup = ""; if ($parameters =~ m!^-W\s+(\S*)\s+(\S.*)$!) { $workgroup = "$1/"; } my $identity = ""; if (($username eq "GUEST") && ($password eq "")) { $identity = ""; } elsif (($username eq "") && ($password eq "")) { $identity = ""; } elsif (($username ne "") && ($password eq "")) { $identity = "$username\@"; } elsif (($username eq "") && ($password ne "")) { $identity = ":$password\@"; } else { $identity = "$username:$password\@"; } $c->{'connect'} = "smb://$identity$workgroup$servershare"; } elsif ($postpipe =~ m!^\s*\|\s*$sysdeps->{'nprint'}\s+(\S.*)$!s) { my $parameters = $1; my $server = ""; if ($parameters =~ m!^-S\s+(\S*)\s+(\S.*)$!) { $server = $1; $parameters = $2; } my $username = ""; if ($parameters =~ m!^-U\s+(\S*)\s+(\S.*)$!) { $username = $1; $parameters = $2; } my $password = ""; if ($parameters =~ m!^-P\s+(\S*)\s+(\S.*)$!) { $password = $1; $parameters = $2; } if ($parameters =~ m!^-n\s+(\S.*)$!) { $parameters = $1; } my $queue = ""; if ($parameters =~ m!^-q\s+(\S*)\s+(\S.*)$!) { $queue = $1; } my $identity = ""; if (($username eq "") && ($password eq "")) { $identity = ""; } elsif (($username ne "") && ($password eq "")) { $identity = "$username\@"; } elsif (($username eq "") && ($password ne "")) { $identity = ":$password\@"; } else { $identity = "$username:$password\@"; } $c->{'connect'} = "ncp://$identity$server/$queue"; } elsif( $postpipe ){ $postpipe =~ m!\s*\|\s*(\S.*)$!; $c->{'connect'} = "postpipe:\"$1\""; } } else { my $lp = $p->{'str'}{'lp'}; if (defined($lp) and $lp and $lp ne '/dev/null') { if (($lp =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($lp =~ m!^/dev/ptal-printd/(.+)$!) || ($lp =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate device for ptal-printd to ptal URI my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $c->{'connect'} = "ptal:/$devname"; } elsif (($lp =~ m!^$sysdeps->{'mtink-pipes'}/(.+)$!) || ($lp =~ m!^/var/mtink/(.+)$!)) { # Translate device for mtinkd to mtink URI $c->{'connect'} = "mtink:/$1"; } elsif ($lp =~ m!^\w+:!i) { $c->{'connect'} = $lp; } else { $c->{'connect'} = "file:$lp"; } } my ($rm, $rp) = ($p->{'str'}{'rm'}, $p->{'str'}{'rp'}); if (defined($rm) and defined($rp)) { $c->{'connect'} = "lpd://$rm/$rp"; } } $dat->{'queuedata'} = $c; } if (!defined($dat->{'queuedata'})) {$dat = undef}; return $dat; } sub load_cups_datablob { my ($queue) = $_[0]; # Load the PPD file my $ppdfile = sprintf('%s/ppd/%s.ppd', $sysdeps->{'cups-etc'}, $queue); #my $ppdfile = sprintf('%s/%s.ppd', # $sysdeps->{'foo-etc'}, # $queue); my $dat = ppdtoperl($ppdfile); if (defined($dat)) { $dat->{'ppdfile'} = $ppdfile; } # Get additional info from /etc/cups/printers.conf my $pconf = load_cups_printersconf(); my $p; for $p (@{$pconf}) { # were we invoked for only one queue? next if ($queue ne $p->{'name'}); # Collect values my $c = {}; $c->{'spooler'} = 'cups'; $c->{'queue'} = $p->{'name'}; $c->{'foomatic'} = 0; if (defined($dat->{'id'}) and defined($dat->{'driver'})) { $c->{'foomatic'} = 1; $c->{'printer'} = $dat->{'id'}; $c->{'driver'} = $dat->{'driver'}; } $c->{'desc'} = $p->{'Info'}; $c->{'loc'} = $p->{'Location'}; my $uri = $p->{'DeviceURI'}; # Is the beh (Backend Error Handler) wrapper backend in use? # If yes, read out its parameters and isolate the original URI. if ($uri =~ m!^beh:/(\d+)/(\d+)/(\d+)/(\S+)$!) { $c->{'dd'} = $1; $c->{'att'} = $2; $c->{'delay'} = $3; $uri = $4; } else { $c->{'dd'} = 0; $c->{'att'} = 1; $c->{'delay'} = 30; } if (($uri =~ m!^file:$sysdeps->{'ptal-pipes'}/(.+)$!) || ($uri =~ m!^file:/dev/ptal-printd/(.+)$!) || ($uri =~ m!^file:/var/run/ptal-printd/(.+)$!)) { # Translate URI for ptal-printd to ptal URI my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $uri = "ptal:/$devname"; } elsif (($uri =~ m!^file:$sysdeps->{'mtink-pipes'}/(.+)$!) || ($uri =~ m!^file:/var/mtink/(.+)$!)) { # Translate URI for mtinkd to mtink URI $uri = "mtink:/$1"; } $c->{'connect'} = $uri; # CUPS-specific extra info $c->{'quotaperiod'} = $p->{'QuotaPeriod'} if defined($p->{'QuotaPeriod'}); $c->{'pagelimit'} = $p->{'PageLimit'} if defined($p->{'PageLimit'}); $c->{'klimit'} = $p->{'KLimit'} if defined($p->{'KLimit'}); # CUPS 1.2-specific settings $c->{'laststatechange'} = $p->{'StateTime'} if defined($p->{'StateTime'}); $c->{'shared'} = $p->{'Shared'} if defined($p->{'Shared'}); $c->{'operationpolicy'} = $p->{'OpPolicy'} if defined($p->{'OpPolicy'}); $c->{'errorpolicy'} = $p->{'ErrorPolicy'} if defined($p->{'ErrorPolicy'}); $dat->{'queuedata'} = $c; } if (!defined($dat->{'queuedata'})) {$dat = undef}; return $dat; } sub load_pdq_datablob { my ($queue) = $_[0]; # Load the PPD file my $ppdfile = sprintf('%s/pdq/%s.ppd', $sysdeps->{'foo-etc'}, $queue); my $dat = ppdtoperl($ppdfile); if (defined($dat)) { $dat->{'ppdfile'} = $ppdfile; } if (defined($dat)) { my $printrc = load_pdq_printrc(); my $p; my $pdqopts; my $pdqargs; for $p (@{$printrc}) { # Omit non-printer-block items next if (!(defined($p->{'name'}))); # Search the current queue next if ($queue ne $p->{'name'}); $pdqopts = $p->{'driver_opts'}; $pdqargs = $p->{'driver_args'}; } my @printrcdefaults = split(",", $pdqopts); push (@printrcdefaults, split(",", $pdqargs)); my $c; @{$c->{'options'}} = (); for my $option (@printrcdefaults) { if ($option =~ m!^\s*\{?\s*\"(OPT_|)(.+?)\"\s*=\s*\"(.*)\"\s*\}?\s*$!) { push (@{$c->{'options'}}, "$2=$3"); } elsif ($option =~ m!^\s*\{?\s*\"(OPT_|)([^_]+?)_(.+?)\"\s*\}?\s*$!) { push (@{$c->{'options'}}, "$2=$3"); } elsif ($option =~ m!^\s*\{?\s*\"(OPT_|)(.+?)\"\s*\}?\s*$!) { push (@{$c->{'options'}}, "$2"); } } set_default_options($c, $dat); } # Get additional info from printrc my $printrc = load_pdq_printrc(); my $p; for $p (@{$printrc}) { # Omit non-printer-block items next if (!(defined($p->{'name'}))); # Search for the appropriate queue next if ($queue ne $p->{'name'}); my $c = {}; $c->{'spooler'} = 'pdq'; $c->{'queue'} = $p->{'name'}; $c->{'foomatic'} = 0; if (defined($dat->{'id'}) and defined($dat->{'driver'})) { $c->{'foomatic'} = 1; $c->{'printer'} = $dat->{'id'}; $c->{'driver'} = $dat->{'driver'}; } if (defined($p->{'model'})) { my $desc = $p->{'model'}; $desc =~ s!^\"!!; $desc =~ s!\"$!!; if ($desc ne '') {$c->{'desc'} = $desc;} } if (defined($p->{'location'})) { my $loc = $p->{'location'}; $loc =~ s!^\"!!; $loc =~ s!\"$!!; if ($loc ne '') {$c->{'loc'} = $loc;} } if ($p->{'interface'} =~ m!local-port!) { # Local printer $p->{'interface_args'} =~ m!\"?PORT\"?\s*=\s*\"?([^\"\s]+)\"?!; my $file = $1; if (($file =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($file =~ m!^/dev/ptal-printd/(.+)$!) || ($file =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate device for ptal-printd to ptal URI my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $c->{'connect'} = "ptal:/$devname"; } elsif (($file =~ m!^$sysdeps->{'mtink-pipes'}/(.+)$!) || ($file =~ m!^/var/mtink/(.+)$!)) { # Translate device for mtinkd to mtink URI $c->{'connect'} = "mtink:/$1"; } elsif ($file =~ m!usb!i) { $c->{'connect'} = "usb:$file"; } elsif ($file =~ m!(tty|serial)!i) { $c->{'connect'} = "serial:$file"; } elsif ($file =~ m!(lp[0-9]|parallel)!i) { $c->{'connect'} = "parallel:$file"; } else { $c->{'connect'} = "file:$file"; } } elsif ($p->{'interface'} =~ m!bsd-lpd!) { # Remote LPD $p->{'interface_args'} =~ m!\"?REMOTE_HOST\"?\s*=\s*\"?([^\"\s]+)\"?!; my $remhost = $1; $p->{'interface_args'} =~ m!\"?QUEUE\"?\s*=\s*\"?([^\"\s]+)\"?!; my $remqueue = $1; $c->{'connect'} = "lpd://$remhost/$remqueue"; } elsif ($p->{'interface'} =~ m!tcp-port!) { # Socket $p->{'interface_args'} =~ m!\"?REMOTE_HOST\"?\s*=\s*\"?([^\"\s]+)\"?!; my $remhost = $1; $p->{'interface_args'} =~ m!\"?REMOTE_PORT\"?\s*=\s*\"?([^\"\s]+)\"?!; my $remport = $1; $c->{'connect'} = "socket://$remhost:$remport"; } $dat->{'queuedata'} = $c; } if (!defined($dat->{'queuedata'})) {$dat = undef}; return $dat; } sub load_ppr_datablob { my ($queue) = $_[0]; # Load the PPD file my $ppdfile = sprintf('%s/ppr/%s.ppd', $sysdeps->{'foo-etc'}, $queue); my $dat = ppdtoperl($ppdfile); if (defined($dat)) { $dat->{'ppdfile'} = $ppdfile; } # Get additional info from /etc/ppr/* my $pconf = load_ppr_printers_conf(); my $p; for $p (@{$pconf}) { # were we invoked for only one queue? next if ($queue ne $p->{'name'}); # Collect values my $c = {}; $c->{'spooler'} = 'ppr'; $c->{'queue'} = $p->{'name'}; $c->{'foomatic'} = 0; if (defined($dat->{'id'}) and defined($dat->{'driver'})) { $c->{'foomatic'} = 1; $c->{'printer'} = $dat->{'id'}; $c->{'driver'} = $dat->{'driver'}; } $c->{'desc'} = $p->{'Comment'}; $c->{'loc'} = $p->{'Location'}; if (defined($dat)) { my @printerdefaults = split('|', $p->{'Switchset'}); my $o; @{$o->{'options'}} = (); for my $option (@printerdefaults) { if (($option =~ /^F\s*\*([^\*\s=:]+)\s+([^\*\s=:]+)\s*$/) || ($option =~ /^F\s*([^\*\s=:]+)\s*=\s*([^\*\s=:]+)\s*$/)) { push (@{$o->{'options'}}, "$1=$2"); } elsif (($option =~ /^F\s*\*([^\*\s=:]+)\s*$/) || ($option =~ /^F\s*([^\*\s=:]+)\s*$/)) { push (@{$o->{'options'}}, "$1"); } } set_default_options($o, $dat); } my $address = $p->{'Address'}; my $interface = $p->{'Interface'}; my $interface_options = $p->{'Options'}; if (($interface eq "foomatic-rip") || ($interface eq "ppromatic")) { if ($interface_options =~ /backend=(\S+)/) { $interface = $1; $interface_options =~ s/backend=(\S+)//; if ($interface_options =~ /^\s*$/) { $interface_options = ""; } } else { $interface = ""; } } my $uri = ""; if (($interface eq "simple") || ($interface eq "parallel") || ($interface eq "serial") || ($interface eq "dummy")) { # local printer if (($address =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($address =~ m!^/dev/ptal-printd/(.+)$!) || ($address =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate device for ptal-printd to ptal URI my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $uri = "ptal:/$devname"; } elsif (($address =~ m!^$sysdeps->{'mtink-pipes'}/(.+)$!) || ($address =~ m!^/var/mtink/(.+)$!)) { # Translate device for mtinkd to mtink URI $uri = "mtink:/$1"; } elsif ($address =~ m!^\w+:!i) { $c->{'connect'} = $address; } else { $uri = "file:$address"; } } elsif ($interface eq "lpr") { # Remote LPD if ($address =~ /^([^\@]+)\@([^\@]+)$/) { my $remhost = $2; my $remqueue = $1; $uri = "lpd://$remhost/$remqueue"; } else { die "Remote LPD configuration of the queue $p->{'name'} " . "broken!\n"; } } elsif ($interface eq "tcpip") { # Socket (AppSocket/HP JetDirect) $uri = "socket://$address"; } elsif ($interface eq "smb") { # SMB (Printer on Windows server) if ($address =~ m!^//([^/]+)/([^/]+)$!) { my $smbserver = $1; my $smbshare = $2; my $smbuser = ""; if ($interface_options =~ /smbuser=(\S+)/) { $smbuser = $1; } else { # The PPR interface for SMB uses the user name "ppr" # when no user name is given. $smbuser = "ppr"; } my $smbpassword = ""; if ($interface_options =~ /smbpassword=(\S+)/) { $smbpassword = $1; } if (($smbpassword ne "") && ($smbuser eq "")) { $smbuser = "GUEST"; } $uri = "$smbserver/$smbshare"; if ($smbuser ne "") { if ($smbpassword ne "") { $smbuser .= ":$smbpassword"; } $uri = "$smbuser\@$uri"; } $uri = "smb://$uri"; } else { die "SMB configuration of the queue $p->{'name'} broken!\n"; } } else { # Interface not supported by Foomatic $uri = "$interface:$address"; } $c->{'connect'} = $uri; $dat->{'queuedata'} = $c; } if (!defined($dat->{'queuedata'})) {$dat = undef}; return $dat; } sub load_direct_datablob { my ($queue) = $_[0]; # Load the PPD file my $ppdfile = sprintf('%s/direct/%s.ppd', $sysdeps->{'foo-etc'}, $queue); my $dat = ppdtoperl($ppdfile); if (defined($dat)) { $dat->{'ppdfile'} = $ppdfile; } my $postpipe = (defined($dat) ? $dat->{'postpipe'} : ""); # Get additional info from /etc/foomatic/direct/.config my $config = load_direct_config(); my $p; for $p (@{$config}) { # invalid entry next if !defined($p->{'name'}); # Search for the correct queue next if ($queue ne $p->{'name'}); # Collect values my $c = {}; my $name = $c->{'queue'} = $p->{'name'}; $c->{'desc'} = $p->{'desc'}; $c->{'loc'} = $p->{'loc'}; $c->{'foomatic'} = 0; if (defined($dat->{'id'}) and defined($dat->{'driver'})) { $c->{'foomatic'} = 1; $c->{'printer'} = $dat->{'id'}; $c->{'driver'} = $dat->{'driver'}; } $c->{'spooler'} = 'direct'; if (defined($postpipe)) { if ($postpipe =~ m!^\s*\|\s*($sysdeps->{'cat'}|cat)\s+-?\s*>\s*([^\s]+)\s*$!) { my $file = $2; if (($file =~ m!^$sysdeps->{'ptal-pipes'}/(.+)$!) || ($file =~ m!^/dev/ptal-printd/(.+)$!) || ($file =~ m!^/var/run/ptal-printd/(.+)$!)) { # Translate device for ptal-printd to ptal URI my $devname = $1; $devname =~ s/_/:/; $devname =~ s/_/:/; $c->{'connect'} = "ptal:/$devname"; } elsif (($file =~ m!^$sysdeps->{'mtink-pipes'}/(.+)$!) || ($file =~ m!^/var/mtink/(.+)$!)) { # Translate device for mtinkd to mtink URI $c->{'connect'} = "mtink:/$1"; } elsif ($file =~ m!usb!i) { $c->{'connect'} = "usb:$file"; } elsif ($file =~ m!(tty|serial)!i) { $c->{'connect'} = "serial:$file"; } elsif ($file =~ m!(lp[0-9]|parallel)!i) { $c->{'connect'} = "parallel:$file"; } else { $c->{'connect'} = "file:$file"; } } elsif ($postpipe =~ m!^\s*\|\s*($sysdeps->{'ptal-connect'}|ptal-connect|ptal-print)\s+(-print\s+|)([^\s]+)(\s+-print|)\s*$!){ $c->{'connect'} = "ptal:/$3"; } elsif ($postpipe =~ m!^\s*\|\s*($sysdeps->{'nc'}|netcat|nc)\s+(-w\s*1\s+|)([^\s]+)\s+([^\s]+)\s*$!){ $c->{'connect'} = "socket://$3:$4"; } elsif ($postpipe =~ m!^\s*\|\s*$sysdeps->{'rlpr'}\s.*-P\s*([^\s\\\@]+)\@([^\s\\\@]+)\s*$!) { $c->{'connect'} = "lpd://$2/$1"; } elsif ($postpipe =~ m!^.*\|\s*$sysdeps->{'smbclient'}\s+\"//([^/\s]+)/([^/\s]+)\"\s+(\S.*)$!s) { my $servershare = "$1/$2"; my $parameters = $3; my $password = ""; if ($parameters =~ m!^([^-]\S*)\s+(\S.*)$!) { $password = $1; $parameters = $2; } my $username = ""; if ($parameters =~ m!^-U\s+(\S*)\s+(\S.*)$!) { $username = $1; $parameters = $2; } my $workgroup = ""; if ($parameters =~ m!^-W\s+(\S*)\s+(\S.*)$!) { $workgroup = "$1/"; } my $identity = ""; if (($username eq "GUEST") && ($password eq "")) { $identity = ""; } elsif (($username eq "") && ($password eq "")) { $identity = ""; } elsif (($username ne "") && ($password eq "")) { $identity = "$username\@"; } elsif (($username eq "") && ($password ne "")) { $identity = ":$password\@"; } else { $identity = "$username:$password\@"; } $c->{'connect'} = "smb://$identity$workgroup$servershare"; } elsif ($postpipe =~ m!^\s*\|\s*$sysdeps->{'nprint'}\s+(\S.*)$!s) { my $parameters = $1; my $server = ""; if ($parameters =~ m!^-S\s+(\S*)\s+(\S.*)$!) { $server = $1; $parameters = $2; } my $username = ""; if ($parameters =~ m!^-U\s+(\S*)\s+(\S.*)$!) { $username = $1; $parameters = $2; } my $password = ""; if ($parameters =~ m!^-P\s+(\S*)\s+(\S.*)$!) { $password = $1; $parameters = $2; } if ($parameters =~ m!^-n\s+(\S.*)$!) { $parameters = $1; } my $queue = ""; if ($parameters =~ m!^-q\s+(\S*)\s+(\S.*)$!) { $queue = $1; } my $identity = ""; if (($username eq "") && ($password eq "")) { $identity = ""; } elsif (($username ne "") && ($password eq "")) { $identity = "$username\@"; } elsif (($username eq "") && ($password ne "")) { $identity = ":$password\@"; } else { $identity = "$username:$password\@"; } $c->{'connect'} = "ncp://$identity$server/$queue"; } else { $postpipe =~ m!\s*\|\s*(\S.*)$!; $c->{'connect'} = "postpipe:\"$1\""; } } else { $c->{'connect'} = "stdout"; } $dat->{'queuedata'} = $c; } if (!defined($dat->{'queuedata'})) {$dat = undef}; return $dat; } sub overtake_defaults { # overtake the option default settings from $olddatablob my ($olddatablob) = $_[0]; my $c; @{$c->{'options'}} = (); for my $opt (@{$olddatablob->{'args'}}) { push (@{$c->{'options'}}, "$opt->{'name'}=$opt->{'default'}"); } set_default_options($c, $db->{'dat'}); } sub set_default_options { # Set the default printing options by doing changes on the Perl # structure produced by "getdat", before the spooler-specific # datafile is generated my ($config) = $_[0]; my ($dest) = $_[1]; if ($#{$config->{'options'}} >= 0) { for (@{$config->{'options'}}) { my $option = $_; if ($option =~ m!^\s*([^=]+)=([^=]*)\s*$!) { # evaluated or numerical option, boolean option with # value "True", "False", "Yes", "No", "On", "Off", "1", "0" # given my $optname = $1; my $optvalue = $2; if (defined($dest->{'args_byname'}{$optname})) { if ($dest->{'args_byname'}{$optname}{'type'} eq 'bool') { if ((lc($optvalue) eq 'true') || (lc($optvalue) eq 'on') || (lc($optvalue) eq 'yes')) { $optvalue = '1'; } elsif ((lc($optvalue) eq 'false') || (lc($optvalue) eq 'off') || (lc($optvalue) eq 'no')) { $optvalue = '0'; } if (($optvalue eq '1') || ($optvalue eq '0')) { $dest->{'args_byname'}{$optname}{'default'} = $optvalue; } } elsif (($dest->{'args_byname'}{$optname}{'type'} eq 'int') || ($dest->{'args_byname'}{$optname}{'type'} eq 'float')) { if (($optvalue =~ m!^\s*[\+\-]?\s*[0-9]*\.?[0-9]*\s*$!) && ($optvalue >= $dest->{'args_byname'}{$optname}{'min'}) && ($optvalue <= $dest->{'args_byname'}{$optname}{'max'})) { $dest->{'args_byname'}{$optname}{'default'} = $optvalue; } } elsif (($dest->{'args_byname'}{$optname}{'type'} eq 'string') || ($dest->{'args_byname'}{$optname}{'type'} eq 'password')) { $optvalue = Foomatic::DB::checkoptionvalue ($dest, $optname, $optvalue, 0); $dest->{'args_byname'}{$optname}{'default'} = $optvalue if defined($optvalue); } else { if (defined($dest->{'args_byname'}{$optname}{'vals_byname'}{$optvalue})) { $dest->{'args_byname'}{$optname}{'default'} = $optvalue; } } } } else { if (($option =~ /^no(.+?)$/) && (defined($dest->{'args_byname'}{$1})) && ($dest->{'args_byname'}{$1}{'type'} eq 'bool')) { $dest->{'args_byname'}{$1}{'default'} = '0'; } elsif ((defined($dest->{'args_byname'}{$option})) && ($dest->{'args_byname'}{$option}{'type'} eq 'bool')) { $dest->{'args_byname'}{$option}{'default'} = '1'; } } } } } sub print_perl_combo_data { my ($config, $olddatablob) = @_; # Get the data if ($config->{'ppdfile'}) { # From PPD file my $dat = ppdtoperl($config->{'ppdfile'}); if (!defined($dat)) { die ("Unable to open PPD file \'$config->{'ppdfile'}\'\n"); } $db->{'dat'} = $dat; } else { # From Foomatic XML database my $possible = $db->getdat($config->{'driver'}, $config->{'printer'}); die "That printer and driver combination is not possible.\n" if (!$possible); die "There is neither a custom PPD file nor the driver database entry contains sufficient data to build a PPD file.\n" if (!$db->{'dat'}{'cmd'}) && (!$db->{'dat'}{'ppdfile'}); # Generate the PPD and extract it to Perl again (to get in the # composite options) my $ppd = $db->getppd($config->{'shortgui'}); delete ($db->{'dat'}); $db->{'dat'} = ppdfromvartoperl([split(/\n/, $ppd)]); } # The data can be viewed with the option defaults of an existing # queue set if ($olddatablob) { my $c; @{$c->{'options'}} = (); for my $opt (@{$olddatablob->{'args'}}) { push (@{$c->{'options'}}, "$opt->{'name'}=$opt->{'default'}"); } set_default_options($c, $db->{'dat'}); } # User can view the data of the combo also with options given on the # command line set_default_options($config, $db->{'dat'}); # Put it out my $asciidata = $db->getascii(); $asciidata =~ s/\$VAR1/\$COMBODATA/g; print $asciidata; return; } sub detect_spooler { # If tcp/localhost:631 opens, cups CUPS is the most sophisticated # spooler, if it is running, it is usually the primary printing # system my $page = ($db->getpage('http://localhost:631/', 1) || ""); if ($page =~ m!Common UNIX Printing System!) { return 'cups'; } # PPR is also very sophisticated so check for this spooler if there is # no CUPS running. if (-x $sysdeps->{'ppr-ppr'}) { # There's a /usr/bin/ppr return 'ppr'; } # Else if /etc/printcap, some sort of lpd thing if (-f $sysdeps->{'lpd-pcap'}) { # If -f /etc/lpd.conf, lprng if (-f $sysdeps->{'lprng-conf'}) { return 'lprng'; } elsif (-x $sysdeps->{'lpd-bin'}) { # There's a /usr/sbin/lpd return 'lpd'; } } # pdq executable in our path somewhere? for (split(':', $ENV{'PATH'})) { if (-x "$_/pdq") { return 'pdq'; } } # If there is no known spooler, set up printers for direct, spooler-less # printing. return "direct"; } sub unimp { die "Sorry, $action for your spooler is unimplemented...\n"; } sub overview { print $db->get_overview_xml($opt_f); exit(0); } sub get_xml { my $x = undef; if (($opt_p) and ($opt_d)) { $x = $db->get_combo_data_xml($opt_d,$opt_p); } elsif ($opt_p) { $x = $db->get_printer_xml($opt_p); } elsif ($opt_d) { $x = $db->get_driver_xml($opt_d); } else { die "You must specify a -p printer and/or -d driver.\n"; } if (defined($x)) { print $x; } else { die "Unable to find object.\n"; } exit(0); } sub help { print STDERR <<EOH; Usage: $progname [ -s spooler ] -n queuename \\ [ -N 'Name/Descr.' ] [ -L 'Location Info' ] \\ [ -c connect ] \\ [ -d driver ] [ -p printer ] [ -f ] [ -w ] \\ [ --ppd ppdfile ] \\ [ -o option1=value1 -o option2 ... ] \\ [ --backend-dont-disable=value ] \\ [ --backend-attempts=value ] \\ [ --backend-delay=value ] \\ [ -q ] or $progname -C [ -s spooler ] -n queuename \\ [ sourcespooler ] sourcequeue \\ [ -N 'Name/Descr.' ] [ -L 'Location Info' ] \\ [ -c connect ] \\ [ -d driver ] [ -p printer ] [ -f ] [ -w ] \\ [ --ppd ppdfile ] \\ [ -o option1=value1 -o option2 ... ] \\ [ --backend-dont-disable=value ] \\ [ --backend-attempts=value ] \\ [ --backend-delay=value ] \\ [ -q ] or $progname -D [ -s spooler ] -n queuename [ -q ] or $progname -R [ -s spooler ] -n queuename [ -q ] or $progname -Q [ -s spooler ] [ -n queuename ] [ -q ] [ -r ] or $progname -P [ -s spooler ] [ -n queuename ] [ -q ] [ N ] or $progname -P [ -s spooler ] [ -n queuename ] \\ [ --ppd ppdfile ] [ -d driver -p printer ] \\ [ -o option1=value1 -o option2 ... ] [ -q ] or $progname -O or $progname -X [ -p printer ] [ -d driver ] -n queuename Configure/create/delete/query this print queue -N Name/Descr. Long name/Short Description. An empty string ("") deletes the description. -L Location Short phrase describing this printer's location. An empty string ("") deletes the location. -c connection Printer is connected thusly (ex file:/dev/lp0), must be given when a new queue is created --ppd ppdfile Set up the queue using the PPD file ppdfile (can be a manufacturer-supplied PPD file for a PostScript printer). gzip-compressed PPD files are allowed, they must have the extension ".gz". -d driver Foomatic database name for desired printer driver or "raw" for a raw queue. When a non-raw queue is created, the printer must be specified in addition ("-p" option) -p printer Foomatic id for printer. When a non-raw queue is created, the driver must be specified in addition ("-d" option) -s spooler Explicit spooler type (cups, lpd, lprng, pdq, ppr, direct) -o option=value Use value as the default for option in this queue -o option Set the switch option by default in this queue --backend-dont-disable=value 1: Do not disable CUPS queue when backend fails, 0: Original CUPS behaviour, queue gets disabled when backend fails. Default: 0 (CUPS only) --backend-attempts=value Try that often when backend fails, for infinite retries set the value to zero, for standard CUPS behaviour to 1. Default: 1 (CUPS only) --backend-delay=value Delay in seconds between retries of failed backend. Default: 30 (CUPS only) -C [sourcespooler] sourcequeue Create a copy of a queue. All characteristics including default option settings are overtaken. Additional arguments modify the copy. This facility allows to overtake one's configured queues when one changes the spooler. -D Set this queue as the queue used by default. -R Remove this whole queue entirely (just give -n queuename) -Q Query existing configuration (gives XML summary). Supplying no queue name gives info about all installed queues for the current/selected spooler, including the default queue. -r list also remote queues (CUPS only). -P Query existing configuration (gives Perl data structure of the complete information about the queue, including options, possible choices, default settings, ..., for use by frontends, the output is done as a Perl array, one element per queue), With printer ID and driver name instead of queue name supplied the Perl data structure of the appropriate printer/driver combo is generated, supplied options are entered as default settings then, from a supplied queue the option default settings are used. Supplying no queue, printer, and driver gives info about all installed queues for the current/selected spooler. N The first index of the Perl array, default: 0 -O Print XML Overview of all known printer/drivers -X Print XML data for -p printer and/or -d driver object -f Force rebuild of PPD file from database -w Generate PPD which is compatible to the CUPS PostScript driver for Windows (GUI strings are limited to 39 characters). This applies only to PPDs built from the Foomatic database, it has no influence on PPDs supplied with the "--ppd" option. -q Run quietly and non-interactive -h --help Show this help message EOH #'# Fix emacs syntax highlighting exit 0; }
Close