-
Notifications
You must be signed in to change notification settings - Fork 4
/
socprint.sh
executable file
·326 lines (273 loc) · 10.1 KB
/
socprint.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
#!/bin/sh
# ======================================================================
#
# MIT LICENSE
#
# Copyright (c) 2021-present Donald Lee and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# ======================================================================
set -euf
export LC_ALL=C
host='stu.comp.nus.edu.sg'
default_script='/usr/local/bin/socprint.sh'
usage() {
cat <<EOF
NAME
socprint.sh - POSIX™-compliant, zero-dependency shell script to print in NUS SoC
SYPNOSIS
socprint.sh (p|print) [options] <username> <printqueue> [-|<filepath>]
socprint.sh (j|jobs ) [options] <username> <printqueue>
socprint.sh (l|list ) [options] <username>
socprint.sh (h|help )
QUICKSTART
To print a file instantly, copy and paste the following line into your shell:
curl -s https://raw.githubusercontent.com/dlqs/SOCprint/master/socprint.sh | sh -s -- print <username> <printqueue> <filepath>
Alternatively, use the hosted version at https://socprint.xyz
DESCRIPTION
This script requires a POSIX™-compliant sh, a NUS SoC account, and connection to
SoC wifi.
Besides the above, this script has zero-dependencies, is portable, and handles text/byte streams. This makes printing
in SoC a painless, non-ass-sucking experience that doesn't require installing any drivers.
COMMANDS (shortname|longname)
(p|print) Print a file at specified printqueue.
(j|jobs ) List jobs at specified printqueue.
(l|list ) List all printqueues.
(h|help ) Show this message.
OPTIONS
<username>
NUS SoC account username.
<printqueue>
Printer + suffix. See PRINTQUEUES for commonly-used printers.
[-|<filepath>]
Print file. Recommended PDF/text. Undefined behaviour for other file types.
If unspecified or -, read from standard input.
-i, --identity-file <filepath>
(optional) Additional identity file to use with ssh. Skip if you already set
up identity files for ssh.
-2
(optional) Prints every two logical pages onto one physical page.
Can only be used for pdf files that have portrait orientation.
--dry-run
(for debugging/tests) Echoes commands to be executed without executing them.
EXAMPLES
To print from filepath:
./socprint.sh print d-lee psc008-dx ~/d/cs3210_tutorial8.pdf
To combine with curl and the pipe operator:
curl -s https://www.comp.nus.edu.sg/~ooibc/bxtree.pdf | ./socprint.sh print d-lee psc008-dx
To print with shortname, using the redirection operator:
./socprint.sh p d-lee psc008-dx < ~/d/cs3210_tutorial8.pdf
To check jobs:
./socprint.sh jobs d-lee psc008-dx
To list printqueues:
./socprint.sh list d-lee
To download and run from any directory:
sudo curl https://raw.githubusercontent.com/dlqs/SOCprint/master/socprint.sh -o $default_script
sudo chmod 755 $default_script
PRINTQUEUES
Popular places:
- COM1 basement: psc008-dx psc008-sx psc011-dx psc011-sx
- COM1 L1, in front of tech svsc: psts-dx psts-sx pstb-dx pstb-sx pstc-dx pstc-sx
- -dx: double sided, -sx: single sided, -nb: no banner
- Most other printers have user restrictions.
See https://dochub.comp.nus.edu.sg/cf/guides/printing/print-queues.
- For the full list of printqueues, generate with the -l option, or view the SOURCE.
IMPLEMENTATION
Roughly speaking, the print command will:
1. Login to stu.comp.nus.edu.sg using ssh.
You will be prompted for your password, unless your identity files are set up.
This script *does not* save/record your password.
2. Copy the file into your home directory in stu, to a temporary file.
3. Submit your job to the printqueue.
4. List the printqueue. You job *should* appear. If not, something has gone wrong.
5. Remove the temporary file.
STANDARDS
This script targets conformance to POSIX.1-2017 standards (https://pubs.opengroup.org/onlinepubs/9699919799/).
Yes, you read that right and no, we're not kidding. POSIX™ compliance is serious enterprise business!!!1
POSIX™ is a Trademark of The IEEE.
SOURCE
https://github.com/dlqs/SOCprint
File bugs or POSIX™ compliance issues above.
CONTRIBUTORS
Donald Lee, Julius Nugroho, Sean Ng
KEYWORDS
how to print NUS SoC National University of Singapore School of Computing
printers shell command line basement mac windows linux bsd ben
LICENSE
This project is licensed under terms of the MIT License. Full text in source code.
GENERATE README
./socprint.sh help > README \
&& echo "List of valid printqueues, generated with list command on 5 March 2021\n" >> README \
&& ./socprint.sh list d-lee >> README
EOF
exit 0
}
msg() {
# Log messages to stderr instead of stdout
printf "%b\n" "${1-}" >&2
}
die() {
msg "$1"
exit 1
}
star_banner() {
printf "If you liked our script, help us out with a star! https://github.com/dlqs/SOCprint" | awk '
BEGIN {
srand();
s=int(rand()*10);
} {
c=128;
w=127;
f=0.1;
for (i=1; i<=length($0); i+=1) {
v=s+f*(i+2*NR);
r=sin(v)*w+c;
g=sin(v+2.094)*w+c;
b=sin(v+4.188)*w+c;
printf "\x1b[38;2;%d;%d;%dm%s", r, g, b, substr($0, i, 1);
}
printf "\x1b[0m\n";
}
'
}
check_updates() {
# Calculate git hash-object hash without git, since it is not POSIX compliant
size=$( wc -c ${default_script} | cut -f 1 -d ' ' )
my_sha=$( (printf "blob %s\0" "$size" && cat ${default_script}) | shasum -a 1 | cut -f 1 -d ' ')
# Pull latest hash from master
github_sha=$( curl -m 1 -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/dlqs/SOCprint/contents/socprint.sh | sed -n 's/.*"sha":\s"\(.*\)",/\1/p' )
if [ "$my_sha" != "$github_sha" ]; then
msg "Hint: You appear to have downloaded this script to $default_script. There's a newer version available ($( printf '%s' "$my_sha" | head -c 10) v $( printf '%s' "$github_sha" | head -c 10 ))."
msg "Run the following command to download the new script:"
msg "sudo curl https://raw.githubusercontent.com/dlqs/SOCprint/master/socprint.sh -o $default_script"
fi
}
command="${1-}"
shift
identity_file=''
options=''
while :; do
case "${1-}" in
-i | --identity-file)
identity_file="${2-}"
shift
;;
-2)
two_pages_to_one=true
shift
;;
--dry-run)
dry_run=true
shift
;;
-?*) die "Unknown option: $1" ;;
*) break ;;
esac
#shift
done
if [ -n "${dry_run-}" ]; then
eval_or_echo_in_dry_run='printf %b\n'
else
eval_or_echo_in_dry_run='eval'
fi
if [ "${command}" = 'h' ] || [ "${command}" = 'help' ]; then
usage
exit 0
fi
check_username() {
[ -z "${1-}" ] && die "Missing required argument: <username>"
username="${1-}"
sshcmd="${username-}@${host}"
# Use the ssh identity_file if provided
[ -n "${identity_file}" ] && sshcmd="${sshcmd} -i ${identity_file}"
return 0
}
check_printqueue() {
[ -z "${2-}" ] && die "Missing required argument: <printqueue>"
printqueue="${2-}"
[ "$(printf "%s" "$printqueue" | head -c1)" != 'p' ] && die "Error: <printqueue> should start with 'p', e.g. psc008-dx. See PRINTQUEUES in help."
return 0
}
case "${command-}" in
p | print)
check_username "$@"
check_printqueue "$@"
filepath="${3-}"
if [ -z "${filepath-}" ] || [ "${filepath-}" = '-' ]; then
filepath='/dev/stdin'
else
[ ! -f "${filepath-}" ] && die "Error: No such file"
# Warn if filetype is unexpected
file "${filepath}" | cut -f 2 -d ':' | grep -Eqv '(PDF|text)' && msg "Warning: File is not PDF or text. Print behaviour is undefined."
fi
# Generate random 8 character alphanumeric string in a POSIX compliant way
tempname=$( awk 'BEGIN{srand();for(i=0;i<8;i++){r=int(61*rand());printf("%c",r<10?48+r:r<35?55+r:62+r)}}' )
tempname="SOCPrint_${tempname}"
if [ -n "${two_pages_to_one-}" ]; then
tempname2="${tempname}2"
tempname3="${tempname}3"
options="pdf2ps ${tempname} ${tempname2}; multips ${tempname2} > ${tempname3}; mv -f ${tempname3} ${tempname}; rm ${tempname2};"
else
options=""
fi
cmd=$( cat <<EOF
ssh $sshcmd "
cat - > ${tempname};
$options
lpr -P ${printqueue} ${tempname};
lpq -P ${printqueue};
rm ${tempname};" < "${filepath}";
star_banner
EOF
)
;;
j | jobs)
check_username "$@"
check_printqueue "$@"
cmd=$( cat <<EOF
ssh $sshcmd "lpq -P ${printqueue};"
EOF
)
;;
l | list)
check_username "$@"
cmd=$( cat <<EOF
ssh $sshcmd "cat /etc/printcap | grep '^p' | sed 's/^\([^:]*\).*$/\1/'"
EOF
)
;;
q | quota)
check_username "$@"
# -t is needed because pusage works with interactive ssh and not without.
# Using -t emulates an interaction session. 'man ssh' for details
cmd=$( cat <<EOF
ssh $sshcmd -t "/usr/local/bin/pusage"
EOF
)
;;
esac
[ -z "${cmd-}" ] && die "Error: unknown command: ${command-}"
msg "Using ${username-}@${host} ..."
$eval_or_echo_in_dry_run "$cmd"
# Only check update if downloaded to local bin and we're not dry-running, as
# this could potentially mess tests up.
[ -f "/usr/local/bin/socprint.sh" ] && [ -z "${dry_run-}" ] && check_updates
exit 0