]> git.saurik.com Git - apple/configd.git/blob - get-network-info
configd-963.200.27.tar.gz
[apple/configd.git] / get-network-info
1 #!/bin/sh
2
3 #
4 # Copyright © 2015-2017 Apple Inc.
5 #
6 # get-network-info
7 #
8 # Collect network information.
9 #
10
11 PATH=/bin:/usr/bin:/sbin:/usr/sbin
12
13 # __SETUP_ROUTINES_BEGIN__
14
15 process_opts () {
16
17 for i in $ARGS
18 do
19 case "$i" in
20 -c)
21 COLLECT_CONFIGURATION_FILES="Y"
22 shift
23 ;;
24 -n)
25 COLLECT_NDF_INFO="Y"
26 shift
27 ;;
28 -P)
29 COLLECT_PCAP="N"
30 shift
31 ;;
32 -s)
33 COLLECT_SENSITIVE_INFO="Y"
34 shift
35 ;;
36 --)
37 shift
38 ;;
39 *)
40 REQUESTED_OUTDIR="${i}"
41 shift
42 ;;
43 esac
44 done
45
46 }
47
48 set_root () {
49
50 PRIV=""
51 if [ ${EUID} -ne 0 ]; then
52 PRIV="sudo"
53 fi
54
55 }
56
57 #
58 # Setup
59 #
60 setup () {
61
62 set_root
63 umask 077
64 cd "${REQUESTED_OUTDIR}"
65
66 }
67
68 # __SETUP_ROUTINES_END__
69
70
71 # __COMMAND_ROUTINES_BEGIN__
72
73 # note: the daemons dump to syslog so you need to wait a bit before
74 # capturing the logs.
75 collect_state_dump_sensitive () {
76
77 ${PRIV} /usr/bin/killall -INFO mDNSResponder 2>/dev/null
78
79 sleep 1 &
80
81 }
82
83 #
84 # network interface configuration
85 #
86 run_ifconfig () {
87
88 if [ ! -x /sbin/ifconfig ]; then
89 return
90 fi
91
92 /sbin/ifconfig -a -L -b -m -r -v -v > ifconfig.txt 2>&1
93 if [ $? -ne 0 ]; then
94 /sbin/ifconfig -a > ifconfig.txt 2>&1
95 fi
96
97 }
98
99 #
100 # network route configuration and statistics
101 #
102 run_netstat () {
103
104 if [ ! -x /usr/sbin/netstat ]; then
105 return
106 fi
107
108 echo "#" > netstat.txt
109 echo "# netstat -n -r -a -l" >> netstat.txt
110 echo "#" >> netstat.txt
111 /usr/sbin/netstat -n -r -a -l >> netstat.txt 2>&1
112
113 echo "#" >> netstat.txt
114 echo "# netstat -A -a -l -n -v" >> netstat.txt
115 echo "#" >> netstat.txt
116 /usr/sbin/netstat -A -a -l -n -v >> netstat.txt 2>&1
117
118 echo "#" >> netstat.txt
119 echo "# netstat -s" >> netstat.txt
120 echo "#" >> netstat.txt
121 /usr/sbin/netstat -s >> netstat.txt 2>&1
122
123 echo "#" >> netstat.txt
124 echo "# netstat -rs" >> netstat.txt
125 echo "#" >> netstat.txt
126 /usr/sbin/netstat -rs >> netstat.txt 2>&1
127
128 echo "#" >> netstat.txt
129 echo "# netstat -mmm" >> netstat.txt
130 echo "#" >> netstat.txt
131 /usr/sbin/netstat -mmm >> netstat.txt 2>&1
132
133 echo "#" >> netstat.txt
134 echo "# netstat -i -n -d" >> netstat.txt
135 echo "#" >> netstat.txt
136 /usr/sbin/netstat -i -n -d >> netstat.txt 2>&1
137
138 echo "#" >> netstat.txt
139 echo "# netstat -i -x R" >> netstat.txt
140 echo "#" >> netstat.txt
141 /usr/sbin/netstat -i -x R >> netstat.txt 2>&1
142
143 echo "#" >> netstat.txt
144 echo "# netstat -a -n -p mptcp" >> netstat.txt
145 echo "#" >> netstat.txt
146 /usr/sbin/netstat -anp mptcp >> netstat.txt 2>&1
147
148 echo "#" >> netstat.txt
149 echo "# netstat -s -p mptcp" >> netstat.txt
150 echo "#" >> netstat.txt
151 /usr/sbin/netstat -s -p mptcp >> netstat.txt 2>&1
152
153 echo "#" >> netstat.txt
154 echo "# netstat -g -n -s" >> netstat.txt
155 echo "#" >> netstat.txt
156 /usr/sbin/netstat -g -n -s >> netstat.txt 2>&1
157
158 if [ -x /sbin/ifconfig ]; then
159 for if in ${IF_LIST}
160 do
161 IF_INFO=`/sbin/ifconfig -v ${if}`
162 `echo $IF_INFO | grep -q TXSTART`
163 if [ $? -eq 0 ]; then
164 echo "#" >> netstat.txt
165 echo "# netstat -qq -I ${if}" >> netstat.txt
166 echo "#" >> netstat.txt
167 /usr/sbin/netstat -qq -I ${if} >> netstat.txt 2>&1
168 fi
169 `echo $IF_INFO | grep -q RXPOLL`
170 if [ $? -eq 0 ]; then
171 echo "#" >> netstat.txt
172 echo "# netstat -Q -I ${if}" >> netstat.txt
173 echo "#" >> netstat.txt
174 /usr/sbin/netstat -Q -I ${if} >> netstat.txt 2>&1
175 fi
176 done
177 fi
178
179 }
180
181 #
182 # ndp
183 #
184 run_ndp () {
185
186 if [ ! -x /usr/sbin/ndp ]; then
187 return
188 fi
189
190 echo "#" > ndp-info.txt
191 echo "# ndp -n -a" >> ndp-info.txt
192 echo "#" >> ndp-info.txt
193 /usr/sbin/ndp -n -a >> ndp-info.txt 2>&1
194
195 echo "#" >> ndp-info.txt
196 echo "# ndp -n -p" >> ndp-info.txt
197 echo "#" >> ndp-info.txt
198 /usr/sbin/ndp -n -p >> ndp-info.txt 2>&1
199
200 echo "#" >> ndp-info.txt
201 echo "# ndp -n -r" >> ndp-info.txt
202 echo "#" >> ndp-info.txt
203 /usr/sbin/ndp -n -r >> ndp-info.txt 2>&1
204
205 if [ -x /sbin/ifconfig ]; then
206 for if in ${IF_LIST}
207 do
208 echo "#" >> ndp-info.txt
209 echo "# ndp -i ${if}" >> ndp-info.txt
210 echo "#" >> ndp-info.txt
211 /usr/sbin/ndp -i ${if} >> ndp-info.txt 2>&1
212 done
213 fi
214
215 }
216
217 #
218 # arp
219 #
220 run_arp () {
221
222 if [ ! -x /usr/sbin/arp ]; then
223 return
224 fi
225
226 echo "#" > arp-info.txt
227 echo "# arp -n -a" >> arp-info.txt
228 echo "#" >> arp-info.txt
229 /usr/sbin/arp -n -a >> arp-info.txt 2>&1
230
231 }
232
233 #
234 # DHCP configuration
235 #
236 run_ipconfig () {
237
238 if [ ! -x /usr/sbin/ipconfig ]; then
239 return
240 fi
241
242 for if in ${IF_LIST}
243 do
244 case ${if} in
245 lo* )
246 ;;
247 *)
248 echo "#" >> ipconfig-info.txt
249 echo "# INTERFACE ${if}" >> ipconfig-info.txt
250 echo "#" >> ipconfig-info.txt
251
252 echo "DHCPv4 information:" >> ipconfig-info.txt
253
254 IPCONFIG_INFO=`/usr/sbin/ipconfig getpacket ${if}`
255 if [ "${IPCONFIG_INFO}" != "" ]; then
256 echo "${IPCONFIG_INFO}" >> ipconfig-info.txt
257 else
258 echo "not available" >> ipconfig-info.txt
259 fi
260
261 echo"" >> ipconfig-info.txt
262
263 echo "DHCPv6 information:" >> ipconfig-info.txt
264
265 IPCONFIG_INFO=`/usr/sbin/ipconfig getv6packet ${if}`
266 if [ "${IPCONFIG_INFO}" != "" ]; then
267 echo "${IPCONFIG_INFO}" >> ipconfig-info.txt
268 else
269 echo "not available" >> ipconfig-info.txt
270 fi
271
272 echo"" >> ipconfig-info.txt
273 ;;
274 esac
275 done
276
277 }
278
279 #
280 # IPsec configuration
281 #
282 run_setkey () {
283
284 if [ ! -x /usr/sbin/setkey -o ! -x /usr/bin/perl ]; then
285 return
286 fi
287
288 echo "#" > ipsec.txt
289 echo "# setkey -D" >> ipsec.txt
290 echo "#" >> ipsec.txt
291 ${PRIV} /usr/sbin/setkey -D \
292 | /usr/bin/perl -l -n -e '
293 if (/^(\s+[AE]:\s+\S+\s+)"?(.*)"?\s*$/) {
294 printf "%s[redacted]%s\n", $1, $3;
295 } else {
296 printf "%s\n", $_;
297 }
298 ' >> ipsec.txt
299
300 echo "" >> ipsec.txt
301 echo "#" >> ipsec.txt
302 echo "# setkey -Pp -D" >> ipsec.txt
303 echo "#" >> ipsec.txt
304 ${PRIV} /usr/sbin/setkey -Pp -D >> ipsec.txt
305
306 for CF in /var/run/racoon/*.conf
307 do
308 if [ ! -r "${CF}" ]; then
309 continue
310 fi
311
312 echo "" >> ipsec.txt
313 echo "#" >> ipsec.txt
314 echo "# ${CF}" >> ipsec.txt
315 echo "#" >> ipsec.txt
316 ${PRIV} cat ${CF} \
317 | /usr/bin/perl -l -n -e '
318 if (/^(\s+shared_secret\s+use\s+)"?([^\s;"]+)"?(.*)/) {
319 printf "%s[redacted]%s\n", $1, $3;
320 } else {
321 printf "%s\n", $_;
322 }
323 ' >> ipsec.txt
324 done
325
326 }
327
328 #
329 # skywalk configuration and statistics
330 #
331 run_skywalk () {
332
333 if [ ! -x /usr/sbin/skywalkctl ]; then
334 return
335 fi
336
337 echo "#" > skywalk.txt
338 echo "# skywalkctl show" >> skywalk.txt
339 echo "#" >> skywalk.txt
340 /usr/sbin/skywalkctl show >> skywalk.txt 2>&1
341
342 echo "#" >> skywalk.txt
343 echo "# skywalkctl flow -n" >> skywalk.txt
344 echo "#" >> skywalk.txt
345 /usr/sbin/skywalkctl flow -n >> skywalk.txt 2>&1
346
347 echo "#" >> skywalk.txt
348 echo "# skywalkctl flow-route -n" >> skywalk.txt
349 echo "#" >> skywalk.txt
350 /usr/sbin/skywalkctl flow-route -n >> skywalk.txt 2>&1
351
352 echo "#" >> skywalk.txt
353 echo "# skywalkctl flow-switch" >> skywalk.txt
354 echo "#" >> skywalk.txt
355 /usr/sbin/skywalkctl flow-switch >> skywalk.txt 2>&1
356
357 echo "#" >> skywalk.txt
358 echo "# skywalkctl flow-owner" >> skywalk.txt
359 echo "#" >> skywalk.txt
360 /usr/sbin/skywalkctl flow-owner >> skywalk.txt 2>&1
361
362 echo "#" >> skywalk.txt
363 echo "# skywalkctl flow-adv" >> skywalk.txt
364 echo "#" >> skywalk.txt
365 /usr/sbin/skywalkctl flow-adv >> skywalk.txt 2>&1
366
367 echo "#" >> skywalk.txt
368 echo "# skywalkctl netstat -s" >> skywalk.txt
369 echo "#" >> skywalk.txt
370 /usr/sbin/skywalkctl netstat -s >> skywalk.txt 2>&1
371
372 echo "#" >> skywalk.txt
373 echo "# skywalkctl netstat -s --global" >> skywalk.txt
374 echo "#" >> skywalk.txt
375 /usr/sbin/skywalkctl netstat -s --global >> skywalk.txt 2>&1
376
377 echo "#" >> skywalk.txt
378 echo "# skywalkctl interface" >> skywalk.txt
379 echo "#" >> skywalk.txt
380 /usr/sbin/skywalkctl interface >> skywalk.txt 2>&1
381
382 echo "#" >> skywalk.txt
383 echo "# skywalkctl channel" >> skywalk.txt
384 echo "#" >> skywalk.txt
385 /usr/sbin/skywalkctl channel >> skywalk.txt 2>&1
386
387 echo "#" >> skywalk.txt
388 echo "# skywalkctl provider -D" >> skywalk.txt
389 echo "#" >> skywalk.txt
390 /usr/sbin/skywalkctl provider -D >> skywalk.txt 2>&1
391
392 echo "#" >> skywalk.txt
393 echo "# skywalkctl netns -a" >> skywalk.txt
394 echo "#" >> skywalk.txt
395 /usr/sbin/skywalkctl netns -a >> skywalk.txt 2>&1
396
397 echo "#" >> skywalk.txt
398 echo "# skywalkctl memory" >> skywalk.txt
399 echo "#" >> skywalk.txt
400 /usr/sbin/skywalkctl memory >> skywalk.txt 2>&1
401
402 }
403
404 #
405 # skywalk configuration and statistics
406 #
407 run_nettop () {
408
409 if [ ! -x /usr/bin/nettop ]; then
410 return
411 fi
412
413 echo "#" > nettop.txt
414 echo "# nettop -U -l 1" >> nettop.txt
415 echo "#" >> nettop.txt
416 /usr/bin/nettop -U -l 1 >> nettop.txt 2>&1
417
418 }
419
420 #
421 # Network preferences
422 #
423 collect_configuration_files () {
424
425 for f in \
426 /Library/Preferences/com.apple.networkextension.plist \
427 /Library/Preferences/com.apple.networkextension.control.plist \
428 /Library/Preferences/com.apple.networkextension.necp.plist \
429 /Library/Preferences/com.apple.networkextension.cache.plist \
430 /Library/Preferences/com.apple.networkextension.uuidcache.plist \
431 /Library/Preferences/SystemConfiguration/com.apple.nat.plist \
432 /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist \
433 /Library/Preferences/SystemConfiguration/com.apple.smb.server.plist \
434 /Library/Preferences/com.apple.mDNSResponder.plist \
435 /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist \
436 /Library/Preferences/SystemConfiguration/preferences.plist \
437
438 do
439 if [ -e "${f}" ]; then
440 b="`basename ${f}`"
441 cat "${f}" > "${b}" 2>&1
442 fi
443 done
444
445 if [ -e /etc/resolv.conf ]; then
446 cat /etc/resolv.conf > etc-resolv-conf.txt 2>&1
447 fi
448 if [ -e /var/run/resolv.conf ]; then
449 cat /var/run/resolv.conf > var-run-resolv-conf.txt 2>&1
450 fi
451 if [ -e /etc/resolver ]; then
452 tar -c -H /etc/resolver > etc-resolver.tar 2>/dev/null
453 fi
454 }
455
456 #
457 # VPN
458 #
459 collect_vpn_logs () {
460
461 for f in \
462 /var/log/vpnd.log \
463 /var/log/racoon.log \
464
465 do
466 if [ -e "${f}" ]; then
467 b="`basename ${f}`"
468 ${PRIV} cat "${f}" > "${b}".txt 2>&1
469 fi
470 done
471 }
472
473 #
474 # Policy
475 #
476 run_neutil () {
477
478 if [ ! -x /usr/local/bin/neutil ]; then
479 return
480 fi
481
482 (
483 echo "#" > necp.txt
484 echo "# neutil policy dump" >> necp.txt
485 echo "#" >> necp.txt
486 /usr/local/bin/neutil policy dump >> necp.txt 2>&1
487
488 echo "#" > network-agents.txt
489 echo "# neutil agent dump" >> network-agents.txt
490 echo "#" >> network-agents.txt
491 /usr/local/bin/neutil agent dump >> network-agents.txt 2>&1
492
493 # Generates a default-level log message containing the current file handles that UserEventAgent has
494 /usr/local/bin/neutil session log-file-handles
495 sleep 1 &
496 ) &
497 }
498
499 #
500 # Path
501 #
502 run_network_test () {
503
504 if [ ! -x /usr/local/bin/network_test ]; then
505 return
506 fi
507
508 /usr/local/bin/network_test path_watcher > nw_path.txt 2>&1
509
510 }
511
512 #
513 # Network, DNS, Proxy, Reachability, Cache information
514 #
515 run_scutil () {
516
517 if [ ! -x /usr/sbin/scutil ]; then
518 return
519 fi
520
521 echo "#" > network-information.txt
522 echo "# scutil -d -v --nwi" >> network-information.txt
523 echo "#" >> network-information.txt
524 /usr/sbin/scutil -d -v --nwi >> network-information.txt 2>&1
525 for if in ${IF_LIST}
526 do
527 echo "" >> network-information.txt
528 echo "#" >> network-information.txt
529 echo "# scutil --nwi ${if}" >> network-information.txt
530 echo "#" >> network-information.txt
531 scutil --nwi ${if} >> network-information.txt 2>&1
532 done
533
534 echo "#" > dns-configuration.txt
535 echo "# scutil -d -v --dns" >> dns-configuration.txt
536 echo "#" >> dns-configuration.txt
537 /usr/sbin/scutil -d -v --dns >> dns-configuration.txt 2>&1
538
539 echo "#" > proxy-configuration.txt
540 echo "# scutil -d -v --proxy" >> proxy-configuration.txt
541 echo "#" >> proxy-configuration.txt
542 /usr/sbin/scutil -d -v --proxy >> proxy-configuration.txt 2>&1
543
544 echo "#" > reachability-info.txt
545 echo '# scutil -d -v -r www.apple.com' >> reachability-info.txt
546 echo "#" >> reachability-info.txt
547 /usr/sbin/scutil -d -v -r www.apple.com >> reachability-info.txt 2>&1
548
549 echo "#" >> reachability-info.txt
550 echo '# scutil -d -v -r 0.0.0.0' >> reachability-info.txt
551 echo "#" >> reachability-info.txt
552 /usr/sbin/scutil -d -v -r 0.0.0.0 >> reachability-info.txt 2>&1
553
554 echo "#" >> reachability-info.txt
555 echo '# scutil -d -v -r 169.254.0.0' >> reachability-info.txt
556 echo "#" >> reachability-info.txt
557 /usr/sbin/scutil -d -v -r 169.254.0.0 >> reachability-info.txt 2>&1
558
559 echo "#" > nc-info.txt
560 echo '# scutil --nc list' >> nc-info.txt
561 echo "#" >> nc-info.txt
562 /usr/sbin/scutil --nc list >> nc-info.txt 2>&1
563
564 /usr/sbin/scutil -p --snapshot SCDynamicStore.plist 2>&1
565
566 }
567
568 #
569 # route
570 #
571 run_route () {
572
573 if [ ! -x /sbin/route ]; then
574 return
575 fi
576
577 echo "#" > route-info.txt
578 echo '# route -n -v get www.apple.com' >> route-info.txt
579 echo "#" >> route-info.txt
580 /sbin/route -n -v get www.apple.com >> route-info.txt 2>&1
581
582 echo "#" >> route-info.txt
583 echo '# route -n -v get 0.0.0.0' >> route-info.txt
584 echo "#" >> route-info.txt
585 /sbin/route -n -v get 0.0.0.0 >> route-info.txt 2>&1
586
587 }
588
589 #
590 # dig
591 #
592 run_dig () {
593
594 if [ ! -x /usr/bin/dig -o ! -f /etc/resolv.conf ]; then
595 return
596 fi
597
598 echo "#" > dig-info.txt
599 echo '# dig -t any -c any www.apple.com' >> dig-info.txt
600 echo "#" >> dig-info.txt
601 /usr/bin/dig +time=2 -t any -c any www.apple.com >> dig-info.txt 2>/dev/null
602
603 }
604
605 #
606 # hostname
607 #
608 run_hostname () {
609
610 if [ ! -x /bin/hostname ]; then
611 return
612 fi
613
614 /bin/hostname > hostname.txt 2>&1
615
616 }
617
618 #
619 # lsof
620 #
621 run_lsof () {
622
623 if [ ! -x /usr/sbin/lsof ]; then
624 return
625 fi
626
627 ${PRIV} /usr/sbin/lsof -i -n -O -P -T q > lsof.txt 2>&1 &
628 LSOF_PID=$!
629 # start a watchdog for lsof
630 (
631 WAIT_TIME=5
632 while [ $WAIT_TIME -gt 0 ]
633 do
634 ${PRIV} kill -0 ${LSOF_PID} 2>/dev/null
635 if [ $? -eq 0 ]; then
636 # lsof is [still] gathering data...
637 sleep 1
638 WAIT_TIME=$((WAIT_TIME - 1))
639 continue
640 fi
641
642 # lsof completed gathering data
643 break
644 done
645
646 if [ $WAIT_TIME -eq 0 ]; then
647 # lsof timed out
648 ${PRIV} kill ${LSOF_PID} 2>/dev/null
649 fi
650 ) &
651
652 }
653
654 start_pcap() {
655 #
656 # collect a packet capture if netdiagnose is available
657 #
658 if [ -x /usr/local/bin/netdiagnose ]; then
659 trap stop_pcap SIGINT
660 /usr/local/bin/netdiagnose -p "${REQUESTED_OUTDIR}" start sysdiagpcap 2>&1 1>/dev/null
661 PCAP_STARTED=1
662 fi
663 }
664
665 stop_pcap () {
666 if [ ${PCAP_STARTED} -ne 0 ]; then
667 trap '' SIGINT
668 /usr/local/bin/netdiagnose stop sysdiagpcap 2>&1 1>/dev/null
669 fi
670 }
671
672 collect_ndf_info () {
673 run_lsof
674 }
675
676 collect_sensitive_info () {
677
678 if [ "${COLLECT_PCAP}" == "Y" ]; then
679 start_pcap
680 fi
681
682 collect_state_dump_sensitive
683 run_ndp
684 run_arp
685 run_neutil
686 run_nettop
687 run_network_test
688 }
689
690 collect_info () {
691
692 if [ "${COLLECT_NDF_INFO}" == "Y" ]; then
693 collect_ndf_info
694 fi
695
696 if [ "${COLLECT_SENSITIVE_INFO}" == "Y" ]; then
697 collect_sensitive_info
698 fi
699
700 run_scutil
701 run_dig
702 run_ifconfig
703 run_netstat
704 run_ipconfig
705 run_setkey
706 run_skywalk
707 collect_vpn_logs
708 run_route
709 run_hostname
710
711 if [ "${COLLECT_CONFIGURATION_FILES}" == "Y" ]; then
712 collect_configuration_files
713 fi
714
715 stop_pcap
716 }
717
718 # __COMMAND_ROUTINES_END__
719
720 # __HELPER_ROUTINES_BEGIN__
721
722 usage () {
723
724 echo "Usage: get-network-info [-c] [-n] [-s] <info-directory>"
725 echo " -c collects system configuration files"
726 echo " -n collects NDF information (lsof)"
727 echo " -P do not collect a packet capture"
728 echo " -s collects sensitive information (ARP/NDP/mDNS cache)"
729 echo " <info-directory> path to directory where all the information will be collected"
730
731 }
732
733 is_outdir_valid () {
734
735 if [ "${REQUESTED_OUTDIR}" = "" ]; then
736 usage
737 exit 1
738 fi
739
740 if [ ! -d ${REQUESTED_OUTDIR} ]; then
741 echo "${REQUESTED_OUTDIR} does not exist"
742 exit 1
743 fi
744
745 if [ ! -w ${REQUESTED_OUTDIR} ]; then
746 echo "${REQUESTED_OUTDIR} is write-protected"
747 exit 1
748 fi
749 }
750
751 #
752 # Collect most used command output to be used later
753 #
754 optimize () {
755
756 if [ ! -x /sbin/ifconfig ]; then
757 return
758 fi
759
760 IF_LIST=`/sbin/ifconfig -l`
761
762 }
763
764 init_globals () {
765 REQUESTED_OUTDIR=""
766 COLLECT_SENSITIVE_INFO=""
767 COLLECT_CONFIGURATION_FILES=""
768 COLLECT_PCAP="Y"
769 PCAP_STARTED=0
770
771 }
772
773 # __HELPER_ROUTINES_END__
774
775 #
776 # __MAIN__
777 #
778 ARGS=`getopt cnPs $*`
779 if [ $? != 0 ]; then
780 usage
781 exit 1
782 fi
783
784 init_globals
785 process_opts
786 is_outdir_valid
787 setup
788 optimize
789 collect_info
790 wait
791
792 exit 0