From 34d340d711a2b033f5da480ed7b5eb147679a588 Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 1 Oct 2007 20:44:58 +0000 Subject: [PATCH] system_cmds-431.tar.gz --- Makefile | 28 +- Makefile.preamble | 3 + PB.project | 4 +- ac.tproj/ac.8 | 57 +- ac.tproj/ac.c | 146 +- accton.tproj/Makefile | 2 +- accton.tproj/Makefile.postamble | 5 + accton.tproj/accton.8 | 51 + accton.tproj/accton.c | 5 +- arch.tproj/Makefile | 5 +- arch.tproj/Makefile.postamble | 3 + arch.tproj/arch.1 | 187 +- arch.tproj/arch.c | 81 - arch.tproj/arch.m | 576 +++ arch.tproj/arch_helper.pl | 98 + arch.tproj/machine.1 | 1 + at.tproj/Makefile | 6 +- at.tproj/Makefile.dist | 15 - at.tproj/Makefile.postamble | 4 +- at.tproj/at.1 | 235 - at.tproj/at.c | 28 +- at.tproj/at.man | 390 ++ at.tproj/pathnames.h | 12 +- at.tproj/perm.c | 1 + atrun.tproj/atrun.8 | 8 +- atrun.tproj/atrun.c | 29 +- atrun.tproj/com.apple.atrun.plist | 2 +- audit.tproj/audit.1 | 2 +- auditd.tproj/audit_warn.c | 1 + auditd.tproj/auditd.c | 1 + auditd.tproj/auditd_control.defs | 4 + {utmp_update.tproj => bootlog.tproj}/Makefile | 14 +- bootlog.tproj/Makefile.postamble | 5 + bootlog.tproj/Makefile.preamble | 1 + bootlog.tproj/PB.project | 24 + bootlog.tproj/bootlog.8 | 41 + bootlog.tproj/bootlog.c | 92 + bootlog.tproj/com.apple.bootlog.plist | 16 + chkpasswd.tproj/Makefile | 2 +- chkpasswd.tproj/PB.project | 2 +- chkpasswd.tproj/chkpasswd.8 | 63 +- chkpasswd.tproj/file_passwd.c | 8 +- chkpasswd.tproj/netinfo_passwd.c | 353 -- chkpasswd.tproj/passwd.c | 12 +- chpass.tproj/Makefile | 12 +- chpass.tproj/Makefile.dist | 15 - chpass.tproj/Makefile.postamble | 12 +- chpass.tproj/Makefile.preamble | 5 +- chpass.tproj/PB.project | 8 +- chpass.tproj/chpass.1 | 265 +- chpass.tproj/chpass.c | 540 +- chpass.tproj/chpass.h | 154 +- chpass.tproj/directory_service.c | 713 --- chpass.tproj/directory_service.h | 74 - chpass.tproj/ds_pw_util.c | 259 - chpass.tproj/edit.c | 447 +- chpass.tproj/field.c | 316 +- chpass.tproj/open_directory.c | 272 + chpass.tproj/open_directory.h | 13 + chpass.tproj/pathnames.h | 62 - chpass.tproj/pw_copy.c | 19 +- chpass.tproj/pw_copy.h | 19 +- chpass.tproj/table.c | 109 +- chpass.tproj/util.c | 274 +- dirhelper.tproj/Makefile | 63 + dirhelper.tproj/client.c | 31 + dirhelper.tproj/com.apple.bsd.dirhelper.plist | 33 + dirhelper.tproj/dirhelper.8 | 51 + dirhelper.tproj/dirhelper.c | 437 ++ dmesg.tproj/Makefile.preamble | 2 +- dmesg.tproj/dmesg.8 | 4 +- dmesg.tproj/dmesg.c | 76 +- dp_notify_lib/backing_store_alerts.defs | 4 + dp_notify_lib/backing_store_triggers.defs | 4 + dynamic_pager.tproj/Makefile | 3 +- dynamic_pager.tproj/Makefile.postamble | 14 + dynamic_pager.tproj/Makefile.preamble | 5 +- dynamic_pager.tproj/PB.project | 3 +- dynamic_pager.tproj/backing_store_alerts.defs | 4 + .../backing_store_triggers.defs | 4 + .../com.apple.dynamic_pager.plist | 16 + dynamic_pager.tproj/dynamic_pager.8 | 50 +- dynamic_pager.tproj/dynamic_pager.c | 179 +- fs_usage.tproj/fs_usage.1 | 71 +- fs_usage.tproj/fs_usage.c | 4436 ++++++++++------- getconf.tproj/confstr.gperf | 3 + getconf.tproj/getconf.1 | 7 +- getconf.tproj/getconf.c | 20 +- getconf.tproj/limits.gperf | 2 +- getconf.tproj/pathconf.gperf | 3 +- getconf.tproj/progenv.gperf | 7 +- getconf.tproj/sysconf.gperf | 13 +- getty.tproj/Makefile | 4 +- getty.tproj/Makefile.postamble | 11 +- getty.tproj/Makefile.preamble | 2 +- getty.tproj/chat.c | 490 ++ getty.tproj/com.apple.getty.plist | 18 + getty.tproj/extern.h | 64 +- getty.tproj/getty.8 | 56 +- getty.tproj/gettytab.5 | 362 +- getty.tproj/gettytab.h | 57 +- getty.tproj/init.c | 88 +- getty.tproj/main.c | 607 ++- getty.tproj/pathnames.h | 25 +- getty.tproj/subr.c | 571 +-- getty.tproj/ttys.5 | 65 +- hostinfo.tproj/hostinfo.c | 4 +- iostat.tproj/iostat.8 | 64 +- iostat.tproj/iostat.c | 200 +- kdump.tproj/Makefile | 53 - kdump.tproj/Makefile.postamble | 8 - kdump.tproj/Makefile.preamble | 7 - kdump.tproj/PB.project | 42 - kdump.tproj/kdump.1 | 102 - kdump.tproj/kdump.c | 492 -- kdump.tproj/mkioctls | 97 - kdump.tproj/syscalls.c | 448 -- kgmon.tproj/Makefile.postamble | 117 - kgmon.tproj/Makefile.preamble | 113 - kgmon.tproj/kgmon.8 | 122 - kgmon.tproj/kgmon.c | 543 -- ktrace.tproj/Makefile | 56 - ktrace.tproj/Makefile.postamble | 4 - ktrace.tproj/Makefile.preamble | 3 - ktrace.tproj/PB.project | 38 - ktrace.tproj/ktrace.1 | 172 - ktrace.tproj/ktrace.c | 233 - ktrace.tproj/ktrace.h | 50 - ktrace.tproj/subr.c | 139 - latency.tproj/latency.1 | 85 +- latency.tproj/latency.c | 22 +- login.tproj/Makefile | 4 + login.tproj/Makefile.preamble | 4 +- login.tproj/login.1 | 55 +- login.tproj/login.c | 227 +- makekey.tproj/makekey.8 | 12 +- makekey.tproj/makekey.c | 5 +- mkfile.tproj/mkfile.8 | 2 +- mkfile.tproj/mkfile.c | 22 +- {pt_chown.tproj => newgrp.tproj}/Makefile | 18 +- newgrp.tproj/Makefile.postamble | 6 + newgrp.tproj/Makefile.preamble | 2 + newgrp.tproj/PB.project | 27 + newgrp.tproj/newgrp.1 | 96 + newgrp.tproj/newgrp.c | 309 ++ nologin.tproj/nologin.8 | 2 +- nvram.tproj/nvram.8 | 24 +- nvram.tproj/nvram.c | 163 +- passwd.tproj/Makefile | 6 +- passwd.tproj/PB.project | 2 +- passwd.tproj/ds_passwd.c | 462 -- passwd.tproj/netinfo_passwd.c | 434 -- passwd.tproj/nis_passwd.c | 2 +- passwd.tproj/od_passwd.c | 315 ++ passwd.tproj/passwd.1 | 47 +- passwd.tproj/passwd.c | 148 +- pt_chown.tproj/Makefile.postamble | 2 - pt_chown.tproj/Makefile.preamble | 1 - pt_chown.tproj/PB.project | 37 - pt_chown.tproj/pt_chown.c | 103 - pwd_mkdb.tproj/pwd_mkdb.8 | 40 +- pwd_mkdb.tproj/pwd_mkdb.c | 6 +- reboot.tproj/reboot.8 | 26 +- reboot.tproj/reboot.c | 99 +- sa.tproj/sa.8 | 52 +- sadc.tproj/sa1.8 | 22 +- sadc.tproj/sa2.8 | 26 +- sadc.tproj/sadc.8 | 21 +- sadc.tproj/sadc.c | 1 - sar.tproj/sar.1 | 76 +- sar.tproj/sar.c | 24 +- sc_usage.tproj/Makefile.postamble | 3 + sc_usage.tproj/sc_usage.c | 68 +- sc_usage.tproj/trace.codes | 313 +- shutdown.tproj/Makefile | 1 + shutdown.tproj/PB.project | 2 +- shutdown.tproj/shutdown.8 | 88 +- shutdown.tproj/shutdown.c | 271 +- sync.tproj/sync.8 | 2 +- sync.tproj/sync.c | 4 + sysctl.tproj/Makefile | 2 +- sysctl.tproj/Makefile.postamble | 2 + sysctl.tproj/sysctl.8 | 32 +- sysctl.tproj/sysctl.c | 95 +- sysctl.tproj/sysctl.conf.5 | 75 + update.tproj/Makefile | 9 +- update.tproj/Makefile.postamble | 14 +- update.tproj/Makefile.preamble | 2 +- update.tproj/PB.project | 8 +- update.tproj/com.apple.update.plist | 14 + update.tproj/disk_power.c | 350 -- update.tproj/disk_power.h | 71 - update.tproj/power_mgmt.c | 114 - update.tproj/power_mgmt.h | 2 - update.tproj/update.8 | 7 +- update.tproj/update.c | 151 +- update.tproj/update.sb | 18 + utmp_update.tproj/Makefile.postamble | 2 - utmp_update.tproj/PB.project | 37 - utmp_update.tproj/utmp_update.c | 147 - {kgmon.tproj => vifs.tproj}/Makefile | 12 +- vifs.tproj/Makefile.postamble | 3 + {kgmon.tproj => vifs.tproj}/PB.project | 8 +- vifs.tproj/vifs.8 | 46 + vifs.tproj/vifs.c | 120 + vipw.tproj/Makefile.postamble | 2 +- vipw.tproj/pw_util.c | 3 +- vipw.tproj/vipw.c | 5 +- vm_stat.tproj/vm_stat.1 | 4 +- vm_stat.tproj/vm_stat.c | 4 +- zdump.tproj/zdump.8 | 23 +- zic.tproj/HACK/Africa/Abidjan | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Accra | Bin 157 -> 0 bytes zic.tproj/HACK/Africa/Addis_Ababa | Bin 74 -> 0 bytes zic.tproj/HACK/Africa/Algiers | Bin 287 -> 0 bytes zic.tproj/HACK/Africa/Asmera | Bin 74 -> 0 bytes zic.tproj/HACK/Africa/Bamako | Bin 95 -> 0 bytes zic.tproj/HACK/Africa/Bangui | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Banjul | Bin 107 -> 0 bytes zic.tproj/HACK/Africa/Bissau | Bin 90 -> 0 bytes zic.tproj/HACK/Africa/Blantyre | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Brazzaville | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Bujumbura | Bin 56 -> 0 bytes zic.tproj/HACK/Africa/Cairo | Bin 939 -> 0 bytes zic.tproj/HACK/Africa/Casablanca | Bin 188 -> 0 bytes zic.tproj/HACK/Africa/Ceuta | Bin 748 -> 0 bytes zic.tproj/HACK/Africa/Conakry | Bin 95 -> 0 bytes zic.tproj/HACK/Africa/Dakar | Bin 90 -> 0 bytes zic.tproj/HACK/Africa/Dar_es_Salaam | Bin 96 -> 0 bytes zic.tproj/HACK/Africa/Djibouti | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Douala | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/El_Aaiun | Bin 90 -> 0 bytes zic.tproj/HACK/Africa/Freetown | Bin 256 -> 0 bytes zic.tproj/HACK/Africa/Gaborone | Bin 79 -> 0 bytes zic.tproj/HACK/Africa/Harare | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Johannesburg | Bin 102 -> 0 bytes zic.tproj/HACK/Africa/Kampala | Bin 109 -> 0 bytes zic.tproj/HACK/Africa/Khartoum | Bin 246 -> 0 bytes zic.tproj/HACK/Africa/Kigali | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Kinshasa | Bin 56 -> 0 bytes zic.tproj/HACK/Africa/Lagos | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Libreville | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Lome | Bin 56 -> 0 bytes zic.tproj/HACK/Africa/Luanda | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Lubumbashi | Bin 56 -> 0 bytes zic.tproj/HACK/Africa/Lusaka | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Malabo | Bin 90 -> 0 bytes zic.tproj/HACK/Africa/Maputo | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Maseru | Bin 96 -> 0 bytes zic.tproj/HACK/Africa/Mbabane | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Mogadishu | Bin 92 -> 0 bytes zic.tproj/HACK/Africa/Monrovia | Bin 90 -> 0 bytes zic.tproj/HACK/Africa/Nairobi | Bin 109 -> 0 bytes zic.tproj/HACK/Africa/Ndjamena | Bin 96 -> 0 bytes zic.tproj/HACK/Africa/Niamey | Bin 95 -> 0 bytes zic.tproj/HACK/Africa/Nouakchott | Bin 95 -> 0 bytes zic.tproj/HACK/Africa/Ouagadougou | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Porto-Novo | Bin 90 -> 0 bytes zic.tproj/HACK/Africa/Sao_Tome | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Timbuktu | Bin 73 -> 0 bytes zic.tproj/HACK/Africa/Tripoli | Bin 669 -> 0 bytes zic.tproj/HACK/Africa/Tunis | Bin 222 -> 0 bytes zic.tproj/HACK/Africa/Windhoek | Bin 532 -> 0 bytes zic.tproj/HACK/America/Adak | Bin 823 -> 0 bytes zic.tproj/HACK/America/Anchorage | Bin 826 -> 0 bytes zic.tproj/HACK/America/Anguilla | Bin 73 -> 0 bytes zic.tproj/HACK/America/Antigua | Bin 90 -> 0 bytes zic.tproj/HACK/America/Aruba | Bin 90 -> 0 bytes zic.tproj/HACK/America/Asuncion | Bin 719 -> 0 bytes zic.tproj/HACK/America/Atka | Bin 823 -> 0 bytes zic.tproj/HACK/America/Barbados | Bin 142 -> 0 bytes zic.tproj/HACK/America/Belize | Bin 368 -> 0 bytes zic.tproj/HACK/America/Bogota | Bin 96 -> 0 bytes zic.tproj/HACK/America/Boise | Bin 849 -> 0 bytes zic.tproj/HACK/America/Buenos_Aires | Bin 427 -> 0 bytes zic.tproj/HACK/America/Caracas | Bin 86 -> 0 bytes zic.tproj/HACK/America/Catamarca | Bin 407 -> 0 bytes zic.tproj/HACK/America/Cayenne | Bin 86 -> 0 bytes zic.tproj/HACK/America/Cayman | Bin 73 -> 0 bytes zic.tproj/HACK/America/Chicago | Bin 1262 -> 0 bytes zic.tproj/HACK/America/Cordoba | Bin 397 -> 0 bytes zic.tproj/HACK/America/Costa_Rica | Bin 126 -> 0 bytes zic.tproj/HACK/America/Cuiaba | Bin 660 -> 0 bytes zic.tproj/HACK/America/Curacao | Bin 90 -> 0 bytes zic.tproj/HACK/America/Dawson | Bin 730 -> 0 bytes zic.tproj/HACK/America/Dawson_Creek | Bin 360 -> 0 bytes zic.tproj/HACK/America/Denver | Bin 860 -> 0 bytes zic.tproj/HACK/America/Detroit | Bin 794 -> 0 bytes zic.tproj/HACK/America/Dominica | Bin 73 -> 0 bytes zic.tproj/HACK/America/Edmonton | Bin 845 -> 0 bytes zic.tproj/HACK/America/El_Salvador | Bin 105 -> 0 bytes zic.tproj/HACK/America/Ensenada | Bin 537 -> 0 bytes zic.tproj/HACK/America/Fort_Wayne | Bin 269 -> 0 bytes zic.tproj/HACK/America/Fortaleza | Bin 185 -> 0 bytes zic.tproj/HACK/America/Glace_Bay | Bin 775 -> 0 bytes zic.tproj/HACK/America/Godthab | Bin 682 -> 0 bytes zic.tproj/HACK/America/Goose_Bay | Bin 1171 -> 0 bytes zic.tproj/HACK/America/Grand_Turk | Bin 675 -> 0 bytes zic.tproj/HACK/America/Grenada | Bin 73 -> 0 bytes zic.tproj/HACK/America/Guadeloupe | Bin 73 -> 0 bytes zic.tproj/HACK/America/Guatemala | Bin 115 -> 0 bytes zic.tproj/HACK/America/Guayaquil | Bin 73 -> 0 bytes zic.tproj/HACK/America/Guyana | Bin 117 -> 0 bytes zic.tproj/HACK/America/Halifax | Bin 1225 -> 0 bytes zic.tproj/HACK/America/Havana | Bin 883 -> 0 bytes zic.tproj/HACK/America/Indiana/Indianapolis | Bin 269 -> 0 bytes zic.tproj/HACK/America/Indiana/Knox | Bin 532 -> 0 bytes zic.tproj/HACK/America/Indiana/Marengo | Bin 289 -> 0 bytes zic.tproj/HACK/America/Indiana/Vevay | Bin 167 -> 0 bytes zic.tproj/HACK/America/Indianapolis | Bin 269 -> 0 bytes zic.tproj/HACK/America/Inuvik | Bin 730 -> 0 bytes zic.tproj/HACK/America/Iqaluit | Bin 701 -> 0 bytes zic.tproj/HACK/America/Jamaica | Bin 185 -> 0 bytes zic.tproj/HACK/America/Jujuy | Bin 449 -> 0 bytes zic.tproj/HACK/America/Juneau | Bin 806 -> 0 bytes zic.tproj/HACK/America/Knox_IN | Bin 532 -> 0 bytes zic.tproj/HACK/America/La_Paz | Bin 92 -> 0 bytes zic.tproj/HACK/America/Lima | Bin 146 -> 0 bytes zic.tproj/HACK/America/Los_Angeles | Bin 1000 -> 0 bytes zic.tproj/HACK/America/Louisville | Bin 984 -> 0 bytes zic.tproj/HACK/America/Maceio | Bin 610 -> 0 bytes zic.tproj/HACK/America/Managua | Bin 142 -> 0 bytes zic.tproj/HACK/America/Manaus | Bin 185 -> 0 bytes zic.tproj/HACK/America/Martinique | Bin 96 -> 0 bytes zic.tproj/HACK/America/Mazatlan | Bin 569 -> 0 bytes zic.tproj/HACK/America/Mendoza | Bin 449 -> 0 bytes zic.tproj/HACK/America/Menominee | Bin 797 -> 0 bytes zic.tproj/HACK/America/Mexico_City | Bin 582 -> 0 bytes zic.tproj/HACK/America/Miquelon | Bin 679 -> 0 bytes zic.tproj/HACK/America/Montevideo | Bin 439 -> 0 bytes zic.tproj/HACK/America/Montreal | Bin 1218 -> 0 bytes zic.tproj/HACK/America/Montserrat | Bin 73 -> 0 bytes zic.tproj/HACK/America/Nassau | Bin 825 -> 0 bytes zic.tproj/HACK/America/New_York | Bin 1250 -> 0 bytes zic.tproj/HACK/America/Nipigon | Bin 728 -> 0 bytes zic.tproj/HACK/America/Nome | Bin 823 -> 0 bytes zic.tproj/HACK/America/Noronha | Bin 185 -> 0 bytes zic.tproj/HACK/America/Panama | Bin 73 -> 0 bytes zic.tproj/HACK/America/Pangnirtung | Bin 701 -> 0 bytes zic.tproj/HACK/America/Paramaribo | Bin 134 -> 0 bytes zic.tproj/HACK/America/Phoenix | Bin 130 -> 0 bytes zic.tproj/HACK/America/Port-au-Prince | Bin 652 -> 0 bytes zic.tproj/HACK/America/Port_of_Spain | Bin 73 -> 0 bytes zic.tproj/HACK/America/Porto_Acre | Bin 165 -> 0 bytes zic.tproj/HACK/America/Puerto_Rico | Bin 78 -> 0 bytes zic.tproj/HACK/America/Rainy_River | Bin 728 -> 0 bytes zic.tproj/HACK/America/Rankin_Inlet | Bin 701 -> 0 bytes zic.tproj/HACK/America/Regina | Bin 362 -> 0 bytes zic.tproj/HACK/America/Rosario | Bin 407 -> 0 bytes zic.tproj/HACK/America/Santiago | Bin 852 -> 0 bytes zic.tproj/HACK/America/Santo_Domingo | Bin 176 -> 0 bytes zic.tproj/HACK/America/Sao_Paulo | Bin 720 -> 0 bytes zic.tproj/HACK/America/Scoresbysund | Bin 707 -> 0 bytes zic.tproj/HACK/America/Shiprock | Bin 860 -> 0 bytes zic.tproj/HACK/America/St_Johns | Bin 1312 -> 0 bytes zic.tproj/HACK/America/St_Kitts | Bin 73 -> 0 bytes zic.tproj/HACK/America/St_Lucia | Bin 73 -> 0 bytes zic.tproj/HACK/America/St_Thomas | Bin 73 -> 0 bytes zic.tproj/HACK/America/St_Vincent | Bin 73 -> 0 bytes zic.tproj/HACK/America/Swift_Current | Bin 202 -> 0 bytes zic.tproj/HACK/America/Tegucigalpa | Bin 105 -> 0 bytes zic.tproj/HACK/America/Thule | Bin 535 -> 0 bytes zic.tproj/HACK/America/Thunder_Bay | Bin 758 -> 0 bytes zic.tproj/HACK/America/Tijuana | Bin 997 -> 0 bytes zic.tproj/HACK/America/Tortola | Bin 73 -> 0 bytes zic.tproj/HACK/America/Vancouver | Bin 1008 -> 0 bytes zic.tproj/HACK/America/Virgin | Bin 73 -> 0 bytes zic.tproj/HACK/America/Whitehorse | Bin 730 -> 0 bytes zic.tproj/HACK/America/Winnipeg | Bin 988 -> 0 bytes zic.tproj/HACK/America/Yakutat | Bin 806 -> 0 bytes zic.tproj/HACK/America/Yellowknife | Bin 701 -> 0 bytes zic.tproj/HACK/Antarctica/Casey | Bin 73 -> 0 bytes zic.tproj/HACK/Antarctica/Mawson | Bin 74 -> 0 bytes zic.tproj/HACK/Antarctica/McMurdo | Bin 730 -> 0 bytes zic.tproj/HACK/Antarctica/Palmer | Bin 777 -> 0 bytes zic.tproj/HACK/Antarctica/South_Pole | Bin 730 -> 0 bytes zic.tproj/HACK/Arctic/Longyearbyen | Bin 806 -> 0 bytes zic.tproj/HACK/Asia/Aden | Bin 73 -> 0 bytes zic.tproj/HACK/Asia/Alma-Ata | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Amman | Bin 684 -> 0 bytes zic.tproj/HACK/Asia/Anadyr | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Aqtau | Bin 759 -> 0 bytes zic.tproj/HACK/Asia/Aqtobe | Bin 747 -> 0 bytes zic.tproj/HACK/Asia/Ashkhabad | Bin 273 -> 0 bytes zic.tproj/HACK/Asia/Baghdad | Bin 669 -> 0 bytes zic.tproj/HACK/Asia/Bahrain | Bin 90 -> 0 bytes zic.tproj/HACK/Asia/Baku | Bin 745 -> 0 bytes zic.tproj/HACK/Asia/Bangkok | Bin 73 -> 0 bytes zic.tproj/HACK/Asia/Beirut | Bin 769 -> 0 bytes zic.tproj/HACK/Asia/Bishkek | Bin 720 -> 0 bytes zic.tproj/HACK/Asia/Brunei | Bin 86 -> 0 bytes zic.tproj/HACK/Asia/Calcutta | Bin 109 -> 0 bytes zic.tproj/HACK/Asia/Chungking | Bin 163 -> 0 bytes zic.tproj/HACK/Asia/Colombo | Bin 127 -> 0 bytes zic.tproj/HACK/Asia/Dacca | Bin 131 -> 0 bytes zic.tproj/HACK/Asia/Damascus | Bin 836 -> 0 bytes zic.tproj/HACK/Asia/Dubai | Bin 73 -> 0 bytes zic.tproj/HACK/Asia/Dushanbe | Bin 278 -> 0 bytes zic.tproj/HACK/Asia/Gaza | Bin 363 -> 0 bytes zic.tproj/HACK/Asia/Harbin | Bin 186 -> 0 bytes zic.tproj/HACK/Asia/Hong_Kong | Bin 443 -> 0 bytes zic.tproj/HACK/Asia/Irkutsk | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Ishigaki | Bin 56 -> 0 bytes zic.tproj/HACK/Asia/Istanbul | Bin 993 -> 0 bytes zic.tproj/HACK/Asia/Jakarta | Bin 140 -> 0 bytes zic.tproj/HACK/Asia/Jayapura | Bin 96 -> 0 bytes zic.tproj/HACK/Asia/Jerusalem | Bin 413 -> 0 bytes zic.tproj/HACK/Asia/Kabul | Bin 69 -> 0 bytes zic.tproj/HACK/Asia/Kamchatka | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Karachi | Bin 126 -> 0 bytes zic.tproj/HACK/Asia/Kashgar | Bin 176 -> 0 bytes zic.tproj/HACK/Asia/Katmandu | Bin 90 -> 0 bytes zic.tproj/HACK/Asia/Krasnoyarsk | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Kuala_Lumpur | Bin 139 -> 0 bytes zic.tproj/HACK/Asia/Kuching | Bin 211 -> 0 bytes zic.tproj/HACK/Asia/Kuwait | Bin 73 -> 0 bytes zic.tproj/HACK/Asia/Macao | Bin 303 -> 0 bytes zic.tproj/HACK/Asia/Magadan | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Manila | Bin 121 -> 0 bytes zic.tproj/HACK/Asia/Muscat | Bin 73 -> 0 bytes zic.tproj/HACK/Asia/Nicosia | Bin 716 -> 0 bytes zic.tproj/HACK/Asia/Novosibirsk | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Omsk | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Phnom_Penh | Bin 108 -> 0 bytes zic.tproj/HACK/Asia/Pyongyang | Bin 97 -> 0 bytes zic.tproj/HACK/Asia/Qatar | Bin 90 -> 0 bytes zic.tproj/HACK/Asia/Rangoon | Bin 108 -> 0 bytes zic.tproj/HACK/Asia/Riyadh | Bin 73 -> 0 bytes zic.tproj/HACK/Asia/Riyadh87 | Bin 3655 -> 0 bytes zic.tproj/HACK/Asia/Riyadh88 | Bin 3580 -> 0 bytes zic.tproj/HACK/Asia/Riyadh89 | Bin 3580 -> 0 bytes zic.tproj/HACK/Asia/Saigon | Bin 108 -> 0 bytes zic.tproj/HACK/Asia/Seoul | Bin 152 -> 0 bytes zic.tproj/HACK/Asia/Shanghai | Bin 165 -> 0 bytes zic.tproj/HACK/Asia/Singapore | Bin 152 -> 0 bytes zic.tproj/HACK/Asia/Taipei | Bin 268 -> 0 bytes zic.tproj/HACK/Asia/Tashkent | Bin 247 -> 0 bytes zic.tproj/HACK/Asia/Tbilisi | Bin 353 -> 0 bytes zic.tproj/HACK/Asia/Tehran | Bin 645 -> 0 bytes zic.tproj/HACK/Asia/Tel_Aviv | Bin 413 -> 0 bytes zic.tproj/HACK/Asia/Thimbu | Bin 90 -> 0 bytes zic.tproj/HACK/Asia/Tokyo | Bin 56 -> 0 bytes zic.tproj/HACK/Asia/Ujung_Pandang | Bin 113 -> 0 bytes zic.tproj/HACK/Asia/Ulan_Bator | Bin 671 -> 0 bytes zic.tproj/HACK/Asia/Urumqi | Bin 163 -> 0 bytes zic.tproj/HACK/Asia/Vientiane | Bin 108 -> 0 bytes zic.tproj/HACK/Asia/Vladivostok | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Yakutsk | Bin 708 -> 0 bytes zic.tproj/HACK/Asia/Yekaterinburg | Bin 751 -> 0 bytes zic.tproj/HACK/Asia/Yerevan | Bin 326 -> 0 bytes zic.tproj/HACK/Atlantic/Azores | Bin 1266 -> 0 bytes zic.tproj/HACK/Atlantic/Bermuda | Bin 725 -> 0 bytes zic.tproj/HACK/Atlantic/Canary | Bin 700 -> 0 bytes zic.tproj/HACK/Atlantic/Cape_Verde | Bin 109 -> 0 bytes zic.tproj/HACK/Atlantic/Faeroe | Bin 664 -> 0 bytes zic.tproj/HACK/Atlantic/Jan_Mayen | Bin 56 -> 0 bytes zic.tproj/HACK/Atlantic/Madeira | Bin 1263 -> 0 bytes zic.tproj/HACK/Atlantic/Reykjavik | Bin 429 -> 0 bytes zic.tproj/HACK/Atlantic/South_Georgia | Bin 56 -> 0 bytes zic.tproj/HACK/Atlantic/St_Helena | Bin 73 -> 0 bytes zic.tproj/HACK/Atlantic/Stanley | Bin 712 -> 0 bytes zic.tproj/HACK/Australia/ACT | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/Adelaide | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/Brisbane | Bin 160 -> 0 bytes zic.tproj/HACK/Australia/Broken_Hill | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/Canberra | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/Darwin | Bin 104 -> 0 bytes zic.tproj/HACK/Australia/Hobart | Bin 825 -> 0 bytes zic.tproj/HACK/Australia/LHI | Bin 663 -> 0 bytes zic.tproj/HACK/Australia/Lindeman | Bin 180 -> 0 bytes zic.tproj/HACK/Australia/Lord_Howe | Bin 663 -> 0 bytes zic.tproj/HACK/Australia/Melbourne | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/NSW | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/North | Bin 104 -> 0 bytes zic.tproj/HACK/Australia/Perth | Bin 150 -> 0 bytes zic.tproj/HACK/Australia/Queensland | Bin 160 -> 0 bytes zic.tproj/HACK/Australia/South | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/Sydney | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/Tasmania | Bin 825 -> 0 bytes zic.tproj/HACK/Australia/Victoria | Bin 785 -> 0 bytes zic.tproj/HACK/Australia/West | Bin 150 -> 0 bytes zic.tproj/HACK/Australia/Yancowinna | Bin 785 -> 0 bytes zic.tproj/HACK/Brazil/Acre | Bin 165 -> 0 bytes zic.tproj/HACK/Brazil/DeNoronha | Bin 185 -> 0 bytes zic.tproj/HACK/Brazil/East | Bin 720 -> 0 bytes zic.tproj/HACK/Brazil/West | Bin 185 -> 0 bytes zic.tproj/HACK/CET | Bin 755 -> 0 bytes zic.tproj/HACK/CST6CDT | Bin 1279 -> 0 bytes zic.tproj/HACK/Canada/Atlantic | Bin 1225 -> 0 bytes zic.tproj/HACK/Canada/Central | Bin 988 -> 0 bytes zic.tproj/HACK/Canada/East-Saskatchewan | Bin 362 -> 0 bytes zic.tproj/HACK/Canada/Eastern | Bin 1218 -> 0 bytes zic.tproj/HACK/Canada/Mountain | Bin 845 -> 0 bytes zic.tproj/HACK/Canada/Newfoundland | Bin 1312 -> 0 bytes zic.tproj/HACK/Canada/Pacific | Bin 1008 -> 0 bytes zic.tproj/HACK/Canada/Saskatchewan | Bin 362 -> 0 bytes zic.tproj/HACK/Canada/Yukon | Bin 730 -> 0 bytes zic.tproj/HACK/Chile/Continental | Bin 852 -> 0 bytes zic.tproj/HACK/Chile/EasterIsland | Bin 789 -> 0 bytes zic.tproj/HACK/Cuba | Bin 891 -> 0 bytes zic.tproj/HACK/EET | Bin 679 -> 0 bytes zic.tproj/HACK/EST | Bin 286 -> 0 bytes zic.tproj/HACK/EST5EDT | Bin 1267 -> 0 bytes zic.tproj/HACK/Egypt | Bin 955 -> 0 bytes zic.tproj/HACK/Eire | Bin 1285 -> 0 bytes zic.tproj/HACK/Etc/GMT | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/GMT+0 | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/GMT+1 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+10 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT+11 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT+12 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT+2 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+3 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+4 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+5 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+6 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+7 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+8 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT+9 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-0 | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/GMT-1 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-10 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT-11 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT-12 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT-13 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT-14 | Bin 59 -> 0 bytes zic.tproj/HACK/Etc/GMT-2 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-3 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-4 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-5 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-6 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-7 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-8 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT-9 | Bin 58 -> 0 bytes zic.tproj/HACK/Etc/GMT0 | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/Greenwich | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/UCT | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/UTC | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/Universal | Bin 56 -> 0 bytes zic.tproj/HACK/Etc/Zulu | Bin 56 -> 0 bytes zic.tproj/HACK/Europe/Amsterdam | Bin 1058 -> 0 bytes zic.tproj/HACK/Europe/Andorra | Bin 624 -> 0 bytes zic.tproj/HACK/Europe/Athens | Bin 823 -> 0 bytes zic.tproj/HACK/Europe/Belfast | Bin 1347 -> 0 bytes zic.tproj/HACK/Europe/Belgrade | Bin 696 -> 0 bytes zic.tproj/HACK/Europe/Berlin | Bin 838 -> 0 bytes zic.tproj/HACK/Europe/Bratislava | Bin 806 -> 0 bytes zic.tproj/HACK/Europe/Brussels | Bin 1049 -> 0 bytes zic.tproj/HACK/Europe/Bucharest | Bin 782 -> 0 bytes zic.tproj/HACK/Europe/Budapest | Bin 866 -> 0 bytes zic.tproj/HACK/Europe/Chisinau | Bin 717 -> 0 bytes zic.tproj/HACK/Europe/Copenhagen | Bin 766 -> 0 bytes zic.tproj/HACK/Europe/Dublin | Bin 1285 -> 0 bytes zic.tproj/HACK/Europe/Gibraltar | Bin 1099 -> 0 bytes zic.tproj/HACK/Europe/Helsinki | Bin 682 -> 0 bytes zic.tproj/HACK/Europe/Istanbul | Bin 993 -> 0 bytes zic.tproj/HACK/Europe/Kaliningrad | Bin 834 -> 0 bytes zic.tproj/HACK/Europe/Kiev | Bin 802 -> 0 bytes zic.tproj/HACK/Europe/Lisbon | Bin 1265 -> 0 bytes zic.tproj/HACK/Europe/Ljubljana | Bin 696 -> 0 bytes zic.tproj/HACK/Europe/London | Bin 1323 -> 0 bytes zic.tproj/HACK/Europe/Luxembourg | Bin 1093 -> 0 bytes zic.tproj/HACK/Europe/Madrid | Bin 947 -> 0 bytes zic.tproj/HACK/Europe/Malta | Bin 941 -> 0 bytes zic.tproj/HACK/Europe/Minsk | Bin 805 -> 0 bytes zic.tproj/HACK/Europe/Monaco | Bin 1085 -> 0 bytes zic.tproj/HACK/Europe/Moscow | Bin 802 -> 0 bytes zic.tproj/HACK/Europe/Oslo | Bin 806 -> 0 bytes zic.tproj/HACK/Europe/Paris | Bin 1088 -> 0 bytes zic.tproj/HACK/Europe/Prague | Bin 806 -> 0 bytes zic.tproj/HACK/Europe/Riga | Bin 804 -> 0 bytes zic.tproj/HACK/Europe/Rome | Bin 951 -> 0 bytes zic.tproj/HACK/Europe/Samara | Bin 751 -> 0 bytes zic.tproj/HACK/Europe/San_Marino | Bin 951 -> 0 bytes zic.tproj/HACK/Europe/Sarajevo | Bin 696 -> 0 bytes zic.tproj/HACK/Europe/Simferopol | Bin 810 -> 0 bytes zic.tproj/HACK/Europe/Skopje | Bin 696 -> 0 bytes zic.tproj/HACK/Europe/Sofia | Bin 735 -> 0 bytes zic.tproj/HACK/Europe/Stockholm | Bin 688 -> 0 bytes zic.tproj/HACK/Europe/Tallinn | Bin 800 -> 0 bytes zic.tproj/HACK/Europe/Tirane | Bin 783 -> 0 bytes zic.tproj/HACK/Europe/Vaduz | Bin 647 -> 0 bytes zic.tproj/HACK/Europe/Vatican | Bin 951 -> 0 bytes zic.tproj/HACK/Europe/Vienna | Bin 786 -> 0 bytes zic.tproj/HACK/Europe/Vilnius | Bin 807 -> 0 bytes zic.tproj/HACK/Europe/Warsaw | Bin 940 -> 0 bytes zic.tproj/HACK/Europe/Zagreb | Bin 696 -> 0 bytes zic.tproj/HACK/Europe/Zurich | Bin 685 -> 0 bytes zic.tproj/HACK/Factory | Bin 93 -> 0 bytes zic.tproj/HACK/GB | Bin 1323 -> 0 bytes zic.tproj/HACK/GMT | Bin 56 -> 0 bytes zic.tproj/HACK/GMT+0 | Bin 56 -> 0 bytes zic.tproj/HACK/GMT-0 | Bin 56 -> 0 bytes zic.tproj/HACK/GMT0 | Bin 56 -> 0 bytes zic.tproj/HACK/Greenwich | Bin 56 -> 0 bytes zic.tproj/HACK/HST | Bin 130 -> 0 bytes zic.tproj/HACK/Hongkong | Bin 426 -> 0 bytes zic.tproj/HACK/Iceland | Bin 429 -> 0 bytes zic.tproj/HACK/Indian/Antananarivo | Bin 104 -> 0 bytes zic.tproj/HACK/Indian/Chagos | Bin 56 -> 0 bytes zic.tproj/HACK/Indian/Christmas | Bin 56 -> 0 bytes zic.tproj/HACK/Indian/Cocos | Bin 56 -> 0 bytes zic.tproj/HACK/Indian/Comoro | Bin 73 -> 0 bytes zic.tproj/HACK/Indian/Mahe | Bin 73 -> 0 bytes zic.tproj/HACK/Indian/Maldives | Bin 73 -> 0 bytes zic.tproj/HACK/Indian/Mauritius | Bin 73 -> 0 bytes zic.tproj/HACK/Indian/Mayotte | Bin 73 -> 0 bytes zic.tproj/HACK/Indian/Reunion | Bin 73 -> 0 bytes zic.tproj/HACK/Iran | Bin 645 -> 0 bytes zic.tproj/HACK/Israel | Bin 803 -> 0 bytes zic.tproj/HACK/Jamaica | Bin 185 -> 0 bytes zic.tproj/HACK/Japan | Bin 73 -> 0 bytes zic.tproj/HACK/Kwajalein | Bin 87 -> 0 bytes zic.tproj/HACK/Libya | Bin 238 -> 0 bytes zic.tproj/HACK/MET | Bin 755 -> 0 bytes zic.tproj/HACK/MST | Bin 130 -> 0 bytes zic.tproj/HACK/MST7MDT | Bin 877 -> 0 bytes zic.tproj/HACK/Mexico/BajaNorte | Bin 997 -> 0 bytes zic.tproj/HACK/Mexico/BajaSur | Bin 569 -> 0 bytes zic.tproj/HACK/Mexico/General | Bin 582 -> 0 bytes zic.tproj/HACK/Mideast/Riyadh87 | Bin 3655 -> 0 bytes zic.tproj/HACK/Mideast/Riyadh88 | Bin 3580 -> 0 bytes zic.tproj/HACK/Mideast/Riyadh89 | Bin 3580 -> 0 bytes zic.tproj/HACK/NZ | Bin 870 -> 0 bytes zic.tproj/HACK/NZ-CHAT | Bin 547 -> 0 bytes zic.tproj/HACK/Navajo | Bin 877 -> 0 bytes zic.tproj/HACK/PRC | Bin 165 -> 0 bytes zic.tproj/HACK/PST8PDT | Bin 1017 -> 0 bytes zic.tproj/HACK/Pacific/Apia | Bin 91 -> 0 bytes zic.tproj/HACK/Pacific/Auckland | Bin 870 -> 0 bytes zic.tproj/HACK/Pacific/Chatham | Bin 547 -> 0 bytes zic.tproj/HACK/Pacific/Easter | Bin 789 -> 0 bytes zic.tproj/HACK/Pacific/Efate | Bin 186 -> 0 bytes zic.tproj/HACK/Pacific/Enderbury | Bin 83 -> 0 bytes zic.tproj/HACK/Pacific/Fakaofo | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Fiji | Bin 73 -> 0 bytes zic.tproj/HACK/Pacific/Funafuti | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Galapagos | Bin 91 -> 0 bytes zic.tproj/HACK/Pacific/Gambier | Bin 74 -> 0 bytes zic.tproj/HACK/Pacific/Guadalcanal | Bin 73 -> 0 bytes zic.tproj/HACK/Pacific/Guam | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Honolulu | Bin 113 -> 0 bytes zic.tproj/HACK/Pacific/Johnston | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Kiritimati | Bin 83 -> 0 bytes zic.tproj/HACK/Pacific/Kosrae | Bin 75 -> 0 bytes zic.tproj/HACK/Pacific/Kwajalein | Bin 87 -> 0 bytes zic.tproj/HACK/Pacific/Majuro | Bin 69 -> 0 bytes zic.tproj/HACK/Pacific/Marquesas | Bin 74 -> 0 bytes zic.tproj/HACK/Pacific/Midway | Bin 90 -> 0 bytes zic.tproj/HACK/Pacific/Nauru | Bin 108 -> 0 bytes zic.tproj/HACK/Pacific/Niue | Bin 82 -> 0 bytes zic.tproj/HACK/Pacific/Norfolk | Bin 73 -> 0 bytes zic.tproj/HACK/Pacific/Noumea | Bin 106 -> 0 bytes zic.tproj/HACK/Pacific/Pago_Pago | Bin 125 -> 0 bytes zic.tproj/HACK/Pacific/Palau | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Pitcairn | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Ponape | Bin 57 -> 0 bytes zic.tproj/HACK/Pacific/Port_Moresby | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Rarotonga | Bin 673 -> 0 bytes zic.tproj/HACK/Pacific/Saipan | Bin 69 -> 0 bytes zic.tproj/HACK/Pacific/Samoa | Bin 125 -> 0 bytes zic.tproj/HACK/Pacific/Tahiti | Bin 74 -> 0 bytes zic.tproj/HACK/Pacific/Tarawa | Bin 57 -> 0 bytes zic.tproj/HACK/Pacific/Tongatapu | Bin 69 -> 0 bytes zic.tproj/HACK/Pacific/Truk | Bin 57 -> 0 bytes zic.tproj/HACK/Pacific/Wake | Bin 57 -> 0 bytes zic.tproj/HACK/Pacific/Wallis | Bin 56 -> 0 bytes zic.tproj/HACK/Pacific/Yap | Bin 70 -> 0 bytes zic.tproj/HACK/Poland | Bin 961 -> 0 bytes zic.tproj/HACK/Portugal | Bin 1264 -> 0 bytes zic.tproj/HACK/ROC | Bin 268 -> 0 bytes zic.tproj/HACK/ROK | Bin 152 -> 0 bytes zic.tproj/HACK/Singapore | Bin 152 -> 0 bytes zic.tproj/HACK/SystemV/AST4 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/AST4ADT | Bin 1428 -> 0 bytes zic.tproj/HACK/SystemV/CST6 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/CST6CDT | Bin 1428 -> 0 bytes zic.tproj/HACK/SystemV/EST5 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/EST5EDT | Bin 1428 -> 0 bytes zic.tproj/HACK/SystemV/HST10 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/MST7 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/MST7MDT | Bin 1428 -> 0 bytes zic.tproj/HACK/SystemV/PST8 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/PST8PDT | Bin 1428 -> 0 bytes zic.tproj/HACK/SystemV/YST9 | Bin 56 -> 0 bytes zic.tproj/HACK/SystemV/YST9YDT | Bin 1428 -> 0 bytes zic.tproj/HACK/Turkey | Bin 993 -> 0 bytes zic.tproj/HACK/UCT | Bin 56 -> 0 bytes zic.tproj/HACK/US/Alaska | Bin 826 -> 0 bytes zic.tproj/HACK/US/Aleutian | Bin 823 -> 0 bytes zic.tproj/HACK/US/Arizona | Bin 130 -> 0 bytes zic.tproj/HACK/US/Central | Bin 1262 -> 0 bytes zic.tproj/HACK/US/East-Indiana | Bin 269 -> 0 bytes zic.tproj/HACK/US/Eastern | Bin 1250 -> 0 bytes zic.tproj/HACK/US/Hawaii | Bin 113 -> 0 bytes zic.tproj/HACK/US/Indiana-Starke | Bin 532 -> 0 bytes zic.tproj/HACK/US/Michigan | Bin 794 -> 0 bytes zic.tproj/HACK/US/Mountain | Bin 860 -> 0 bytes zic.tproj/HACK/US/Pacific | Bin 1000 -> 0 bytes zic.tproj/HACK/US/Pacific-New | Bin 1000 -> 0 bytes zic.tproj/HACK/US/Samoa | Bin 125 -> 0 bytes zic.tproj/HACK/UTC | Bin 56 -> 0 bytes zic.tproj/HACK/Universal | Bin 56 -> 0 bytes zic.tproj/HACK/W-SU | Bin 815 -> 0 bytes zic.tproj/HACK/WET | Bin 679 -> 0 bytes zic.tproj/HACK/Zulu | Bin 56 -> 0 bytes zic.tproj/Makefile | 3 +- zic.tproj/Makefile.postamble | 17 +- zic.tproj/PB.project | 2 +- zic.tproj/datfiles/Theory | 506 -- zic.tproj/datfiles/tzdata2007h.tar.gz | Bin 162187 -> 0 bytes zic.tproj/zic.8 | 35 +- zprint.tproj/zprint.1 | 20 +- zprint.tproj/zprint.c | 8 +- 714 files changed, 11491 insertions(+), 11554 deletions(-) create mode 100644 accton.tproj/accton.8 delete mode 100644 arch.tproj/arch.c create mode 100644 arch.tproj/arch.m create mode 100755 arch.tproj/arch_helper.pl delete mode 100644 at.tproj/Makefile.dist delete mode 100644 at.tproj/at.1 create mode 100644 at.tproj/at.man rename {utmp_update.tproj => bootlog.tproj}/Makefile (82%) create mode 100644 bootlog.tproj/Makefile.postamble create mode 100644 bootlog.tproj/Makefile.preamble create mode 100644 bootlog.tproj/PB.project create mode 100644 bootlog.tproj/bootlog.8 create mode 100644 bootlog.tproj/bootlog.c create mode 100644 bootlog.tproj/com.apple.bootlog.plist delete mode 100644 chkpasswd.tproj/netinfo_passwd.c delete mode 100644 chpass.tproj/Makefile.dist delete mode 100644 chpass.tproj/directory_service.c delete mode 100644 chpass.tproj/directory_service.h delete mode 100644 chpass.tproj/ds_pw_util.c create mode 100644 chpass.tproj/open_directory.c create mode 100644 chpass.tproj/open_directory.h delete mode 100644 chpass.tproj/pathnames.h create mode 100644 dirhelper.tproj/Makefile create mode 100644 dirhelper.tproj/client.c create mode 100644 dirhelper.tproj/com.apple.bsd.dirhelper.plist create mode 100644 dirhelper.tproj/dirhelper.8 create mode 100644 dirhelper.tproj/dirhelper.c create mode 100644 dynamic_pager.tproj/com.apple.dynamic_pager.plist create mode 100644 getty.tproj/chat.c create mode 100644 getty.tproj/com.apple.getty.plist delete mode 100644 kdump.tproj/Makefile delete mode 100644 kdump.tproj/Makefile.postamble delete mode 100644 kdump.tproj/Makefile.preamble delete mode 100644 kdump.tproj/PB.project delete mode 100644 kdump.tproj/kdump.1 delete mode 100644 kdump.tproj/kdump.c delete mode 100644 kdump.tproj/mkioctls delete mode 100644 kdump.tproj/syscalls.c delete mode 100644 kgmon.tproj/Makefile.postamble delete mode 100644 kgmon.tproj/Makefile.preamble delete mode 100644 kgmon.tproj/kgmon.8 delete mode 100644 kgmon.tproj/kgmon.c delete mode 100644 ktrace.tproj/Makefile delete mode 100644 ktrace.tproj/Makefile.postamble delete mode 100644 ktrace.tproj/Makefile.preamble delete mode 100644 ktrace.tproj/PB.project delete mode 100644 ktrace.tproj/ktrace.1 delete mode 100644 ktrace.tproj/ktrace.c delete mode 100644 ktrace.tproj/ktrace.h delete mode 100644 ktrace.tproj/subr.c rename {pt_chown.tproj => newgrp.tproj}/Makefile (77%) create mode 100644 newgrp.tproj/Makefile.postamble create mode 100644 newgrp.tproj/Makefile.preamble create mode 100644 newgrp.tproj/PB.project create mode 100644 newgrp.tproj/newgrp.1 create mode 100644 newgrp.tproj/newgrp.c delete mode 100644 passwd.tproj/ds_passwd.c delete mode 100644 passwd.tproj/netinfo_passwd.c create mode 100644 passwd.tproj/od_passwd.c delete mode 100644 pt_chown.tproj/Makefile.postamble delete mode 100644 pt_chown.tproj/Makefile.preamble delete mode 100644 pt_chown.tproj/PB.project delete mode 100644 pt_chown.tproj/pt_chown.c create mode 100644 sysctl.tproj/sysctl.conf.5 create mode 100644 update.tproj/com.apple.update.plist delete mode 100644 update.tproj/disk_power.c delete mode 100644 update.tproj/disk_power.h delete mode 100644 update.tproj/power_mgmt.c delete mode 100644 update.tproj/power_mgmt.h create mode 100644 update.tproj/update.sb delete mode 100644 utmp_update.tproj/Makefile.postamble delete mode 100644 utmp_update.tproj/PB.project delete mode 100644 utmp_update.tproj/utmp_update.c rename {kgmon.tproj => vifs.tproj}/Makefile (85%) create mode 100644 vifs.tproj/Makefile.postamble rename {kgmon.tproj => vifs.tproj}/PB.project (87%) create mode 100644 vifs.tproj/vifs.8 create mode 100644 vifs.tproj/vifs.c delete mode 100644 zic.tproj/HACK/Africa/Abidjan delete mode 100644 zic.tproj/HACK/Africa/Accra delete mode 100644 zic.tproj/HACK/Africa/Addis_Ababa delete mode 100644 zic.tproj/HACK/Africa/Algiers delete mode 100644 zic.tproj/HACK/Africa/Asmera delete mode 100644 zic.tproj/HACK/Africa/Bamako delete mode 100644 zic.tproj/HACK/Africa/Bangui delete mode 100644 zic.tproj/HACK/Africa/Banjul delete mode 100644 zic.tproj/HACK/Africa/Bissau delete mode 100644 zic.tproj/HACK/Africa/Blantyre delete mode 100644 zic.tproj/HACK/Africa/Brazzaville delete mode 100644 zic.tproj/HACK/Africa/Bujumbura delete mode 100644 zic.tproj/HACK/Africa/Cairo delete mode 100644 zic.tproj/HACK/Africa/Casablanca delete mode 100644 zic.tproj/HACK/Africa/Ceuta delete mode 100644 zic.tproj/HACK/Africa/Conakry delete mode 100644 zic.tproj/HACK/Africa/Dakar delete mode 100644 zic.tproj/HACK/Africa/Dar_es_Salaam delete mode 100644 zic.tproj/HACK/Africa/Djibouti delete mode 100644 zic.tproj/HACK/Africa/Douala delete mode 100644 zic.tproj/HACK/Africa/El_Aaiun delete mode 100644 zic.tproj/HACK/Africa/Freetown delete mode 100644 zic.tproj/HACK/Africa/Gaborone delete mode 100644 zic.tproj/HACK/Africa/Harare delete mode 100644 zic.tproj/HACK/Africa/Johannesburg delete mode 100644 zic.tproj/HACK/Africa/Kampala delete mode 100644 zic.tproj/HACK/Africa/Khartoum delete mode 100644 zic.tproj/HACK/Africa/Kigali delete mode 100644 zic.tproj/HACK/Africa/Kinshasa delete mode 100644 zic.tproj/HACK/Africa/Lagos delete mode 100644 zic.tproj/HACK/Africa/Libreville delete mode 100644 zic.tproj/HACK/Africa/Lome delete mode 100644 zic.tproj/HACK/Africa/Luanda delete mode 100644 zic.tproj/HACK/Africa/Lubumbashi delete mode 100644 zic.tproj/HACK/Africa/Lusaka delete mode 100644 zic.tproj/HACK/Africa/Malabo delete mode 100644 zic.tproj/HACK/Africa/Maputo delete mode 100644 zic.tproj/HACK/Africa/Maseru delete mode 100644 zic.tproj/HACK/Africa/Mbabane delete mode 100644 zic.tproj/HACK/Africa/Mogadishu delete mode 100644 zic.tproj/HACK/Africa/Monrovia delete mode 100644 zic.tproj/HACK/Africa/Nairobi delete mode 100644 zic.tproj/HACK/Africa/Ndjamena delete mode 100644 zic.tproj/HACK/Africa/Niamey delete mode 100644 zic.tproj/HACK/Africa/Nouakchott delete mode 100644 zic.tproj/HACK/Africa/Ouagadougou delete mode 100644 zic.tproj/HACK/Africa/Porto-Novo delete mode 100644 zic.tproj/HACK/Africa/Sao_Tome delete mode 100644 zic.tproj/HACK/Africa/Timbuktu delete mode 100644 zic.tproj/HACK/Africa/Tripoli delete mode 100644 zic.tproj/HACK/Africa/Tunis delete mode 100644 zic.tproj/HACK/Africa/Windhoek delete mode 100644 zic.tproj/HACK/America/Adak delete mode 100644 zic.tproj/HACK/America/Anchorage delete mode 100644 zic.tproj/HACK/America/Anguilla delete mode 100644 zic.tproj/HACK/America/Antigua delete mode 100644 zic.tproj/HACK/America/Aruba delete mode 100644 zic.tproj/HACK/America/Asuncion delete mode 100644 zic.tproj/HACK/America/Atka delete mode 100644 zic.tproj/HACK/America/Barbados delete mode 100644 zic.tproj/HACK/America/Belize delete mode 100644 zic.tproj/HACK/America/Bogota delete mode 100644 zic.tproj/HACK/America/Boise delete mode 100644 zic.tproj/HACK/America/Buenos_Aires delete mode 100644 zic.tproj/HACK/America/Caracas delete mode 100644 zic.tproj/HACK/America/Catamarca delete mode 100644 zic.tproj/HACK/America/Cayenne delete mode 100644 zic.tproj/HACK/America/Cayman delete mode 100644 zic.tproj/HACK/America/Chicago delete mode 100644 zic.tproj/HACK/America/Cordoba delete mode 100644 zic.tproj/HACK/America/Costa_Rica delete mode 100644 zic.tproj/HACK/America/Cuiaba delete mode 100644 zic.tproj/HACK/America/Curacao delete mode 100644 zic.tproj/HACK/America/Dawson delete mode 100644 zic.tproj/HACK/America/Dawson_Creek delete mode 100644 zic.tproj/HACK/America/Denver delete mode 100644 zic.tproj/HACK/America/Detroit delete mode 100644 zic.tproj/HACK/America/Dominica delete mode 100644 zic.tproj/HACK/America/Edmonton delete mode 100644 zic.tproj/HACK/America/El_Salvador delete mode 100644 zic.tproj/HACK/America/Ensenada delete mode 100644 zic.tproj/HACK/America/Fort_Wayne delete mode 100644 zic.tproj/HACK/America/Fortaleza delete mode 100644 zic.tproj/HACK/America/Glace_Bay delete mode 100644 zic.tproj/HACK/America/Godthab delete mode 100644 zic.tproj/HACK/America/Goose_Bay delete mode 100644 zic.tproj/HACK/America/Grand_Turk delete mode 100644 zic.tproj/HACK/America/Grenada delete mode 100644 zic.tproj/HACK/America/Guadeloupe delete mode 100644 zic.tproj/HACK/America/Guatemala delete mode 100644 zic.tproj/HACK/America/Guayaquil delete mode 100644 zic.tproj/HACK/America/Guyana delete mode 100644 zic.tproj/HACK/America/Halifax delete mode 100644 zic.tproj/HACK/America/Havana delete mode 100644 zic.tproj/HACK/America/Indiana/Indianapolis delete mode 100644 zic.tproj/HACK/America/Indiana/Knox delete mode 100644 zic.tproj/HACK/America/Indiana/Marengo delete mode 100644 zic.tproj/HACK/America/Indiana/Vevay delete mode 100644 zic.tproj/HACK/America/Indianapolis delete mode 100644 zic.tproj/HACK/America/Inuvik delete mode 100644 zic.tproj/HACK/America/Iqaluit delete mode 100644 zic.tproj/HACK/America/Jamaica delete mode 100644 zic.tproj/HACK/America/Jujuy delete mode 100644 zic.tproj/HACK/America/Juneau delete mode 100644 zic.tproj/HACK/America/Knox_IN delete mode 100644 zic.tproj/HACK/America/La_Paz delete mode 100644 zic.tproj/HACK/America/Lima delete mode 100644 zic.tproj/HACK/America/Los_Angeles delete mode 100644 zic.tproj/HACK/America/Louisville delete mode 100644 zic.tproj/HACK/America/Maceio delete mode 100644 zic.tproj/HACK/America/Managua delete mode 100644 zic.tproj/HACK/America/Manaus delete mode 100644 zic.tproj/HACK/America/Martinique delete mode 100644 zic.tproj/HACK/America/Mazatlan delete mode 100644 zic.tproj/HACK/America/Mendoza delete mode 100644 zic.tproj/HACK/America/Menominee delete mode 100644 zic.tproj/HACK/America/Mexico_City delete mode 100644 zic.tproj/HACK/America/Miquelon delete mode 100644 zic.tproj/HACK/America/Montevideo delete mode 100644 zic.tproj/HACK/America/Montreal delete mode 100644 zic.tproj/HACK/America/Montserrat delete mode 100644 zic.tproj/HACK/America/Nassau delete mode 100644 zic.tproj/HACK/America/New_York delete mode 100644 zic.tproj/HACK/America/Nipigon delete mode 100644 zic.tproj/HACK/America/Nome delete mode 100644 zic.tproj/HACK/America/Noronha delete mode 100644 zic.tproj/HACK/America/Panama delete mode 100644 zic.tproj/HACK/America/Pangnirtung delete mode 100644 zic.tproj/HACK/America/Paramaribo delete mode 100644 zic.tproj/HACK/America/Phoenix delete mode 100644 zic.tproj/HACK/America/Port-au-Prince delete mode 100644 zic.tproj/HACK/America/Port_of_Spain delete mode 100644 zic.tproj/HACK/America/Porto_Acre delete mode 100644 zic.tproj/HACK/America/Puerto_Rico delete mode 100644 zic.tproj/HACK/America/Rainy_River delete mode 100644 zic.tproj/HACK/America/Rankin_Inlet delete mode 100644 zic.tproj/HACK/America/Regina delete mode 100644 zic.tproj/HACK/America/Rosario delete mode 100644 zic.tproj/HACK/America/Santiago delete mode 100644 zic.tproj/HACK/America/Santo_Domingo delete mode 100644 zic.tproj/HACK/America/Sao_Paulo delete mode 100644 zic.tproj/HACK/America/Scoresbysund delete mode 100644 zic.tproj/HACK/America/Shiprock delete mode 100644 zic.tproj/HACK/America/St_Johns delete mode 100644 zic.tproj/HACK/America/St_Kitts delete mode 100644 zic.tproj/HACK/America/St_Lucia delete mode 100644 zic.tproj/HACK/America/St_Thomas delete mode 100644 zic.tproj/HACK/America/St_Vincent delete mode 100644 zic.tproj/HACK/America/Swift_Current delete mode 100644 zic.tproj/HACK/America/Tegucigalpa delete mode 100644 zic.tproj/HACK/America/Thule delete mode 100644 zic.tproj/HACK/America/Thunder_Bay delete mode 100644 zic.tproj/HACK/America/Tijuana delete mode 100644 zic.tproj/HACK/America/Tortola delete mode 100644 zic.tproj/HACK/America/Vancouver delete mode 100644 zic.tproj/HACK/America/Virgin delete mode 100644 zic.tproj/HACK/America/Whitehorse delete mode 100644 zic.tproj/HACK/America/Winnipeg delete mode 100644 zic.tproj/HACK/America/Yakutat delete mode 100644 zic.tproj/HACK/America/Yellowknife delete mode 100644 zic.tproj/HACK/Antarctica/Casey delete mode 100644 zic.tproj/HACK/Antarctica/Mawson delete mode 100644 zic.tproj/HACK/Antarctica/McMurdo delete mode 100644 zic.tproj/HACK/Antarctica/Palmer delete mode 100644 zic.tproj/HACK/Antarctica/South_Pole delete mode 100644 zic.tproj/HACK/Arctic/Longyearbyen delete mode 100644 zic.tproj/HACK/Asia/Aden delete mode 100644 zic.tproj/HACK/Asia/Alma-Ata delete mode 100644 zic.tproj/HACK/Asia/Amman delete mode 100644 zic.tproj/HACK/Asia/Anadyr delete mode 100644 zic.tproj/HACK/Asia/Aqtau delete mode 100644 zic.tproj/HACK/Asia/Aqtobe delete mode 100644 zic.tproj/HACK/Asia/Ashkhabad delete mode 100644 zic.tproj/HACK/Asia/Baghdad delete mode 100644 zic.tproj/HACK/Asia/Bahrain delete mode 100644 zic.tproj/HACK/Asia/Baku delete mode 100644 zic.tproj/HACK/Asia/Bangkok delete mode 100644 zic.tproj/HACK/Asia/Beirut delete mode 100644 zic.tproj/HACK/Asia/Bishkek delete mode 100644 zic.tproj/HACK/Asia/Brunei delete mode 100644 zic.tproj/HACK/Asia/Calcutta delete mode 100644 zic.tproj/HACK/Asia/Chungking delete mode 100644 zic.tproj/HACK/Asia/Colombo delete mode 100644 zic.tproj/HACK/Asia/Dacca delete mode 100644 zic.tproj/HACK/Asia/Damascus delete mode 100644 zic.tproj/HACK/Asia/Dubai delete mode 100644 zic.tproj/HACK/Asia/Dushanbe delete mode 100644 zic.tproj/HACK/Asia/Gaza delete mode 100644 zic.tproj/HACK/Asia/Harbin delete mode 100644 zic.tproj/HACK/Asia/Hong_Kong delete mode 100644 zic.tproj/HACK/Asia/Irkutsk delete mode 100644 zic.tproj/HACK/Asia/Ishigaki delete mode 100644 zic.tproj/HACK/Asia/Istanbul delete mode 100644 zic.tproj/HACK/Asia/Jakarta delete mode 100644 zic.tproj/HACK/Asia/Jayapura delete mode 100644 zic.tproj/HACK/Asia/Jerusalem delete mode 100644 zic.tproj/HACK/Asia/Kabul delete mode 100644 zic.tproj/HACK/Asia/Kamchatka delete mode 100644 zic.tproj/HACK/Asia/Karachi delete mode 100644 zic.tproj/HACK/Asia/Kashgar delete mode 100644 zic.tproj/HACK/Asia/Katmandu delete mode 100644 zic.tproj/HACK/Asia/Krasnoyarsk delete mode 100644 zic.tproj/HACK/Asia/Kuala_Lumpur delete mode 100644 zic.tproj/HACK/Asia/Kuching delete mode 100644 zic.tproj/HACK/Asia/Kuwait delete mode 100644 zic.tproj/HACK/Asia/Macao delete mode 100644 zic.tproj/HACK/Asia/Magadan delete mode 100644 zic.tproj/HACK/Asia/Manila delete mode 100644 zic.tproj/HACK/Asia/Muscat delete mode 100644 zic.tproj/HACK/Asia/Nicosia delete mode 100644 zic.tproj/HACK/Asia/Novosibirsk delete mode 100644 zic.tproj/HACK/Asia/Omsk delete mode 100644 zic.tproj/HACK/Asia/Phnom_Penh delete mode 100644 zic.tproj/HACK/Asia/Pyongyang delete mode 100644 zic.tproj/HACK/Asia/Qatar delete mode 100644 zic.tproj/HACK/Asia/Rangoon delete mode 100644 zic.tproj/HACK/Asia/Riyadh delete mode 100644 zic.tproj/HACK/Asia/Riyadh87 delete mode 100644 zic.tproj/HACK/Asia/Riyadh88 delete mode 100644 zic.tproj/HACK/Asia/Riyadh89 delete mode 100644 zic.tproj/HACK/Asia/Saigon delete mode 100644 zic.tproj/HACK/Asia/Seoul delete mode 100644 zic.tproj/HACK/Asia/Shanghai delete mode 100644 zic.tproj/HACK/Asia/Singapore delete mode 100644 zic.tproj/HACK/Asia/Taipei delete mode 100644 zic.tproj/HACK/Asia/Tashkent delete mode 100644 zic.tproj/HACK/Asia/Tbilisi delete mode 100644 zic.tproj/HACK/Asia/Tehran delete mode 100644 zic.tproj/HACK/Asia/Tel_Aviv delete mode 100644 zic.tproj/HACK/Asia/Thimbu delete mode 100644 zic.tproj/HACK/Asia/Tokyo delete mode 100644 zic.tproj/HACK/Asia/Ujung_Pandang delete mode 100644 zic.tproj/HACK/Asia/Ulan_Bator delete mode 100644 zic.tproj/HACK/Asia/Urumqi delete mode 100644 zic.tproj/HACK/Asia/Vientiane delete mode 100644 zic.tproj/HACK/Asia/Vladivostok delete mode 100644 zic.tproj/HACK/Asia/Yakutsk delete mode 100644 zic.tproj/HACK/Asia/Yekaterinburg delete mode 100644 zic.tproj/HACK/Asia/Yerevan delete mode 100644 zic.tproj/HACK/Atlantic/Azores delete mode 100644 zic.tproj/HACK/Atlantic/Bermuda delete mode 100644 zic.tproj/HACK/Atlantic/Canary delete mode 100644 zic.tproj/HACK/Atlantic/Cape_Verde delete mode 100644 zic.tproj/HACK/Atlantic/Faeroe delete mode 100644 zic.tproj/HACK/Atlantic/Jan_Mayen delete mode 100644 zic.tproj/HACK/Atlantic/Madeira delete mode 100644 zic.tproj/HACK/Atlantic/Reykjavik delete mode 100644 zic.tproj/HACK/Atlantic/South_Georgia delete mode 100644 zic.tproj/HACK/Atlantic/St_Helena delete mode 100644 zic.tproj/HACK/Atlantic/Stanley delete mode 100644 zic.tproj/HACK/Australia/ACT delete mode 100644 zic.tproj/HACK/Australia/Adelaide delete mode 100644 zic.tproj/HACK/Australia/Brisbane delete mode 100644 zic.tproj/HACK/Australia/Broken_Hill delete mode 100644 zic.tproj/HACK/Australia/Canberra delete mode 100644 zic.tproj/HACK/Australia/Darwin delete mode 100644 zic.tproj/HACK/Australia/Hobart delete mode 100644 zic.tproj/HACK/Australia/LHI delete mode 100644 zic.tproj/HACK/Australia/Lindeman delete mode 100644 zic.tproj/HACK/Australia/Lord_Howe delete mode 100644 zic.tproj/HACK/Australia/Melbourne delete mode 100644 zic.tproj/HACK/Australia/NSW delete mode 100644 zic.tproj/HACK/Australia/North delete mode 100644 zic.tproj/HACK/Australia/Perth delete mode 100644 zic.tproj/HACK/Australia/Queensland delete mode 100644 zic.tproj/HACK/Australia/South delete mode 100644 zic.tproj/HACK/Australia/Sydney delete mode 100644 zic.tproj/HACK/Australia/Tasmania delete mode 100644 zic.tproj/HACK/Australia/Victoria delete mode 100644 zic.tproj/HACK/Australia/West delete mode 100644 zic.tproj/HACK/Australia/Yancowinna delete mode 100644 zic.tproj/HACK/Brazil/Acre delete mode 100644 zic.tproj/HACK/Brazil/DeNoronha delete mode 100644 zic.tproj/HACK/Brazil/East delete mode 100644 zic.tproj/HACK/Brazil/West delete mode 100644 zic.tproj/HACK/CET delete mode 100644 zic.tproj/HACK/CST6CDT delete mode 100644 zic.tproj/HACK/Canada/Atlantic delete mode 100644 zic.tproj/HACK/Canada/Central delete mode 100644 zic.tproj/HACK/Canada/East-Saskatchewan delete mode 100644 zic.tproj/HACK/Canada/Eastern delete mode 100644 zic.tproj/HACK/Canada/Mountain delete mode 100644 zic.tproj/HACK/Canada/Newfoundland delete mode 100644 zic.tproj/HACK/Canada/Pacific delete mode 100644 zic.tproj/HACK/Canada/Saskatchewan delete mode 100644 zic.tproj/HACK/Canada/Yukon delete mode 100644 zic.tproj/HACK/Chile/Continental delete mode 100644 zic.tproj/HACK/Chile/EasterIsland delete mode 100644 zic.tproj/HACK/Cuba delete mode 100644 zic.tproj/HACK/EET delete mode 100644 zic.tproj/HACK/EST delete mode 100644 zic.tproj/HACK/EST5EDT delete mode 100644 zic.tproj/HACK/Egypt delete mode 100644 zic.tproj/HACK/Eire delete mode 100644 zic.tproj/HACK/Etc/GMT delete mode 100644 zic.tproj/HACK/Etc/GMT+0 delete mode 100644 zic.tproj/HACK/Etc/GMT+1 delete mode 100644 zic.tproj/HACK/Etc/GMT+10 delete mode 100644 zic.tproj/HACK/Etc/GMT+11 delete mode 100644 zic.tproj/HACK/Etc/GMT+12 delete mode 100644 zic.tproj/HACK/Etc/GMT+2 delete mode 100644 zic.tproj/HACK/Etc/GMT+3 delete mode 100644 zic.tproj/HACK/Etc/GMT+4 delete mode 100644 zic.tproj/HACK/Etc/GMT+5 delete mode 100644 zic.tproj/HACK/Etc/GMT+6 delete mode 100644 zic.tproj/HACK/Etc/GMT+7 delete mode 100644 zic.tproj/HACK/Etc/GMT+8 delete mode 100644 zic.tproj/HACK/Etc/GMT+9 delete mode 100644 zic.tproj/HACK/Etc/GMT-0 delete mode 100644 zic.tproj/HACK/Etc/GMT-1 delete mode 100644 zic.tproj/HACK/Etc/GMT-10 delete mode 100644 zic.tproj/HACK/Etc/GMT-11 delete mode 100644 zic.tproj/HACK/Etc/GMT-12 delete mode 100644 zic.tproj/HACK/Etc/GMT-13 delete mode 100644 zic.tproj/HACK/Etc/GMT-14 delete mode 100644 zic.tproj/HACK/Etc/GMT-2 delete mode 100644 zic.tproj/HACK/Etc/GMT-3 delete mode 100644 zic.tproj/HACK/Etc/GMT-4 delete mode 100644 zic.tproj/HACK/Etc/GMT-5 delete mode 100644 zic.tproj/HACK/Etc/GMT-6 delete mode 100644 zic.tproj/HACK/Etc/GMT-7 delete mode 100644 zic.tproj/HACK/Etc/GMT-8 delete mode 100644 zic.tproj/HACK/Etc/GMT-9 delete mode 100644 zic.tproj/HACK/Etc/GMT0 delete mode 100644 zic.tproj/HACK/Etc/Greenwich delete mode 100644 zic.tproj/HACK/Etc/UCT delete mode 100644 zic.tproj/HACK/Etc/UTC delete mode 100644 zic.tproj/HACK/Etc/Universal delete mode 100644 zic.tproj/HACK/Etc/Zulu delete mode 100644 zic.tproj/HACK/Europe/Amsterdam delete mode 100644 zic.tproj/HACK/Europe/Andorra delete mode 100644 zic.tproj/HACK/Europe/Athens delete mode 100644 zic.tproj/HACK/Europe/Belfast delete mode 100644 zic.tproj/HACK/Europe/Belgrade delete mode 100644 zic.tproj/HACK/Europe/Berlin delete mode 100644 zic.tproj/HACK/Europe/Bratislava delete mode 100644 zic.tproj/HACK/Europe/Brussels delete mode 100644 zic.tproj/HACK/Europe/Bucharest delete mode 100644 zic.tproj/HACK/Europe/Budapest delete mode 100644 zic.tproj/HACK/Europe/Chisinau delete mode 100644 zic.tproj/HACK/Europe/Copenhagen delete mode 100644 zic.tproj/HACK/Europe/Dublin delete mode 100644 zic.tproj/HACK/Europe/Gibraltar delete mode 100644 zic.tproj/HACK/Europe/Helsinki delete mode 100644 zic.tproj/HACK/Europe/Istanbul delete mode 100644 zic.tproj/HACK/Europe/Kaliningrad delete mode 100644 zic.tproj/HACK/Europe/Kiev delete mode 100644 zic.tproj/HACK/Europe/Lisbon delete mode 100644 zic.tproj/HACK/Europe/Ljubljana delete mode 100644 zic.tproj/HACK/Europe/London delete mode 100644 zic.tproj/HACK/Europe/Luxembourg delete mode 100644 zic.tproj/HACK/Europe/Madrid delete mode 100644 zic.tproj/HACK/Europe/Malta delete mode 100644 zic.tproj/HACK/Europe/Minsk delete mode 100644 zic.tproj/HACK/Europe/Monaco delete mode 100644 zic.tproj/HACK/Europe/Moscow delete mode 100644 zic.tproj/HACK/Europe/Oslo delete mode 100644 zic.tproj/HACK/Europe/Paris delete mode 100644 zic.tproj/HACK/Europe/Prague delete mode 100644 zic.tproj/HACK/Europe/Riga delete mode 100644 zic.tproj/HACK/Europe/Rome delete mode 100644 zic.tproj/HACK/Europe/Samara delete mode 100644 zic.tproj/HACK/Europe/San_Marino delete mode 100644 zic.tproj/HACK/Europe/Sarajevo delete mode 100644 zic.tproj/HACK/Europe/Simferopol delete mode 100644 zic.tproj/HACK/Europe/Skopje delete mode 100644 zic.tproj/HACK/Europe/Sofia delete mode 100644 zic.tproj/HACK/Europe/Stockholm delete mode 100644 zic.tproj/HACK/Europe/Tallinn delete mode 100644 zic.tproj/HACK/Europe/Tirane delete mode 100644 zic.tproj/HACK/Europe/Vaduz delete mode 100644 zic.tproj/HACK/Europe/Vatican delete mode 100644 zic.tproj/HACK/Europe/Vienna delete mode 100644 zic.tproj/HACK/Europe/Vilnius delete mode 100644 zic.tproj/HACK/Europe/Warsaw delete mode 100644 zic.tproj/HACK/Europe/Zagreb delete mode 100644 zic.tproj/HACK/Europe/Zurich delete mode 100644 zic.tproj/HACK/Factory delete mode 100644 zic.tproj/HACK/GB delete mode 100644 zic.tproj/HACK/GMT delete mode 100644 zic.tproj/HACK/GMT+0 delete mode 100644 zic.tproj/HACK/GMT-0 delete mode 100644 zic.tproj/HACK/GMT0 delete mode 100644 zic.tproj/HACK/Greenwich delete mode 100644 zic.tproj/HACK/HST delete mode 100644 zic.tproj/HACK/Hongkong delete mode 100644 zic.tproj/HACK/Iceland delete mode 100644 zic.tproj/HACK/Indian/Antananarivo delete mode 100644 zic.tproj/HACK/Indian/Chagos delete mode 100644 zic.tproj/HACK/Indian/Christmas delete mode 100644 zic.tproj/HACK/Indian/Cocos delete mode 100644 zic.tproj/HACK/Indian/Comoro delete mode 100644 zic.tproj/HACK/Indian/Mahe delete mode 100644 zic.tproj/HACK/Indian/Maldives delete mode 100644 zic.tproj/HACK/Indian/Mauritius delete mode 100644 zic.tproj/HACK/Indian/Mayotte delete mode 100644 zic.tproj/HACK/Indian/Reunion delete mode 100644 zic.tproj/HACK/Iran delete mode 100644 zic.tproj/HACK/Israel delete mode 100644 zic.tproj/HACK/Jamaica delete mode 100644 zic.tproj/HACK/Japan delete mode 100644 zic.tproj/HACK/Kwajalein delete mode 100644 zic.tproj/HACK/Libya delete mode 100644 zic.tproj/HACK/MET delete mode 100644 zic.tproj/HACK/MST delete mode 100644 zic.tproj/HACK/MST7MDT delete mode 100644 zic.tproj/HACK/Mexico/BajaNorte delete mode 100644 zic.tproj/HACK/Mexico/BajaSur delete mode 100644 zic.tproj/HACK/Mexico/General delete mode 100644 zic.tproj/HACK/Mideast/Riyadh87 delete mode 100644 zic.tproj/HACK/Mideast/Riyadh88 delete mode 100644 zic.tproj/HACK/Mideast/Riyadh89 delete mode 100644 zic.tproj/HACK/NZ delete mode 100644 zic.tproj/HACK/NZ-CHAT delete mode 100644 zic.tproj/HACK/Navajo delete mode 100644 zic.tproj/HACK/PRC delete mode 100644 zic.tproj/HACK/PST8PDT delete mode 100644 zic.tproj/HACK/Pacific/Apia delete mode 100644 zic.tproj/HACK/Pacific/Auckland delete mode 100644 zic.tproj/HACK/Pacific/Chatham delete mode 100644 zic.tproj/HACK/Pacific/Easter delete mode 100644 zic.tproj/HACK/Pacific/Efate delete mode 100644 zic.tproj/HACK/Pacific/Enderbury delete mode 100644 zic.tproj/HACK/Pacific/Fakaofo delete mode 100644 zic.tproj/HACK/Pacific/Fiji delete mode 100644 zic.tproj/HACK/Pacific/Funafuti delete mode 100644 zic.tproj/HACK/Pacific/Galapagos delete mode 100644 zic.tproj/HACK/Pacific/Gambier delete mode 100644 zic.tproj/HACK/Pacific/Guadalcanal delete mode 100644 zic.tproj/HACK/Pacific/Guam delete mode 100644 zic.tproj/HACK/Pacific/Honolulu delete mode 100644 zic.tproj/HACK/Pacific/Johnston delete mode 100644 zic.tproj/HACK/Pacific/Kiritimati delete mode 100644 zic.tproj/HACK/Pacific/Kosrae delete mode 100644 zic.tproj/HACK/Pacific/Kwajalein delete mode 100644 zic.tproj/HACK/Pacific/Majuro delete mode 100644 zic.tproj/HACK/Pacific/Marquesas delete mode 100644 zic.tproj/HACK/Pacific/Midway delete mode 100644 zic.tproj/HACK/Pacific/Nauru delete mode 100644 zic.tproj/HACK/Pacific/Niue delete mode 100644 zic.tproj/HACK/Pacific/Norfolk delete mode 100644 zic.tproj/HACK/Pacific/Noumea delete mode 100644 zic.tproj/HACK/Pacific/Pago_Pago delete mode 100644 zic.tproj/HACK/Pacific/Palau delete mode 100644 zic.tproj/HACK/Pacific/Pitcairn delete mode 100644 zic.tproj/HACK/Pacific/Ponape delete mode 100644 zic.tproj/HACK/Pacific/Port_Moresby delete mode 100644 zic.tproj/HACK/Pacific/Rarotonga delete mode 100644 zic.tproj/HACK/Pacific/Saipan delete mode 100644 zic.tproj/HACK/Pacific/Samoa delete mode 100644 zic.tproj/HACK/Pacific/Tahiti delete mode 100644 zic.tproj/HACK/Pacific/Tarawa delete mode 100644 zic.tproj/HACK/Pacific/Tongatapu delete mode 100644 zic.tproj/HACK/Pacific/Truk delete mode 100644 zic.tproj/HACK/Pacific/Wake delete mode 100644 zic.tproj/HACK/Pacific/Wallis delete mode 100644 zic.tproj/HACK/Pacific/Yap delete mode 100644 zic.tproj/HACK/Poland delete mode 100644 zic.tproj/HACK/Portugal delete mode 100644 zic.tproj/HACK/ROC delete mode 100644 zic.tproj/HACK/ROK delete mode 100644 zic.tproj/HACK/Singapore delete mode 100644 zic.tproj/HACK/SystemV/AST4 delete mode 100644 zic.tproj/HACK/SystemV/AST4ADT delete mode 100644 zic.tproj/HACK/SystemV/CST6 delete mode 100644 zic.tproj/HACK/SystemV/CST6CDT delete mode 100644 zic.tproj/HACK/SystemV/EST5 delete mode 100644 zic.tproj/HACK/SystemV/EST5EDT delete mode 100644 zic.tproj/HACK/SystemV/HST10 delete mode 100644 zic.tproj/HACK/SystemV/MST7 delete mode 100644 zic.tproj/HACK/SystemV/MST7MDT delete mode 100644 zic.tproj/HACK/SystemV/PST8 delete mode 100644 zic.tproj/HACK/SystemV/PST8PDT delete mode 100644 zic.tproj/HACK/SystemV/YST9 delete mode 100644 zic.tproj/HACK/SystemV/YST9YDT delete mode 100644 zic.tproj/HACK/Turkey delete mode 100644 zic.tproj/HACK/UCT delete mode 100644 zic.tproj/HACK/US/Alaska delete mode 100644 zic.tproj/HACK/US/Aleutian delete mode 100644 zic.tproj/HACK/US/Arizona delete mode 100644 zic.tproj/HACK/US/Central delete mode 100644 zic.tproj/HACK/US/East-Indiana delete mode 100644 zic.tproj/HACK/US/Eastern delete mode 100644 zic.tproj/HACK/US/Hawaii delete mode 100644 zic.tproj/HACK/US/Indiana-Starke delete mode 100644 zic.tproj/HACK/US/Michigan delete mode 100644 zic.tproj/HACK/US/Mountain delete mode 100644 zic.tproj/HACK/US/Pacific delete mode 100644 zic.tproj/HACK/US/Pacific-New delete mode 100644 zic.tproj/HACK/US/Samoa delete mode 100644 zic.tproj/HACK/UTC delete mode 100644 zic.tproj/HACK/Universal delete mode 100644 zic.tproj/HACK/W-SU delete mode 100644 zic.tproj/HACK/WET delete mode 100644 zic.tproj/HACK/Zulu delete mode 100644 zic.tproj/datfiles/Theory delete mode 100644 zic.tproj/datfiles/tzdata2007h.tar.gz diff --git a/Makefile b/Makefile index 6377bda..bde6f0c 100644 --- a/Makefile +++ b/Makefile @@ -12,17 +12,25 @@ NAME = system_cmds PROJECTVERSION = 2.8 PROJECT_TYPE = Aggregate -TOOLS = dynamic_pager.tproj ac.tproj accton.tproj arch.tproj at.tproj\ - auditd.tproj audit.tproj\ - atrun.tproj chkpasswd.tproj chpass.tproj dmesg.tproj\ - getconf.tproj getty.tproj hostinfo.tproj iostat.tproj kgmon.tproj\ - ktrace.tproj login.tproj makekey.tproj\ - mkfile.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\ - reboot.tproj shutdown.tproj sync.tproj sysctl.tproj\ - update.tproj vipw.tproj zic.tproj zdump.tproj vm_stat.tproj\ +Embedded=$(shell tconf --test TARGET_OS_EMBEDDED) + +TOOLS = dynamic_pager.tproj ac.tproj accton.tproj arch.tproj\ + bootlog.tproj\ + dirhelper.tproj dmesg.tproj\ + getconf.tproj getty.tproj hostinfo.tproj iostat.tproj\ + login.tproj makekey.tproj\ + mkfile.tproj newgrp.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\ + reboot.tproj sync.tproj sysctl.tproj\ + update.tproj vipw.tproj vifs.tproj zic.tproj zdump.tproj vm_stat.tproj\ zprint.tproj latency.tproj sc_usage.tproj fs_usage.tproj\ - kdump.tproj sadc.tproj sar.tproj pt_chown.tproj sa.tproj\ - utmp_update.tproj + sadc.tproj sar.tproj sa.tproj + +ifeq "$(Embedded)" "NO" +TOOLS += at.tproj atrun.tproj\ + auditd.tproj audit.tproj\ + chkpasswd.tproj chpass.tproj\ + shutdown.tproj +endif LIBRARIES = dp_notify_lib diff --git a/Makefile.preamble b/Makefile.preamble index 7d83496..bb77a84 100644 --- a/Makefile.preamble +++ b/Makefile.preamble @@ -1,3 +1,6 @@ CLEAN_ALL_SUBPROJECTS = YES SUBPROJECTS = OTHER_CFLAGS = -mdynamic-no-pic +ifeq "$(shell tconf --test TARGET_OS_EMBEDDED)" "YES" +OTHER_LDFLAGS = -dead_strip +endif diff --git a/PB.project b/PB.project index 300cc26..e6e80d6 100644 --- a/PB.project +++ b/PB.project @@ -24,16 +24,17 @@ "auditd.tproj", "chkpasswd.tproj", "chpass.tproj", + "dirhelper.tproj", "dmesg.tproj", "getconf.tproj", "getty.tproj", "hostinfo.tproj", "iostat.tproj", "kgmon.tproj", - "ktrace.tproj", "login.tproj", "makekey.tproj", "mkfile.tproj", + "newgrp.tproj", "nologin.tproj", "nvram.tproj", "pagesize.tproj", @@ -52,7 +53,6 @@ "latency.tproj", "sc_usage.tproj", "fs_usage.tproj", - "kdump.tproj", "sadc.tproj", "sar.tproj" ); diff --git a/ac.tproj/ac.8 b/ac.tproj/ac.8 index 0c834a7..dd40a55 100644 --- a/ac.tproj/ac.8 +++ b/ac.tproj/ac.8 @@ -36,7 +36,7 @@ .Os BSD 4 .Sh NAME .Nm ac -.Nd display connect time accounting +.Nd display connect-time accounting .Sh SYNOPSIS .Nm ac .Op Fl d @@ -44,20 +44,17 @@ .Op Fl w Ar file .Op Ar users ... .Sh DESCRIPTION -If the file -.Pa /var/log/wtmp -exists, -a record of individual -login and logout times are written to it by -.Xr init 8 -and +A record of individual +login and logout times are written to the system log by .Xr login 8 +and +.Xr launchd 8 , respectively. The program .Nm ac -examines these -records and writes the accumulated connect time for all logins to the -standard output. +examines these records +and writes the accumulated connect time (in decimal hours) +for all logins to the standard output. .Pp Options available: .Bl -tag -width people @@ -67,41 +64,23 @@ Display the connect times in 24 hour chunks. Display individual user totals. .It Fl w Ar file Read raw connect time data from -.Ar file -instead of the default file -.Pa /var/log/wtmp . +.Ar file , +instead of the system log. .It Ar users ... Display totals for the given individuals only. .El .Pp If no arguments are given, -.Nm -displays the total amount of login time for all active accounts on the -system. -.Pp -The default -.Pa wtmp -file is an infinitely increasing file -unless frequently truncated. This is normally -done by the daily daemon scripts scheduled by -.Xr cron 8 -which rename and rotate the -.Pa wtmp -files before truncating them (and keeping about a weeks worth on hand). -No login times are collected however, if the file does not exist. -.Sh FILES -.Bl -tag -width /var/log/wtmp.[0-7] -compact -.It Pa /var/log/wtmp -.It Pa /var/log/wtmp.[0-7] -rotated files -.El +.Nm ac +displays the total amount of login time +for all active accounts on the system. .Sh SEE ALSO -.Xr init 8 , -.Xr sa 8 , .Xr login 1 , -.Xr utmp 5 . +.Xr utmpx 5 , +.Xr launchd 8 , +.Xr sa 8 .Sh HISTORY -A -.Nm +An +.Nm ac command appeared in Version 6 AT&T UNIX. diff --git a/ac.tproj/ac.c b/ac.tproj/ac.c index f23915c..a6fc154 100644 --- a/ac.tproj/ac.c +++ b/ac.tproj/ac.c @@ -37,7 +37,8 @@ */ #ifndef lint -static char rcsid[] = "$Id: ac.c,v 1.1.1.2 2000/01/11 02:09:57 wsanchez Exp $"; +#include +__unused static char rcsid[] = "$Id: ac.c,v 1.2 2006/02/07 05:51:22 lindak Exp $"; #endif #include @@ -49,15 +50,17 @@ static char rcsid[] = "$Id: ac.c,v 1.1.1.2 2000/01/11 02:09:57 wsanchez Exp $"; #include #include #include -#include +#include #include +#define UT_NAMESIZE 8 /* from utmp.h; only for formatting */ + /* * this is for our list of currently logged in sessions */ struct utmp_list { struct utmp_list *next; - struct utmp usr; + struct utmpx usr; }; /* @@ -65,7 +68,7 @@ struct utmp_list { */ struct user_list { struct user_list *next; - char name[UT_NAMESIZE+1]; + char name[_UTX_USERSIZE+1]; time_t secs; }; @@ -74,7 +77,7 @@ struct user_list { */ struct tty_list { struct tty_list *next; - char name[UT_LINESIZE+3]; + char name[_UTX_USERSIZE+3]; int len; int ret; }; @@ -104,12 +107,11 @@ static int Debug = 0; #endif int main __P((int, char **)); -int ac __P((FILE *)); +int ac __P((void)); struct tty_list *add_tty __P((char *)); int do_tty __P((char *)); -FILE *file __P((char *)); -struct utmp_list *log_in __P((struct utmp_list *, struct utmp *)); -struct utmp_list *log_out __P((struct utmp_list *, struct utmp *)); +struct utmp_list *log_in __P((struct utmp_list *, struct utmpx *)); +struct utmp_list *log_out __P((struct utmp_list *, struct utmpx *)); int on_console __P((struct utmp_list *)); void show __P((char *, time_t)); void show_today __P((struct user_list *, struct utmp_list *, @@ -118,23 +120,6 @@ void show_users __P((struct user_list *)); struct user_list *update_user __P((struct user_list *, char *, time_t)); void usage __P((void)); -/* - * open wtmp or die - */ -FILE * -file(name) - char *name; -{ - FILE *fp; - - if ((fp = fopen(name, "r")) == NULL) - err(1, "%s", name); - /* in case we want to discriminate */ - if (strcmp(_PATH_WTMP, name)) - Flags |= AC_W; - return fp; -} - struct tty_list * add_tty(name) char *name; @@ -273,7 +258,7 @@ main(argc, argv) add_tty(optarg); break; case 'w': - fp = file(optarg); + wtmpxname(optarg); break; case '?': default: @@ -292,16 +277,7 @@ main(argc, argv) } if (Flags & AC_D) Flags &= ~AC_P; - if (fp == NULL) { - /* - * if _PATH_WTMP does not exist, exit quietly - */ - if (access(_PATH_WTMP, 0) != 0 && errno == ENOENT) - return 0; - - fp = file(_PATH_WTMP); - } - ac(fp); + ac(); return 0; } @@ -349,9 +325,9 @@ show_today(users, logins, secs) yesterday++; for (lp = logins; lp != NULL; lp = lp->next) { - secs = yesterday - lp->usr.ut_time; - Users = update_user(Users, lp->usr.ut_name, secs); - lp->usr.ut_time = yesterday; /* as if they just logged in */ + secs = yesterday - lp->usr.ut_tv.tv_sec; + Users = update_user(Users, lp->usr.ut_user, secs); + lp->usr.ut_tv.tv_sec = yesterday; /* as if they just logged in */ } secs = 0; for (up = users; up != NULL; up = up->next) { @@ -370,22 +346,22 @@ show_today(users, logins, secs) struct utmp_list * log_out(head, up) struct utmp_list *head; - struct utmp *up; + struct utmpx *up; { struct utmp_list *lp, *lp2, *tlp; time_t secs; for (lp = head, lp2 = NULL; lp != NULL; ) - if (*up->ut_line == '~' || strncmp(lp->usr.ut_line, up->ut_line, + if (up->ut_type == BOOT_TIME || up->ut_type == SHUTDOWN_TIME || strncmp(lp->usr.ut_line, up->ut_line, sizeof (up->ut_line)) == 0) { - secs = up->ut_time - lp->usr.ut_time; - Users = update_user(Users, lp->usr.ut_name, secs); + secs = up->ut_tv.tv_sec - lp->usr.ut_tv.tv_sec; + Users = update_user(Users, lp->usr.ut_user, secs); #ifdef DEBUG if (Debug) printf("%-.*s %-.*s: %-.*s logged out (%2d:%02d:%02d)\n", - 19, ctime(&up->ut_time), - sizeof (lp->usr.ut_line), lp->usr.ut_line, - sizeof (lp->usr.ut_name), lp->usr.ut_name, + 19, ctime(&up->ut_tv.tv_sec), + (int)sizeof (lp->usr.ut_line), lp->usr.ut_line, + (int)sizeof (lp->usr.ut_user), lp->usr.ut_user, secs / 3600, (secs % 3600) / 60, secs % 60); #endif /* @@ -412,7 +388,7 @@ log_out(head, up) struct utmp_list * log_in(head, up) struct utmp_list *head; - struct utmp *up; + struct utmpx *up; { struct utmp_list *lp; @@ -437,9 +413,9 @@ log_in(head, up) return head; /* * ok, no recorded login, so they were here when wtmp - * started! Adjust ut_time! + * started! Adjust ut_tv.tv_sec! */ - up->ut_time = FirstTime; + up->ut_tv.tv_sec = FirstTime; /* * this allows us to pick the right logout */ @@ -462,14 +438,14 @@ log_in(head, up) err(1, "malloc"); lp->next = head; head = lp; - memmove((char *)&lp->usr, (char *)up, sizeof (struct utmp)); + memmove((char *)&lp->usr, (char *)up, sizeof (struct utmpx)); #ifdef DEBUG if (Debug) { printf("%-.*s %-.*s: %-.*s logged in", 19, - ctime(&lp->usr.ut_time), sizeof (up->ut_line), - up->ut_line, sizeof (up->ut_name), up->ut_name); + ctime(&lp->usr.ut_tv.tv_sec), (int)sizeof (up->ut_line), + up->ut_line, (int)sizeof (up->ut_user), up->ut_user); if (*up->ut_host) - printf(" (%-.*s)", sizeof (up->ut_host), up->ut_host); + printf(" (%-.*s)", (int)sizeof (up->ut_host), up->ut_host); putchar('\n'); } #endif @@ -477,26 +453,26 @@ log_in(head, up) } int -ac(fp) - FILE *fp; +ac() { struct utmp_list *lp, *head = NULL; - struct utmp usr; + struct utmpx *u, end; struct tm *ltm; time_t secs = 0; int day = -1; - while (fread((char *)&usr, sizeof(usr), 1, fp) == 1) { + setutxent_wtmp(1); /* read in forward direction */ + while ((u = getutxent_wtmp()) != NULL) { if (!FirstTime) - FirstTime = usr.ut_time; + FirstTime = u->ut_tv.tv_sec; if (Flags & AC_D) { - ltm = localtime(&usr.ut_time); + ltm = localtime(&u->ut_tv.tv_sec); if (day >= 0 && day != ltm->tm_yday) { day = ltm->tm_yday; /* * print yesterday's total */ - secs = usr.ut_time; + secs = u->ut_tv.tv_sec; secs -= ltm->tm_sec; secs -= 60 * ltm->tm_min; secs -= 3600 * ltm->tm_hour; @@ -504,48 +480,50 @@ ac(fp) } else day = ltm->tm_yday; } - switch(*usr.ut_line) { - case '|': - secs = usr.ut_time; + switch(u->ut_type) { + case OLD_TIME: + secs = u->ut_tv.tv_sec; break; - case '{': - secs -= usr.ut_time; + case NEW_TIME: + secs -= u->ut_tv.tv_sec; /* * adjust time for those logged in */ for (lp = head; lp != NULL; lp = lp->next) - lp->usr.ut_time -= secs; + lp->usr.ut_tv.tv_sec -= secs; break; - case '~': /* reboot or shutdown */ - head = log_out(head, &usr); - FirstTime = usr.ut_time; /* shouldn't be needed */ + case BOOT_TIME: /* reboot or shutdown */ + case SHUTDOWN_TIME: + head = log_out(head, u); + FirstTime = u->ut_tv.tv_sec; /* shouldn't be needed */ break; - default: + case USER_PROCESS: /* * if they came in on tty[p-y]*, then it is only * a login session if the ut_host field is non-empty */ - if (*usr.ut_name) { - if (strncmp(usr.ut_line, "tty", 3) != 0 || - strchr("pqrstuvwxy", usr.ut_line[3]) == 0 || - *usr.ut_host != '\0') - head = log_in(head, &usr); - } else - head = log_out(head, &usr); + if (strncmp(u->ut_line, "tty", 3) != 0 || + strchr("pqrstuvwxy", u->ut_line[3]) == 0 || + *u->ut_host != '\0') + head = log_in(head, u); + break; + case DEAD_PROCESS: + head = log_out(head, u); break; } } - (void)fclose(fp); - usr.ut_time = time((time_t *)0); - (void)strcpy(usr.ut_line, "~"); + endutxent_wtmp(); + bzero(&end, sizeof(end)); + end.ut_tv.tv_sec = time((time_t *)0); + end.ut_type = SHUTDOWN_TIME; if (Flags & AC_D) { - ltm = localtime(&usr.ut_time); + ltm = localtime(&end.ut_tv.tv_sec); if (day >= 0 && day != ltm->tm_yday) { /* * print yesterday's total */ - secs = usr.ut_time; + secs = end.ut_tv.tv_sec; secs -= ltm->tm_sec; secs -= 60 * ltm->tm_min; secs -= 3600 * ltm->tm_hour; @@ -555,7 +533,7 @@ ac(fp) /* * anyone still logged in gets time up to now */ - head = log_out(head, &usr); + head = log_out(head, &end); if (Flags & AC_D) show_today(Users, head, time((time_t *)0)); diff --git a/accton.tproj/Makefile b/accton.tproj/Makefile index 1f7fe19..6444923 100644 --- a/accton.tproj/Makefile +++ b/accton.tproj/Makefile @@ -14,7 +14,7 @@ PROJECT_TYPE = Tool CFILES = accton.c -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble accton.8 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/accton.tproj/Makefile.postamble b/accton.tproj/Makefile.postamble index 70b747f..74be9f9 100644 --- a/accton.tproj/Makefile.postamble +++ b/accton.tproj/Makefile.postamble @@ -107,3 +107,8 @@ # Makefile API), which are rules that get invoked before and after the install # target runs. Such rules should be specified with the '::' syntax rather than # a single colon. + +after_install: + install -d $(DSTROOT)/usr/share/man/man8 + install -m 0444 accton.8 $(DSTROOT)/usr/share/man/man8/accton.8 + diff --git a/accton.tproj/accton.8 b/accton.tproj/accton.8 new file mode 100644 index 0000000..17841a3 --- /dev/null +++ b/accton.tproj/accton.8 @@ -0,0 +1,51 @@ +.\" Copyright (c) 1993 Christopher G. Demetriou +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: accton.8,v 1.2 2005/11/03 05:42:25 lindak Exp $ +.\" +.Dd October 18, 1993 +.Dt ACCTON 8 +.Os BSD 4 +.Sh NAME +.Nm accton +.Nd enable/disable system accounting +.Sh SYNOPSIS +.Nm accton +.Op Ar file +.Sh DESCRIPTION +With an argument naming an existing +.Ar file , +.Nm accton +causes system accounting information for every process executed +to be placed at the end of the file. If no argument is given, +accounting is turned off. +.Sh SEE ALSO +.Xr lastcomm 1 , +.Xr acct 5 +.Sh HISTORY +The +.Nm accton +command has existed nearly forever, but this man page is new. diff --git a/accton.tproj/accton.c b/accton.tproj/accton.c index 723c336..5cb2456 100644 --- a/accton.tproj/accton.c +++ b/accton.tproj/accton.c @@ -54,14 +54,15 @@ * SUCH DAMAGE. */ +#include #ifndef lint -static char copyright[] = +__unused static char copyright[] = "@(#) Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)accton.c 8.1 (Berkeley) 6/6/93"; +__unused static char sccsid[] = "@(#)accton.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #include diff --git a/arch.tproj/Makefile b/arch.tproj/Makefile index c490a16..a055465 100644 --- a/arch.tproj/Makefile +++ b/arch.tproj/Makefile @@ -12,9 +12,10 @@ NAME = arch PROJECTVERSION = 2.8 PROJECT_TYPE = Tool -CFILES = arch.c +MFILES = arch.m +FRAMEWORKS = -framework Foundation -OTHERSRCS = Makefile PB.project Makefile.postamble arch.1 machine.1 +OTHERSRCS = Makefile PB.project Makefile.postamble arch.1 machine.1 arch_helper.pl MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/arch.tproj/Makefile.postamble b/arch.tproj/Makefile.postamble index e031809..70b993c 100644 --- a/arch.tproj/Makefile.postamble +++ b/arch.tproj/Makefile.postamble @@ -1,6 +1,9 @@ +HELPERDIR = /AppleInternal/Developer/Tools after_install:: install -d $(DSTROOT)/usr/share/man/man1 install -c -m 444 arch.1 $(DSTROOT)/usr/share/man/man1 install -c -m 444 machine.1 $(DSTROOT)/usr/share/man/man1 @-$(RM) -f $(DSTROOT)$(INSTALLDIR)/machine ln $(DSTROOT)$(INSTALLDIR)/arch $(DSTROOT)$(INSTALLDIR)/machine + install -d $(DSTROOT)$(HELPERDIR) + install -c -m 755 arch_helper.pl $(DSTROOT)$(HELPERDIR) diff --git a/arch.tproj/arch.1 b/arch.tproj/arch.1 index 71ce882..dcae9ef 100644 --- a/arch.tproj/arch.1 +++ b/arch.tproj/arch.1 @@ -29,18 +29,197 @@ .\" $OpenBSD: arch.1,v 1.2 1996/06/29 20:29:34 tholo Exp $ .\" .\" Modifications made 8/20/97 (c) Apple Computer, Inc. +.\" Modifications made 11/12/06 (c) Apple Computer, Inc. -.Dd August 20, 1997 +.Dd November 12, 2006 .Dt ARCH 1 -.Os Mac OS X +.Os "Mac OS X" .Sh NAME .Nm arch -.Nd print architecture type +.Nd print architecture type or run selected architecture of a universal binary .Sh SYNOPSIS .Nm arch +.Nm arch +.Op Fl h +.Oo +.Oo Fl Ns Ar arch_name | Fl arch Ar arch_name Oc Ns ... +.Oc +.Ar prog +.Op Ar args No ... .Sh DESCRIPTION The .Nm arch -command displays the machine's architecture type. +command with no arguments, displays the machine's architecture type. +.Pp +The other use of the +.Nm arch +command it to run a selected architecture of a universal binary. +A universal binary contains code that can run on different architectures. +By default, the operating system will select the architecture that most closely +matches the processor type. +This means that an intel architecture is selected on intel processors and a +powerpc architecture is selected on powerpc processors. +A 64-bit architecuture is preferred over a 32-bit architecture on a 64-bit +processor, while only 32-bit architectures can run on a 32-bit processor. +.Pp +When the most natural architecture is unavailable, the operating system will +try to pick another architecture. +On 64-bit processors, a 32-bit architecture is tried. +If this is also unavailable, the operating system on an intel processor will +try running a 32-bit powerpc architecture. +Otherwise, no architecture is run, and an error results. +.Pp +The +.Nm arch +command can be use to alter the operating system's normal selection order. +The most common use is to select the 32-bit architecture on a 64-bit processor, +even if a 64-bit architecture is available. +.Pp +The +.Fl h +option prints a usage message and exits. +.Pp +The +.Ar arch_name +argument must be one of the currently supported architectures: +.Bl -tag -width x86_64 -offset indent +.It i386 +32-bit intel +.It ppc +32-bit powerpc +.It ppc64 +64-bit powerpc +.It x86_64 +64-bit intel +.El +.Pp +Either prefix the architecture with a hyphen, or (for compatibility with +other commands), use +.Fl arch +followed by the architecture. +.Pp +If more than one architecture is specified, the operating system will try each +one in order, skipping an architecture that is not supported on the current +processor, or is unavailable in the universal binary. +.Pp +The +.Ar prog +argument is the command to run, followed by any arguments to pass to the +command. +It can be a full or partial path, while a lone name will be lookup in the user's +command search path. +.Pp +If no architectures are specified on the command line, the +.Nm arch +command takes the basename of the +.Ar prog +argument and searches for the first property list file with that basename and +the +.Pa \&.plist +suffix, in the +.Pa archSettings +sub-directory in each of the standard domains, in the following order: +.Bl -tag -width ".Pa /Network/Library/archSettings" -offset indent +.It ~/Library/archSettings +User settings +.It /Library/archSettings +Local settings +.It /Network/Library/archSettings +Network settings +.It /System/Library/archSettings +System settings +.El +.Pp +This property list contains the architecture order preferences, as well +as the full path to the real executable. +For examples of the property list format, look at the files in +.Pa /System/Library/archSettings . +.Ss Example +On an intel processor: +.Bd -literal -offset indent +% perl -MConfig -e 'printf "%s\\n", $Config{byteorder}' +1234 +.Ed +.Pp +shows the intel little endian byte order, while: +.Bd -literal -offset indent +% arch -ppc perl -MConfig -e 'printf "%s\\n", $Config{byteorder}' +4321 +.Ed +.Pp +runs the powerpc architecture, and displays big endian byte order. +.Ss Making links to the arch command +When a link is made to +.Nm arch +command with a different name, that name is used to find +the corresponding property list file. +Thus, other commands can be wrapped so that they have custom architecture +selection order. +.Pp +Because of some internal logic in the code, hard links to the +.Nm arch +command may not work quite right. +It is best to avoid using hard links, and only use symbolic links to the +.Nm arch +command. +.Ss Environment +The environment variable +.Ev ARCHPREFERENCE +can be used to provide architecture order preferences. +It is checked before looking for the corresponding property list file. +.Pp +The value of the environment variable +.Ev ARCHPREFERENCE +is composed of one or more specifiers, separated by semicolons. +A specifier is made up of one, two or three fields, separated by colons. +Architectures specified in order, are separated by commas and make up the last +(mandatory) field. +The first field, if specified, is a name of a program, which selects this +specifier if that name matches the program name in question. +If the name field is empty or there is no name field, the specifier matches +any program name. +Thus, ordering of specifiers is important, and the one with no name should +be last. +.Pp +When the +.Nm arch +command is called directly, the +.Ar prog +name provides the path information to the executable (possibly via the command +search path). +When a name is specified in a +.Ev ARCHPREFERENCE +specifier, the path information can alternately be specified as a second +field following the name. +When the +.Nm arch +command is called indirectly via a link, this path information must be +specified. +If not specified as a second field in a specifier, the executable path will +be looked up in the corresponding property list file. +.Ss Example ARCHPREFERENCE Values +.Bl -tag -width " " +.It ppc,i386,ppc64,x86_64 +A specifier that matches any name. +.It foo:ppc,i386,ppc64,x86_64 +A specifier that matches the program named +.Nm foo +(the full executable path is in the +.Pa foo.plist +file). +.It foo:/op/bin/boo:ppc,i386,ppc64,x86_64 +A specifier with all fields specified. +.It baz:ppc,i386;i386,ppc +A specifier for +.Nm baz +and a second specifier that would match any other name. +.El +.Sh BUGS +Running the +.Nm arch +command on an interpreter script may not work if the interpreter is a link +to the arch command, especially if a 64-bit architecture is specified (since the +.Nm arch +command is 2-way universal, 32-bit only). .Sh SEE ALSO .Xr machine 1 diff --git a/arch.tproj/arch.c b/arch.tproj/arch.c deleted file mode 100644 index 0e140fe..0000000 --- a/arch.tproj/arch.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * arch.c - determine the architecture of the machine ran on - */ - -#include -#include -#include -#include - -char * - get_progname (char *name) -{ - char *tmp; - if (tmp = strrchr(name,'/')) - return tmp+1; - else return name; -} - -int - main (int argc, char **argv) -{ - char *progname; - const NXArchInfo *arch; - - if (argc > 1) - { - fprintf (stderr,"*error: %s takes no arguments\n",argv[0]); - exit (-1); - } - arch = NXGetLocalArchInfo(); - if (arch == NULL) - { - fprintf (stderr,"Unknown architecture.\n"); - exit(-1); - } - progname = get_progname(argv[0]); - if (strcmp (progname,ARCH_PROG) == 0) { - arch = NXGetArchInfoFromCpuType(arch->cputype, CPU_SUBTYPE_MULTIPLE); - if (arch == NULL) - { - fprintf (stderr,"Unknown architecture.\n"); - exit(-1); - } - } - else if (strcmp (progname,MACHINE_PROG) == 0) - ; - else - { - fprintf - (stderr,"*error: This program must be named either %s or %s\n",ARCH_PROG,MACHINE_PROG); - exit (-1); - } - if (!isatty(fileno(stdin))) - printf("%s", arch->name); - else - printf ("%s\n", arch->name); - return 0; -} diff --git a/arch.tproj/arch.m b/arch.tproj/arch.m new file mode 100644 index 0000000..eeeece6 --- /dev/null +++ b/arch.tproj/arch.m @@ -0,0 +1,576 @@ +/* + * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef ARCH_PROG +#define ARCH_PROG "arch" +#endif +#define CPUDELTA 10 +#ifndef MACHINE_PROG +#define MACHINE_PROG "machine" +#endif + +#define CPUCOUNT(c) ((c)->ptr - (c)->buf) + +static NSMutableDictionary *ArchDict; +static NSString *KeyExecPath = @"ExecutablePath"; +static NSString *KeyPlistVersion = @"PropertyListVersion"; +static NSString *KeyPrefOrder = @"PreferredOrder"; +static NSString *PlistExtension = @"plist"; +static NSString *SettingsDir = @"archSettings"; + +static const char envname[] = "ARCHPREFERENCE"; + +typedef struct { + cpu_type_t *buf; + cpu_type_t *ptr; + cpu_type_t *end; + int errs; +} CPU; + +typedef struct { + char *str; + int i; +} StrInt; + +static StrInt initArches[] = { + {"i386", CPU_TYPE_I386}, + {"ppc", CPU_TYPE_POWERPC}, + {"ppc64", CPU_TYPE_POWERPC64}, + {"x86_64", CPU_TYPE_X86_64}, + {NULL, 0} +}; + +/* + * arch - perform the original behavior of the arch and machine commands. + * The archcmd flag is non-zero for the arch command, zero for the machine + * command. This routine never returns. + */ +static void __dead2 +arch(int archcmd) +{ + const NXArchInfo *arch = NXGetLocalArchInfo(); + + if(!arch) + errx(-1, "Unknown architecture."); + if(archcmd) { + arch = NXGetArchInfoFromCpuType(arch->cputype, CPU_SUBTYPE_MULTIPLE); + if(!arch) + errx(-1, "Unknown architecture."); + } + printf("%s%s", arch->name, (isatty(STDIN_FILENO) ? "\n" : "")); + exit(0); +} + +/* + * spawnIt - run the posix_spawn command. count is the number of CPU types + * in the prefs array. pflag is non-zero to call posix_spawnp; zero means to + * call posix_spawn. str is the name/path to pass to posix_spawn{,p}, and + * argv and environ are the argument and environment arrays to pass. This + * routine never returns. + */ +static void __dead2 +spawnIt(int count, cpu_type_t *prefs, int pflag, const char *str, char **argv, char **environ) +{ + + posix_spawnattr_t attr; + pid_t pid; + int ret; + size_t copied; + + if((ret = posix_spawnattr_init(&attr)) != 0) + errc(1, ret, "posix_spawnattr_init"); + /* do the equivalent of exec, rather than creating a separate process */ + if((ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETEXEC)) != 0) + errc(1, ret, "posix_spawnattr_setflags"); + if((ret = posix_spawnattr_setbinpref_np(&attr, count, prefs, &copied)) != 0) + errc(1, ret, "posix_spawnattr_setbinpref_np"); + if(copied != count) + errx(1, "posix_spawnattr_setbinpref_np only copied %d of %d", (int)copied, count); + if(pflag) + ret = posix_spawnp(&pid, str, NULL, &attr, argv, environ); + else + ret = posix_spawn(&pid, str, NULL, &attr, argv, environ); + errc(1, ret, "posix_spawn%s: %s", (pflag ? "p" : ""), str); +} + +/* + * initCPU - initialize a CPU structure, a dynamically expanding CPU types + * array. + */ +static void +initCPU(CPU *cpu) +{ + cpu->buf = (cpu_type_t *)malloc(CPUDELTA * sizeof(cpu_type_t)); + if(!cpu->buf) + err(1, "Failed to malloc CPU buffer"); + cpu->ptr = cpu->buf; + cpu->end = cpu->buf + CPUDELTA; + cpu->errs = 0; +} + +/* + * addCPU - add a new CPU type value to the CPU structure, expanding + * the array as necessary. + */ +static void +addCPU(CPU *cpu, int n) +{ + if(cpu->ptr >= cpu->end) { + cpu_type_t *new = realloc(cpu->buf, (cpu->end - cpu->buf + CPUDELTA) * sizeof(cpu_type_t)); + if(!new) + err(1, "Out of memory realloc-ing CPU structure"); + ptrdiff_t diff = (void *)new - (void *)cpu->buf; + cpu->buf = new; + cpu->ptr = (cpu_type_t *)((void *)cpu->ptr + diff); + cpu->end = (cpu_type_t *)((void *)cpu->end + diff) + CPUDELTA; + } + *cpu->ptr++ = n; +} + +/* + * addCPUbyname - add a new CPU type, given by name, to the CPU structure, + * expanding the array as necessary. The name is converted to a type value + * by the ArchDict dictionary. + */ +static void +addCPUbyname(CPU *cpu, const char *name) +{ + NSNumber *n = (NSNumber *)[ArchDict objectForKey: [[NSString stringWithUTF8String: name] lowercaseString]]; + if(n == nil) { + warnx("Unknown architecture: %s", name); + cpu->errs++; + return; + } + addCPU(cpu, [n intValue]); +} + +/* + * useEnv - parse the environment variable for CPU preferences. Use name + * to look for program-specific preferences, and append any CPU types to cpu. + * Returns the number of CPU types. Returns any specified execute path in + * execpath. + * + * The environment variable ARCHPREFERENCE has the format: + * spec[;spec]... + * a semicolon separated list of specifiers. Each specifier has the format: + * [prog:[execpath:]]type[,type]... + * a comma separate list of CPU type names, optionally proceeded by a program + * name and an execpath. If program name exist, that types only apply to that + * program. If execpath is specified, it is returned. If no program name + * exists, then it applies to all programs. So ordering of the specifiers is + * important, as the default (no program name) specifier must be last. + */ +static int +useEnv(CPU *cpu, const char *name, char **execpath) +{ + char *val = getenv(envname); + if(!val) + return 0; + + /* cp will point to the basename of name */ + const char *cp = strrchr(name, '/'); + if(cp) { + cp++; + if(!*cp) + errx(1, "%s: no name after last slash", name); + } else + cp = name; + /* make a copy of the environment variable value, so we can modify it */ + val = strdup(val); + if(!val) + err(1, "Can't copy environment %s", envname); + char *str = val; + char *blk; + /* for each specifier */ + while((blk = strsep(&str, ";")) != NULL) { + if(*blk == 0) + continue; /* two adjacent semicolons */ + /* now split on colons */ + char *n = strsep(&blk, ":"); + if(blk) { + char *p = strsep(&blk, ":"); + if(!blk) { /* there is only one colon, so no execpath */ + blk = p; + p = NULL; + } else if(!*p) /* two consecutive colons, so no execpath */ + p = NULL; + if(!*blk) + continue; /* no cpu list, so skip */ + /* if the name matches, or there is no name, process the cpus */ + if(!*n || strcmp(n, cp) == 0) { + if(CPUCOUNT(cpu) <= 0) { /* only if we don't already have cpu types */ + char *t; + while((t = strsep(&blk, ",")) != NULL) + addCPUbyname(cpu, t); + } + *execpath = (*n ? p : NULL); /* only use the exec path is name is set */ + break; + } + } else { /* no colons at all, so process as default */ + if(CPUCOUNT(cpu) <= 0) { /* only if we don't already have cpu types */ + blk = n; + while((n = strsep(&blk, ",")) != NULL) + addCPUbyname(cpu, n); + } + *execpath = NULL; + break; + } + } + if(cpu->errs) /* errors during addCPUbyname are fatal */ + exit(1); + return CPUCOUNT(cpu); /* return count of cpus */ +} + +/* + * spawnFromPreference - called when argv[0] is not "arch" or "machine", or + * argv[0] was arch, but no commandline architectures were specified. + * If the environment variable ARCHPREFERENCE is specified, and there is a + * match to argv[0], use the specified cpu preferences. If no exec path + * is specified in ARCHPREFERENCE, or no match is found in ARCHPREFERENCE, + * get any additional information from a .plist file with the name of argv[0]. + * This routine never returns. + */ +static void __dead2 +spawnFromPreferences(CPU *cpu, int needexecpath, char **argv, char **environ) +{ + char *epath = NULL; + int count; + const char *prog = strrchr(*argv, '/'); + if(prog) + prog++; + else + prog = *argv; + if(!*prog) + errx(1, "Not program name specified"); + + /* check the environment variable first */ + if((count = useEnv(cpu, prog, &epath)) > 0) { + /* if we were called as arch, use posix_spawnp */ + if(!needexecpath) + spawnIt(count, cpu->buf, 1, (epath ? epath : *argv), argv, environ); + /* otherwise, if we have the executable path, call posix_spawn */ + if(epath) + spawnIt(count, cpu->buf, 0, epath, argv, environ); + } + + /* pathArray is use to build the .plist file path for each domain */ + NSMutableArray *pathArray = [NSMutableArray arrayWithCapacity: 3]; + if(!pathArray) + errx(1, "Can't create NSMutableArray"); + [pathArray addObject: @""]; // placeholder for domain directory + [pathArray addObject: SettingsDir]; + [pathArray addObject: [[NSString stringWithUTF8String: prog] stringByAppendingPathExtension: PlistExtension]]; + + /* get the list of top level directories for all domains */ + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, true); + int cnt = [paths count]; + if(!cnt) + errx(1, "No domains"); + + /* create the .plist path, and try to read it */ + int i; + NSString *path = NULL; + NSData *data = NULL; + for(i = 0; i < cnt; i++) { + [pathArray replaceObjectAtIndex: 0 withObject: [paths objectAtIndex: i]]; + path = [NSString pathWithComponents: pathArray]; + data = [NSData dataWithContentsOfFile: path]; + if(data) /* found it */ + break; + } + if(!data) + errx(1, "Can't find any plists for %s", prog); + + /* try to convert the file into a NSDictionary */ + NSString *error; + id plist = [NSPropertyListSerialization propertyListFromData: data mutabilityOption: NSPropertyListImmutable format: nil errorDescription: &error]; + if(!plist) + errx(1, "%s: NSPropertyListSerialization error: %s", [path UTF8String], [error UTF8String]); + if(![plist isKindOfClass: [NSDictionary class]]) + errx(1, "%s: plist not a dictionary", [path UTF8String]); + + NSString *execpath; + int errs = 0; /* scan for all errors and fail later */ + do { /* begin block */ + /* check the plist version */ + NSString *vers = [(NSDictionary *)plist objectForKey: KeyPlistVersion]; + if(!vers) { + warnx("%s: No key %s", [path UTF8String], [KeyPlistVersion UTF8String]); + errs++; + } else if(![vers isKindOfClass: [NSString class]]) { + warnx("%s: %s is not a string", [path UTF8String], [KeyPlistVersion UTF8String]); + errs++; + } else if(![vers isEqualToString: @"1.0"]) { + warnx("%s: %s not 1.0", [path UTF8String], [KeyPlistVersion UTF8String]); + errs++; + } + /* get the execpath */ + execpath = [(NSDictionary *)plist objectForKey: KeyExecPath]; + if(!execpath) { + warnx("%s: No key %s", [path UTF8String], [KeyExecPath UTF8String]); + errs++; + } else if(![execpath isKindOfClass: [NSString class]]) { + warnx("%s: %s is not a string", [path UTF8String], [KeyExecPath UTF8String]); + errs++; + } + /* if we already got cpu preferences from ARCHPREFERENCE, we are done */ + if(count > 0) + break; + /* otherwise, parse the cpu preferences from the plist */ + id p = [(NSDictionary *)plist objectForKey: KeyPrefOrder]; + if(!p) { + warnx("%s: No key %s", [path UTF8String], [KeyPrefOrder UTF8String]); + errs++; + } else if(![p isKindOfClass: [NSArray class]]) { + warnx("%s: %s is not an array", [path UTF8String], [KeyPrefOrder UTF8String]); + errs++; + } else if((count = [p count]) == 0) { + warnx("%s: no entries in %s", [path UTF8String], [KeyPrefOrder UTF8String]); + errs++; + } else { + /* finally but the cpu type array */ + for(i = 0; i < count; i++) { + id a = [(NSArray *)p objectAtIndex: i]; + NSNumber *n; + if(![a isKindOfClass: [NSString class]]) { + warnx("%s: entries %d of %s is not a string", [path UTF8String], i, [KeyPrefOrder UTF8String]); + errs++; + } else if((n = (NSNumber *)[ArchDict objectForKey: [(NSString *)a lowercaseString]]) == nil) { + warnx("%s: %s: unknown architecture %s", [path UTF8String], [KeyPrefOrder UTF8String], [(NSString *)a UTF8String]); + errs++; + } else { + addCPU(cpu, [n intValue]); + } + } + } + } while(0); /* end block */ + if(errs) /* exit if there were any reported errors */ + exit(1); + + /* call posix_spawn */ + spawnIt(count, cpu->buf, 0, [execpath fileSystemRepresentation], argv, environ); +} + +static void __dead2 +usage(int ret) +{ + fprintf(stderr, + "Usage: %s\n" + " Display the machine's architecture type\n" + "Usage: %s [-h] [[-arch_name | -arch arch_name] ...] prog [arg ...]\n" + " Run prog with any arguments, using the given architecture\n" + " order. If no architectures are specified, use the\n" + " ARCHPREFERENCE environment variable, or a property list file.\n" + " -h will print usage message and exit.\n", + ARCH_PROG, ARCH_PROG); + exit(ret); +} + +/* + * wrapped - check the path to see if it is a link to /usr/bin/arch. + */ +static int +wrapped(const char *name) +{ + int lp, ln; + char *p; + char *bp = NULL; + char *cur, *path; + char buf[MAXPATHLEN], rpbuf[MAXPATHLEN]; + struct stat sb; + + ln = strlen(name); + + do { /* begin block */ + /* If it's an absolute or relative path name, it's easy. */ + if(index(name, '/')) { + if(stat(name, &sb) == 0 && S_ISREG(sb.st_mode) && access(name, X_OK) == 0) { + bp = (char *)name; + break; + } + errx(1, "%s isn't executable", name); + } + + /* search the PATH, looking for name */ + if((path = getenv("PATH")) == NULL) + path = _PATH_DEFPATH; + + cur = alloca(strlen(path) + 1); + if(cur == NULL) + err(1, "alloca"); + strcpy(cur, path); + while((p = strsep(&cur, ":")) != NULL) { + /* + * It's a SHELL path -- double, leading and trailing colons + * mean the current directory. + */ + if(*p == '\0') { + p = "."; + lp = 1; + } else + lp = strlen(p); + + /* + * If the path is too long complain. This is a possible + * security issue; given a way to make the path too long + * the user may execute the wrong program. + */ + if(lp + ln + 2 > sizeof(buf)) { + warn("%s: path too long", p); + continue; + } + bcopy(p, buf, lp); + buf[lp] = '/'; + bcopy(name, buf + lp + 1, ln); + buf[lp + ln + 1] = '\0'; + if(stat(buf, &sb) == 0 && S_ISREG(sb.st_mode) && access(buf, X_OK) == 0) { + bp = buf; + break; + } + } + if(p == NULL) + errx(1, "Can't find %s in PATH", name); + } while(0); /* end block */ + if(realpath(bp, rpbuf) == NULL) + errx(1, "realpath failed on %s", bp); + return (strcmp(rpbuf, "/usr/bin/" ARCH_PROG) == 0); +} + +/* + * spawnFromArgs - called when arch has arguments specified. The arch command + * line arguments are: + * % arch [[{-xxx | -arch xxx}]...] prog [arg]... + * where xxx is a cpu name, and the command to execute and its arguments follow. + * If no commandline cpu names are given, the environment variable + * ARCHPREFERENCE is used. This routine never returns. + */ +static void __dead2 +spawnFromArgs(CPU *cpu, char **argv, char **environ) +{ + char *ap; + + /* process cpu options */ + for(argv++; *argv && **argv == '-'; argv++) { + if(strcmp(*argv, "-arch") == 0) { + if(*++argv == NULL) { + warnx("-arch without architecture"); + usage(1); + } + ap = *argv; + } else if(strcmp(*argv, "-h") == 0) { + usage(0); + } else + ap = *argv + 1; + addCPUbyname(cpu, ap); + } + if(cpu->errs) + exit(1); + if(!*argv || !**argv) { + warnx("No command to execute"); + usage(1); + } + /* if the program is already a link to arch, then force execpath */ + int needexecpath = wrapped(*argv); + + /* + * If we don't have any architecutures, try ARCHPREFERENCE and plist + * files. + */ + int count = CPUCOUNT(cpu); + if(count <= 0 || needexecpath) + spawnFromPreferences(cpu, needexecpath, argv, environ); /* doesn't return */ + + /* + * Call posix_spawnp on the program name. + */ + spawnIt(count, cpu->buf, 1, *argv, argv, environ); +} + +/* + * init - initializes the ArchDict dictionary from the values in initArches, + * and the CPU structure. + */ +static void +init(CPU *cpu) +{ + ArchDict = [NSMutableDictionary dictionaryWithCapacity: 4]; + if(!ArchDict) + errx(1, "Can't create NSMutableDictionary"); + StrInt *sp; + for(sp = initArches; sp->str; sp++) { + NSString *s = [NSString stringWithUTF8String: sp->str]; + if(!s) + errx(1, "Can't create NSString for %s", sp->str); + NSNumber *n = [NSNumber numberWithInt: sp->i]; + if(!n) + errx(1, "Can't create NSNumber for %s", sp->str); + [ArchDict setObject: n forKey: s]; + } + initCPU(cpu); +} + +/* the main() routine */ +int +main(int argc, char **argv, char **environ) +{ + const char *prog = getprogname(); + int my_name_is_arch; + CPU cpu; + + if(strcmp(prog, MACHINE_PROG) == 0) { + if(argc > 1) + errx(-1, "no arguments accepted"); + arch(0); /* the "machine" command was called */ + } else if((my_name_is_arch = (strcmp(prog, ARCH_PROG) == 0))) { + if(argc == 1) + arch(1); /* the "arch" command with no arguments was called */ + } + + /* set up Objective C autorelease pool */ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + init(&cpu); /* initialize */ + + if(my_name_is_arch) + spawnFromArgs(&cpu, argv, environ); + else + spawnFromPreferences(&cpu, 1, argv, environ); + /* should never get here */ + [pool release]; + errx(1, "returned from spawn"); +} diff --git a/arch.tproj/arch_helper.pl b/arch.tproj/arch_helper.pl new file mode 100755 index 0000000..13a0d61 --- /dev/null +++ b/arch.tproj/arch_helper.pl @@ -0,0 +1,98 @@ +#!/usr/bin/perl -w +# +# Copyright (c) 2006 Apple Computer, Inc. All rights reserved. +# +# @APPLE_LICENSE_HEADER_START@ +# +# This file contains Original Code and/or Modifications of Original Code +# as defined in and that are subject to the Apple Public Source License +# Version 2.0 (the 'License'). You may not use this file except in +# compliance with the License. Please obtain a copy of the License at +# http://www.opensource.apple.com/apsl/ and read it before using this +# file. +# +# The Original Code and all software distributed under the License are +# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +# Please see the License for the specific language governing rights and +# limitations under the License. +# +# @APPLE_LICENSE_HEADER_END@ +# +# arch_helper.pl is a perl script that automates the process of wrapping +# a command (in the DSTROOT) to use the architecture selection feature of +# the arch command. The first argument is the full path (relative to root) +# of the command, and the second argument is the DSTROOT. arch_helper.pl +# will move the command to a new directory in the DSTROOT, create a symbolic +# link from to old command path to the arch command, and create a plist file +# in /System/Library/archSettings to default to 32-bit over 64-bit +# architectures. + +use strict; +use File::Basename (); +use File::Path (); +use File::Spec; +use IO::File; + +my $ArchSettings = '/System/Library/archSettings'; +my %Known = ( + '/usr/bin' => '/usr/archexec', + '/usr/local/bin' => '/usr/local/archexec', +); +my $MyName = File::Basename::basename($0); + +sub usage { + print STDERR <splitpath($ARGV[0]); # unix assumes $vol we be empty +$dir = File::Spec->canonpath($dir); +my $new = $Known{$dir}; +die "$MyName: Unsupported directory $dir\n" unless defined($new); +my $dstroot = $ARGV[1]; +die "$MyName: $dstroot: Not a full path\n" unless File::Spec->file_name_is_absolute($dstroot); +File::Path::mkpath(File::Spec->join($dstroot, $new), 1, 0755); +File::Path::mkpath(File::Spec->join($dstroot, $ArchSettings), 1, 0755); +my $execpath = File::Spec->canonpath(File::Spec->join($new, $file)); +my $do = File::Spec->join($dstroot, $dir, $file); +my $dn = File::Spec->join($dstroot, $execpath); +rename($do, $dn) or die "$MyName: Can't move $file to $dn: $!\n"; +print "renamed $do -> $dn\n"; +my $l = File::Spec->abs2rel('/usr/bin/arch', $dir); +symlink($l, $do) or die "$MyName: Can't symlink $do -> $l: $!\n"; +print "symlink $do -> $l\n"; +my $plist = File::Spec->join($dstroot, $ArchSettings, $file . '.plist'); +my $p = IO::File->new($plist, 'w') or die "$MyName: $plist: $!\n"; +$p->print( < + + + + ExecutablePath + $execpath + PreferredOrder + + i386 + x86_64 + ppc + ppc64 + + PropertyListVersion + 1.0 + + +PLIST +$p->close(); +print "created $plist\n"; diff --git a/arch.tproj/machine.1 b/arch.tproj/machine.1 index 5c130aa..0a81d22 100644 --- a/arch.tproj/machine.1 +++ b/arch.tproj/machine.1 @@ -45,6 +45,7 @@ The .Nm machine command displays the machine type. .Sh SEE ALSO +.Xr arch 1 , .Xr make 1 .Sh HISTORY The diff --git a/at.tproj/Makefile b/at.tproj/Makefile index 2c36024..bde6f8c 100644 --- a/at.tproj/Makefile +++ b/at.tproj/Makefile @@ -16,8 +16,7 @@ HFILES = at.h panic.h parsetime.h pathnames.h privs.h perm.h CFILES = at.c panic.c parsetime.c perm.c -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\ - at.1 +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble at.man MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles @@ -35,7 +34,8 @@ PROJECT_HEADERS = privs.h pathnames.h NEXTSTEP_PB_CFLAGS += -D__FBSDID=__RCSID -DDAEMON_UID=1 -DDAEMON_GID=1 \ -DDEFAULT_AT_QUEUE=\'a\' -DDEFAULT_BATCH_QUEUE=\'b\' \ - -DPERM_PATH=\"/var/at/\" -I/System/Library/Frameworks/System.framework/PrivateHeaders + -DPERM_PATH=\"/usr/lib/cron/\" \ + -I/System/Library/Frameworks/System.framework/PrivateHeaders NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(NAME)/Build diff --git a/at.tproj/Makefile.dist b/at.tproj/Makefile.dist deleted file mode 100644 index 1468a6c..0000000 --- a/at.tproj/Makefile.dist +++ /dev/null @@ -1,15 +0,0 @@ -# $Id: Makefile.dist,v 1.1 1999/05/02 04:21:18 wsanchez Exp $ - -PROG= at -SRCS= at.c panic.c parsetime.c -LINKS= ${BINDIR}/at ${BINDIR}/atq \ - ${BINDIR}/at ${BINDIR}/atrm \ - ${BINDIR}/at ${BINDIR}/batch -MLINKS= at.1 batch.1 \ - at.1 atq.1 \ - at.1 atrm.1 - -BINOWN= root -BINMODE= 4555 - -.include diff --git a/at.tproj/Makefile.postamble b/at.tproj/Makefile.postamble index 8104d89..e65f481 100644 --- a/at.tproj/Makefile.postamble +++ b/at.tproj/Makefile.postamble @@ -6,8 +6,10 @@ after_install:: $(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)$(INSTALLDIR)/batch install -o daemon -d "$(DSTROOT)/private/var/at/spool" touch "$(DSTROOT)/private/var/at/at.deny" + mkdir -p "$(DSTROOT)/usr/lib" + ln -sf ../../var/at "$(DSTROOT)/usr/lib/cron" mkdir -p "$(DSTROOT)/usr/share/man/man1" - install -c -m 644 at.1 "$(DSTROOT)/usr/share/man/man1/at.1" + install -c -m 644 at.man "$(DSTROOT)/usr/share/man/man1/at.1" ln -f "$(DSTROOT)/usr/share/man/man1/at.1" "$(DSTROOT)/usr/share/man/man1/atrm.1" ln -f "$(DSTROOT)/usr/share/man/man1/at.1" "$(DSTROOT)/usr/share/man/man1/atq.1" ln -f "$(DSTROOT)/usr/share/man/man1/at.1" "$(DSTROOT)/usr/share/man/man1/batch.1" diff --git a/at.tproj/at.1 b/at.tproj/at.1 deleted file mode 100644 index 78a978e..0000000 --- a/at.tproj/at.1 +++ /dev/null @@ -1,235 +0,0 @@ -.\" -.\" Copyright (c) 1993 Christopher G. Demetriou -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by Christopher G. Demetriou. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $Id: at.1,v 1.5 2005/02/18 00:22:38 lindak Exp $ -.\" -.Dd December 5, 1993 -.Dt "AT" 1 -.Os NetBSD 0.9a -.Sh NAME -.Nm at, batch, atq, atrm -.Nd queue, examine, or delete jobs for later execution -.\" -.Sh SYOPSIS -.Nm at -.Op Fl q Ar queue -.Op Fl f Ar file -.Op Fl m -.Ar time -.Pp -.Nm atq -.Op Fl q Ar queue -.Op Fl v -.Pp -.Nm atrm -.Ar job -.Op Ar job ... -.Pp -.Nm batch -.Op Fl f Ar file -.Op Fl m -.Ar time -.Sh NOTE -.Nm at , -.Nm batch , -.Nm atq , -.Nm atrm -are all disabled by default on Mac OS X. -Each of these commands depend on the execution of -.Xr atrun 8 -which has been disabled due to power management concerns. -Those who would like to use these commands, must first (as root) re-enable -.Nm atrun -by running: -.Bd -literal -launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist -.Ed -.Sh DESCRIPTION -The -.Nm at -and -.Nm batch -utilities read commands from the standard input or a specified file -which are to be executed at a later time, using -.Xr sh 1 . -.Pp -The functions of the commands are as follows: -.Bl -tag -width indent -.It Nm at -Executes commands at a specified time. -.It Nm atq -Lists the user's pending jobs, unless the user is -the superuser. In that case, everybody's jobs are -listed. -.It Nm atrm -Deletes jobs. -.It Nm batch -Executes commands when system load levels drop below a user-specifed threshold. -The load threshold for batch jobs is specifed -as an argument when executing -.Xr atrun 8 . -.El -.Pp -For both -.Nm at -and -.Nm batch , -the working directory, environment (except for the variables -.Nm TERM , -.Nm TERMCAP , -.Nm DISPLAY , -and -.Nm _ ) -and the umask are retained from the time of invocation. The user -will be mailed the standard output and standard error from -his commands if any output is generated. If -.Nm at -is executed from a -.Xr su 1 -shell, the owner of the login shell will receive the mail. -.Sh OPTIONS -.Bl -tag -width indent -The available options are as follows: -.It Fl q Ar queue -Use the specified queue. A queue designation consists -of a single letter; valid queue designation range from -.Ar a -to -.Ar l . -The -.Ar a -queue is the default, and -.Ar b -is the batch queue. Queues with higher letters run with -increased niceness. If -.Nm atq -is given a specific queue, it will only show jobs pending -in that queue. -.It Fl m -Send mail to the user when the job has completed, even if -there was no output. -.It Fl f Ar file -Reads the job from -.Ar file -rather than the standard input. -.It Fl v -Shows completed but not yet deleted jobs in the queue. -.El -.Sh TIME SPECIFICATION -.Nm At -allows some moderately complex time specifications. -It accepts times of the form -.Ar HHMM -or -.Ar HH:MM -to run a job at a specific time of day. If -that time is already passed, the next day is assumed. -You may also specify -.Nm midnight , -.Nm noon , -or -.Nm teatime -(4PM) and you can give a time of day suffixed with -.Nm AM -or -.Nm PM -for running in the morning or the evening. You can -also specify the date on which the job will be run -by giving a date in the form -.Ar month-name day -with an optional -.Ar year , -or giving a date of the form -.Ar MMDDYY , -.Ar MM/DD/YY -or -.Ar DD.MM.YY . -You can also give times like -.Nm now + -.Ar count time-units , -where the time units can be -.Nm minutes, hours, days, -or -.Nm weeks -You can suffix the time with -.Nm today -to run the job today, or -.Nm tomorrow -to run the job tomorrow. -.Pp -For example, to run a job at 4PM three days from now, you -would specify a time of -.Nm 4PM + 3 days . -To run a job at 10:00AM on on July 31, you would specify -a time of -.Nm 10AM Jul 31 . -Finally, to run a job at 1AM tomorrow, you would specify -a time of -.Nm 1AM tomorrow . -.Sh FILES -.Bl -tag -width /var/at/lockfile -compact -.It Pa /var/at/jobs -Directory containing job files -.It Pa /var/at/spool -Directory containing output spool files -.It Pa /var/at/lockfile -Job-creation lock file. -.It Pa /var/run/utmp -.El -.Sh SEE ALSO -.Xr launchctl 1 , -.Xr launchd 8 , -.Xr nice 1 , -.Xr sh 1 , -.Xr compat 5 , -.Xr atrun 8 -.Sh AUTHOR -.Bl -tag -Thomas Koenig, ig25@rz.uni-karlsruhe.de -.El -.Sh BUGS -Traditional access control to -.Nm at -and -.Nm batch -via the files -.Pa /var/at/at.allow -and -.Pa /var/at/at.deny -is not implemented. -.Pp -If the file -.Pa /var/run/utmp -is not available or corrupted, or if the user is not -logged in at the time -.Nm at -is invoked, the mail is sent to the userid found in the -environment variable -.Nm LOGNAME . -If that is undefined or empty, the current userid is assumed. diff --git a/at.tproj/at.c b/at.tproj/at.c index 48b1599..fabb9e2 100644 --- a/at.tproj/at.c +++ b/at.tproj/at.c @@ -229,6 +229,7 @@ writefile(time_t runtimer, char queue) int ch; mode_t cmask; struct flock lock; + char * oldpwd_str = NULL; #ifdef __FreeBSD__ (void) setlocale(LC_TIME, ""); @@ -368,11 +369,19 @@ writefile(time_t runtimer, char queue) else { size_t i; - for (i=0; i&2\n\t exit 1\n}\n"); + /* Put OLDPWD back, since the cd has set it */ + /* Although this is added to fix conformance test at.ex 891, it seems like */ + /* the right thing to do always, so the code is not posix_pedantic only */ + if (oldpwd_str) { + fprintf(fp, "%s; export OLDPWD\n", oldpwd_str); + } else { + fprintf(fp, "unset OLDPWD\n"); + } + while((ch = getchar()) != EOF) fputc(ch, fp); @@ -769,6 +787,8 @@ main(int argc, char **argv) timer = -1; RELINQUISH_PRIVS + if (argv[0] == NULL) + usage(); /* Eat any leading paths */ if ((pgm = strrchr(argv[0], '/')) == NULL) diff --git a/at.tproj/at.man b/at.tproj/at.man new file mode 100644 index 0000000..5cd4960 --- /dev/null +++ b/at.tproj/at.man @@ -0,0 +1,390 @@ +.\" $FreeBSD: src/usr.bin/at/at.man,v 1.34 2003/03/26 02:38:18 keramida Exp $ +.Dd January 13, 2002 +.Dt "AT" 1 +.Os +.Sh NAME +.Nm at , +.Nm batch , +.Nm atq , +.Nm atrm +.Nd queue, examine, or delete jobs for later execution +.Sh SYNOPSIS +.Nm at +.Op Fl q Ar queue +.Op Fl f Ar file +.Op Fl mldbv +.Ar time +.Nm at +.Op Fl q Ar queue +.Op Fl f Ar file +.Op Fl mldbv +.Fl t +.Sm off +.Op Oo Ar CC Oc Ar YY +.Ar MM DD hh mm Op . Ar SS +.Sm on +.Nm at +.Fl c Ar job Op Ar job ... +.Nm at +.Fl l Op Ar job ... +.Nm at +.Fl l +.Fl q Ar queue +.Nm at +.Fl r Ar job Op Ar job ... +.Pp +.Nm atq +.Op Fl q Ar queue +.Op Fl v +.Pp +.Nm atrm +.Ar job +.Op Ar job ... +.Pp +.Nm batch +.Op Fl q Ar queue +.Op Fl f Ar file +.Op Fl mv +.Op Ar time +.Sh DESCRIPTION +The +.Nm at +and +.Nm batch +utilities +read commands from standard input or a specified file. +The commands are executed at a later time, using +.Xr sh 1 . +.Bl -tag -width indent +.It Nm at +executes commands at a specified time; +.It Nm atq +lists the user's pending jobs, unless the user is the superuser; in that +case, everybody's jobs are listed; +.It Nm atrm +deletes jobs; +.It Nm batch +executes commands when system load levels permit; in other words, when the load average +drops below _LOADAVG_MX, or the value specified in the invocation of +.Nm atrun . +.El +.Pp +The +.Nm at +utility allows some moderately complex +.Ar time +specifications. +It accepts times of the form +.Ar HHMM +or +.Ar HH:MM +to run a job at a specific time of day. +(If that time is already past, the next day is assumed.) +As an alternative, the following keywords may be specified: +.Em midnight , +.Em noon , +or +.Em teatime +(4pm) +and time-of-day may be suffixed with +.Em AM +or +.Em PM +for running in the morning or the evening. +The day on which the job is to be run may also be specified +by giving a date in the form +.Ar \%month-name day +with an optional +.Ar year , +or giving a date of the forms +.Ar DD.MM.YYYY , +.Ar DD.MM.YY , +.Ar MM/DD/YYYY , +.Ar MM/DD/YY , +.Ar MMDDYYYY , or +.Ar MMDDYY . +The specification of a date must follow the specification of +the time of day. +Time can also be specified as: +.Op Em now +.Em + Ar count \%time-units , +where the time-units can be +.Em minutes , +.Em hours , +.Em days , +.Em weeks , +.Em months +or +.Em years +and +.Nm at +may be told to run the job today by suffixing the time with +.Em today +and to run the job tomorrow by suffixing the time with +.Em tomorrow . +.Pp +For example, to run a job at 4pm three days from now, use +.Nm at Ar 4pm + 3 days , +to run a job at 10:00am on July 31, use +.Nm at Ar 10am Jul 31 +and to run a job at 1am tomorrow, use +.Nm at Ar 1am tomorrow . +.Pp +The +.Nm at +utility also supports the +.Tn POSIX +time format (see +.Fl t +option). +.Pp +For both +.Nm at +and +.Nm batch , +commands are read from standard input or the file specified +with the +.Fl f +option. +The working directory, the environment (except for the variables +.Ev TERM , +.Ev TERMCAP , +.Ev DISPLAY +and +.Em _ ) , +and the +.Ar umask +are retained from the time of invocation. +An +.Nm at +or +.Nm batch +command invoked from a +.Xr su 1 +shell will retain the current userid. +The user will be mailed standard error and standard output from his +commands, if any. +Mail will be sent using the command +.Xr sendmail 8 . +If +.Nm at +is executed from a +.Xr su 1 +shell, the owner of the login shell will receive the mail. +.Pp +The superuser may use these commands in any case. +For other users, permission to use +.Nm at +is determined by the files +.Pa _PERM_PATH/at.allow +and +.Pa _PERM_PATH/at.deny . +.Pp +If the file +.Pa _PERM_PATH/at.allow +exists, only usernames mentioned in it are allowed to use +.Nm at . +In these two files, +a user is considered to be listed +only if the user name has no blank or other characters +before it on its line and a newline character immediately after the name, +even at the end of the file. +Other lines are ignored and may be used for comments. +.Pp +If +.Pa _PERM_PATH/at.allow +does not exist, +.Pa _PERM_PATH/at.deny +is checked, every username not mentioned in it is then allowed +to use +.Nm at . +.Pp +If neither exists, only the superuser is allowed use of +.Nm at . +This is the default configuration. +.Sh IMPLEMENTATION NOTES +Note that +.Nm at +is implemented through the +.Xr cron 8 +daemon by calling +.Xr atrun 8 +every five minutes. +This implies that the granularity of +.Nm at +might not be optimal for every deployment. +If a finer granularity is needed, the system crontab at +.Pa /etc/crontab +needs to be changed. +.Sh OPTIONS +.Bl -tag -width indent +.\" ========== +.It Fl b +Is an alias for +.Nm batch . +.\" ========== +.It Fl c +Cat the jobs listed on the command line to standard output. +.\" ========== +.It Fl d +Is an alias for +.Nm atrm +(this option is deprecated; use +.Fl r +instead). +.\" ========== +.It Fl f Ar file +Read the job from +.Ar file +rather than standard input. +.\" ========== +.It Fl l +With no arguments, list all jobs for the invoking user. +If one or more +job numbers are given, list only those jobs. +.\" ========== +.It Fl m +Send mail to the user when the job has completed even if there was no +output. +.\" ========== +.It Fl q Ar queue +Use the specified queue. +A queue designation consists of a single letter; valid queue designations +range from +.Ar a +to +.Ar z +and +.Ar A +to +.Ar Z . +The +.Ar _DEFAULT_AT_QUEUE +queue (a) is the default for +.Nm at +and the +.Ar _DEFAULT_BATCH_QUEUE +queue (b) is the default for +.Nm batch . +Queues with higher letters run with increased niceness. +If a job is submitted to a queue designated with an uppercase letter, it +is treated as if it had been submitted to batch at that time. +If +.Nm atq +is given a specific queue, it will only show jobs pending in that queue. +.\" ========== +.It Fl r +Remove the specified jobs. +.\" ========== +.It Fl t +Specify the job time using the \*[Px] time format. +The argument should be in the form +.Sm off +.Op Oo Ar CC Oc Ar YY +.Ar MM DD hh mm Op . Ar SS +.Sm on +where each pair of letters represents the following: +.Pp +.Bl -tag -width indent -compact -offset indent +.\" ========== +.It Ar CC +The first two digits of the year (the century). +.\" ========== +.It Ar YY +The second two digits of the year. +.\" ========== +.It Ar MM +The month of the year, from 1 to 12. +.\" ========== +.It Ar DD +the day of the month, from 1 to 31. +.\" ========== +.It Ar hh +The hour of the day, from 0 to 23. +.\" ========== +.It Ar mm +The minute of the hour, from 0 to 59. +.\" ========== +.It Ar SS +The second of the minute, from 0 to 61. +.El +.Pp +If the +.Ar CC +and +.Ar YY +letter pairs are not specified, the values default to the current +year. +If the +.Ar SS +letter pair is not specified, the value defaults to 0. +.\" ========== +.It Fl v +For +.Nm atq , +shows completed but not yet deleted jobs in the queue; otherwise +shows the time the job will be executed. +.El +.Sh FILES +.Bl -tag -width _ATJOB_DIR/_LOCKFILE -compact +.\" ========== +.It Pa _ATJOB_DIR +directory containing job files +(/usr/lib/cron/jobs/) +.\" ========== +.It Pa _ATJOB_DIR/_LOCKFILE +job-creation lock file +(/usr/lib/cron/jobs/...) +.\" ========== +.It Pa _ATSPOOL_DIR +directory containing output spool files +(/usr/lib/cron/spool/) +.\" ========== +.It Pa _PERM_PATH/at.allow +allow permission control +(/usr/lib/cron/at.allow) +.\" ========== +.It Pa _PERM_PATH/at.deny +deny permission control +(/usr/lib/cron/at.deny) +.It Pa /var/run/utmpx +login records +.El +.Sh SEE ALSO +.Xr nice 1 , +.Xr sh 1 , +.Xr umask 2 , +.Xr compat 5 , +.Xr atrun 8 , +.Xr cron 8 , +.Xr sendmail 8 +.Sh BUGS +If the file +.Pa /var/run/utmpx +is not available or corrupted, +or if the user is not logged on at the time +.Nm at +is invoked, the mail is sent to the userid found +in the environment variable +.Ev LOGNAME . +If that is undefined or empty, the current userid is assumed. +.Pp +The +.Nm at +and +.Nm batch +utilities +as presently implemented are not suitable when users are competing for +resources. +If this is the case, another batch system such as +.Em nqs +may be more suitable. +.Pp +Specifying a date past 2038 may not work on some systems. +.Sh AUTHORS +At was mostly written by +.An Thomas Koenig Aq ig25@rz.uni-karlsruhe.de . +The time parsing routines are by +.An David Parsons Aq orc@pell.chi.il.us , +with minor enhancements by +.An Joe Halpin Aq joe.halpin@attbi.com . diff --git a/at.tproj/pathnames.h b/at.tproj/pathnames.h index daf1edc..b05b7a5 100644 --- a/at.tproj/pathnames.h +++ b/at.tproj/pathnames.h @@ -51,7 +51,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pathnames.h,v 1.1.1.2 2000/01/11 02:10:05 wsanchez Exp $ + * $Id: pathnames.h,v 1.2 2005/07/30 01:30:01 lindak Exp $ */ #ifndef _PATHNAMES_H_ @@ -59,9 +59,11 @@ #include -#define _PATH_ATJOBS "/var/at/jobs/" -#define _PATH_ATSPOOL "/var/at/spool/" -#define _PATH_LOCKFILE "/var/at/.lockfile" -#define _PATH_AT "/var/at/" +#define _PATH_ATJOBS "/usr/lib/cron/jobs/" +#define _PATH_ATSPOOL "/usr/lib/cron/spool/" +/* Note: _PATH_LOCKFILE appears to be unused; /usr/lib/cron/jobs/.lockfile + is the file currently being used by at.*/ +#define _PATH_LOCKFILE "/usr/lib/cron/.lockfile" +#define _PATH_AT "/usr/lib/cron/" #endif /* !_PATHNAMES_H_ */ diff --git a/at.tproj/perm.c b/at.tproj/perm.c index 872ce44..0dfad78 100644 --- a/at.tproj/perm.c +++ b/at.tproj/perm.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD: src/usr.bin/at/perm.c,v 1.13 2001/12/10 21:13:01 dwmalone Ex /* Local headers */ #include "at.h" +#include "panic.h" #include "perm.h" #include "privs.h" diff --git a/atrun.tproj/atrun.8 b/atrun.tproj/atrun.8 index 8d50f58..2e06d61 100644 --- a/atrun.tproj/atrun.8 +++ b/atrun.tproj/atrun.8 @@ -56,8 +56,8 @@ Directory containing output spool files Job-creation lock file. .El .Sh SEE ALSO -.Xr crond 8 , -.Xr at 1 +.Xr at 1 , +.Xr crond 8 .Sh AUTHOR .Bl -tag Thomas Koenig, ig25@rz.uni-karlsruhe.de @@ -65,10 +65,10 @@ Thomas Koenig, ig25@rz.uni-karlsruhe.de .Sh BUGS The functionality of .Nm atrun -should arguaby be merged into +should arguably be merged into .Xr crond 8 . .Sh CAVEATS -Since the default configuration causes +Because the default configuration causes .Nm atrun to be invoked every ten minutes, commands queued by diff --git a/atrun.tproj/atrun.c b/atrun.tproj/atrun.c index 4eac2cc..40552c0 100644 --- a/atrun.tproj/atrun.c +++ b/atrun.tproj/atrun.c @@ -48,14 +48,18 @@ static const char rcsid[] = #include #include #include -#include +#include #if 1 #include #else #include #endif +#if (MAXLOGNAME-1) > _UTX_USERSIZE +#define LOGNAMESIZE _UTX_USERSIZE +#else #define LOGNAMESIZE (MAXLOGNAME-1) +#endif /* Local headers */ @@ -144,6 +148,13 @@ run_file(const char *filename, uid_t uid, gid_t gid) else if (pid != 0) return; +#ifdef __APPLE__ + { + pid_t pg = setsid(); + if (pg == -1) syslog(LOG_ERR,"setsid() failed: %m"); + } +#endif + /* Let's see who we mail to. Hopefully, we can read it from * the command file; if not, send it to the owner, or, failing that, * to root. @@ -286,12 +297,12 @@ run_file(const char *filename, uid_t uid, gid_t gid) nice(tolower(queue) - 'a'); - if (initgroups(pentry->pw_name,pentry->pw_gid)) - perr("cannot delete saved userids"); - if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0) perr("cannot change group"); + if (initgroups(pentry->pw_name,pentry->pw_gid)) + perr("cannot delete saved userids"); + if (setlogin(pentry->pw_name)) perr("cannot set login name"); @@ -324,12 +335,12 @@ run_file(const char *filename, uid_t uid, gid_t gid) { PRIV_START - if (initgroups(pentry->pw_name,pentry->pw_gid)) - perr("cannot delete saved userids"); - if (setgid(gid) < 0 || setegid(pentry->pw_gid) < 0) perr("cannot change group"); + if (initgroups(pentry->pw_name,pentry->pw_gid)) + perr("cannot delete saved userids"); + if (setlogin(pentry->pw_name)) perr("cannot set login name"); @@ -485,6 +496,10 @@ main(int argc, char *argv[]) run_file(batch_name, batch_uid, batch_gid); closelog(); +#if __APPLE__ + // allow enough time for child processes to call setsid(2) + sleep(1); +#endif exit(EXIT_SUCCESS); } diff --git a/atrun.tproj/com.apple.atrun.plist b/atrun.tproj/com.apple.atrun.plist index 34867ea..bdb53c0 100644 --- a/atrun.tproj/com.apple.atrun.plist +++ b/atrun.tproj/com.apple.atrun.plist @@ -9,7 +9,7 @@ /usr/libexec/atrun StartInterval - 300 + 30 Disabled diff --git a/audit.tproj/audit.1 b/audit.tproj/audit.1 index 3b800a8..61e5949 100644 --- a/audit.tproj/audit.1 +++ b/audit.tproj/audit.1 @@ -39,5 +39,5 @@ The auditd(8) daemon must already be running. Default audit policy file used to configure the auditing system. .El .Sh SEE ALSO +.Xr audit_control 5 , .Xr auditd 8 -.Xr audit_control 5 diff --git a/auditd.tproj/audit_warn.c b/auditd.tproj/audit_warn.c index 22657a1..67383be 100644 --- a/auditd.tproj/audit_warn.c +++ b/auditd.tproj/audit_warn.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/auditd.tproj/auditd.c b/auditd.tproj/auditd.c index 459bee3..2d73e1e 100644 --- a/auditd.tproj/auditd.c +++ b/auditd.tproj/auditd.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/auditd.tproj/auditd_control.defs b/auditd.tproj/auditd_control.defs index 1cf8346..0aad081 100644 --- a/auditd.tproj/auditd_control.defs +++ b/auditd.tproj/auditd_control.defs @@ -30,6 +30,10 @@ subsystem KernelUser auditd_control 456; +#ifndef __MigTypeCheck +#define __MigTypeCheck 1 +#endif + #include #include diff --git a/utmp_update.tproj/Makefile b/bootlog.tproj/Makefile similarity index 82% rename from utmp_update.tproj/Makefile rename to bootlog.tproj/Makefile index bcb031d..8cdd7ca 100644 --- a/utmp_update.tproj/Makefile +++ b/bootlog.tproj/Makefile @@ -7,15 +7,15 @@ # and Makefile.postamble (both optional), and Makefile will include them. # -NAME = utmp_update +NAME = bootlog -PROJECTVERSION = 1.1 +PROJECTVERSION = 1.0 PROJECT_TYPE = Tool -CFILES = utmp_update.c - -OTHERSRCS = Makefile Makefile.postamble +CFILES = bootlog.c +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\ + com.apple.bootlog.plist bootlog.8 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles CODE_GEN_STYLE = DYNAMIC @@ -28,12 +28,14 @@ DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) + + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc NEXTSTEP_JAVA_COMPILER = /usr/bin/javac WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe -PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac include $(MAKEFILEDIR)/platform.make diff --git a/bootlog.tproj/Makefile.postamble b/bootlog.tproj/Makefile.postamble new file mode 100644 index 0000000..55649eb --- /dev/null +++ b/bootlog.tproj/Makefile.postamble @@ -0,0 +1,5 @@ +after_install: + mkdir -p $(DSTROOT)/usr/share/man/man8 + install -c -m 444 bootlog.8 $(DSTROOT)/usr/share/man/man8 + mkdir -p $(DSTROOT)/System/Library/LaunchDaemons + install -c -m 444 com.apple.bootlog.plist $(DSTROOT)/System/Library/LaunchDaemons diff --git a/bootlog.tproj/Makefile.preamble b/bootlog.tproj/Makefile.preamble new file mode 100644 index 0000000..1bb8bf6 --- /dev/null +++ b/bootlog.tproj/Makefile.preamble @@ -0,0 +1 @@ +# empty diff --git a/bootlog.tproj/PB.project b/bootlog.tproj/PB.project new file mode 100644 index 0000000..020b199 --- /dev/null +++ b/bootlog.tproj/PB.project @@ -0,0 +1,24 @@ +{ + DOCICONFILES = (); + FILESTABLE = { + CLASSES = (); + OTHER_LIBS = (); + OTHER_LINKED = (dummy.c); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); + SUBPROJECTS = (); + }; + LANGUAGE = English; + LOCALIZABLE_FILES = {}; + NEXTSTEP_INSTALLDIR = /usr/bin; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_INSTALLDIR = /usr/bin; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = usr-share-locale; + PROJECTTYPE = Tool; + PROJECTVERSION = 2.8; + WINDOWS_INSTALLDIR = /usr/bin; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/bootlog.tproj/bootlog.8 b/bootlog.tproj/bootlog.8 new file mode 100644 index 0000000..ae14b71 --- /dev/null +++ b/bootlog.tproj/bootlog.8 @@ -0,0 +1,41 @@ +.\" +.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved. +.\" +.\" @APPLE_LICENSE_HEADER_START@ +.\" +.\" This file contains Original Code and/or Modifications of Original Code +.\" as defined in and that are subject to the Apple Public Source License +.\" Version 2.0 (the 'License'). You may not use this file except in +.\" compliance with the License. Please obtain a copy of the License at +.\" http://www.opensource.apple.com/apsl/ and read it before using this +.\" file. +.\" +.\" The Original Code and all software distributed under the License are +.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +.\" Please see the License for the specific language governing rights and +.\" limitations under the License. +.\" +.\" @APPLE_LICENSE_HEADER_END@ +.\" +.Dd Dec 15, 2006 +.Dt BOOTLOG 8 +.Sh NAME +.Nm bootlog +.Nd log a utmpx boot record +.\" +.Sh SYOPSIS +.Nm bootlog +.Sh DESCRIPTION +The +.Nm bootlog +command simply creates a +.Xr utmpx 5 +boot record at boot time. +It is run by +.Xr launchd 8 . +.Sh SEE ALSO +.Xr utmpx 5 , +.Xr launchd 8 diff --git a/bootlog.tproj/bootlog.c b/bootlog.tproj/bootlog.c new file mode 100644 index 0000000..5f735a3 --- /dev/null +++ b/bootlog.tproj/bootlog.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _PATH_ASL_IN "/var/run/asl_input" + +#define REPEAT 100 +#define SLEEP 2 + +static void +asl_running(void) +{ + int sock, i; + struct sockaddr_un server; + socklen_t len; + int status; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + exit(1); + + memset(&server, 0, sizeof(struct sockaddr_un)); + server.sun_family = AF_UNIX; + + strcpy(server.sun_path, _PATH_ASL_IN); + server.sun_len = strlen(server.sun_path) + 1; + len = sizeof(server.sun_len) + sizeof(server.sun_family) + server.sun_len; + + i = REPEAT; + for(;;) { + status = connect(sock, (const struct sockaddr *)&server, len); + if (status >= 0) + break; + if(--i <= 0) + exit(1); + sleep(SLEEP); + } + + close(sock); +} + +int +main() +{ + int mib[2] = {CTL_KERN, KERN_BOOTTIME}; + struct utmpx utx; + size_t len; + + bzero(&utx, sizeof(utx)); + utx.ut_type = BOOT_TIME; + utx.ut_pid = 1; // on behave of launchd + + /* get the boot time */ + len = sizeof(struct timeval); + if(sysctl(mib, 2, &utx.ut_tv, &len, NULL, 0) < 0) + gettimeofday(&utx.ut_tv, NULL); /* fallback to now */ + + /* wait for asl before logging */ + asl_running(); + pututxline(&utx); + return 0; +} diff --git a/bootlog.tproj/com.apple.bootlog.plist b/bootlog.tproj/com.apple.bootlog.plist new file mode 100644 index 0000000..40579f8 --- /dev/null +++ b/bootlog.tproj/com.apple.bootlog.plist @@ -0,0 +1,16 @@ + + + + + Label + com.apple.bootlog + ProgramArguments + + /usr/libexec/bootlog + + RunAtLoad + + LaunchOnlyOnce + + + diff --git a/chkpasswd.tproj/Makefile b/chkpasswd.tproj/Makefile index 236688c..744d3b7 100644 --- a/chkpasswd.tproj/Makefile +++ b/chkpasswd.tproj/Makefile @@ -14,7 +14,7 @@ PROJECT_TYPE = Tool HFILES = stringops.h -CFILES = ds_passwd.c nis_passwd.c file_passwd.c netinfo_passwd.c passwd.c\ +CFILES = ds_passwd.c nis_passwd.c file_passwd.c passwd.c\ stringops.c OTHERSRCS = Makefile.preamble Makefile Makefile.postamble chkpasswd.8 diff --git a/chkpasswd.tproj/PB.project b/chkpasswd.tproj/PB.project index 600cfef..41733e0 100644 --- a/chkpasswd.tproj/PB.project +++ b/chkpasswd.tproj/PB.project @@ -5,7 +5,7 @@ C_FILES = (); H_FILES = (stringops.h); OTHER_LIBS = (); - OTHER_LINKED = (nis_passwd.c, file_passwd.c, netinfo_passwd.c, passwd.c, stringops.c); + OTHER_LINKED = (nis_passwd.c, file_passwd.c, passwd.c, stringops.c); OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); SUBPROJECTS = (); }; diff --git a/chkpasswd.tproj/chkpasswd.8 b/chkpasswd.tproj/chkpasswd.8 index 96b9840..1f488a4 100644 --- a/chkpasswd.tproj/chkpasswd.8 +++ b/chkpasswd.tproj/chkpasswd.8 @@ -5,49 +5,52 @@ .Nm chkpasswd .Nd verifies user password against various systems .Sh SYNOPSIS -.Nm +.Nm chkpasswd .Op Fl i Ar infosystem .Op Fl l Ar location .Op Fl c .Op Ar name .Sh DESCRIPTION -.Nm -verifies a supplied username and password against NetInfo, file, NIS, or OpenDirectory backends. +.Nm chkpasswd +verifies a supplied username and password against file, NIS, +or OpenDirectory infosystems. .Pp The options are as follows: .Bl -tag -width Ds -.Fl i Ar infosystem -Specify the system against which to check the password (default is OpenDirectory). Valid systems: -.Pp -.Bl -tag -width "opendirectory" -compact -.It Cm netinfo -NetInfo database -.It Cm file +.\" ========== +.It Fl c +The supplied password is compared verbatim without first being encrypted. +.\" ========== +.It Fl i Ar infosystem +Specify the system against which to check the password +(default is OpenDirectory). Valid systems: +.Bl -tag -width "opendirectory" +.It Ar file File-based passwords -.It Cm nis +.It Ar nis NIS/YP authentication -.It Cm opendirectory -OpenDirectory (Directory Services) authentication +.It Ar opendirectory +OpenDirectory (Directory Services) authentication. +If no +.Fl l +option is specified, the search node is used. .El -.Fl l Ar location -Specify a location; varies based on info system type: .Pp -.Bl -tag -width "opendirectory" -compact -.It Cm netinfo -Domain name or server/tag. -.It Cm file -Filename (default: /etc/passwd). -.It Cm nis +.\" ========== +.It Fl l Ar location +Specify a location; varies based on infosystem type: +.Bl -tag -width "for opendirectory" +.It for file +Filename (default: /etc/master.passwd). +.It for nis NIS domainname. -.It Cm opendirectory -Directory node name. +.It for opendirectory +A directory node name such as /Local/Default. .El -.Fl c -The supplied password is compared verbatim without first being crypted. -.Ar name -Username +.Pp .El +.Ar name +username .Sh SEE ALSO -.Xr nicl 1 , -.Xr passwd 5 , -.Xr dscl 1 +.Xr dscl 1 , +.Xr passwd 5 diff --git a/chkpasswd.tproj/file_passwd.c b/chkpasswd.tproj/file_passwd.c index 51fc8c1..56e7a00 100644 --- a/chkpasswd.tproj/file_passwd.c +++ b/chkpasswd.tproj/file_passwd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "stringops.h" #define TEMP_FILE "/tmp/.pwtmp" @@ -37,8 +38,6 @@ extern void checkpasswd(char *, char *); -static int do_compat = 1; - char * getline(FILE *fp) { @@ -197,7 +196,7 @@ rewrite_file(char *pwname, FILE *fp, struct passwd *newpw) continue; } - fprintf(tfp, "%s:%s:%d:%d:%s:%d:%d:%s:%s:%s\n", + fprintf(tfp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", newpw->pw_name, newpw->pw_passwd, newpw->pw_uid, newpw->pw_gid, newpw->pw_class, newpw->pw_change, newpw->pw_expire, newpw->pw_gecos, newpw->pw_dir, newpw->pw_shell); @@ -253,8 +252,7 @@ file_check_passwd(char *uname, char *locn) fname = _PASSWD_FILE; if (locn != NULL) fname = locn; - fp = fopen(fname, "r"); - if (fp == NULL) + if (access(fname,R_OK) || (fp = fopen(fname, "r")) == NULL) { fprintf(stderr, "can't read file \"%s\": ", fname); perror(""); diff --git a/chkpasswd.tproj/netinfo_passwd.c b/chkpasswd.tproj/netinfo_passwd.c deleted file mode 100644 index 762f00d..0000000 --- a/chkpasswd.tproj/netinfo_passwd.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void checkpasswd(char *, char *); - -static int -sys_ismyaddress(unsigned long addr) -{ - struct ifconf ifc; - struct ifreq *ifr; - char buf[1024]; /* XXX */ - int offset; - int sock; - struct sockaddr_in *sin; - int i, len; - - if (addr == htonl(INADDR_LOOPBACK)) return 1; - - sock = socket(AF_INET, SOCK_DGRAM, 0); - - if (sock < 0) return 0; - - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - - if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) - { - close(sock); - return 0; - } - - offset = 0; - - while (offset <= ifc.ifc_len) - { - ifr = (struct ifreq *)(ifc.ifc_buf + offset); - offset += IFNAMSIZ + ifr->ifr_addr.sa_len; - - if (ifr->ifr_addr.sa_family != AF_INET) continue; - if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue; - - sin = (struct sockaddr_in *)&ifr->ifr_addr; - if ((ifr->ifr_flags & IFF_UP) && - (!(ifr->ifr_flags & IFF_LOOPBACK)) && - (sin->sin_addr.s_addr == addr)) - { - close(sock); - return 1; - } - } - - close(sock); - return 0; -} - -static int -is_root_on_master(void *d) -{ - int uid; - char myhostname[MAXHOSTNAMELEN + 1]; - char *p; - ni_index where; - ni_proplist pl; - int status; - ni_id dir; - struct sockaddr_in addr; - char *tag; - - uid = getuid(); - if (uid != 0) return 0; - - gethostname(myhostname, MAXHOSTNAMELEN); - p = strchr(myhostname, '.'); - if (p != NULL) *p = '\0'; - - status = ni_root(d, &dir); - if (status != NI_OK) return 0; - - status = ni_read(d, &dir, &pl); - if (status != NI_OK) return 0; - - where = ni_proplist_match(pl, "master", NULL); - if (where == NI_INDEX_NULL) - { - ni_proplist_free(&pl); - return 0; - } - - if (pl.ni_proplist_val[where].nip_val.ni_namelist_len == 0) - { - ni_proplist_free(&pl); - fprintf(stderr, "No value for NetInfo master property\n"); - return 0; - } - - p = strchr(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], '/'); - if (p != NULL) *p = '\0'; - - p = strchr(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], '.'); - if (p != NULL) *p = '\0'; - - if (!strcmp(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], myhostname)) - { - ni_proplist_free(&pl); - return 1; - } - - if (!strcmp(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], "localhost")) - { - ni_proplist_free(&pl); - ni_addrtag(d, &addr, &tag); - if (sys_ismyaddress(addr.sin_addr.s_addr)) return 1; - } - - ni_proplist_free(&pl); - return 0; -} - -static int -secure_passwords() -{ - void *d, *d1; - int status; - ni_index where; - ni_id dir; - ni_namelist nl; - - status = ni_open(NULL, ".", &d); - while (status == NI_OK) - { - dir.nii_object = 0; - status = ni_lookupprop(d, &dir, "security_options", &nl); - if (status == NI_OK) - { - where = ni_namelist_match(nl, "secure_passwords"); - if (where != NI_INDEX_NULL) - { - ni_free(d); - return 1; - } - } - - d1 = d; - status = ni_open(d1, "..", &d); - ni_free(d1); - } - - return 0; -} - -static void -parse_server_tag(char *str, struct sockaddr_in *server, char **t) -{ - /* utility to parse a server/tag string */ - - int len, i; - char *host, *tag, *slash; - struct hostent *hent; - - len = strlen(str); - - /* find the "/" character */ - slash = index(str, '/'); - - /* check to see if the "/" is missing */ - if (slash == NULL) - { - fprintf(stderr, "incorrect format \"%s\" for domain name\n", str); - exit(1); - } - - /* find the location of the '/' */ - i = slash - str; - - /* check if host string is empty */ - if (i == 0) - { - fprintf(stderr, "incorrect format \"%s\" for domain name\n", str); - fprintf(stderr, "no server name specified\n"); - exit(1); - } - - /* check if tag string is empty */ - if (i == (len - 1)) - { - fprintf(stderr, "incorrect format \"%s\" for domain name\n", str); - fprintf(stderr, "no tag specified\n"); - exit(1); - } - - /* allocate some space for the host and tag */ - host = (char *)malloc(i + 1); - *t = (char *)malloc(len - i); - tag = *t; - - /* copy out the host */ - strncpy(host, str, i); - host[i] = '\0'; - - /* copy out the tag */ - strcpy(tag, slash + 1); - - /* try interpreting the host portion as an address */ - server->sin_addr.s_addr = inet_addr(host); - - if (server->sin_addr.s_addr == -1) - { - /* This isn't a valid address. Is it a known hostname? */ - hent = gethostbyname(host); - if (hent != NULL) - { - /* found a host with that name */ - bcopy(hent->h_addr, &server->sin_addr, hent->h_length); - } - else - { - fprintf(stderr, "Can't find address for %s\n", host); - free(host); - free(tag); - exit(1); - } - } - - free(host); -} - -static void * -domain_for_user(char *uname, char *locn, ni_id *dir) -{ - char *upath; - int status; - void *d, *d1; - struct sockaddr_in server; - char *tag; - int bytag; - - /* - * Find the user in NetInfo. - */ - upath = malloc(8 + strlen(uname)); - sprintf(upath, "/users/%s", uname); - - if (locn != NULL) - { - bytag = 1; - - if (locn[0] == '/') bytag = 0; - else if (!strncmp(locn, "./", 2)) bytag = 0; - else if (!strncmp(locn, "../", 3)) bytag = 0; - - if (bytag == 1) - { - parse_server_tag(locn, &server, &tag); - d = ni_connect(&server, tag); - if (d == (void *)NULL) return (void *)NULL; - } - else status = ni_open(NULL, locn, &d); - status = ni_pathsearch(d, dir, upath); - free(upath); - - if (status == NI_OK) return d; - - ni_free(d); - return (void *)NULL; - } - - status = ni_open(NULL, ".", &d); - while (status == NI_OK) - { - status = ni_pathsearch(d, dir, upath); - if (status == NI_OK) break; - d1 = d; - status = ni_open(d1, "..", &d); - ni_free(d1); - } - - free(upath); - - if (status == NI_OK) return d; - return (void *)NULL; -} - -int -netinfo_check_passwd(char *uname, char *locn) -{ - char *oldpw; - void *d; - int status; - ni_id dir; - ni_namelist nl; - - d = domain_for_user(uname, locn, &dir); - if (d == (void *)NULL) - { - fprintf(stderr, "user %s not found in NetInfo\n", uname); - exit(1); - } - - /* - * Read the passwd and uid from NetInfo. - */ - status = ni_lookupprop(d, &dir, "passwd", &nl); - if (status == NI_NOPROP) nl.ni_namelist_len = 0; - else if (status != NI_OK) - { - ni_free(d); - fprintf(stderr, "NetInfo read failed: %s\n", ni_error(status)); - exit(1); - } - - oldpw = NULL; - if (nl.ni_namelist_len > 0) oldpw = nl.ni_namelist_val[0]; - - checkpasswd(uname, oldpw); - ni_free(d); - return (0); -} diff --git a/chkpasswd.tproj/passwd.c b/chkpasswd.tproj/passwd.c index 2115573..ac50cd0 100644 --- a/chkpasswd.tproj/passwd.c +++ b/chkpasswd.tproj/passwd.c @@ -21,7 +21,6 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#define INFO_NETINFO 0 #define INFO_FILE 1 #define INFO_NIS 2 #define INFO_DIRECTORYSERVICES 3 @@ -39,7 +38,6 @@ #include #include #include -#include #include "stringops.h" #ifdef __SLICK__ @@ -49,7 +47,6 @@ static int literal = 0; extern int file_check_passwd(char *, char *); -extern int netinfo_check_passwd(char *, char *); extern int nis_check_passwd(char *, char *); extern int ds_check_passwd(char *, char *); @@ -84,11 +81,9 @@ usage() { fprintf(stderr, "usage: chkpasswd [-i infosystem] [-l location] [-c] [name]\n"); fprintf(stderr, "supported infosystems are:\n"); - fprintf(stderr, " netinfo\n"); fprintf(stderr, " file\n"); fprintf(stderr, " nis\n"); fprintf(stderr, " opendirectory\n"); - fprintf(stderr, "for netinfo, location may be a domain name or server/tag\n"); fprintf(stderr, "for file, location may be a file name (%s is the default)\n", _PASSWD_FILE); fprintf(stderr, "for nis, location may be a NIS domainname\n"); @@ -119,9 +114,7 @@ main(int argc, char *argv[]) usage(); } - if (!strcmp(argv[i], "NetInfo")) infosystem = INFO_NETINFO; - else if (!strcmp(argv[i], "netinfo")) infosystem = INFO_NETINFO; - else if (!strcmp(argv[i], "File")) infosystem = INFO_FILE; + if (!strcmp(argv[i], "File")) infosystem = INFO_FILE; else if (!strcmp(argv[i], "file")) infosystem = INFO_FILE; else if (!strcmp(argv[i], "NIS")) infosystem = INFO_NIS; else if (!strcmp(argv[i], "nis")) infosystem = INFO_NIS; @@ -161,9 +154,6 @@ main(int argc, char *argv[]) switch (infosystem) { - case INFO_NETINFO: - netinfo_check_passwd(user, locn); - break; case INFO_FILE: file_check_passwd(user, locn); break; diff --git a/chpass.tproj/Makefile b/chpass.tproj/Makefile index d0c8e02..8cb711e 100644 --- a/chpass.tproj/Makefile +++ b/chpass.tproj/Makefile @@ -12,13 +12,12 @@ NAME = chpass PROJECTVERSION = 2.8 PROJECT_TYPE = Tool -HFILES = chpass.h pathnames.h pw_copy.h pw_scan.h pw_util.h directory_service.h +HFILES = chpass.h open_directory.h pw_copy.h CFILES = chpass.c edit.c field.c pw_copy.c table.c util.c \ - directory_service.c ds_pw_util.c + open_directory.c -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble chpass.1 \ - Makefile.dist +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble chpass.1 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles @@ -32,8 +31,9 @@ DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) -HEADER_PATHS = -I../pwd_mkdb.tproj -I../vipw.tproj -FRAMEWORKS = -framework DirectoryService +HEADER_PATHS = -I../pwd_mkdb.tproj -I../vipw.tproj +FRAMEWORK_PATHS = -F/System/Library/PrivateFrameworks +FRAMEWORKS = -framework OpenDirectory -framework CoreFoundation PROJECT_HEADERS = pw_copy.h diff --git a/chpass.tproj/Makefile.dist b/chpass.tproj/Makefile.dist deleted file mode 100644 index b68ad10..0000000 --- a/chpass.tproj/Makefile.dist +++ /dev/null @@ -1,15 +0,0 @@ -# @(#)Makefile 8.2 (Berkeley) 4/2/94 - -PROG= chpass -SRCS= chpass.c edit.c field.c pw_copy.c pw_scan.c pw_util.c table.c util.c -BINOWN= root -BINMODE=4555 -.PATH: ${.CURDIR}/../../usr.sbin/pwd_mkdb ${.CURDIR}/../../usr.sbin/vipw -CFLAGS+=-I${.CURDIR}/../../usr.sbin/pwd_mkdb -I${.CURDIR}/../../usr.sbin/vipw -LINKS= ${BINDIR}/chpass ${BINDIR}/chfn ${BINDIR}/chpass ${BINDIR}/chsh -MLINKS= chpass.1 chfn.1 chpass.1 chsh.1 - -afterinstall: - chflags schg /usr/bin/chpass - -.include diff --git a/chpass.tproj/Makefile.postamble b/chpass.tproj/Makefile.postamble index 2630582..d24a24f 100644 --- a/chpass.tproj/Makefile.postamble +++ b/chpass.tproj/Makefile.postamble @@ -1,20 +1,18 @@ -VPATH += :../pwd_mkdb.tproj:../vipw.tproj +#VPATH += :../pwd_mkdb.tproj:../vipw.tproj INSTALL_AS_USER = root INSTALL_AS_GROUP = wheel -INSTALL_PERMISSIONS =4555 -#CHFLAGS = /usr/bin/chflags +INSTALL_PERMISSIONS = 4555 + after_install:: install -o $(INSTALL_AS_USER) -m 755 -d $(DSTROOT)/usr/share/man/man1 install -o $(INSTALL_AS_USER) -m 644 -c chpass.1 \ $(DSTROOT)/usr/share/man/man1 - $(LN) -s chpass.1 $(DSTROOT)/usr/share/man/man1/chfn.1 - $(LN) -s chpass.1 $(DSTROOT)/usr/share/man/man1/chsh.1 + $(LN) -sf chpass.1 $(DSTROOT)/usr/share/man/man1/chfn.1 + $(LN) -sf chpass.1 $(DSTROOT)/usr/share/man/man1/chsh.1 chown $(INSTALL_AS_USER):$(INSTALL_AS_GROUP) \ $(DSTROOT)/usr/share/man/man1/chfn.1 chown $(INSTALL_AS_USER):$(INSTALL_AS_GROUP) \ $(DSTROOT)/usr/share/man/man1/chsh.1 $(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)$(INSTALLDIR)/chfn $(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)$(INSTALLDIR)/chsh -# $(CHFLAGS) schg $(DSTROOT)$(INSTALLDIR)/$(NAME) - diff --git a/chpass.tproj/Makefile.preamble b/chpass.tproj/Makefile.preamble index 24ac6bf..56871f3 100644 --- a/chpass.tproj/Makefile.preamble +++ b/chpass.tproj/Makefile.preamble @@ -1,5 +1,6 @@ CLEAN_ALL_SUBPROJECTS = YES -OTHER_CFLAGS = -DDIRECTORY_SERVICE -OTHER_OFILES = pw_scan.o +OTHER_CFLAGS = -DOPEN_DIRECTORY -fconstant-cfstrings +OTHER_LDFLAGS = +OTHER_OFILES = OTHER_GENERATED_OFILES = $(VERS_OFILE) diff --git a/chpass.tproj/PB.project b/chpass.tproj/PB.project index 849c116..03849a4 100644 --- a/chpass.tproj/PB.project +++ b/chpass.tproj/PB.project @@ -3,11 +3,11 @@ FILESTABLE = { CLASSES = (); C_FILES = (); - HEADERSEARCH = (../pwd_mkdb.tproj, ../vipw.tproj); - H_FILES = (chpass.h, pathnames.h, pw_copy.h); + HEADERSEARCH = (); + H_FILES = (chpass.h, pw_copy.h, open_directory.h); OTHER_LIBS = (); - OTHER_LINKED = (chpass.c, edit.c, field.c, pw_copy.c, table.c, util.c); - OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, chpass.1, Makefile.dist); + OTHER_LINKED = (chpass.c, edit.c, field.c, pw_copy.c, table.c, util.c, open_directory.c); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, chpass.1); PROJECT_HEADERS = (pw_copy.h); SUBPROJECTS = (); }; diff --git a/chpass.tproj/chpass.1 b/chpass.tproj/chpass.1 index d515a76..aadaa97 100644 --- a/chpass.tproj/chpass.1 +++ b/chpass.tproj/chpass.1 @@ -9,11 +9,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -30,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)chpass.1 8.2 (Berkeley) 12/30/93 -.\" $FreeBSD: src/usr.bin/chpass/chpass.1,v 1.34 2002/12/24 13:41:47 ru Exp $ +.\" $FreeBSD: src/usr.bin/chpass/chpass.1,v 1.38.2.1 2005/09/24 01:59:39 keramida Exp $ .\" .Dd December 30, 1993 .Dt CHPASS 1 @@ -38,13 +34,18 @@ .Sh NAME .Nm chpass , .Nm chfn , -.Nm chsh , +.Nm chsh +.\".Nm ypchpass , +.\".Nm ypchfn , +.\".Nm ypchsh .Nd add or change user database information .Sh SYNOPSIS .Nm -.Op Fl a Ar list -.Op Fl p Ar encpass -.Op Fl e Ar expiretime +.\".Op Fl a Ar list +.\".Op Fl p Ar encpass +.\".Op Fl e Ar expiretime +.Op Fl l Ar location +.Op Fl u Ar authname .Op Fl s Ar newshell .Op user .Sh DESCRIPTION @@ -57,9 +58,22 @@ with or, by default, the current user. .Pp The +.Nm +utility +.Em cannot +change the user's password on Open Directory +systems. Use the +.Xr passwd 1 +utility instead. +.Pp +The .Nm chfn , and .Nm chsh +.\".Nm ypchpass , +.\".Nm ypchfn +.\"and +.\".Nm ypchsh utilities behave identically to .Nm . (There is only one program.) @@ -70,29 +84,36 @@ Only the information that the user is allowed to change is displayed. .Pp The options are as follows: .Bl -tag -width indent -.It Fl a -The super-user is allowed to directly supply a user database -entry, in the format specified by -.Xr passwd 5 , -as an argument. -This argument must be a colon -.Pq Dq \&: -separated list of all the -user database fields, although they may be empty. -[Note that this only changes the user database, -.Li master.passwd Ns .] -.It Fl p -The super-user is allowed to directly supply an encrypted password field, -in the format used by -.Xr crypt 3 , -as an argument. -[See the discussion in -.Xr getpwent 3 -about types of passwords; this option may not be appropriate.] -.It Fl e Ar expiretime -Change the account expire time. -This option is used to set the expire time -from a script as if it was done in the interactive editor. +.\".It Fl a +.\"The super-user is allowed to directly supply a user database +.\"entry, in the format specified by +.\".Xr passwd 5 , +.\"as an argument. +.\"This argument must be a colon +.\".Pq Dq \&: +.\"separated list of all the +.\"user database fields, although they may be empty. +.\".It Fl p +.\"The super-user is allowed to directly supply an encrypted password field, +.\"in the format used by +.\".Xr crypt 3 , +.\"as an argument. +.\".It Fl e Ar expiretime +.\"Change the account expire time. +.\"This option is used to set the expire time +.\"from a script as if it were done in the interactive editor. +.It Fl l Ar location +If not specified, +.Nm +will perform a search for the user record on all available +Open Directory nodes. +When specified, +.Nm +will edit the user record on the directory node at the given +.Ar location . +.It Fl u Ar authname +The user name to use when authenticating to the directory node containing the +user. .It Fl s Ar newshell Attempt to change the user's shell to .Ar newshell . @@ -103,60 +124,47 @@ Possible display items are as follows: .Bl -tag -width "Other Information:" -compact -offset indent .It Login: user's login name -.It Password: -user's encrypted password -[do -.Em not -use this to change a password; use -.Xr passwd 1 -instead] +.\".It Password: +.\"user's encrypted password .It Uid: user's login .It Gid: user's login group -.It Class: -user's general classification -.It Change: -password change time -.It Expire: -account expiration time +.It Generated uid: +user's UUID +.\".It Class: +.\"user's general classification +.\".It Change: +.\"password change time +.\".It Expire: +.\"account expiration time .It Full Name: -user's real name (*) -.\"user's real name -.\".It Office Location: -.\"user's office location (1) -.\".It Office Phone: -.\"user's office phone (1) -.\".It Home Phone: -.\"user's home phone (1) +user's real name +.It Office Location: +user's office location +.It Office Phone: +user's office phone +.It Home Phone: +user's home phone .\".It Other Information: -.\"any locally defined parameters for user (1) +.\"any locally defined parameters for user .It Home Directory: user's home directory .It Shell: user's login shell .Pp -.It NOTE(*) - +.\".It NOTE(1) - .\"In the actual master.passwd file, these fields are comma-delimited .\"fields embedded in the FullName field. -Historically, the so-call -.Qq GECOS -field in the user database entry contain the full name plus other information. -Only the full name is currently supported. .El .Pp The .Ar login field is the user name used to access the computer account. -.Pp -The -.Ar password -field contains the encrypted form of the user's password. -Do -.Em not -use this to change a password; use -.Xr passwd 1 -instead. +.\".Pp +.\"The +.\".Ar password +.\"field contains the encrypted form of the user's password. .Pp The .Ar uid @@ -167,7 +175,8 @@ Both of these fields should be unique across the system (and often across a group of systems) as they control file access. .Pp While it is possible to have multiple entries with identical login names -and/or identical user id's, it is usually a mistake to do so. Routines +and/or identical user id's, it is usually a mistake to do so. +Routines that manipulate these files will often return only one of the multiple entries, and that one by random selection. .Pp @@ -183,34 +192,38 @@ This field may be filled in with either a number or a group name (see .Xr group 5 ) . .Pp The -.Ar class -field references class descriptions in -.Pa /etc/login.conf -and is typically used to initialize the user's system resource limits -when they login. -.Pp -The -.Ar change -field is the date by which the password must be changed. -.Pp -The -.Ar expire -field is the date on which the account expires. -.Pp -Both the -.Ar change -and -.Ar expire -fields should be entered in the form -.Dq month day year -where -.Ar month -is the month name (the first three characters are sufficient), -.Ar day -is the day of the month, and -.Ar year -is the year. -.Pp +.Ar generated uid +field is the globally unique identifier (UUID) for the user. +.\".Pp +.\"The +.\".Ar class +.\"field references class descriptions in +.\".Pa /etc/login.conf +.\"and is typically used to initialize the user's system resource limits +.\"when they login. +.\".Pp +.\"The +.\".Ar change +.\"field is the date by which the password must be changed. +.\".Pp +.\"The +.\".Ar expire +.\"field is the date on which the account expires. +.\".Pp +.\"Both the +.\".Ar change +.\"and +.\".Ar expire +.\"fields should be entered in the form +.\".Dq month day year +.\"where +.\".Ar month +.\"is the month name (the first three characters are sufficient), +.\".Ar day +.\"is the day of the month, and +.\".Ar year +.\"is the year. +.\".Pp .\"Five fields are available for storing the user's .\".Ar full name , office location , .\".Ar work @@ -250,24 +263,22 @@ shell. Non-standard is defined as a shell not found in .Pa /etc/shells . .Pp -Once the information has been verified, -.Nm -uses -.Xr pwd_mkdb 8 -to update the user database. -.Sh LOOKUPD AND DIRECTORY SERVICE AWARENESS -User database entries (among other things) are under the control of -.Xr lookupd 8 -and may be physically located in many different places, including local -and remote -.Xr netinfo 5 -databases, directory service agents such as LDAP servers and flat file databases -such as -.Li master.passwd . +The +.Ar picture +field is the path to a picture to be displayed for the user. +.Sh OPEN DIRECTORY +User database entries are under the control of +.Xr DirectoryService 8 +and may be physically located in many different places, +including the local Directory Service node, +and remote LDAP servers. This version of .Nm -is currently limited to changing user database entries in the flat file -and local netinfo databases. +uses Open Directory to change user database information. +It does not interact with the historic flat file +database +.Pa /etc/master.passwd +. .Sh ENVIRONMENT The .Xr vi 1 @@ -279,40 +290,24 @@ When the editor terminates, the information is re-read and used to update the user database itself. Only the user, or the super-user, may edit the information associated with the user. -.Pp -See -.Xr pwd_mkdb 8 -for an explanation of the impact of setting the -.Ev PW_SCAN_BIG_IDS -environment variable. .Sh FILES -.Bl -tag -width /etc/master.passwd -compact -.It Pa /etc/master.passwd -the user database -.It Pa /etc/passwd -a Version 7 format password file -.It Pa /etc/chpass.XXXXXX -temporary copy of the password file +.Bl -tag -width /tmp/chpass.XXXXXX -compact +.It Pa /tmp/chpass.XXXXXX +temporary copy of the data to edit .It Pa /etc/shells the list of approved shells .El .Sh SEE ALSO -.Xr finger 1 , +.\".Xr finger 1 , .Xr login 1 , .Xr passwd 1 , .Xr getusershell 3 , -.Xr login.conf 5 , -.Xr passwd 5 , -.Xr pwd_mkdb 8 , -.Xr vipw 8 +.Xr passwd 5 .Rs .%A Robert Morris -and .%A Ken Thompson .%T "UNIX Password security" .Re -.Sh BUGS -User information should (and eventually will) be stored elsewhere. .Sh HISTORY The .Nm diff --git a/chpass.tproj/chpass.c b/chpass.tproj/chpass.c index 331fbc4..596d31a 100644 --- a/chpass.tproj/chpass.c +++ b/chpass.tproj/chpass.c @@ -1,29 +1,35 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /*- - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +41,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -54,67 +60,98 @@ * SUCH DAMAGE. */ +#if 0 +#if 0 #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1988, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ +#ifndef lint +static char sccsid[] = "@(#)chpass.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ +#endif +#include +__FBSDID("$FreeBSD: src/usr.bin/chpass/chpass.c,v 1.27.8.1 2006/09/29 06:13:20 marck Exp $"); +#endif + #include #include #include #include #include -#include #include #include -#include #include #include #include #include #include +#ifdef YP +#include +#endif +#ifndef OPEN_DIRECTORY #include -#include -#include "pw_copy.h" +#include +#endif #include "chpass.h" -#include "pathnames.h" -#ifdef DIRECTORY_SERVICE -#include "directory_service.h" -#define PWSETFIELD(field, in, out) if(in->field) out.field = strdup(in->field) -#endif /* DIRECTORY_SERVICE */ +int master_mode; -char *progname = "chpass"; -char *tempname; -uid_t uid; -#ifdef DIRECTORY_SERVICE -int dswhere; -#endif /* DIRECTORY_SERVICE */ +#ifdef OPEN_DIRECTORY +#include "open_directory.h" +char *progname = NULL; +CFStringRef DSPath = NULL; +#endif /* OPEN_DIRECTORY */ -void baduser __P((void)); -void usage __P((void)); +static void baduser(void); +static void usage(void); int -main(argc, argv) - int argc; - char **argv; +main(int argc, char *argv[]) { - enum { NEWSH, LOADENTRY, EDITENTRY } op; - struct passwd *pw, lpw; + enum { NEWSH, LOADENTRY, EDITENTRY, NEWPW, NEWEXP } op; +#ifndef OPEN_DIRECTORY + struct passwd lpw, *old_pw, *pw; int ch, pfd, tfd; - char *arg; -#ifdef DIRECTORY_SERVICE - struct passwd pworig; - char *task_argv[3] = { NULL }; -#endif /* DIRECTORY_SERVICE */ + const char *password; +#else + struct passwd *old_pw, *pw; + int ch, tfd; + char tfn[MAXPATHLEN]; +#endif + char *arg = NULL; + uid_t uid; +#ifdef YP + struct ypclnt *ypclnt; + const char *yp_domain = NULL, *yp_host = NULL; +#endif +#ifdef OPEN_DIRECTORY + CFStringRef username = NULL; + CFStringRef authname = NULL; + CFStringRef location = NULL; + + progname = strrchr(argv[0], '/'); + if (progname) progname++; + else progname = argv[0]; +#endif /* OPEN_DIRECTORY */ + pw = old_pw = NULL; op = EDITENTRY; - while ((ch = getopt(argc, argv, "a:s:")) != EOF) - switch(ch) { +#ifdef OPEN_DIRECTORY + while ((ch = getopt(argc, argv, "a:s:l:u:")) != -1) +#else /* OPEN_DIRECTORY */ +#ifdef YP + while ((ch = getopt(argc, argv, "a:p:s:e:d:h:loy")) != -1) +#else + while ((ch = getopt(argc, argv, "a:p:s:e:")) != -1) +#endif +#endif /* OPEN_DIRECTORY */ + switch (ch) { case 'a': op = LOADENTRY; arg = optarg; @@ -123,223 +160,296 @@ main(argc, argv) op = NEWSH; arg = optarg; break; +#ifndef OPEN_DIRECTORY + case 'p': + op = NEWPW; + arg = optarg; + break; + case 'e': + op = NEWEXP; + arg = optarg; + break; +#ifdef YP + case 'd': + yp_domain = optarg; + break; + case 'h': + yp_host = optarg; + break; + case 'l': + case 'o': + case 'y': + /* compatibility */ + break; +#endif +#else /* OPEN_DIRECTORY */ + case 'l': + location = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); + break; + case 'u': + authname = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); + break; +#endif case '?': default: usage(); } + argc -= optind; argv += optind; + if (argc > 1) + usage(); + uid = getuid(); - if (op == EDITENTRY || op == NEWSH) -#ifdef DIRECTORY_SERVICE - { -#endif /* DIRECTORY_SERVICE */ - switch(argc) { - case 0: - if (!(pw = getpwuid(uid))) - errx(1, "unknown user: uid %u", uid); - break; - case 1: - if (!(pw = getpwnam(*argv))) + if (op == EDITENTRY || op == NEWSH || op == NEWPW || op == NEWEXP) { + if (argc == 0) { + if ((pw = getpwuid(uid)) == NULL) + errx(1, "unknown user: uid %lu", + (unsigned long)uid); + } else { + if ((pw = getpwnam(*argv)) == NULL) errx(1, "unknown user: %s", *argv); -#ifndef DIRECTORY_SERVICE - if (uid && uid != pw->pw_uid) +#ifndef OPEN_DIRECTORY + if (uid != 0 && uid != pw->pw_uid) baduser(); -#endif /* DIRECTORY_SERVICE */ - break; - default: - usage(); +#endif } - /* getpwnam(3) returns a pointer to local storage */ - lpw = *pw; - PWSETFIELD(pw_name, pw, lpw); - PWSETFIELD(pw_passwd, pw, lpw); - PWSETFIELD(pw_class, pw, lpw); - PWSETFIELD(pw_gecos, pw, lpw); - PWSETFIELD(pw_dir, pw, lpw); - PWSETFIELD(pw_shell, pw, lpw); +#ifndef OPEN_DIRECTORY + /* Make a copy for later verification */ + if ((pw = pw_dup(pw)) == NULL || + (old_pw = pw_dup(pw)) == NULL) + err(1, "pw_dup"); +#endif + } - pw = &lpw; +#if OPEN_DIRECTORY + master_mode = (uid == 0); -#ifdef DIRECTORY_SERVICE - if ((dswhere = wherepwent(pw->pw_name)) < 0) { - if(dswhere > E_NOTFOUND) - errc(1, dswhere, "wherepwent"); - else - errx(1, "wherepwent returned %d", dswhere); - } - switch(dswhere) { - case WHERE_REMOTENI: - errx(1, -"Can't change info for user \"%s\", which resides in the\n" -"netinfo domain \"%s\"", - pw->pw_name, DSPath); - case WHERE_DS: - errx(1, -"Can't change info for user \"%s\", which resides in the\n" -"Directory Service path \"%s\"", - pw->pw_name, DSPath); - case WHERE_NIS: - errx(1, -"Can't change info for user \"%s\", which resides in NIS", - pw->pw_name); - case WHERE_LOCALNI: - pworig = *pw; - PWSETFIELD(pw_name, pw, pworig); - PWSETFIELD(pw_passwd, pw, pworig); - PWSETFIELD(pw_class, pw, pworig); - PWSETFIELD(pw_gecos, pw, pworig); - PWSETFIELD(pw_dir, pw, pworig); - PWSETFIELD(pw_shell, pw, pworig); - /* drop through */ - default: - if (uid && uid != pw->pw_uid) - baduser(); - } + /* + * Find the user record and copy its details. + */ + username = CFStringCreateWithCString(NULL, pw->pw_name, kCFStringEncodingUTF8); + + if (strcmp(progname, "chsh") == 0 || op == NEWSH) { + cfprintf(stderr, "Changing shell for %@.\n", username); + } else if (strcmp(progname, "chfn") == 0) { + cfprintf(stderr, "Changing finger information for %@.\n", username); + } else if (strcmp(progname, "chpass") == 0) { + cfprintf(stderr, "Changing account information for %@.\n", username); } -#endif /* DIRECTORY_SERVICE */ + + /* + * odGetUser updates DSPath global variable, performs authentication + * if necessary, and extracts the attributes. + */ + CFDictionaryRef attrs_orig = NULL; + CFDictionaryRef attrs = NULL; + ODRecordRef rec = odGetUser(location, authname, username, &attrs_orig); + + if (!rec || !attrs_orig) exit(1); +#endif /* OPEN_DIRECTORY */ + +#ifdef YP + if (pw != NULL && (pw->pw_fields & _PWF_SOURCE) == _PWF_NIS) { + ypclnt = ypclnt_new(yp_domain, "passwd.byname", yp_host); + master_mode = (ypclnt != NULL && + ypclnt_connect(ypclnt) != -1 && + ypclnt_havepasswdd(ypclnt) == 1); + ypclnt_free(ypclnt); + } else +#endif + master_mode = (uid == 0); if (op == NEWSH) { /* protect p_shell -- it thinks NULL is /bin/sh */ if (!arg[0]) usage(); - if (p_shell(arg, pw, (ENTRY *)NULL)) - pw_error((char *)NULL, 0, 1); + if (p_shell(arg, pw, (ENTRY *)NULL) == -1) + exit(1); +#ifdef OPEN_DIRECTORY + else { + ENTRY* ep; + + setrestricted(attrs_orig); + + for (ep = list; ep->prompt; ep++) { + if (strncasecmp(ep->prompt, "shell", ep->len) == 0) { + if (!ep->restricted) { + CFStringRef shell = CFStringCreateWithCString(NULL, arg, kCFStringEncodingUTF8); + if (shell) { + attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (attrs) CFDictionarySetValue((CFMutableDictionaryRef)attrs, CFSTR(kDS1AttrUserShell), shell); + CFRelease(shell); + } + } else { + warnx("shell is restricted"); + exit(1); + } + } + } + } +#endif } +#ifndef OPEN_DIRECTORY + if (op == NEWEXP) { + if (uid) /* only root can change expire */ + baduser(); + if (p_expire(arg, pw, (ENTRY *)NULL) == -1) + exit(1); + } +#endif + if (op == LOADENTRY) { -#ifdef DIRECTORY_SERVICE - warnx("-a is only supported for %s", MasterPasswd); - dswhere = WHERE_FILES; -#endif /* DIRECTORY_SERVICE */ if (uid) baduser(); +#ifdef OPEN_DIRECTORY + warnx("-a is not supported for Open Directory."); + exit(1); +#else pw = &lpw; - if (!pw_scan(arg, pw, NULL)) + old_pw = NULL; + if (!__pw_scan(arg, pw, _PWSCAN_WARN|_PWSCAN_MASTER)) exit(1); +#endif /* OPEN_DIRECTORY */ } - /* - * The temporary file/file descriptor usage is a little tricky here. - * 1: We start off with two fd's, one for the master password - * file (used to lock everything), and one for a temporary file. - * 2: Display() gets an fp for the temporary file, and copies the - * user's information into it. It then gives the temporary file - * to the user and closes the fp, closing the underlying fd. - * 3: The user edits the temporary file some number of times. - * 4: Verify() gets an fp for the temporary file, and verifies the - * contents. It can't use an fp derived from the step #2 fd, - * because the user's editor may have created a new instance of - * the file. Once the file is verified, its contents are stored - * in a password structure. The verify routine closes the fp, - * closing the underlying fd. - * 5: Delete the temporary file. - * 6: Get a new temporary file/fd. Pw_copy() gets an fp for it - * file and copies the master password file into it, replacing - * the user record with a new one. We can't use the first - * temporary file for this because it was owned by the user. - * Pw_copy() closes its fp, flushing the data and closing the - * underlying file descriptor. We can't close the master - * password fp, or we'd lose the lock. - * 7: Call pw_mkdb() (which renames the temporary file) and exit. - * The exit closes the master passwd fp/fd. - */ - pw_init(); -#ifdef DIRECTORY_SERVICE - if (dswhere == WHERE_FILES) -#endif /* DIRECTORY_SERVICE */ - pfd = pw_lock(); - tfd = pw_tmp(); +#ifndef OPEN_DIRECTORY + if (op == NEWPW) { + if (uid) + baduser(); - if (op == EDITENTRY) { -#ifdef DIRECTORY_SERVICE - setrestricted(dswhere, pw); -#endif /* DIRECTORY_SERVICE */ - display(tfd, pw); - edit(pw); - (void)unlink(tempname); -#ifdef DIRECTORY_SERVICE - if (dswhere == WHERE_FILES) -#endif /* DIRECTORY_SERVICE */ - tfd = pw_tmp(); + if (strchr(arg, ':')) + errx(1, "invalid format for password"); + pw->pw_passwd = arg; } - -#ifdef DIRECTORY_SERVICE - switch (dswhere) { - case WHERE_LOCALNI: - update_local_ni(&pworig, pw); - break; - case WHERE_FILES: -#endif /* DIRECTORY_SERVICE */ - pw_copy(pfd, tfd, pw); +#endif /* OPEN_DIRECTORY */ - if (pw_mkdb() != 0) - pw_error((char *)NULL, 0, 1); -#ifdef DIRECTORY_SERVICE + if (op == EDITENTRY) { +#ifdef OPEN_DIRECTORY + setrestricted(attrs_orig); + snprintf(tfn, sizeof(tfn), "/tmp/%s.XXXXXX", progname); + if ((tfd = mkstemp(tfn)) == -1) + err(1, "%s", tfn); + attrs = (CFMutableDictionaryRef)edit(tfn, attrs_orig); + (void)unlink(tfn); +#else + /* + * We don't really need pw_*() here, but pw_edit() (used + * by edit()) is just too useful... + */ + if (pw_init(NULL, NULL)) + err(1, "pw_init()"); + if ((tfd = pw_tmp(-1)) == -1) { + pw_fini(); + err(1, "pw_tmp()"); + } + free(pw); + pw = edit(pw_tempname(), old_pw); + pw_fini(); + if (pw == NULL) + err(1, "edit()"); + /* + * pw_equal does not check for crypted passwords, so we + * should do it explicitly + */ + if (pw_equal(old_pw, pw) && + strcmp(old_pw->pw_passwd, pw->pw_passwd) == 0) + errx(0, "user information unchanged"); +#endif /* OPEN_DIRECTORY */ } - task_argv[0] = "/usr/sbin/lookupd"; - task_argv[1] = "-flushcache"; - task_argv[2] = NULL; - LaunchTaskWithPipes( task_argv[0], task_argv, NULL, NULL ); -#endif /* DIRECTORY_SERVICE */ - exit(0); -} -#ifdef DIRECTORY_SERVICE -// read from 0 -int LaunchTaskWithPipes(const char *path, char *const argv[], int *outPipe0, int *outPipe1) -{ - int outputPipe[2]; - pid_t pid; - - if (outPipe0 != NULL) - pipe(outputPipe); - - pid = fork(); - if (pid == -1) - return -1; - - /* Handle the child */ - if (pid == 0) - { - int result = -1; - - if (outPipe0 != NULL) - dup2(outputPipe[1], fileno(stdout)); - - result = execv(path, argv); - if (result == -1) { - _exit(1); - } - - /* This should never be reached */ - _exit(1); +#ifndef OPEN_DIRECTORY + if (old_pw && !master_mode) { + password = getpass("Password: "); + if (strcmp(crypt(password, old_pw->pw_passwd), + old_pw->pw_passwd) != 0) + baduser(); + } else { + password = ""; } +#endif + +#ifdef OPEN_DIRECTORY + odUpdateUser(rec, attrs_orig, attrs); - /* Now the parent */ - if ( outPipe0 != NULL ) - *outPipe0 = outputPipe[0]; - if ( outPipe1 != NULL ) - *outPipe1 = outputPipe[1]; + if (rec) CFRelease(rec); + exit(0); return 0; +#else /* OPEN_DIRECTORY */ + exit(0); + if (old_pw != NULL) + pw->pw_fields |= (old_pw->pw_fields & _PWF_SOURCE); + switch (pw->pw_fields & _PWF_SOURCE) { +#ifdef YP + case _PWF_NIS: + ypclnt = ypclnt_new(yp_domain, "passwd.byname", yp_host); + if (ypclnt == NULL || + ypclnt_connect(ypclnt) == -1 || + ypclnt_passwd(ypclnt, pw, password) == -1) { + warnx("%s", ypclnt->error); + ypclnt_free(ypclnt); + exit(1); + } + ypclnt_free(ypclnt); + errx(0, "NIS user information updated"); +#endif /* YP */ + case 0: + case _PWF_FILES: + if (pw_init(NULL, NULL)) + err(1, "pw_init()"); + if ((pfd = pw_lock()) == -1) { + pw_fini(); + err(1, "pw_lock()"); + } + if ((tfd = pw_tmp(-1)) == -1) { + pw_fini(); + err(1, "pw_tmp()"); + } + if (pw_copy(pfd, tfd, pw, old_pw) == -1) { + pw_fini(); + err(1, "pw_copy"); + } + if (pw_mkdb(pw->pw_name) == -1) { + pw_fini(); + err(1, "pw_mkdb()"); + } + pw_fini(); + errx(0, "user information updated"); + break; + default: + errx(1, "unsupported passwd source"); + } +#endif /* OPEN_DIRECTORY */ } -#endif /* DIRECTORY_SERVICE */ -void -baduser() +static void +baduser(void) { errx(1, "%s", strerror(EACCES)); } -void -usage() +static void +usage(void) { - (void)fprintf(stderr, "usage: chpass [-a list] [-s shell] [user]\n"); + (void)fprintf(stderr, + "usage: chpass%s %s [user]\n", +#ifdef OPEN_DIRECTORY + "", + "[-l location] [-u authname] [-s shell]"); +#else /* OPEN_DIRECTORY */ +#ifdef YP + " [-d domain] [-h host]", +#else + "", +#endif + "[-a list] [-p encpass] [-s shell] [-e mmm dd yy]"); +#endif /* OPEN_DIRECTORY */ exit(1); } diff --git a/chpass.tproj/chpass.h b/chpass.tproj/chpass.h index 6aab2a2..8ce5781 100644 --- a/chpass.tproj/chpass.h +++ b/chpass.tproj/chpass.h @@ -1,29 +1,35 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1988, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +41,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -53,90 +59,74 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)chpass.h 8.4 (Berkeley) 4/2/94 + * @(#)chpass.h 8.4 (Berkeley) 4/2/94 + * $FreeBSD: src/usr.bin/chpass/chpass.h,v 1.7 2004/01/18 21:46:39 charnier Exp $ */ -#ifdef DIRECTORY_SERVICE -#include -#include - -struct display { - struct passwd *pw; - char *fullname; - char *location; - char *officephone; - char *homephone; -}; +#ifdef OPEN_DIRECTORY +#include "open_directory.h" -int LaunchTaskWithPipes(const char *path, char *const argv[], int *outPipe0, int *outPipe1); -#endif /* DIRECTORY_SERVICE */ +extern char* progname; +extern CFStringRef DSPath; +#endif /* OPEN_DIRECTORY */ struct passwd; typedef struct _entry { - char *prompt; -#ifdef DIRECTORY_SERVICE + const char *prompt; +#ifdef OPEN_DIRECTORY void (*display)(); -#endif /* DIRECTORY_SERVICE */ - int (*func)(), restricted, len; +#endif + int (*func)(char *, struct passwd *, struct _entry *); + int restricted; + size_t len; +#if OPEN_DIRECTORY + char *except; + CFStringRef attrName; +#else /* OPEN_DIRECTORY */ char *except, *save; +#endif /* OPEN_DIRECTORY */ } ENTRY; /* Field numbers. */ -#ifdef DIRECTORY_SERVICE -#define E_LOGIN 0 -#define E_PASSWD 1 -#define E_UID 2 -#define E_GID 3 -#define E_CHANGE 4 -#define E_EXPIRE 5 -#define E_CLASS 6 -#define E_HOME 7 -#define E_SHELL 8 -#define E_NAME 9 -#define E_LOCATE 10 -#define E_BPHONE 11 -#define E_HPHONE 12 -#else /* DIRECTORY_SERVICE */ #define E_BPHONE 8 #define E_HPHONE 9 #define E_LOCATE 10 #define E_NAME 7 -#define E_SHELL 12 -#endif /* DIRECTORY_SERVICE */ +#define E_OTHER 11 +#define E_SHELL 13 extern ENTRY list[]; -extern uid_t uid; +extern int master_mode; + +#ifdef OPEN_DIRECTORY +/* edit.c */ +void display_time(CFDictionaryRef, CFStringRef, const char*, FILE *); +void display_string(CFDictionaryRef, CFStringRef, const char*, FILE *); +CFDictionaryRef edit(const char *tfn, CFDictionaryRef pw); + +/* util.c */ +int cfprintf(FILE* file, const char* format, ...); +int editfile(const char* tfn); +#endif /* OPEN_DIRECTORY */ -int atot __P((char *, time_t *)); -#ifdef DIRECTORY_SERVICE -void d_change __P((struct display *, FILE *)); -void d_class __P((struct display *, FILE *)); -void d_expire __P((struct display *, FILE *)); -void d_fullname __P((struct display *, FILE *)); -void d_gid __P((struct display *, FILE *)); -void d_hdir __P((struct display *, FILE *)); -void d_homephone __P((struct display *, FILE *)); -void d_login __P((struct display *, FILE *)); -void d_location __P((struct display *, FILE *)); -void d_officephone __P((struct display *, FILE *)); -void d_passwd __P((struct display *, FILE *)); -void d_shell __P((struct display *, FILE *)); -void d_uid __P((struct display *, FILE *)); -#endif /* DIRECTORY_SERVICE */ -void display __P((int, struct passwd *)); -void edit __P((struct passwd *)); -char *ok_shell __P((char *)); -int p_change __P((char *, struct passwd *, ENTRY *)); -int p_class __P((char *, struct passwd *, ENTRY *)); -int p_expire __P((char *, struct passwd *, ENTRY *)); -int p_gecos __P((char *, struct passwd *, ENTRY *)); -int p_gid __P((char *, struct passwd *, ENTRY *)); -int p_hdir __P((char *, struct passwd *, ENTRY *)); -int p_login __P((char *, struct passwd *, ENTRY *)); -int p_login __P((char *, struct passwd *, ENTRY *)); -int p_passwd __P((char *, struct passwd *, ENTRY *)); -int p_shell __P((char *, struct passwd *, ENTRY *)); -int p_uid __P((char *, struct passwd *, ENTRY *)); -char *ttoa __P((time_t)); -int verify __P((struct passwd *)); +int atot(char *, time_t *); +#ifndef OPEN_DIRECTORY +struct passwd *edit(const char *, struct passwd *); +#endif /* OPEN_DIRECTORY */ +int ok_shell(char *); +char *dup_shell(char *); +int p_change(char *, struct passwd *, ENTRY *); +int p_class(char *, struct passwd *, ENTRY *); +int p_expire(char *, struct passwd *, ENTRY *); +int p_gecos(char *, struct passwd *, ENTRY *); +int p_gid(char *, struct passwd *, ENTRY *); +int p_hdir(char *, struct passwd *, ENTRY *); +int p_login(char *, struct passwd *, ENTRY *); +int p_passwd(char *, struct passwd *, ENTRY *); +int p_shell(char *, struct passwd *, ENTRY *); +int p_uid(char *, struct passwd *, ENTRY *); +#ifdef OPEN_DIRECTORY +int p_uuid(char *, struct passwd *, ENTRY *); +#endif /* OPEN_DIRECTORY */ +char *ttoa(time_t); diff --git a/chpass.tproj/directory_service.c b/chpass.tproj/directory_service.c deleted file mode 100644 index b857cf5..0000000 --- a/chpass.tproj/directory_service.c +++ /dev/null @@ -1,713 +0,0 @@ -#ifdef DIRECTORY_SERVICE - -#include "directory_service.h" -#include "chpass.h" -#include -#include - -#include -extern int errno; - -#define CONFIGNAMELEN 14 -#define GLOBALCONFIGLEN 20 -#define LOOKUPORDERLEN 13 -#define LINESIZE 128 -#define NETINFOROOTLEN 13 -#define NLIST 13 -#define REMOTEINFOLEN 9 -#define USERCONFIGLEN 18 - -/*--------------------------------------------------------------------------- - * Global variables - *---------------------------------------------------------------------------*/ -char *DSPath = NULL; -const char MasterPasswd[] = "/etc/master.passwd"; - -/*--------------------------------------------------------------------------- - * Local variables - *---------------------------------------------------------------------------*/ -static char Agent[] = "Agent"; -static char ConfigName[] = "_config_name: "; -static char DSFiles[] = "/BSD/local"; -static char FFPatFmt[] = "^%s:"; -static char GlobalConfig[] = "Global Configuration"; -static char LocalNI[] = "/NetInfo/DefaultLocalNode"; -static char LookupOrder[] = "LookupOrder: "; -static char LookupOrderSep[] = " "; -static char NetinfoRoot[] = "/NetInfo/root"; -static char NiclPathFmt[] = "/users/%s"; -static char NISPatFmt[] = "/usr/bin/ypcat passwd.byname | /usr/bin/grep -q '^%s:'"; -static char RemoteNI[] = "/NetInfo/"; -static char UserConfig[] = "User Configuration"; -static unsigned char RestrictedFFRoot[] = { - 0, /*E_LOGIN */ - 0, /*E_PASSWD */ - 0, /*E_UID */ - 0, /*E_GID */ - 0, /*E_CHANGE */ - 0, /*E_EXPIRE */ - 0, /*E_CLASS */ - 0, /*E_HOME */ - 0, /*E_SHELL */ - 0, /*E_NAME */ - 1, /*E_LOCATE */ - 1, /*E_BPHONE */ - 1, /*E_HPHONE */ -}; -static unsigned char RestrictedFFUser[] = { - 1, /*E_LOGIN */ - 1, /*E_PASSWD */ - 1, /*E_UID */ - 1, /*E_GID */ - 1, /*E_CHANGE */ - 1, /*E_EXPIRE */ - 1, /*E_CLASS */ - 1, /*E_HOME */ - 0, /*E_SHELL */ - 0, /*E_NAME */ - 1, /*E_LOCATE */ - 1, /*E_BPHONE */ - 1, /*E_HPHONE */ -}; -static unsigned char RestrictedLocalNIRoot[] = { - 0, /*E_LOGIN */ - 1, /*E_PASSWD */ - 0, /*E_UID */ - 0, /*E_GID */ - 0, /*E_CHANGE */ - 0, /*E_EXPIRE */ - 0, /*E_CLASS */ - 0, /*E_HOME */ - 0, /*E_SHELL */ - 0, /*E_NAME */ - 1, /*E_LOCATE */ - 1, /*E_BPHONE */ - 1, /*E_HPHONE */ -}; -static unsigned char RestrictedLocalNIUser[] = { - 1, /*E_LOGIN */ - 1, /*E_PASSWD */ - 1, /*E_UID */ - 1, /*E_GID */ - 1, /*E_CHANGE */ - 1, /*E_EXPIRE */ - 1, /*E_CLASS */ - 1, /*E_HOME */ - 0, /*E_SHELL */ - 0, /*E_NAME */ - 1, /*E_LOCATE */ - 1, /*E_BPHONE */ - 1, /*E_HPHONE */ -}; - -#define NWHERE 4 - -typedef int (*wherefunc)(const char *); - -static int compar(const void *, const void *); -static int runnicl(char *name, char *key, char *val); -static int whereCache(const char *); -static int whereDS(const char *); -static int whereFF(const char *); -static int whereNI(const char *); -static int whereNIL(const char *); -static int whereNIS(const char *); - -/*--------------------------------------------------------------------------- - * WhereList determines what functions to call when the LookupOrder is followed - *---------------------------------------------------------------------------*/ -struct where { - char *agent; - int len; - wherefunc func; -} WhereList[] = { - {"Cache", 5, whereCache}, - {"DS", 2, whereDS}, - {"FF", 2, whereFF}, - {"NI", 2, whereNI}, - {"NIL", 3, whereNIL}, - {"NIS", 3, whereNIS}, -}; - -#define PATINDEX 2 -static char *Grep[] = { - "/usr/bin/grep", - "-q", - NULL, /* pattern goes here */ - (char *)MasterPasswd, - NULL -}; - -#define NICLPATHINDEX 3 -#define NICLKEYINDEX 4 -#define NICLVALUEINDEX 5 -static char *Nicl[] = { - "/usr/bin/nicl", - ".", - "-create", - NULL, /* path goes here */ - NULL, /* key goes here */ - NULL, /* value goes here */ - NULL -}; - -#define YPCATINDEX 2 -static char *Ypcat[] = { - "/bin/sh", - "-c", - NULL, /* ypcat cmd goes here */ - NULL -}; - -/*--------------------------------------------------------------------------- - * compar - called by bsearch() to search WhereList for an agent - *---------------------------------------------------------------------------*/ -#define A ((const struct where *)a) -#define KEY ((const char *)key) -static int -compar(const void *key, const void *a) -{ - int result = strncmp(KEY, A->agent, A->len); - if(result) - return result; - if(KEY[A->len] == 0) - return 0; - return strcmp(KEY + A->len, Agent); -} -#undef KEY -#undef A - -/*--------------------------------------------------------------------------- - * runnicl - run the nicl command to update local netinfo fields - *---------------------------------------------------------------------------*/ -static int -runnicl(char *name, char *key, char *val) -{ - char path[128]; - pid_t pid; - int estat; - int status; - - IF((pid = fork()) >= 0) { - if(pid == 0) { - sprintf(path, NiclPathFmt, name); - Nicl[NICLPATHINDEX] = path; - Nicl[NICLKEYINDEX] = key; - Nicl[NICLVALUEINDEX] = val; - /*--------------------------------------------------------------- - * Become fully root to call nicl - *---------------------------------------------------------------*/ - setuid(geteuid()); - execv(Nicl[0], Nicl); - _exit(1); - } - if(waitpid(pid, &estat, 0) < 0) { - status = errno; - break; - } - if(!WIFEXITED(estat)) { - status = E_NICLFAILED; - break; - } - status = (WEXITSTATUS(estat) == 0 ? 0 : E_NICLFAILED); - } CLEANUP { - } ELSE { - status = errno; - } ENDIF - return status; -} -/*--------------------------------------------------------------------------- - * PUBLIC setrestricted - sets the restricted flag - *---------------------------------------------------------------------------*/ -void -setrestricted(int where, struct passwd *pw) -{ - unsigned char *restricted; - int i; - ENTRY *ep; - - switch(where) - { - case WHERE_FILES: - restricted = uid ? RestrictedFFUser : RestrictedFFRoot; - break; - case WHERE_LOCALNI: - restricted = uid ? RestrictedLocalNIUser : RestrictedLocalNIRoot; - break; - default: - return; - } - - for (ep = list, i = NLIST; i > 0; i--) - (ep++)->restricted = *restricted++; - - if (uid && !ok_shell(pw->pw_shell)) - list[E_SHELL].restricted = 1; -} - -/*--------------------------------------------------------------------------- - * PUBLIC update_local_ni - update local netinfo - *---------------------------------------------------------------------------*/ -void -update_local_ni(struct passwd *pworig, struct passwd *pw) -{ - char buf[64]; - char *np, *op, *bp; - - if(pworig->pw_uid != pw->pw_uid) { - sprintf(buf, "%d", pw->pw_uid); - runnicl(pworig->pw_name, "uid", buf); - } - if(pworig->pw_gid != pw->pw_gid) { - sprintf(buf, "%d", pw->pw_gid); - runnicl(pworig->pw_name, "gid", buf); - } - if(pworig->pw_change != pw->pw_change) { - sprintf(buf, "%lu", pw->pw_change); - runnicl(pworig->pw_name, "change", buf); - } - if(pworig->pw_expire != pw->pw_expire) { - sprintf(buf, "%lu", pw->pw_expire); - runnicl(pworig->pw_name, "expire", buf); - } - if(strcmp(pworig->pw_dir, pw->pw_dir) != 0) - runnicl(pworig->pw_name, "home", pw->pw_dir); - if(strcmp(pworig->pw_shell, pw->pw_shell) != 0) - runnicl(pworig->pw_name, "shell", pw->pw_shell); - if(strcmp(pworig->pw_class, pw->pw_class) != 0) - runnicl(pworig->pw_name, "class", pw->pw_class); - - bp = pworig->pw_gecos; - op = strsep(&bp, ","); - if(!op) - op = ""; - bp = pw->pw_gecos; - np = strsep(&bp, ","); - if(!np) - np = ""; - if(strcmp(op, np) != 0) - runnicl(pworig->pw_name, "realname", np); - - if(strcmp(pworig->pw_name, pw->pw_name) != 0) - runnicl(pworig->pw_name, "name", pw->pw_name); - - warnx("netinfo domain \"%s\" updated", DSPath); -} - -/*--------------------------------------------------------------------------- - * whereCache - we skip the cache - *---------------------------------------------------------------------------*/ -static int -whereCache(const char *name) -{ - return E_NOTFOUND; -} - -/*--------------------------------------------------------------------------- - * whereDS - call DirectoryService. This does both netinfo and other directory - * services, so we cache the value so we only process once. - *---------------------------------------------------------------------------*/ -static int -whereDS(const char *name) -{ - tDirReference dsRef; - static tDirStatus status; - static int dsCached = 0; - - if(dsCached) - return status; - dsCached = 1; - IF((status = dsOpenDirService(&dsRef)) == eDSNoErr) { - tDataBuffer *dataBuff; - - IF((dataBuff = dsDataBufferAllocate(dsRef, 4096)) != NULL) { - tContextData context = NULL; - unsigned long nodeCount; - - /*--------------------------------------------------------------- - * Find and open the search node. - *---------------------------------------------------------------*/ - IF((status = dsFindDirNodes(dsRef, dataBuff, NULL, - eDSAuthenticationSearchNodeName, &nodeCount, &context)) - == eDSNoErr) - { - tDataListPtr nodeName; - if(nodeCount < 1) { - status = eDSNodeNotFound; - break; - } - nodeName = NULL; - IF((status = dsGetDirNodeName(dsRef, dataBuff, 1, &nodeName)) == eDSNoErr) - { - tDirNodeReference nodeRef; - - IF((status = dsOpenDirNode(dsRef, nodeName, &nodeRef)) == eDSNoErr) { - tDataListPtr pRecType; - tDataListPtr pAttrType; - tDataListPtr pPattern; - unsigned long recCount; - tContextData context2 = NULL; - - /*--------------------------------------------------- - * Now search the search node for the given user name. - *---------------------------------------------------*/ - pRecType = dsBuildListFromStrings(dsRef, - kDSStdRecordTypeUsers, NULL); - pAttrType = dsBuildListFromStrings(dsRef, - kDSNAttrMetaNodeLocation, NULL); - pPattern = dsBuildListFromStrings(dsRef, name, NULL); - IF((status = dsGetRecordList(nodeRef, dataBuff, - pPattern, eDSExact, pRecType, pAttrType, 0, &recCount, - &context2)) == eDSNoErr) { - tAttributeListRef attrListRef; - tRecordEntry *pRecEntry; - - if(recCount < 1) { - status = E_NOTFOUND; - break; - } - /*----------------------------------------------- - * Get the attributes for the first entry we find - *-----------------------------------------------*/ - IF((status = dsGetRecordEntry(nodeRef, - dataBuff, 1, &attrListRef, &pRecEntry)) == - eDSNoErr) { - tAttributeValueListRef valueRef; - tAttributeEntry *pAttrEntry; - - /*------------------------------------------- - * Get the first (only) attribute - *-------------------------------------------*/ - IF((status = dsGetAttributeEntry( nodeRef, dataBuff, attrListRef, 1, &valueRef, - &pAttrEntry)) == eDSNoErr) - { - tAttributeValueEntry *pValueEntry; - - /*--------------------------------------- - * Put the attribute values into a data - * list. - *---------------------------------------*/ - - status = dsGetAttributeValue(nodeRef, dataBuff, 1, valueRef, &pValueEntry); - if ( status == eDSNoErr ) - { - DSPath = (char *) malloc( pValueEntry->fAttributeValueData.fBufferLength + 1 ); - if ( DSPath != NULL ) - strlcpy( DSPath, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength + 1 ); - - dsDeallocAttributeValueEntry(dsRef, pValueEntry); - } - - if(status != eDSNoErr) - break; - - if(strcmp(DSPath, LocalNI) == 0) - { - status = WHERE_LOCALNI; - /*--------------------------- - * Translate to netinfo path - *---------------------------*/ - free((void *)DSPath); - DSPath = strdup("."); - } - else if(strcmp(DSPath, DSFiles) == 0) - { - status = WHERE_FILES; - /*--------------------------- - * Translate to master.passwd - * path - *---------------------------*/ - free((void *)DSPath); - DSPath = strdup(MasterPasswd); - } - else if(strncmp(DSPath, RemoteNI, REMOTEINFOLEN) == 0) - { - status = WHERE_REMOTENI; - /*--------------------------- - * Translate to netinfo path - *---------------------------*/ - if(strncmp(DSPath, NetinfoRoot, - NETINFOROOTLEN) == 0) { - if(DSPath[NETINFOROOTLEN] - == 0) { - free((void *)DSPath); - DSPath = strdup("/"); - } else { - char *tmp = - strdup(DSPath + - NETINFOROOTLEN); - free((void *)DSPath); - DSPath = tmp; - } - } - } - else - { - status = WHERE_DS; - } - } CLEANUP { - dsCloseAttributeValueList(valueRef); - dsDeallocAttributeEntry(dsRef, pAttrEntry); - } ELSE { - } ENDIF - } CLEANUP { - dsCloseAttributeList(attrListRef); - dsDeallocRecordEntry(dsRef, pRecEntry); - } ENDIF - } CLEANUP { - if(context2) - dsReleaseContinueData(dsRef, context2); - } ENDIF - dsDataListDeallocate(dsRef, pRecType); - free(pRecType); - dsDataListDeallocate(dsRef, pAttrType); - free(pAttrType); - dsDataListDeallocate(dsRef, pPattern); - free(pPattern); - } CLEANUP { - dsCloseDirNode(nodeRef); - } ENDIF - } CLEANUP { - dsDataListDeallocate(dsRef, nodeName); - } ENDIF - } CLEANUP { - if(context) - dsReleaseContinueData(dsRef, context); - } ENDIF - } CLEANUP { - dsDataBufferDeAllocate(dsRef, dataBuff); - } ELSE { - status = eMemoryAllocError; - } ENDIF - } CLEANUP { - dsCloseDirService(dsRef); - } ENDIF - return status; -} - -/*--------------------------------------------------------------------------- - * whereFF - check the flat file (/etc/master.passwd) - *---------------------------------------------------------------------------*/ -static int -whereFF(const char *name) -{ - pid_t pid; - int estat; - int status; - - IF((pid = fork()) >= 0) { - if(pid == 0) { - char pat[64]; - - sprintf(pat, FFPatFmt, name); - Grep[PATINDEX] = pat; - /*--------------------------------------------------------------- - * Become fully root to read /etc/master.passwd - *---------------------------------------------------------------*/ - setuid(geteuid()); - execv(Grep[0], Grep); - _exit(1); - } - if(waitpid(pid, &estat, 0) < 0) { - status = errno; - break; - } - if(!WIFEXITED(estat)) { - status = E_CHILDFAILED; - break; - } - status = (WEXITSTATUS(estat) == 0 ? WHERE_FILES : E_NOTFOUND); - } CLEANUP { - } ELSE { - status = errno; - } ENDIF - return status; -} - -/*--------------------------------------------------------------------------- - * whereNI - call whereDS to do the work, then the entry is found in directory - * service (and not netinfo), mark as not found. - *---------------------------------------------------------------------------*/ -static int -whereNI(const char *name) -{ - int status = whereDS(name); - - if(status == WHERE_DS) - status = E_NOTFOUND; - return status; -} - -/*--------------------------------------------------------------------------- - * whereNIL - we skip the NILAgent - *---------------------------------------------------------------------------*/ -static int -whereNIL(const char *name) -{ - return E_NOTFOUND; -} - -/*--------------------------------------------------------------------------- - * whereNIS - check NIS passwd.byname - *---------------------------------------------------------------------------*/ -static int -whereNIS(const char *name) -{ - pid_t pid; - int estat; - int status; - - IF((pid = fork()) >= 0) { - if(pid == 0) { - char cmd[256]; - - sprintf(cmd, NISPatFmt, name); - Ypcat[YPCATINDEX] = cmd; - execv(Ypcat[0], Ypcat); - _exit(1); - } - if(waitpid(pid, &estat, 0) < 0) { - status = errno; - break; - } - if(!WIFEXITED(estat)) { - status = E_CHILDFAILED; - break; - } - status = (WEXITSTATUS(estat) == 0 ? WHERE_NIS : E_NOTFOUND); - } CLEANUP { - } ELSE { - status = errno; - } ENDIF - return status; -} - -/*--------------------------------------------------------------------------- - * PUBLIC wherepwent - Given a const char *, determine lookupd's LookupOrder - * and then search for the corresponding record for each agent. - *---------------------------------------------------------------------------*/ -int -wherepwent(const char *name) -{ - char user[LINESIZE]; - char *cp, *str; - struct where *w; - FILE *fp = NULL; - int status = 0; - fd_set fdset; - struct timeval selectTimeout = { 2, 0 }; - int result; - char order[LINESIZE], line[LINESIZE]; - char *task_argv[3] = {NULL}; - int readPipe = -1; - int writePipe = -1; - - /*------------------------------------------------------------------- - * Save the first LookupOrder as the global setting. We make sure - * that the first _config_name is Global Configuration. - *-------------------------------------------------------------------*/ - - do - { - task_argv[0] = "/usr/sbin/lookupd"; - task_argv[1] = "-configuration"; - task_argv[2] = NULL; - - if ( LaunchTaskWithPipes(task_argv[0], task_argv, &readPipe, &writePipe) != 0 ) - return E_NOTFOUND; - - // close this pipe now so the forked process quits on completion - if ( writePipe != -1 ) - close( writePipe ); - - // wait for data (and skip signals) - FD_ZERO( &fdset ); - FD_SET( readPipe, &fdset ); - do { - result = select( FD_SETSIZE, &fdset, NULL, NULL, &selectTimeout ); - } - while ( result == -1 && errno == EINTR ); - if ( result == -1 || result == 0 ) { - status = E_NOTFOUND; - break; - } - - // now that the descriptor is ready, parse the configuration - fp = fdopen(readPipe, "r"); - if ( fp == NULL ) { - status = E_NOTFOUND; - break; - } - *user = 0; - while(fgets(line, LINESIZE, fp)) - { - if(strncasecmp(line, LookupOrder, LOOKUPORDERLEN) == 0) { - if((cp = strchr(line, '\n')) != NULL) - *cp = 0; - strcpy(user, line + LOOKUPORDERLEN); - continue; - } - if(strncasecmp(line, ConfigName, CONFIGNAMELEN) == 0) { - if(strncasecmp(line + CONFIGNAMELEN, GlobalConfig, GLOBALCONFIGLEN) != 0) { - status = E_NOGLOBALCONFIG; - } - break; - } - } - if(status < 0) - break; - /*------------------------------------------------------------------- - * Save the each LookupOrder and look for _config_name of User - * Configuration. If found, replace the global order with this one. - *-------------------------------------------------------------------*/ - *order = 0; - while(fgets(line, LINESIZE, fp)) - { - if(strncasecmp(line, LookupOrder, LOOKUPORDERLEN) == 0) { - if((cp = strchr(line, '\n')) != NULL) - *cp = 0; - strcpy(order, line + LOOKUPORDERLEN); - continue; - } - if(strncasecmp(line, ConfigName, CONFIGNAMELEN) == 0) { - if(strncasecmp(line + CONFIGNAMELEN, UserConfig, USERCONFIGLEN) == 0) { - if(*order) - strcpy(user, order); - break; - } - *order = 0; - } - } - if(*user == 0) { - status = E_NOLOOKUPORDER; - break; - } - } - while ( 0 ); - - if ( fp != NULL ) - fclose( fp ); - else if ( readPipe != -1 ) - close( readPipe ); - - if(status < 0) - return status; - - /*----------------------------------------------------------------------- - * Now for each agent, call the corresponding where function. If the - * return value is no E_NOTFOUND, then we either have found it or have - * detected an error. - *-----------------------------------------------------------------------*/ - str = user; - while((cp = strtok(str, LookupOrderSep)) != NULL) { - if((w = bsearch(cp, WhereList, NWHERE, sizeof(struct where), - compar)) != NULL) { - if((status = w->func(name)) != E_NOTFOUND) - return status; - } else - printf("%s not supported\n", cp); - str = NULL; - } - return E_NOTFOUND; -} -#endif /* DIRECTORY_SERVICE */ diff --git a/chpass.tproj/directory_service.h b/chpass.tproj/directory_service.h deleted file mode 100644 index 4c5c606..0000000 --- a/chpass.tproj/directory_service.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _DIRECTORY_SERVICE_H_ -#define _DIRECTORY_SERVICE_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*--------------------------------------------------------------------------- - * Convenience macros: to be used to provide a cleanup section (eg, to - * deallocate memory, etc). IF, CLEANUP and ENDIF must always be used, and - * must be used with braces; ELSE is optional, but must also be used with - * braces. - * - * IF(expression) { - * ... - * } CLEANUP { - * ... - * } ELSE { - * ... - * } ENDIF - * - * "break" may be used in the IF section to exit the block prematurely; the - * CLEANUP section will still be performed. "break" in the CLEANUP and ELSE - * sections apply to higher level blocks. - *---------------------------------------------------------------------------*/ -#define IF(x) if(x) { do -#define CLEANUP while(0); -#define ELSE } else { -#define ENDIF } - -/*--------------------------------------------------------------------------- - * Error codes (not including DirectoryService error codes and standard error - * codes) - *---------------------------------------------------------------------------*/ -#define E_NOTFOUND -1000 -#define E_NOGLOBALCONFIG -1001 -#define E_NOLOOKUPORDER -1002 -#define E_POPENFAILED -1003 -#define E_CHILDFAILED -1004 -#define E_DATALISTOUTOFMEM -1005 -#define E_PATHOUTOFMEM -1006 -#define E_NICLFAILED -1007 - -/*--------------------------------------------------------------------------- - * Success return values from wherepwent() - *---------------------------------------------------------------------------*/ -enum { - WHERE_FILES = 0, - WHERE_LOCALNI, - WHERE_REMOTENI, - WHERE_DS, - WHERE_NIS, -}; - -/*--------------------------------------------------------------------------- - * Global variables - *---------------------------------------------------------------------------*/ -extern char *DSPath; -extern const char MasterPasswd[]; - -/*--------------------------------------------------------------------------- - * Function prototypes - *---------------------------------------------------------------------------*/ -extern void setrestricted(int where, struct passwd *pw); -extern void update_local_ni(struct passwd *pworig, struct passwd *pw); -extern int wherepwent(const char *name); - -#endif /* _DIRECTORY_SERVICE_H_ */ diff --git a/chpass.tproj/ds_pw_util.c b/chpass.tproj/ds_pw_util.c deleted file mode 100644 index 1b76cad..0000000 --- a/chpass.tproj/ds_pw_util.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)pw_util.c 8.4 (Berkeley) 4/28/95"; -#endif /* not lint */ - -/* - * This file is used by all the "password" programs; vipw(8), chpass(1), - * and passwd(1). - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pw_util.h" -#ifdef DIRECTORY_SERVICE -#include "directory_service.h" -#endif /* DIRECTORY_SERVICE */ - -extern char *tempname; -static pid_t editpid = -1; -static int lockfd; - -void -pw_cont(sig) - int sig; -{ - - if (editpid != -1) - kill(editpid, sig); -} - -void -pw_init() -{ - struct rlimit rlim; - - /* Unlimited resource limits. */ - rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; - (void)setrlimit(RLIMIT_CPU, &rlim); - (void)setrlimit(RLIMIT_FSIZE, &rlim); - (void)setrlimit(RLIMIT_STACK, &rlim); - (void)setrlimit(RLIMIT_DATA, &rlim); - (void)setrlimit(RLIMIT_RSS, &rlim); - - /* Don't drop core (not really necessary, but GP's). */ - rlim.rlim_cur = rlim.rlim_max = 0; - (void)setrlimit(RLIMIT_CORE, &rlim); - - /* Turn off signals. */ - (void)signal(SIGALRM, SIG_IGN); - (void)signal(SIGHUP, SIG_IGN); - (void)signal(SIGINT, SIG_IGN); - (void)signal(SIGPIPE, SIG_IGN); - (void)signal(SIGQUIT, SIG_IGN); - (void)signal(SIGTERM, SIG_IGN); - (void)signal(SIGCONT, pw_cont); - - /* Create with exact permissions. */ - (void)umask(0); -} - -int -pw_lock() -{ - /* - * If the master password file doesn't exist, the system is hosed. - * Might as well try to build one. Set the close-on-exec bit so - * that users can't get at the encrypted passwords while editing. - * Open should allow flock'ing the file; see 4.4BSD. XXX - */ - lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0); - if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) - err(1, "%s", _PATH_MASTERPASSWD); - if (flock(lockfd, LOCK_EX|LOCK_NB)) - errx(1, "the password db file is busy"); - return (lockfd); -} - -int -pw_tmp() -{ - static char path[MAXPATHLEN] = _PATH_MASTERPASSWD; - int fd; - char *p; - - if (p = strrchr(path, '/')) - ++p; - else - p = path; - strcpy(p, "pw.XXXXXX"); - if ((fd = mkstemp(path)) == -1) - err(1, "%s", path); - tempname = path; - return (fd); -} - -int -pw_mkdb() -{ - int pstat; - pid_t pid; - - warnx("rebuilding the database..."); - (void)fflush(stderr); - if (!(pid = vfork())) { - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL); - pw_error(_PATH_PWD_MKDB, 1, 1); - } - pid = waitpid(pid, &pstat, 0); - if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) - return (1); - warnx("done"); - return (0); -} - -void -pw_edit(notsetuid) - int notsetuid; -{ - int pstat; - char *p, *editor; - - if (!(editor = getenv("EDITOR"))) - editor = _PATH_VI; - if (p = strrchr(editor, '/')) - ++p; - else - p = editor; - - if (!(editpid = vfork())) { - if (notsetuid) { - (void)setgid(getgid()); - (void)setuid(getuid()); - } - execlp(editor, p, tempname, NULL); - _exit(1); - } - for (;;) { - editpid = waitpid(editpid, (int *)&pstat, WUNTRACED); - if (editpid == -1) - pw_error(editor, 1, 1); - else if (WIFSTOPPED(pstat)) - raise(WSTOPSIG(pstat)); - else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0) - break; - else - pw_error(editor, 1, 1); - } - editpid = -1; -} - -void -pw_prompt() -{ - int c; - - (void)printf("re-edit the password file? [y]: "); - (void)fflush(stdout); - c = getchar(); - if (c != EOF && c != '\n') - while (getchar() != '\n'); - if (c == 'n') - pw_error(NULL, 0, 0); -} - -void -pw_error(name, err, eval) - char *name; - int err, eval; -{ -#ifdef DIRECTORY_SERVICE - extern int dswhere; -#endif /* DIRECTORY_SERVICE */ - if (err) - warn("%s", name); - -#ifdef DIRECTORY_SERVICE - switch(dswhere) { - case WHERE_LOCALNI: - warnx("netinfo domain \"%s\": unchanged", DSPath); - break; - case WHERE_FILES: -#endif /* DIRECTORY_SERVICE */ - warnx("%s: unchanged", _PATH_MASTERPASSWD); -#ifdef DIRECTORY_SERVICE - } -#endif /* DIRECTORY_SERVICE */ - (void)unlink(tempname); - exit(eval); -} diff --git a/chpass.tproj/edit.c b/chpass.tproj/edit.c index 855300f..666b84d 100644 --- a/chpass.tproj/edit.c +++ b/chpass.tproj/edit.c @@ -1,29 +1,35 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /*- * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +41,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -54,6 +60,17 @@ * SUCH DAMAGE. */ +#if 0 +#if 0 +#ifndef lint +static char sccsid[] = "@(#)edit.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ +#endif + +#include +__FBSDID("$FreeBSD: src/usr.bin/chpass/edit.c,v 1.23 2003/04/09 18:18:42 des Exp $"); +#endif + #include #include @@ -67,37 +84,69 @@ #include #include +#ifndef OPEN_DIRECTORY #include -#include +#include +#endif #include "chpass.h" -#ifdef DIRECTORY_SERVICE -#include "directory_service.h" - -extern int dswhere; -#endif /* DIRECTORY_SERVICE */ -extern char *tempname; +#ifdef OPEN_DIRECTORY +static int display(const char *tfn, CFDictionaryRef attrs); +static CFDictionaryRef verify(const char *tfn, CFDictionaryRef attrs); +#else +static int display(const char *tfn, struct passwd *pw); +static struct passwd *verify(const char *tfn, struct passwd *pw); +#endif -void -edit(pw) - struct passwd *pw; +#ifdef OPEN_DIRECTORY +CFDictionaryRef +edit(const char *tfn, CFDictionaryRef pw) +#else +struct passwd * +edit(const char *tfn, struct passwd *pw) +#endif { - struct stat begin, end; +#ifdef OPEN_DIRECTORY + CFDictionaryRef npw; +#else + struct passwd *npw; +#endif + char *line; + size_t len; + if (display(tfn, pw) == -1) + return (NULL); for (;;) { - if (stat(tempname, &begin)) - pw_error(tempname, 1, 1); - pw_edit(1); - if (stat(tempname, &end)) - pw_error(tempname, 1, 1); - if (begin.st_mtime == end.st_mtime) { - warnx("no changes made"); - pw_error(NULL, 0, 0); - } - if (verify(pw)) +#ifdef OPEN_DIRECTORY + switch (editfile(tfn)) { +#else + switch (pw_edit(1)) { +#endif + case -1: + return (NULL); + case 0: +#ifdef OPEN_DIRECTORY + return (NULL); +#else + return (pw_dup(pw)); +#endif + default: break; - pw_prompt(); + } + if ((npw = verify(tfn, pw)) != NULL) + return (npw); +#ifndef OPEN_DIRECTORY + free(npw); +#endif + printf("re-edit the password file? "); + fflush(stdout); + if ((line = fgetln(stdin, &len)) == NULL) { + warn("fgetln()"); + return (NULL); + } + if (len > 0 && (*line == 'N' || *line == 'n')) + return (NULL); } } @@ -106,56 +155,43 @@ edit(pw) * print out the file for the user to edit; strange side-effect: * set conditional flag if the user gets to edit the shell. */ -void -display(fd, pw) - int fd; - struct passwd *pw; +#if OPEN_DIRECTORY +static int +display(const char *tfn, CFDictionaryRef attrs) +#else +static int +display(const char *tfn, struct passwd *pw) +#endif { FILE *fp; - char *bp, *p, *ttoa(); -#ifdef DIRECTORY_SERVICE - ENTRY *ep; - struct display d; - int ndisplayed = 0; -#endif /* DIRECTORY_SERVICE */ - - if (!(fp = fdopen(fd, "w"))) - pw_error(tempname, 1, 1); +#ifndef OPEN_DIRECTORY + char *bp, *gecos, *p; +#endif - (void)fprintf(fp, - "# Changing user database information for %s.\n" - "#\n" - "# (use \"passwd\" to change the password)\n" - "##\n", - pw->pw_name); - -#ifdef DIRECTORY_SERVICE - switch (dswhere) { - case WHERE_FILES: - (void)fprintf(fp, - "# Flat file: /etc/master.passwd\n" - "##\n"); - break; - case WHERE_LOCALNI: - (void)fprintf(fp, - "# Local NetInfo Database\n" - "##\n"); - break; + if ((fp = fopen(tfn, "w")) == NULL) { + warn("%s", tfn); + return (-1); } - d.pw = pw; - bp = pw->pw_gecos; - p = strsep(&bp, ","); - d.fullname = (p ? p : ""); - p = strsep(&bp, ","); - d.location = (p ? p : ""); - p = strsep(&bp, ","); - d.officephone = (p ? p : ""); - p = strsep(&bp, ","); - d.homephone = ( p ? p : ""); +#ifdef OPEN_DIRECTORY + CFArrayRef values = CFDictionaryGetValue(attrs, CFSTR(kDSNAttrRecordName)); + CFStringRef username = (values && CFArrayGetCount(values)) > 0 ? CFArrayGetValueAtIndex(values, 0) : NULL; + + (void)cfprintf(fp, + "# Changing user information for %@.\n" + "# Use \"passwd\" to change the password.\n" + "##\n" + "# Open Directory%s%@\n" + "##\n", + username, + DSPath ? ": " : "", + DSPath ? DSPath : CFSTR("")); + + int ndisplayed = 0; + ENTRY* ep; for (ep = list; ep->prompt; ep++) if (!ep->restricted) { - ep->display(&d, fp); + ep->display(attrs, ep->attrName, ep->prompt, fp); ndisplayed++; } if(!ndisplayed) { @@ -163,23 +199,15 @@ display(fd, pw) (void)fprintf(fp, "# No fields are available to change\n"); (void)fprintf(fp, "###################################\n"); } -#else /* DIRECTORY_SERVICE */ - (void)fprintf(fp, - "##\n" - "# User Database\n" - "# \n" - "# Note: This program edits the /etc/master.passwd file which is only \n" - "# consulted when the system is running in single-user mode. At other times \n" - "# this information is handled by lookupd. By default, lookupd gets \n" - "# information from NetInfo, so this file will not be consulted unless you \n" - "# have changed lookupd's configuration.\n" - "##\n"); - - if (!uid) { +#else OPEN_DIRECTORY + (void)fprintf(fp, + "#Changing user information for %s.\n", pw->pw_name); + if (master_mode) { (void)fprintf(fp, "Login: %s\n", pw->pw_name); (void)fprintf(fp, "Password: %s\n", pw->pw_passwd); - (void)fprintf(fp, "Uid [#]: %d\n", pw->pw_uid); - (void)fprintf(fp, "Gid [# or name]: %d\n", pw->pw_gid); + (void)fprintf(fp, "Uid [#]: %lu\n", (unsigned long)pw->pw_uid); + (void)fprintf(fp, "Gid [# or name]: %lu\n", + (unsigned long)pw->pw_gid); (void)fprintf(fp, "Change [month day year]: %s\n", ttoa(pw->pw_change)); (void)fprintf(fp, "Expire [month day year]: %s\n", @@ -190,115 +218,198 @@ display(fd, pw) *pw->pw_shell ? pw->pw_shell : _PATH_BSHELL); } /* Only admin can change "restricted" shells. */ +#if 0 else if (ok_shell(pw->pw_shell)) /* * Make shell a restricted field. Ugly with a * necklace, but there's not much else to do. */ +#else + else if ((!list[E_SHELL].restricted && ok_shell(pw->pw_shell)) || + master_mode) + /* + * If change not restrict (table.c) and standard shell + * OR if root, then allow editing of shell. + */ +#endif (void)fprintf(fp, "Shell: %s\n", *pw->pw_shell ? pw->pw_shell : _PATH_BSHELL); else list[E_SHELL].restricted = 1; - bp = pw->pw_gecos; + + if ((bp = gecos = strdup(pw->pw_gecos)) == NULL) { + warn(NULL); + fclose(fp); + return (-1); + } + p = strsep(&bp, ","); - (void)fprintf(fp, "Full Name: %s\n", p ? p : ""); + p = strdup(p ? p : ""); + list[E_NAME].save = p; + if (!list[E_NAME].restricted || master_mode) + (void)fprintf(fp, "Full Name: %s\n", p); + p = strsep(&bp, ","); - (void)fprintf(fp, "Location: %s\n", p ? p : ""); + p = strdup(p ? p : ""); + list[E_LOCATE].save = p; + if (!list[E_LOCATE].restricted || master_mode) + (void)fprintf(fp, "Office Location: %s\n", p); + p = strsep(&bp, ","); - (void)fprintf(fp, "Office Phone: %s\n", p ? p : ""); + p = strdup(p ? p : ""); + list[E_BPHONE].save = p; + if (!list[E_BPHONE].restricted || master_mode) + (void)fprintf(fp, "Office Phone: %s\n", p); + p = strsep(&bp, ","); - (void)fprintf(fp, "Home Phone: %s\n", p ? p : ""); -#endif /* DIRECTORY_SERVICE */ + p = strdup(p ? p : ""); + list[E_HPHONE].save = p; + if (!list[E_HPHONE].restricted || master_mode) + (void)fprintf(fp, "Home Phone: %s\n", p); + + bp = strdup(bp ? bp : ""); + list[E_OTHER].save = bp; + if (!list[E_OTHER].restricted || master_mode) + (void)fprintf(fp, "Other information: %s\n", bp); + + free(gecos); +#endif /* OPEN_DIRECTORY */ - (void)fchown(fd, getuid(), getgid()); + (void)fchown(fileno(fp), getuid(), getgid()); (void)fclose(fp); + return (0); } -int -verify(pw) - struct passwd *pw; +#ifdef OPEN_DIRECTORY +static CFDictionaryRef +verify(const char* tfn, CFDictionaryRef pw) +#else +static struct passwd * +verify(const char *tfn, struct passwd *pw) +#endif { +#ifdef OPEN_DIRECTORY + CFMutableDictionaryRef npw; +#else + struct passwd *npw; +#endif ENTRY *ep; - char *p; + char *buf, *p, *val; struct stat sb; FILE *fp; - int len; - static char buf[LINE_MAX]; + int line; + size_t len; - if (!(fp = fopen(tempname, "r"))) - pw_error(tempname, 1, 1); - if (fstat(fileno(fp), &sb)) - pw_error(tempname, 1, 1); +#ifdef OPEN_DIRECTORY + if ((npw = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == NULL) + return (NULL); +#else + if ((pw = pw_dup(pw)) == NULL) + return (NULL); +#endif + if ((fp = fopen(tfn, "r")) == NULL || + fstat(fileno(fp), &sb) == -1) { + warn("%s", tfn); +#ifndef OPEN_DIRECTORY + free(pw); +#endif + return (NULL); + } if (sb.st_size == 0) { warnx("corrupted temporary file"); - goto bad; + fclose(fp); +#ifndef OPEN_DIRECTORY + free(pw); +#endif + return (NULL); } - while (fgets(buf, sizeof(buf), fp)) { - if (!buf[0] || buf[0] == '#') + val = NULL; + for (line = 1; (buf = fgetln(fp, &len)) != NULL; ++line) { + if (*buf == '\0' || *buf == '#') continue; - if (!(p = strchr(buf, '\n'))) { - warnx("line too long"); - goto bad; - } - *p = '\0'; + while (len > 0 && isspace(buf[len - 1])) + --len; for (ep = list;; ++ep) { if (!ep->prompt) { - warnx("unrecognized field"); + warnx("%s: unrecognized field on line %d", + tfn, line); goto bad; } - if (!strncasecmp(buf, ep->prompt, ep->len)) { - if (ep->restricted && uid) { - warnx( - "you may not change the %s field", - ep->prompt); - goto bad; - } - if (!(p = strchr(buf, ':'))) { - warnx("line corrupted"); - goto bad; - } - while (isspace(*++p)); - if (ep->except && strpbrk(p, ep->except)) { - warnx( - "illegal character in the \"%s\" field", - ep->prompt); - goto bad; - } - if ((ep->func)(p, pw, ep)) { -bad: (void)fclose(fp); - return (0); + if (ep->len > len) + continue; + if (strncasecmp(buf, ep->prompt, ep->len) != 0) + continue; + if (ep->restricted && !master_mode) { + warnx("%s: you may not change the %s field", + tfn, ep->prompt); + goto bad; + } + for (p = buf; p < buf + len && *p != ':'; ++p) + /* nothing */ ; + if (*p != ':') { + warnx("%s: line %d corrupted", tfn, line); + goto bad; + } + while (++p < buf + len && isspace(*p)) + /* nothing */ ; + free(val); + asprintf(&val, "%.*s", (int)(buf + len - p), p); + if (val == NULL) + goto bad; + if (ep->except && strpbrk(val, ep->except)) { + warnx("%s: invalid character in \"%s\" field '%s'", + tfn, ep->prompt, val); + goto bad; + } +#ifdef OPEN_DIRECTORY + if ((ep->func)(val, NULL, NULL)) + goto bad; + { + CFStringRef str = CFStringCreateWithCString(NULL, val, kCFStringEncodingUTF8); + if (str) { + CFDictionarySetValue(npw, ep->attrName, str); + CFRelease(str); } - break; } +#else + if ((ep->func)(val, pw, ep)) + goto bad; +#endif + break; } } - (void)fclose(fp); + free(val); + fclose(fp); +#ifndef OPEN_DIRECTORY /* Build the gecos field. */ -#ifdef DIRECTORY_SERVICE - if (list[E_NAME].save) { - if (list[E_LOCATE].save) { -#endif /* DIRECTORY_SERVICE */ - len = strlen(list[E_NAME].save) + strlen(list[E_BPHONE].save) + - strlen(list[E_HPHONE].save) + strlen(list[E_LOCATE].save) + 4; - if (!(p = malloc(len))) - err(1, NULL); - (void)sprintf(pw->pw_gecos = p, "%s,%s,%s,%s", list[E_NAME].save, - list[E_LOCATE].save, list[E_BPHONE].save, list[E_HPHONE].save); -#ifdef DIRECTORY_SERVICE - } else - pw->pw_gecos = list[E_NAME].save; - } else - pw->pw_gecos = ""; -#endif /* DIRECTORY_SERVICE */ - - if (snprintf(buf, sizeof(buf), - "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s", - pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class, - pw->pw_change, pw->pw_expire, pw->pw_gecos, pw->pw_dir, - pw->pw_shell) >= sizeof(buf)) { - warnx("entries too long"); - return (0); + len = asprintf(&p, "%s,%s,%s,%s,%s", list[E_NAME].save, + list[E_LOCATE].save, list[E_BPHONE].save, + list[E_HPHONE].save, list[E_OTHER].save); + if (p == NULL) { + warn("asprintf()"); + free(pw); + return (NULL); + } + while (len > 0 && p[len - 1] == ',') + p[--len] = '\0'; + pw->pw_gecos = p; + buf = pw_make(pw); + free(pw); + free(p); + if (buf == NULL) { + warn("pw_make()"); + return (NULL); } - return (pw_scan(buf, pw, NULL)); + npw = pw_scan(buf, PWSCAN_WARN|PWSCAN_MASTER); +#endif /* !OPEN_DIRECTORY */ + free(buf); + return (npw); +bad: +#ifndef OPEN_DIRECTORY + free(pw); +#endif + free(val); + fclose(fp); + return (NULL); } diff --git a/chpass.tproj/field.c b/chpass.tproj/field.c index bb3c062..784f2a8 100644 --- a/chpass.tproj/field.c +++ b/chpass.tproj/field.c @@ -1,29 +1,35 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1988, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +41,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -54,40 +60,49 @@ * SUCH DAMAGE. */ +#if 0 +#if 0 +#ifndef lint +static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94"; +#endif /* not lint */ +#endif + +#include +__FBSDID("$FreeBSD: src/usr.bin/chpass/field.c,v 1.9 2004/01/18 21:46:39 charnier Exp $"); +#endif + #include +#include #include #include #include #include +#include #include -#include #include #include -#include #include "chpass.h" -#include "pathnames.h" /* ARGSUSED */ int -p_login(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_login(char *p, struct passwd *pw, ENTRY *ep __unused) { if (!*p) { warnx("empty login field"); - return (1); + return (-1); } if (*p == '-') { warnx("login names may not begin with a hyphen"); - return (1); + return (-1); } +#ifndef OPEN_DIRECTORY if (!(pw->pw_name = strdup(p))) { warnx("can't save entry"); - return (1); + return (-1); } +#endif if (strchr(p, '.')) warnx("\'.\' is dangerous in a login name"); for (; *p; ++p) @@ -100,55 +115,48 @@ p_login(p, pw, ep) /* ARGSUSED */ int -p_passwd(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_passwd(char *p, struct passwd *pw, ENTRY *ep __unused) { - if (!*p) - pw->pw_passwd = ""; /* "NOLOGIN"; */ - else if (!(pw->pw_passwd = strdup(p))) { +#ifndef OPEN_DIRECTORY + if (!(pw->pw_passwd = strdup(p))) { warnx("can't save password entry"); - return (1); + return (-1); } - +#endif + return (0); } /* ARGSUSED */ int -p_uid(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_uid(char *p, struct passwd *pw, ENTRY *ep __unused) { uid_t id; char *np; if (!*p) { warnx("empty uid field"); - return (1); + return (-1); } if (!isdigit(*p)) { warnx("illegal uid"); - return (1); + return (-1); } errno = 0; id = strtoul(p, &np, 10); - if (*np || (id == ULONG_MAX && errno == ERANGE)) { + if (*np || (id == (uid_t)ULONG_MAX && errno == ERANGE)) { warnx("illegal uid"); - return (1); + return (-1); } +#ifndef OPEN_DIRECTORY pw->pw_uid = id; +#endif return (0); } /* ARGSUSED */ int -p_gid(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_gid(char *p, struct passwd *pw, ENTRY *ep __unused) { struct group *gr; gid_t id; @@ -156,213 +164,183 @@ p_gid(p, pw, ep) if (!*p) { warnx("empty gid field"); - return (1); + return (-1); } if (!isdigit(*p)) { if (!(gr = getgrnam(p))) { warnx("unknown group %s", p); - return (1); + return (-1); } +#ifndef OPEN_DIRECTORY pw->pw_gid = gr->gr_gid; +#endif return (0); } errno = 0; id = strtoul(p, &np, 10); - if (*np || (id == ULONG_MAX && errno == ERANGE)) { + if (*np || (id == (uid_t)ULONG_MAX && errno == ERANGE)) { warnx("illegal gid"); - return (1); + return (-1); } +#ifndef OPEN_DIRECTORY pw->pw_gid = id; +#endif return (0); } /* ARGSUSED */ int -p_class(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_class(char *p, struct passwd *pw, ENTRY *ep __unused) { - if (!*p) - pw->pw_class = ""; - else if (!(pw->pw_class = strdup(p))) { +#ifndef OPEN_DIRECTORY + if (!(pw->pw_class = strdup(p))) { warnx("can't save entry"); - return (1); + return (-1); } - +#endif + return (0); } /* ARGSUSED */ int -p_change(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_change(char *p, struct passwd *pw, ENTRY *ep __unused) { +#ifndef OPEN_DIRECTORY if (!atot(p, &pw->pw_change)) return (0); warnx("illegal date for change field"); - return (1); +#endif + return (-1); } /* ARGSUSED */ int -p_expire(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_expire(char *p, struct passwd *pw, ENTRY *ep __unused) { +#ifndef OPEN_DIRECTORY if (!atot(p, &pw->pw_expire)) return (0); warnx("illegal date for expire field"); - return (1); +#endif + return (-1); } /* ARGSUSED */ int -p_gecos(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_gecos(char *p, struct passwd *pw __unused, ENTRY *ep) { - if (!*p) - ep->save = ""; - else if (!(ep->save = strdup(p))) { +#ifndef OPEN_DIRECTORY + if (!(ep->save = strdup(p))) { warnx("can't save entry"); - return (1); + return (-1); } +#endif return (0); } /* ARGSUSED */ int -p_hdir(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_hdir(char *p, struct passwd *pw, ENTRY *ep __unused) { if (!*p) { warnx("empty home directory field"); - return (1); + return (-1); } +#ifndef OPEN_DIRECTORY if (!(pw->pw_dir = strdup(p))) { warnx("can't save entry"); - return (1); + return (-1); } +#endif return (0); } + /* ARGSUSED */ int -p_shell(p, pw, ep) - char *p; - struct passwd *pw; - ENTRY *ep; +p_shell(char *p, struct passwd *pw, ENTRY *ep __unused) { - char *t, *ok_shell(); + struct stat sbuf; +#ifdef OPEN_DIRECTORY + struct passwd lpw; + pw = &lpw; + memset(pw, 0, sizeof(lpw)); + pw->pw_shell = p; +#endif +#ifndef OPEN_DIRECTORY if (!*p) { - pw->pw_shell = _PATH_BSHELL; + pw->pw_shell = strdup(_PATH_BSHELL); return (0); } /* only admin can change from or to "restricted" shells */ - if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) { + if (!master_mode && pw->pw_shell && !ok_shell(pw->pw_shell)) { warnx("%s: current shell non-standard", pw->pw_shell); - return (1); + return (-1); } - if (!(t = ok_shell(p))) { - if (uid) { +#endif /* !OPEN_DIRECTORY */ + if (!ok_shell(p)) { + if (!master_mode) { warnx("%s: non-standard shell", p); - return (1); + return (-1); } +#ifndef OPEN_DIRECTORY + pw->pw_shell = strdup(p); +#endif } +#ifndef OPEN_DIRECTORY else - p = t; - if (!(pw->pw_shell = strdup(p))) { + pw->pw_shell = dup_shell(p); + if (!pw->pw_shell) { warnx("can't save entry"); - return (1); + return (-1); + } +#endif + if (stat(pw->pw_shell, &sbuf) < 0) { + if (errno == ENOENT) + warnx("WARNING: shell '%s' does not exist", + pw->pw_shell); + else + warn("WARNING: can't stat shell '%s'", pw->pw_shell); + return (0); + } + if (!S_ISREG(sbuf.st_mode)) { + warnx("WARNING: shell '%s' is not a regular file", + pw->pw_shell); + return (0); + } + if ((sbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) == 0) { + warnx("WARNING: shell '%s' is not executable", pw->pw_shell); + return (0); } return (0); } -#ifdef DIRECTORY_SERVICE -void -d_change(struct display *d, FILE *fp) -{ - fprintf(fp, "Change [month day year]: %s\n", ttoa(d->pw->pw_change)); -} - -void -d_class(struct display *d, FILE *fp) -{ - fprintf(fp, "Class: %s\n", d->pw->pw_class); -} - -void -d_expire(struct display *d, FILE *fp) -{ - fprintf(fp, "Expire [month day year]: %s\n", ttoa(d->pw->pw_expire)); -} - -void -d_fullname(struct display *d, FILE *fp) -{ - fprintf(fp, "Full Name: %s\n", d->fullname); -} - -void -d_gid(struct display *d, FILE *fp) -{ - fprintf(fp, "Gid [# or name]: %d\n", d->pw->pw_gid); -} -void -d_hdir(struct display *d, FILE *fp) -{ - fprintf(fp, "Home directory: %s\n", d->pw->pw_dir); -} - -void -d_homephone(struct display *d, FILE *fp) -{ - fprintf(fp, "Home Phone: %s\n", d->homephone); -} - -void -d_login(struct display *d, FILE *fp) -{ - fprintf(fp, "Login: %s\n", d->pw->pw_name); -} - -void -d_location(struct display *d, FILE *fp) -{ - fprintf(fp, "Location: %s\n", d->location); -} - -void -d_officephone(struct display *d, FILE *fp) -{ - fprintf(fp, "Office Phone: %s\n", d->officephone); -} - -void -d_passwd(struct display *d, FILE *fp) -{ - fprintf(fp, "Password: %s\n", d->pw->pw_passwd); -} - -void -d_shell(struct display *d, FILE *fp) +#ifdef OPEN_DIRECTORY +#include +/* ARGSUSED */ +int +p_uuid(char *p, struct passwd *pw __unused, ENTRY *ep) { - fprintf(fp, "Shell: %s\n", *d->pw->pw_shell ? d->pw->pw_shell - : _PATH_BSHELL); + uuid_t uu; + if (uuid_parse(p, uu) != 0) { + warnx("invalid UUID"); + return (-1); + } + return (0); } void -d_uid(struct display *d, FILE *fp) +display_string(CFDictionaryRef attrs, CFStringRef attrName, const char* prompt, FILE *fp) { - fprintf(fp, "Uid [#]: %d\n", d->pw->pw_uid); + CFTypeRef value = CFSTR(""); + CFArrayRef values = CFDictionaryGetValue(attrs, attrName); + if (values) { + value = CFArrayGetCount(values) > 0 ? CFArrayGetValueAtIndex(values, 0) : NULL; + if (value && CFGetTypeID(value) != CFStringGetTypeID()) value = NULL; + } + cfprintf(fp, "%s: %@\n", prompt, value); } -#endif /* DIRECTORY_SERVICE */ +#endif /* OPEN_DIRECTORY */ diff --git a/chpass.tproj/open_directory.c b/chpass.tproj/open_directory.c new file mode 100644 index 0000000..b2cd9b4 --- /dev/null +++ b/chpass.tproj/open_directory.c @@ -0,0 +1,272 @@ +#ifdef OPEN_DIRECTORY +#include "open_directory.h" +#include "chpass.h" +#include +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * PUBLIC setrestricted - sets the restricted flag + *---------------------------------------------------------------------------*/ +void +setrestricted(CFDictionaryRef attrs) +{ + const char* user_allowed[] = { "shell", "full name", "office location", "office phone", "home phone", "picture", NULL }; + const char* root_restricted[] = { "password", "change", "expire", "class", NULL }; + ENTRY* ep; + const char** pp; + int restrict_by_default = !master_mode; + + // for ordinary users, everything is restricted except for the values + // expressly permitted above + // for root, everything is permitted except for the values expressly + // restricted above + + for (ep = list; ep->prompt; ep++) { + ep->restricted = restrict_by_default; + pp = restrict_by_default ? user_allowed : root_restricted; + for (; *pp; pp++) { + if (strncasecmp(ep->prompt, *pp, ep->len) == 0) { + ep->restricted = !restrict_by_default; + break; + } + } + + // If not root, then it is only permitted to change the shell + // when the original value is one of the approved shells. + // Otherwise, the assumption is that root has given this user + // a restricted shell which they must not change away from. + if (restrict_by_default && strcmp(ep->prompt, "shell") == 0) { + ep->restricted = 1; + CFArrayRef values = CFDictionaryGetValue(attrs, CFSTR(kDS1AttrUserShell)); + CFTypeRef value = values && CFArrayGetCount(values) > 0 ? CFArrayGetValueAtIndex(values, 0) : NULL; + if (value && CFGetTypeID(value) == CFStringGetTypeID()) { + size_t size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), kCFStringEncodingUTF8)+1; + char* shell = malloc(size); + if (CFStringGetCString(value, shell, size, kCFStringEncodingUTF8)) { + if (ok_shell(shell)) { + ep->restricted = 0; + } + } + } + } + } +} + +static CFStringRef +prompt_passwd(CFStringRef user) +{ + CFStringRef result = NULL; + CFStringRef prompt = CFStringCreateWithFormat(NULL, NULL, CFSTR("Password for %@: "), user); + char buf[128]; + CFStringGetCString(prompt, buf, sizeof(buf), kCFStringEncodingUTF8); + char* pass = getpass(buf); + result = CFStringCreateWithCString(NULL, pass, kCFStringEncodingUTF8); + memset(pass, 0, strlen(pass)); + CFRelease(prompt); + return result; +} + +static void +show_error(CFErrorRef error) { + if (error) { + CFStringRef desc = CFErrorCopyDescription(error); + if (desc) { + cfprintf(stderr, "%s: %@", progname, desc); + CFRelease(desc); + } + desc = CFErrorCopyFailureReason(error); + if (desc) cfprintf(stderr, " %@", desc); + + desc = CFErrorCopyRecoverySuggestion(error); + if (desc) cfprintf(stderr, " %@", desc); + + fprintf(stderr, "\n"); + } +} + +static int +is_singleuser(void) { + uint32_t su = 0; + size_t susz = sizeof(su); + if (sysctlbyname("kern.singleuser", &su, &susz, NULL, 0) != 0) { + return 0; + } else { + return (int)su; + } +} + +static int +load_DirectoryServicesLocal() { + const char* launchctl = "/bin/launchctl"; + const char* plist = "/System/Library/LaunchDaemons/com.apple.DirectoryServicesLocal.plist"; + + pid_t pid = fork(); + int status, res; + switch (pid) { + case -1: // ERROR + perror("launchctl"); + return 0; + case 0: // CHILD + execl(launchctl, launchctl, "load", plist, NULL); + /* NOT REACHED */ + perror("launchctl"); + exit(1); + break; + default: // PARENT + do { + res = waitpid(pid, &status, 0); + } while (res == -1 && errno == EINTR); + if (res == -1) { + perror("launchctl"); + return 0; + } + break; + } + return (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS)); +} + +ODRecordRef +odGetUser(CFStringRef location, CFStringRef authname, CFStringRef user, CFDictionaryRef* attrs) +{ + ODSessionRef session = NULL; + ODNodeRef node = NULL; + ODRecordRef rec = NULL; + CFErrorRef error = NULL; + + assert(attrs); + + /* + * Connect to DS server + */ + session = ODSessionCreate(NULL, NULL, &error); + if ( !session && error && CFErrorGetCode(error) == eServerNotRunning ) { + /* + * In single-user mode, attempt to load the local DS daemon. + */ + if (is_singleuser() && load_DirectoryServicesLocal()) { + CFTypeRef keys[] = { kODSessionLocalPath }; + CFTypeRef vals[] = { CFSTR("/var/db/dslocal") }; + CFDictionaryRef opts = CFDictionaryCreate(NULL, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (opts) { + session = ODSessionCreate(NULL, opts, &error); + CFRelease(opts); + } + + if (!location) { + location = CFRetain(CFSTR("/Local/Default")); + } + } else { + show_error(error); + return -1; + } + } + + /* + * Open the specified node, or perform a search. + * Copy the record and put the record's location into DSPath. + */ + if (location) { + node = ODNodeCreateWithName(NULL, session, location, &error); + } else { + node = ODNodeCreateWithNodeType(NULL, session, kODTypeAuthenticationSearchNode, &error); + } + if (session) CFRelease(session); + if (node) { + CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; + CFArrayRef desiredAttrs = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); + rec = ODNodeCopyRecord(node, CFSTR(kDSStdRecordTypeUsers), user, desiredAttrs, &error ); + if (desiredAttrs) CFRelease(desiredAttrs); + CFRelease(node); + } + if (rec) { + *attrs = ODRecordCopyDetails(rec, NULL, &error); + if (*attrs) { + CFArrayRef values = CFDictionaryGetValue(*attrs, CFSTR(kDSNAttrMetaNodeLocation)); + DSPath = (values && CFArrayGetCount(values) > 0) ? CFArrayGetValueAtIndex(values, 0) : NULL; + } + + /* + * Prompt for a password if -u was specified, + * or if we are not root, + * or if we are updating something not on the + * local node. + */ + if (authname || !master_mode || + (DSPath && CFStringCompareWithOptions(DSPath, CFSTR("/Local/"), CFRangeMake(0, 7), 0) != kCFCompareEqualTo)) { + + CFStringRef password = NULL; + + if (!authname) authname = user; + + password = prompt_passwd(authname); + if (!ODRecordSetNodeCredentials(rec, authname, password, &error)) { + CFRelease(rec); + rec = NULL; + } + } + } + + if (error) show_error(error); + return rec; +} + +void +odUpdateUser(ODRecordRef rec, CFDictionaryRef attrs_orig, CFDictionaryRef attrs) +{ + CFErrorRef error = NULL; + int updated = 0; + ENTRY* ep; + + for (ep = list; ep->prompt; ep++) { + + // Nothing to update + if (!rec || !attrs_orig || !attrs) break; + + // No need to update if entry is restricted + if (ep->restricted) continue; + + CFArrayRef values_orig = CFDictionaryGetValue(attrs_orig, ep->attrName); + CFTypeRef value_orig = values_orig && CFArrayGetCount(values_orig) ? CFArrayGetValueAtIndex(values_orig, 0) : NULL; + CFTypeRef value = CFDictionaryGetValue(attrs, ep->attrName); + + // No need to update if both values are the same + if (value == value_orig) continue; + + // No need to update if strings are equal + if (value && value_orig) { + if (CFGetTypeID(value_orig) == CFStringGetTypeID() && + CFStringCompare(value_orig, value, 0) == kCFCompareEqualTo) continue; + } + + // No need to update if empty string replaces NULL + if (!value_orig && value) { + if (CFStringGetLength(value) == 0) continue; + } + + // Needs update + if (value) { + // if new value is an empty string, send an empty dictionary which will delete the property. + CFIndex count = CFEqual(value, CFSTR("")) ? 0 : 1; + CFTypeRef vals[] = { value }; + CFArrayRef values = CFArrayCreate(NULL, vals, count, &kCFTypeArrayCallBacks); + if (values && ODRecordSetValues(rec, ep->attrName, values, &error)) { + updated = 1; + } + if (values) CFRelease(values); + if (error) show_error(error); + } + } + + if (updated) { + updated = ODRecordSynchronize(rec, &error); + if (error) show_error(error); + } + if (!updated) { + fprintf(stderr, "%s: no changes made\n", progname); + } +} +#endif /* OPEN_DIRECTORY */ diff --git a/chpass.tproj/open_directory.h b/chpass.tproj/open_directory.h new file mode 100644 index 0000000..e6011b7 --- /dev/null +++ b/chpass.tproj/open_directory.h @@ -0,0 +1,13 @@ +#ifndef _OPEN_DIRECTORY_H_ +#define _OPEN_DIRECTORY_H_ + +#include +#include + +extern void setrestricted(CFDictionaryRef attrs); + +ODRecordRef odGetUser(CFStringRef location, CFStringRef authname, CFStringRef user, CFDictionaryRef* attrs); + +void odUpdateUser(ODRecordRef rec, CFDictionaryRef attrs_orig, CFDictionaryRef attrs); + +#endif /* _OPEN_DIRECTORY_H_ */ diff --git a/chpass.tproj/pathnames.h b/chpass.tproj/pathnames.h deleted file mode 100644 index 03c43a3..0000000 --- a/chpass.tproj/pathnames.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 - */ - -#include - -#undef _PATH_TMP -#define _PATH_TMP "/tmp/chpass.XXXXXX" diff --git a/chpass.tproj/pw_copy.c b/chpass.tproj/pw_copy.c index 64ddc9f..b6d156a 100644 --- a/chpass.tproj/pw_copy.c +++ b/chpass.tproj/pw_copy.c @@ -3,21 +3,20 @@ * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ diff --git a/chpass.tproj/pw_copy.h b/chpass.tproj/pw_copy.h index 4a742ac..8616d2e 100644 --- a/chpass.tproj/pw_copy.h +++ b/chpass.tproj/pw_copy.h @@ -3,21 +3,20 @@ * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ diff --git a/chpass.tproj/table.c b/chpass.tproj/table.c index 1cd169b..a6dae3e 100644 --- a/chpass.tproj/table.c +++ b/chpass.tproj/table.c @@ -1,29 +1,28 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /*- * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +34,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -54,6 +53,16 @@ * SUCH DAMAGE. */ +#if 0 +#if 0 +#ifndef lint +static const char sccsid[] = "@(#)table.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ +#endif +#include +__FBSDID("$FreeBSD: src/usr.bin/chpass/table.c,v 1.10 2003/05/03 19:44:45 obrien Exp $"); +#endif + #include #include #include "chpass.h" @@ -61,38 +70,48 @@ char e1[] = ": "; char e2[] = ":,"; -#ifdef DIRECTORY_SERVICE +#ifdef OPEN_DIRECTORY +#include "open_directory.h" + ENTRY list[] = { - { "login", d_login, p_login, 0, 5, e1, }, - { "password", d_passwd, p_passwd, 0, 8, e1, }, - { "uid", d_uid, p_uid, 0, 3, e1, }, - { "gid", d_gid, p_gid, 0, 3, e1, }, - { "change", d_change, p_change, 0, 6, NULL, }, - { "expire", d_expire, p_expire, 0, 6, NULL, }, - { "class", d_class, p_class, 0, 5, e1, }, - { "home directory", d_hdir, p_hdir, 0, 14, e1, }, - { "shell", d_shell, p_shell, 0, 5, e1, }, - { "full name", d_fullname, p_gecos, 0, 9, e2, }, - { "location", d_location, p_gecos, 0, 8, e2, }, - { "office phone", d_officephone, p_gecos, 0, 12, e2, }, - { "home phone", d_homephone, p_gecos, 0, 10, e2, }, - { NULL }, + { "Login", display_string, p_login, 1, 5, e1, CFSTR(kDSNAttrRecordName), }, + { "Password", display_string, p_passwd, 1, 8, e1, CFSTR(kDS1AttrPassword), }, + { "Uid [#]", display_string, p_uid, 1, 3, e1, CFSTR(kDS1AttrUniqueID), }, + { "Gid [# or name]", display_string, p_gid, 1, 3, e1, CFSTR(kDS1AttrPrimaryGroupID), }, + { "Generated uid", display_string, p_uuid, 1, 13, NULL, CFSTR(kDS1AttrGeneratedUID), }, +#if 0 + { "Change [month day year]", display_time, p_change, 1, 6, NULL, CFSTR(kDS1AttrChange), }, + { "Expire [month day year]", display_time, p_expire, 1, 6, NULL, CFSTR(kDS1AttrExpire), }, + { "Class", display_string, p_class, 0, 5, e1, CFSTR(""), "Class" }, +#endif + { "Home directory", display_string, p_hdir, 1, 14, e1, CFSTR(kDS1AttrNFSHomeDirectory), }, + { "Shell", display_string, p_shell, 1, 5, e1, CFSTR(kDS1AttrUserShell), }, + { "Full Name", display_string, p_gecos, 1, 9, e2, CFSTR(kDS1AttrDistinguishedName), }, + { "Office Location", display_string, p_gecos, 1, 8, e2, CFSTR(kDSNAttrBuilding), }, + { "Office Phone", display_string, p_gecos, 1, 12, e2, CFSTR(kDSNAttrPhoneNumber), }, + { "Home Phone", display_string, p_gecos, 1, 10, e2, CFSTR(kDSNAttrHomePhoneNumber), }, + { NULL, NULL, NULL, 0, 0, NULL, NULL,}, }; -#else /* DIRECTORY_SERVICE */ +#else /* OPEN_DIRECTORY */ ENTRY list[] = { - { "login", p_login, 1, 5, e1, }, - { "password", p_passwd, 1, 8, e1, }, - { "uid", p_uid, 1, 3, e1, }, - { "gid", p_gid, 1, 3, e1, }, - { "class", p_class, 1, 5, e1, }, - { "change", p_change, 1, 6, NULL, }, - { "expire", p_expire, 1, 6, NULL, }, - { "full name", p_gecos, 0, 9, e2, }, - { "office phone", p_gecos, 0, 12, e2, }, - { "home phone", p_gecos, 0, 10, e2, }, - { "location", p_gecos, 0, 8, e2, }, - { "home directory", p_hdir, 1, 14, e1, }, - { "shell", p_shell, 0, 5, e1, }, - { NULL, 0, }, + { "login", p_login, 1, 5, e1, NULL }, + { "password", p_passwd, 1, 8, e1, NULL }, + { "uid", p_uid, 1, 3, e1, NULL }, + { "gid", p_gid, 1, 3, e1, NULL }, + { "class", p_class, 1, 5, e1, NULL }, + { "change", p_change, 1, 6, NULL, NULL }, + { "expire", p_expire, 1, 6, NULL, NULL }, +#ifdef RESTRICT_FULLNAME_CHANGE /* do not allow fullname changes */ + { "full name", p_gecos, 1, 9, e2, NULL }, +#else + { "full name", p_gecos, 0, 9, e2, NULL }, +#endif + { "office phone", p_gecos, 0, 12, e2, NULL }, + { "home phone", p_gecos, 0, 10, e2, NULL }, + { "office location", p_gecos, 0, 15, e2, NULL }, + { "other information", p_gecos, 0, 11, e1, NULL }, + { "home directory", p_hdir, 1, 14, e1, NULL }, + { "shell", p_shell, 0, 5, e1, NULL }, + { NULL, NULL, 0, 0, NULL, NULL }, }; -#endif /* DIRECTORY_SERVICE */ +#endif /* OPEN_DIRECTORY */ diff --git a/chpass.tproj/util.c b/chpass.tproj/util.c index c4dd4d3..493fb4e 100644 --- a/chpass.tproj/util.c +++ b/chpass.tproj/util.c @@ -1,29 +1,35 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /*- - * Copyright (c) 1988, 1993, 1994 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,8 +41,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -54,10 +60,19 @@ * SUCH DAMAGE. */ +#if 0 +#ifndef lint +#if 0 +static char sccsid[] = "@(#)util.c 8.4 (Berkeley) 4/2/94"; +#endif +#endif /* not lint */ +#include +__FBSDID("$FreeBSD: src/usr.bin/chpass/util.c,v 1.13 2004/01/18 21:46:39 charnier Exp $"); +#endif + #include #include -#include #include #include #include @@ -66,18 +81,23 @@ #include #include "chpass.h" -#include "pathnames.h" -static int dmsize[] = - { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -static char *months[] = +#if OPEN_DIRECTORY +#include +#include +#include +#include "open_directory.h" + +char* tempname; +#endif /* OPEN_DIRECTORY */ + +static const char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", NULL }; char * -ttoa(tval) - time_t tval; +ttoa(time_t tval) { struct tm *tp; static char tbuf[50]; @@ -90,15 +110,14 @@ ttoa(tval) else *tbuf = '\0'; return (tbuf); -} +} int -atot(p, store) - char *p; - time_t *store; +atot(char *p, time_t *store) { static struct tm *lt; - char *t, **mp; + char *t; + const char **mp; time_t tval; int day, month, year; @@ -113,12 +132,16 @@ atot(p, store) } if (!(t = strtok(p, " \t"))) goto bad; - for (mp = months;; ++mp) { - if (!*mp) - goto bad; - if (!strncasecmp(*mp, t, 3)) { - month = mp - months + 1; - break; + if (isdigit(*t)) { + month = atoi(t); + } else { + for (mp = months;; ++mp) { + if (!*mp) + goto bad; + if (!strncasecmp(*mp, t, 3)) { + month = mp - months + 1; + break; + } } } if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) @@ -127,38 +150,183 @@ atot(p, store) if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) goto bad; year = atoi(t); - if (day < 1 || day > 31 || month < 1 || month > 12 || !year) + if (day < 1 || day > 31 || month < 1 || month > 12) goto bad; - if (year < 100) + /* Allow two digit years 1969-2068 */ + if (year < 69) + year += 2000; + else if (year < 100) year += TM_YEAR_BASE; - if (year <= EPOCH_YEAR) + if (year < EPOCH_YEAR) bad: return (1); - tval = isleap(year) && month > 2; - for (--year; year >= EPOCH_YEAR; --year) - tval += isleap(year) ? - DAYSPERLYEAR : DAYSPERNYEAR; - while (--month) - tval += dmsize[month]; - tval += day; - tval = tval * HOURSPERDAY * MINSPERHOUR * SECSPERMIN; - tval -= lt->tm_gmtoff; + lt->tm_year = year - TM_YEAR_BASE; + lt->tm_mon = month - 1; + lt->tm_mday = day; + lt->tm_hour = 0; + lt->tm_min = 0; + lt->tm_sec = 0; + lt->tm_isdst = -1; + if ((tval = mktime(lt)) < 0) + return (1); *store = tval; return (0); } -char * -ok_shell(name) - char *name; +int +ok_shell(char *name) { +#ifdef __APPLE__ + char *sh; +#else char *p, *sh; +#endif setusershell(); - while (sh = getusershell()) { - if (!strcmp(name, sh)) - return (name); + while ((sh = getusershell())) { + if (!strcmp(name, sh)) { + endusershell(); + return (1); + } +#ifndef __APPLE__ /* allow just shell name, but use "real" path */ - if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) - return (sh); + if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) { + endusershell(); + return (1); + } +#endif } + endusershell(); + return (0); +} + +char * +dup_shell(char *name) +{ + char *p, *sh, *ret; + + setusershell(); + while ((sh = getusershell())) { + if (!strcmp(name, sh)) { + endusershell(); + return (strdup(name)); + } + /* allow just shell name, but use "real" path */ + if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) { + ret = strdup(sh); + endusershell(); + return (ret); + } + } + endusershell(); return (NULL); } + +#if OPEN_DIRECTORY +int +cfprintf(FILE* file, const char* format, ...) { + char* cstr; + int result = 0; + va_list args; + va_start(args, format); + CFStringRef formatStr = CFStringCreateWithCStringNoCopy(NULL, format, kCFStringEncodingUTF8, kCFAllocatorNull); + if (formatStr) { + CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, formatStr, args); + if (str) { + size_t size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1; + va_end(args); + cstr = malloc(size); + if (cstr && CFStringGetCString(str, cstr, size, kCFStringEncodingUTF8)) { + result = fprintf(file, "%s", cstr); + free(cstr); + } + CFRelease(str); + } + CFRelease(formatStr); + } + return result; +} + +/* + * Edit the temp file. Return -1 on error, >0 if the file was modified, 0 + * if it was not. + */ +int +editfile(const char* tfn) +{ + struct sigaction sa, sa_int, sa_quit; + sigset_t oldsigset, sigset; + struct stat st1, st2; + const char *p, *editor; + int pstat; + pid_t editpid; + + if ((editor = getenv("EDITOR")) == NULL) + editor = _PATH_VI; + if (p = strrchr(editor, '/')) + ++p; + else + p = editor; + + if (stat(tfn, &st1) == -1) + return (-1); + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGINT, &sa, &sa_int); + sigaction(SIGQUIT, &sa, &sa_quit); + sigemptyset(&sigset); + sigaddset(&sigset, SIGCHLD); + sigprocmask(SIG_BLOCK, &sigset, &oldsigset); + switch ((editpid = fork())) { + case -1: + return (-1); + case 0: + sigaction(SIGINT, &sa_int, NULL); + sigaction(SIGQUIT, &sa_quit, NULL); + sigprocmask(SIG_SETMASK, &oldsigset, NULL); + errno = 0; + if (!master_mode) { + (void)setgid(getgid()); + (void)setuid(getuid()); + } + execlp(editor, p, tfn, (char *)NULL); + _exit(errno); + default: + /* parent */ + break; + } + for (;;) { + if (waitpid(editpid, &pstat, WUNTRACED) == -1) { + if (errno == EINTR) + continue; + unlink(tfn); + editpid = -1; + break; + } else if (WIFSTOPPED(pstat)) { + raise(WSTOPSIG(pstat)); + } else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0) { + editpid = -1; + break; + } else { + unlink(tfn); + editpid = -1; + break; + } + } + sigaction(SIGINT, &sa_int, NULL); + sigaction(SIGQUIT, &sa_quit, NULL); + sigprocmask(SIG_SETMASK, &oldsigset, NULL); + if (stat(tfn, &st2) == -1) + return (-1); + return (st1.st_mtime != st2.st_mtime); +} + +void +pw_error(char *name, int err, int eval) +{ + if (err) + warn("%s", name); + exit(eval); +} + +#endif /* OPEN_DIRECTORY */ diff --git a/dirhelper.tproj/Makefile b/dirhelper.tproj/Makefile new file mode 100644 index 0000000..5ba9105 --- /dev/null +++ b/dirhelper.tproj/Makefile @@ -0,0 +1,63 @@ + +ifeq "$(SRCROOT)" "" + SRCROOT=$(shell pwd) +endif +ifeq "$(OBJROOT)" "" + OBJROOT=$(shell pwd) +endif +ifeq "$(SYMROOT)" "" + SYMROOT=$(shell pwd) +endif +ifeq "$(DSTROOT)" "" + DSTROOT= +endif + +ifneq "$(shell basename $(SRCROOT))" "dirhelper.tproj" +SRCDIR=$(SRCROOT)/dirhelper.tproj +else +SRCDIR=$(SRCROOT) +endif +OBJDIR=$(OBJROOT)/dirhelper.obj + +CFLAGS = -g -mdynamic-no-pic -Os -Wall -Wextra -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 $(RC_CFLAGS) -I $(OBJDIR) + +LDFLAGS = -lbsm + +all: dirhelper + +dirhelper: mighdrs + cc -c $(CFLAGS) -o $(OBJDIR)/dirhelperServer.o $(OBJDIR)/dirhelperServer.c + cc -c $(CFLAGS) -o $(OBJDIR)/dirhelperUser.o $(OBJDIR)/dirhelperUser.c + cc -c $(CFLAGS) -o $(OBJDIR)/dirhelper.o $(SRCDIR)/dirhelper.c + cc $(CFLAGS) $(LDFLAGS) -o $(SYMROOT)/dirhelper $(OBJDIR)/dirhelperServer.o $(OBJDIR)/dirhelperUser.o $(OBJDIR)/dirhelper.o + +client: mighdrs + cc $(CFLAGS) $(LDFLAGS) -o $(SYMROOT)/client $(SRCDIR)/client.c $(OBJDIR)/dirhelperUser.c + +install: dirhelper + install -m 0644 -o root -g wheel -d $(DSTROOT)/System/Library/LaunchDaemons + install -m 0644 -o root -g wheel com.apple.bsd.dirhelper.plist $(DSTROOT)/System/Library/LaunchDaemons/ + install -m 0755 -o root -g wheel -d $(DSTROOT)/usr/libexec + install -m 0755 -o root -g wheel $(SYMROOT)/dirhelper $(DSTROOT)/usr/libexec/ + strip -S $(DSTROOT)/usr/libexec/dirhelper + mkdir -p "$(DSTROOT)/usr/share/man/man8" + gzip -c "$(SRCDIR)/dirhelper.8" > "$(DSTROOT)/usr/share/man/man8/dirhelper.8.gz" + +installsrc: + mkdir "$(SRCDIR)" + tar cf - . | tar xf - -C "$(SRCDIR)" + +mighdrs: + mkdir -p $(OBJDIR) + cd $(OBJDIR) && mig -sheader dirhelperServer.h /usr/local/include/dirhelper.defs + +installhdrs: + @echo nothing to install + +#installhdrs: mighdrs +# install -m 0755 -o root -g wheel -d $(DSTROOT)/usr/local/include +# install -m 0644 -o root -g wheel $(OBJDIR)/dirhelper.h $(DSTROOT)/usr/local/include/ + +clean: + -rm -f *.o client dirhelper + -rm -rf dirhelper.obj diff --git a/dirhelper.tproj/client.c b/dirhelper.tproj/client.c new file mode 100644 index 0000000..88dd15f --- /dev/null +++ b/dirhelper.tproj/client.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "dirhelper.h" + +#define DIRHELPER_BOOTSTRAP_NAME "com.apple.bsd.dirhelper" + +int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) +{ + kern_return_t kr; + mach_port_t mp; + + kr = bootstrap_look_up(bootstrap_port, DIRHELPER_BOOTSTRAP_NAME, &mp); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "bootstrap_look_up(): %s\n", bootstrap_strerror(kr)); + exit(EXIT_FAILURE); + } + + kr = __dirhelper_create_user_local(mp); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "dirhelper_create_user_local(): %s\n", mach_error_string(kr)); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} diff --git a/dirhelper.tproj/com.apple.bsd.dirhelper.plist b/dirhelper.tproj/com.apple.bsd.dirhelper.plist new file mode 100644 index 0000000..fca6e3e --- /dev/null +++ b/dirhelper.tproj/com.apple.bsd.dirhelper.plist @@ -0,0 +1,33 @@ + + + + + Label + com.apple.bsd.dirhelper + MachServices + + com.apple.bsd.dirhelper + + + ProgramArguments + + /usr/libexec/dirhelper + + RunAtLoad + + TimeOut + 30 + StartCalendarInterval + + Hour + 3 + Minute + 35 + + EnvironmentVariables + + CLEAN_FILES_OLDER_THAN_DAYS + 3 + + + diff --git a/dirhelper.tproj/dirhelper.8 b/dirhelper.tproj/dirhelper.8 new file mode 100644 index 0000000..356ca98 --- /dev/null +++ b/dirhelper.tproj/dirhelper.8 @@ -0,0 +1,51 @@ +.\" +.\" Copyright (c) 2006-2007 Apple Inc. All rights reserved. +.\" +.\" @APPLE_LICENSE_HEADER_START@ +.\" +.\" This file contains Original Code and/or Modifications of Original Code +.\" as defined in and that are subject to the Apple Public Source License +.\" Version 2.0 (the 'License'). You may not use this file except in +.\" compliance with the License. Please obtain a copy of the License at +.\" http://www.opensource.apple.com/apsl/ and read it before using this +.\" file. +.\" +.\" The Original Code and all software distributed under the License are +.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +.\" Please see the License for the specific language governing rights and +.\" limitations under the License. +.\" +.\" @APPLE_LICENSE_HEADER_END@ +.\" +.Dd November 1, 2006 +.Dt dirhelper 8 +.Os "Mac OS X" +.Sh NAME +.Nm dirhelper +.Nd helper for special directory creation +.Sh SYNOPSIS +.Nm dirhelper +.Sh DESCRIPTION +The +.Nm dirhelper +command is a launch-on-demand helper for special +directory creation. It is launched in a privileged +context via +.Nm launchd +in order to create special directories where the user +would not otherwise have permission to do so. +.Pp +The +.Nm dirhelper +command should not be invoked directly. It will exit +automatically after a period of inactivity. +.Sh FILES +.Bl -tag -width "/System/Library/LaunchDaemons/com.apple.bsd.dirhelper.plist" -compact +.It Pa /System/Library/LaunchDaemons/com.apple.bsd.dirhelper.plist +.El +.Sh SEE ALSO +.Xr launchd 8 , +.Xr launchd.plist 5 diff --git a/dirhelper.tproj/dirhelper.c b/dirhelper.tproj/dirhelper.c new file mode 100644 index 0000000..f9ceffb --- /dev/null +++ b/dirhelper.tproj/dirhelper.c @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2006-2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "dirhelper.h" +#include "dirhelperServer.h" + +// globals for idle exit +struct idle_globals { + mach_port_t mp; + long timeout; + struct timeval lastmsg; +}; + +struct idle_globals idle_globals; + +void* idle_thread(void* param __attribute__((unused))); + +int file_check(const char* path, int mode, int uid, int gid); +#define is_file(x) file_check((x), S_IFREG, -1, -1) +#define is_directory(x) file_check((x), S_IFDIR, -1, -1) +#define is_root_wheel_directory(x) file_check((x), S_IFDIR, 0, 0) + +int is_safeboot(void); + +void clean_files_older_than(const char* path, time_t when); +void clean_directory(const char* name, int); + +kern_return_t +do___dirhelper_create_user_local( + mach_port_t server_port __attribute__((unused)), + audit_token_t au_tok) +{ + int res = 0; + uid_t euid; + gid_t gid = 0; + struct passwd* pwd = NULL; + + gettimeofday(&idle_globals.lastmsg, NULL); + + audit_token_to_au32(au_tok, + NULL, // audit uid + &euid, // euid + NULL, // egid + NULL, // ruid + NULL, // rgid + NULL, // remote_pid + NULL, // asid + NULL); // aud_tid_t + + // Look-up the primary gid of the user. We'll use this for chown(2) + // so that the created directory is owned by a group that the user + // belongs to, avoiding warnings if files are moved outside this dir. + pwd = getpwuid(euid); + if (pwd) gid = pwd->pw_gid; + + do { // begin block + char path[PATH_MAX]; + char *next; + + if (__user_local_dirname(euid, DIRHELPER_USER_LOCAL, path, sizeof(path)) == NULL) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, + "__user_local_dirname: %s", strerror(errno)); + break; + } + + // + // 1. Starting with VAR_FOLDERS_PATH, make each subdirectory + // in path, ignoring failure if it already exists. + // 2. Change ownership of directory to the user. + // + next = path + strlen(VAR_FOLDERS_PATH); + while ((next = strchr(next, '/')) != NULL) { + *next = 0; // temporarily truncate + res = mkdir(path, 0755); + if (res != 0 && errno != EEXIST) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, + "mkdir(%s): %s", path, strerror(errno)); + break; + } + *next++ = '/'; // restore the slash and increment + } + if(next || res) // an error occurred + break; + res = chown(path, euid, gid); + if (res != 0) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, + "chown(%s): %s", path, strerror(errno)); + } + } while(0); // end block + return KERN_SUCCESS; +} + +kern_return_t +do___dirhelper_idle_exit( + mach_port_t server_port __attribute__((unused)), + audit_token_t au_tok __attribute__((unused))) { + + struct timeval now; + gettimeofday(&now, NULL); + long delta = now.tv_sec - idle_globals.lastmsg.tv_sec; + if (delta >= idle_globals.timeout) { + asl_log(NULL, NULL, ASL_LEVEL_DEBUG, + "idle exit after %ld seconds", delta); + exit(EXIT_SUCCESS); + } + + return KERN_SUCCESS; +} + +void* +idle_thread(void* param __attribute__((unused))) { + for(;;) { + struct timeval now; + gettimeofday(&now, NULL); + long delta = (now.tv_sec - idle_globals.lastmsg.tv_sec); + if (delta < idle_globals.timeout) { + // sleep for remainder of timeout + sleep(idle_globals.timeout - delta); + } else { + // timeout has elapsed, attempt to idle exit + __dirhelper_idle_exit(idle_globals.mp); + } + } + return NULL; +} + +// If when == 0, all files are removed. Otherwise, only regular files older than when. +void +clean_files_older_than(const char* path, time_t when) { + FTS* fts; + + char* path_argv[] = { (char*)path, NULL }; + fts = fts_open(path_argv, FTS_PHYSICAL | FTS_XDEV, NULL); + if (fts) { + FTSENT* ent; + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Cleaning %s", path); + while ((ent = fts_read(fts))) { + switch(ent->fts_info) { + case FTS_F: + case FTS_DEFAULT: + // Unlink the file if it has not been accessed since + // the specified time. Obtain an exclusive lock so + // that we can avoid a race with other processes + // attempting to open the file. + if (when == 0) { + (void)unlink(ent->fts_path); + } else if (S_ISREG(ent->fts_statp->st_mode) && ent->fts_statp->st_atime < when) { + int fd = open(ent->fts_path, O_RDONLY | O_NONBLOCK); + if (fd != -1) { + int res = flock(fd, LOCK_EX | LOCK_NB); + if (res == 0) { + struct stat sb; + res = fstat(fd, &sb); + if (res == 0 && sb.st_atime < when) { + (void)unlink(ent->fts_path); + } + (void)flock(fd, LOCK_UN); + } + close(fd); + } + } + break; + + case FTS_SL: + case FTS_SLNONE: + if (when == 0) { + (void)unlink(ent->fts_path); + } + break; + + case FTS_DP: + if (when == 0) { + (void)rmdir(ent->fts_path); + } + break; + + case FTS_ERR: + case FTS_NS: + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", ent->fts_path, strerror(ent->fts_errno)); + break; + + default: + break; + } + } + fts_close(fts); + } else { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", path, strerror(errno)); + } +} + +int +file_check(const char* path, int mode, int uid, int gid) { + int check = 1; + struct stat sb; + if (lstat(path, &sb) == 0) { + check = check && ((sb.st_mode & S_IFMT) == mode); + check = check && ((sb.st_uid == (uid_t)uid) || uid == -1); + check = check && ((sb.st_gid == (gid_t)gid) || gid == -1); + } else { + if (errno != ENOENT) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", path, strerror(errno)); + } + check = 0; + } + return check; +} + +int +is_safeboot(void) { + uint32_t sb = 0; + size_t sbsz = sizeof(sb); + + if (sysctlbyname("kern.safeboot", &sb, &sbsz, NULL, 0) != 0) { + return 0; + } else { + return (int)sb; + } +} + +void +clean_directory(const char* name, int machineBoot) { + DIR* d; + time_t when = 0; + + if (!machineBoot) { + struct timeval now; + long days = 3; + const char* str = getenv("CLEAN_FILES_OLDER_THAN_DAYS"); + if (str) { + days = strtol(str, NULL, 0); + } + (void)gettimeofday(&now, NULL); + + asl_log(NULL, NULL, ASL_LEVEL_INFO, "Cleaning %s older than %ld days", name, days); + + when = now.tv_sec - (days * 60 * 60 * 24); + } + + // Look up the boot time + struct timespec boottime; + size_t len = sizeof(boottime); + if (sysctlbyname("kern.boottime", &boottime, &len, NULL, 0) == -1) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", "sysctl kern.boottime", strerror(errno)); + return; + } + + if (!is_root_wheel_directory(VAR_FOLDERS_PATH)) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", VAR_FOLDERS_PATH, "invalid ownership"); + return; + } + + if ((d = opendir(VAR_FOLDERS_PATH))) { + struct dirent* e; + char path[PATH_MAX]; + + // /var/folders/* + while ((e = readdir(d))) { + if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0) continue; + + snprintf(path, sizeof(path), "%s%s", VAR_FOLDERS_PATH, e->d_name); + if (is_root_wheel_directory(path)) { + DIR* d2 = opendir(path); + if (d2) { + struct dirent* e2; + + // /var/folders/*/* + while ((e2 = readdir(d2))) { + char temporary_items[PATH_MAX]; + if (strcmp(e2->d_name, ".") == 0 || strcmp(e2->d_name, "..") == 0) continue; + + snprintf(temporary_items, sizeof(temporary_items), + "%s/%s/%s", path, e2->d_name, name); + if (is_directory(temporary_items)) { + // at boot time we clean all files, + // otherwise only clean regular files. + clean_files_older_than(temporary_items, when); + } + } + + closedir(d2); + } else { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", path, strerror(errno)); + } + } + } + + closedir(d); + } else { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", VAR_FOLDERS_PATH, strerror(errno)); + } +} + +int +main(int argc, char* argv[]) { + mach_msg_size_t mxmsgsz = MAX_TRAILER_SIZE; + kern_return_t kr; + long idle_timeout = 30; // default 30 second timeout + + // Clean up TemporaryItems directory when launched at boot. + // It is safe to clean all file types at this time. + if (argc > 1 && strcmp(argv[1], "-machineBoot") == 0) { + clean_directory(DIRHELPER_TEMP_STR, 1); + clean_directory("TemporaryItems", 1); + clean_directory("Cleanup At Startup", 1); + if (is_safeboot()) clean_directory(DIRHELPER_CACHE_STR, 1); + exit(EXIT_SUCCESS); + } else if (argc > 1 && strcmp(argv[1], "-cleanTemporaryItems") == 0) { + clean_directory(DIRHELPER_TEMP_STR, 0); + clean_directory("TemporaryItems", 0); + exit(EXIT_SUCCESS); + } else if (argc > 1) { + exit(EXIT_FAILURE); + } + + launch_data_t config = NULL, checkin = NULL; + checkin = launch_data_new_string(LAUNCH_KEY_CHECKIN); + config = launch_msg(checkin); + if (!config || launch_data_get_type(config) == LAUNCH_DATA_ERRNO) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "launchd checkin failed"); + exit(EXIT_FAILURE); + } + + launch_data_t tmv; + tmv = launch_data_dict_lookup(config, LAUNCH_JOBKEY_TIMEOUT); + if (tmv) { + idle_timeout = launch_data_get_integer(tmv); + asl_log(NULL, NULL, ASL_LEVEL_DEBUG, + "idle timeout set: %ld seconds", idle_timeout); + } + + launch_data_t svc; + svc = launch_data_dict_lookup(config, LAUNCH_JOBKEY_MACHSERVICES); + if (!svc) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "no mach services"); + exit(EXIT_FAILURE); + } + + svc = launch_data_dict_lookup(svc, DIRHELPER_BOOTSTRAP_NAME); + if (!svc) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "no mach service: %s", + DIRHELPER_BOOTSTRAP_NAME); + exit(EXIT_FAILURE); + } + + mach_port_t mp = launch_data_get_machport(svc); + if (mp == MACH_PORT_NULL) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "NULL mach service: %s", + DIRHELPER_BOOTSTRAP_NAME); + exit(EXIT_FAILURE); + } + + // insert a send right so we can send our idle exit message + kr = mach_port_insert_right(mach_task_self(), mp, mp, + MACH_MSG_TYPE_MAKE_SEND); + if (kr != KERN_SUCCESS) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, "send right failed: %s", + mach_error_string(kr)); + exit(EXIT_FAILURE); + } + + // spawn a thread for our idle timeout + pthread_t thread; + idle_globals.mp = mp; + idle_globals.timeout = idle_timeout; + gettimeofday(&idle_globals.lastmsg, NULL); + pthread_create(&thread, NULL, &idle_thread, NULL); + + // look to see if we have any messages queued. if not, assume + // we were launched because of the calendar interval, and attempt + // to clean the temporary items. + mach_msg_type_number_t status_count = MACH_PORT_RECEIVE_STATUS_COUNT; + mach_port_status_t status; + kr = mach_port_get_attributes(mach_task_self(), mp, + MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status, &status_count); + if (kr == KERN_SUCCESS && status.mps_msgcount == 0) { + clean_directory(DIRHELPER_TEMP_STR, 0); + clean_directory("TemporaryItems", 0); + } + + // main event loop + + kr = mach_msg_server(dirhelper_server, mxmsgsz, mp, + MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | + MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)); + if (kr != KERN_SUCCESS) { + asl_log(NULL, NULL, ASL_LEVEL_ERR, + "mach_msg_server(mp): %s", mach_error_string(kr)); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} diff --git a/dmesg.tproj/Makefile.preamble b/dmesg.tproj/Makefile.preamble index cca6d6d..965d56b 100644 --- a/dmesg.tproj/Makefile.preamble +++ b/dmesg.tproj/Makefile.preamble @@ -1,4 +1,4 @@ -OTHER_CFLAGS = -I/System/Library/Frameworks/System.framework/PrivateHeaders +OTHER_CFLAGS = -I$(NEXT_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders OTHER_LIBS = -lproc OTHER_GENERATED_OFILES = $(VERS_OFILE) diff --git a/dmesg.tproj/dmesg.8 b/dmesg.tproj/dmesg.8 index fd7d21b..ca3758b 100644 --- a/dmesg.tproj/dmesg.8 +++ b/dmesg.tproj/dmesg.8 @@ -43,9 +43,9 @@ .Op Fl N Ar system .Sh DESCRIPTION .Nm Dmesg -displays the contents of the system message buffer. This command needs to be run as root. +displays the contents of the system message buffer. +This command needs to be run as root. .Pp -.El .Sh SEE ALSO .Xr syslogd 8 .Sh HISTORY diff --git a/dmesg.tproj/dmesg.c b/dmesg.tproj/dmesg.c index 3b73c88..373653d 100644 --- a/dmesg.tproj/dmesg.c +++ b/dmesg.tproj/dmesg.c @@ -54,84 +54,34 @@ * SUCH DAMAGE. */ -#include -#include - -#include -#include #include #include -#include -#include #include #include - -void usage __P((void)); +void +usage() { + (void)fprintf(stderr, "usage: sudo dmesg\n"); + exit(1); +} int -main(argc, argv) - int argc; - char *argv[]; -{ - register int ch, newl, skip; - register char *p, *ep; - struct msgbuf cur; - char buf[5]; +main(int argc, char **argv) { + char msgbuf[16*1024], *visbuf; + long data_size; if (argc > 1) usage(); - if (proc_kmsgbuf(&cur, sizeof(struct msgbuf)) == 0){ + if ((data_size = proc_kmsgbuf(msgbuf, sizeof(msgbuf))) == 0){ perror("Unable to obtain kernel buffer"); usage(); - exit(1); } - if (cur.msg_magic != MSG_MAGIC) { - perror("magic number incorrect"); - exit(1); - } - if (cur.msg_bufx >= MSG_BSIZE) - cur.msg_bufx = 0; - - /* - * The message buffer is circular; start at the read pointer, and - * go to the write pointer - 1. - */ - p = cur.msg_bufc + cur.msg_bufx; - ep = cur.msg_bufc + cur.msg_bufx - 1; - for (newl = skip = 0; p != ep; ++p) { - if (p == cur.msg_bufc + MSG_BSIZE) - p = cur.msg_bufc; - ch = *p; - /* Skip "\n<.*>" syslog sequences. */ - if (skip) { - if (ch == '>') - newl = skip = 0; - continue; - } - if (newl && ch == '<') { - skip = 1; - continue; - } - if (ch == '\0') - continue; - newl = ch == '\n'; - (void)vis(buf, ch, 0, 0); - if (buf[1] == 0) - (void)putchar(buf[0]); - else - (void)printf("%s", buf); - } - if (!newl) - (void)putchar('\n'); + visbuf = malloc(data_size*4); + strvis(visbuf, msgbuf, 0); + printf("%s", visbuf); + free(visbuf); exit(0); } -void -usage() -{ - (void)fprintf(stderr, "usage: sudo dmesg\n"); - exit(1); -} diff --git a/dp_notify_lib/backing_store_alerts.defs b/dp_notify_lib/backing_store_alerts.defs index 661af83..4326949 100644 --- a/dp_notify_lib/backing_store_alerts.defs +++ b/dp_notify_lib/backing_store_alerts.defs @@ -10,6 +10,10 @@ subsystem backing_store_alerts 1000; +#ifndef __MigTypeCheck +#define __MigTypeCheck 1 +#endif + #include #include diff --git a/dp_notify_lib/backing_store_triggers.defs b/dp_notify_lib/backing_store_triggers.defs index a279266..bbb45a1 100644 --- a/dp_notify_lib/backing_store_triggers.defs +++ b/dp_notify_lib/backing_store_triggers.defs @@ -10,6 +10,10 @@ subsystem backing_store_triggers 1200; +#ifndef __MigTypeCheck +#define __MigTypeCheck 1 +#endif + #include #include diff --git a/dynamic_pager.tproj/Makefile b/dynamic_pager.tproj/Makefile index 40d68a4..3ddd6e8 100644 --- a/dynamic_pager.tproj/Makefile +++ b/dynamic_pager.tproj/Makefile @@ -16,7 +16,8 @@ CFILES = dynamic_pager.c OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\ default_pager_alerts.defs backing_store_alerts.defs\ - backing_store_triggers.defs dynamic_pager.8 + backing_store_triggers.defs dynamic_pager.8\ + com.apple.dynamic_pager.plist MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/dynamic_pager.tproj/Makefile.postamble b/dynamic_pager.tproj/Makefile.postamble index b00ad8b..f6c4e3b 100644 --- a/dynamic_pager.tproj/Makefile.postamble +++ b/dynamic_pager.tproj/Makefile.postamble @@ -105,6 +105,8 @@ SRC_ROOT = $(SRCROOT) # MIGFLAGS = -no-cpp-precomp -R -untyped -DNO_DIRECT_RPC MIG = $(NEXT_ROOT)/usr/bin/mig + +Embedded=$(shell tconf --test TARGET_OS_EMBEDDED) default_pager_alerts_server.c : backing_store_alerts.c \ backing_store_triggers_server.c \ @@ -128,3 +130,15 @@ backing_store_triggers_server.c: \ install-man-page: install -d $(DSTROOT)/usr/share/man/man8 install -c -m 444 dynamic_pager.8 $(DSTROOT)/usr/share/man/man8/dynamic_pager.8 + +LAUNCHD_PLIST_DIR = $(DSTROOT)/System/Library/LaunchDaemons +LAUNCHD_PLIST = com.apple.dynamic_pager.plist + +install-launchd-plist: + install -d $(LAUNCHD_PLIST_DIR) + install -c -m 644 $(LAUNCHD_PLIST) $(LAUNCHD_PLIST_DIR)/$(LAUNCHD_PLIST) +ifeq "$(Embedded)" "YES" + /usr/libexec/PlistBuddy -x \ + -c "Add :Disabled bool true" \ + "$(LAUNCHD_PLIST_DIR)/$(LAUNCHD_PLIST)" +endif diff --git a/dynamic_pager.tproj/Makefile.preamble b/dynamic_pager.tproj/Makefile.preamble index 2b74ce3..1acf0bc 100644 --- a/dynamic_pager.tproj/Makefile.preamble +++ b/dynamic_pager.tproj/Makefile.preamble @@ -125,6 +125,7 @@ OTHER_OFILES = default_pager_alerts_server.o backing_store_alerts.o backing_stor #OTHER_PUBLIC_HEADERS = default_pager_alerts_server.h #OTHER_GENERATED_OFILES = $(VERS_OFILE) -include ../Makefile.include -OTHER_CFLAGS = +OTHER_CFLAGS = -I$(NEXT_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders +OTHER_LDFLAGS = -framework CoreFoundation -framework IOKit BEFORE_BUILD = default_pager_alerts_server.o -AFTER_INSTALL += install-man-page +AFTER_INSTALL += install-man-page install-launchd-plist diff --git a/dynamic_pager.tproj/PB.project b/dynamic_pager.tproj/PB.project index 05aa432..35c4a82 100644 --- a/dynamic_pager.tproj/PB.project +++ b/dynamic_pager.tproj/PB.project @@ -10,7 +10,8 @@ default_pager_alerts.defs, backing_store_alerts.defs, backing_store_triggers.defs, - dynamic_pager.8 + dynamic_pager.8, + com.apple.dynamic_pager.plist ); }; LANGUAGE = English; diff --git a/dynamic_pager.tproj/backing_store_alerts.defs b/dynamic_pager.tproj/backing_store_alerts.defs index 661af83..4326949 100644 --- a/dynamic_pager.tproj/backing_store_alerts.defs +++ b/dynamic_pager.tproj/backing_store_alerts.defs @@ -10,6 +10,10 @@ subsystem backing_store_alerts 1000; +#ifndef __MigTypeCheck +#define __MigTypeCheck 1 +#endif + #include #include diff --git a/dynamic_pager.tproj/backing_store_triggers.defs b/dynamic_pager.tproj/backing_store_triggers.defs index a279266..bbb45a1 100644 --- a/dynamic_pager.tproj/backing_store_triggers.defs +++ b/dynamic_pager.tproj/backing_store_triggers.defs @@ -10,6 +10,10 @@ subsystem backing_store_triggers 1200; +#ifndef __MigTypeCheck +#define __MigTypeCheck 1 +#endif + #include #include diff --git a/dynamic_pager.tproj/com.apple.dynamic_pager.plist b/dynamic_pager.tproj/com.apple.dynamic_pager.plist new file mode 100644 index 0000000..5b2c7b8 --- /dev/null +++ b/dynamic_pager.tproj/com.apple.dynamic_pager.plist @@ -0,0 +1,16 @@ + + + + + Label + com.apple.dynamic_pager + ProgramArguments + + /sbin/dynamic_pager + -F + /private/var/vm/swapfile + + OnDemand + + + diff --git a/dynamic_pager.tproj/dynamic_pager.8 b/dynamic_pager.tproj/dynamic_pager.8 index ad6a27f..eaae275 100644 --- a/dynamic_pager.tproj/dynamic_pager.8 +++ b/dynamic_pager.tproj/dynamic_pager.8 @@ -5,7 +5,7 @@ .Os "Mac OS X" .Sh NAME .Nm dynamic_pager -.Nd dynamic pager external storage manager +.Nd external storage manager for dynamic pager .Sh SYNOPSIS .Nm dynamic_pager .Op Fl E @@ -17,42 +17,34 @@ .Sh DESCRIPTION The .Nm dynamic_pager -daemon manages a pool of external swap files which the kernel uses to -support demand paging. This pool is expanded with new swap files as load on -the system increases, and contracted when the swapping resources are no -longer needed. The +daemon manages a pool of external swap files +which the kernel uses to support demand paging. +This pool is expanded with new swap files +as load on the system increases. +It is contracted when the swapping resources are no longer needed. The .Nm dynamic_pager -daemon also provides a notification service for those applications which -wish to receive notices when the external paging pool expands or contracts. +daemon also provides a notification service +for those applications which wish to receive notices +when the external paging pool expands or contracts. .Sh OPTIONS .Bl -tag -width Ds +.\" ========== .It Fl E Encrypt the data in the swap files. +.\" ========== .It Fl F The base name of the .Ar filename to use for the external paging files. By default this is .Pa /private/var/vm/swapfile . -.It Fl S -The fixed -.Ar filesize -[in bytes] to use for the paging files. By default -.Nm dynamic_pager -uses variable sized paging files, using larger sized files as paging demands -increase. The -.Fl S , -.Fl H -and -.Fl L -options disable that default and cause -.Nm dynamic_pager -to use a series of fixed sized external paging files. +.\" ========== .It Fl H If there are less than .Ar high-water-trigger bytes free in the external paging files, the kernel will signal .Nm dynamic_pager to add a new external paging file. +.\" ========== .It Fl L If there are more than .Ar low-water-trigger @@ -65,8 +57,24 @@ must be greater than .Ar high-water-trigger + .Ar filesize . +.\" ========== .It Fl P This option is currently unimplemented. +.\" ========== +.It Fl S +The fixed +.Ar filesize +[in bytes] to use for the paging files. By default +.Nm dynamic_pager +uses variable sized paging files, using larger sized files as paging demands +increase. The +.Fl S , +.Fl H +and +.Fl L +options disable that default and cause +.Nm dynamic_pager +to use a series of fixed sized external paging files. .El .Sh FILES .Bl -tag -width /private/var/vp/swapfile* -compact diff --git a/dynamic_pager.tproj/dynamic_pager.c b/dynamic_pager.tproj/dynamic_pager.c index 08a7d1a..2e056c8 100644 --- a/dynamic_pager.tproj/dynamic_pager.c +++ b/dynamic_pager.tproj/dynamic_pager.c @@ -19,8 +19,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -29,6 +29,12 @@ #include #include #include +#include + +#include +#include +#include +#include #include #include @@ -443,8 +449,6 @@ paging_setup(flags, size, priority, low, high, encrypted) if(hi_water) { mach_msg_type_name_t poly; - daemon(0,0); - if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &trigger_port) != KERN_SUCCESS) { @@ -467,6 +471,123 @@ paging_setup(flags, size, priority, low, high, encrypted) } exit(EXIT_SUCCESS); } + +static void +clean_swap_directory(const char *path) +{ + DIR *dir; + struct dirent *entry; + char buf[1024]; + + dir = opendir(path); + if (dir == NULL) { + fprintf(stderr,"dynamic_pager: cannot open swap directory %s\n", path); + exit(EXIT_FAILURE); + } + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_namlen>= 4 && strncmp(entry->d_name, "swap", 4) == 0) { + snprintf(buf, sizeof buf, "%s/%s", path, entry->d_name); + unlink(buf); + } + } + + closedir(dir); +} + +#define VM_PREFS_PLIST "/Library/Preferences/com.apple.virtualMemory.plist" +#define VM_PREFS_ENCRYPT_SWAP_KEY "UseEncryptedSwap" + +static boolean_t +should_encrypt_swap(void) +{ + CFPropertyListRef propertyList; + CFTypeID propertyListType; + CFStringRef errorString; + CFDataRef resourceData; + SInt32 errorCode; + CFURLRef fileURL; + CFTypeRef value; + boolean_t should_encrypt; + boolean_t explicit_value; + CFTypeRef snap; + + explicit_value = false; + + fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)VM_PREFS_PLIST, strlen(VM_PREFS_PLIST), false); + if (fileURL == NULL) { + /*fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), VM_PREFS_PLIST);*/ + goto done; + } + + if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) { + /*fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), VM_PREFS_PLIST, (int)errorCode);*/ + CFRelease(fileURL); + goto done; + } + + CFRelease(fileURL); + propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString); + if (propertyList == NULL) { + /*fprintf(stderr, "%s: cannot get XML propertyList %s\n", getprogname(), VM_PREFS_PLIST);*/ + CFRelease(resourceData); + goto done; + } + + propertyListType = CFGetTypeID(propertyList); + + if (propertyListType == CFDictionaryGetTypeID()) { + value = (CFTypeRef) CFDictionaryGetValue((CFDictionaryRef) propertyList, CFSTR(VM_PREFS_ENCRYPT_SWAP_KEY)); + if (value == NULL) { + /* no value: use the default value */ + } else if (CFGetTypeID(value) != CFBooleanGetTypeID()) { + fprintf(stderr, "%s: wrong type for key \"%s\"\n", + getprogname(), VM_PREFS_ENCRYPT_SWAP_KEY); + /* bogus value, assume it's "true" for safety's sake */ + should_encrypt = true; + explicit_value = true; + } else { + should_encrypt = CFBooleanGetValue((CFBooleanRef)value); + explicit_value = true; + } + } + else { + /*fprintf(stderr, "%s: invalid propertyList type %d (not a dictionary)\n", getprogname(), propertyListType);*/ + } + CFRelease(resourceData); + CFRelease(propertyList); + +done: + if (! explicit_value) { + /* by default, encrypt swap on laptops only */ + mach_timespec_t w; + kern_return_t kr; + + /* wait up to 60 seconds for IOKit to quiesce */ + w.tv_sec = 60; + w.tv_nsec = 0; + kr = IOKitWaitQuiet(kIOMasterPortDefault, &w); + if (kr != kIOReturnSuccess) { + /* + * Can't tell if we're on a laptop, + * assume we do want encrypted swap. + */ + should_encrypt = TRUE; + /*fprintf(stderr, "dynamic_pager: IOKitWaitQuiet ret 0x%x (%s)\n", kr, mach_error_string(kr));*/ + } else { + /* + * Look for battery power source. + */ + snap = IOPSCopyPowerSourcesInfo(); + should_encrypt = (kCFBooleanTrue == IOPSPowerSourceSupported(snap, CFSTR(kIOPMBatteryPowerKey))); + CFRelease(snap); + /*fprintf(stderr, "dynamic_pager: battery power source: %d\n", should_encrypt);*/ + } + } + + return should_encrypt; +} + int main(int argc, char **argv) { @@ -475,7 +596,12 @@ main(int argc, char **argv) char default_filename[] = "/private/var/vm/swapfile"; int ch; int variable_sized = 1; - boolean_t encrypted_swap = FALSE; + boolean_t encrypted_swap; + +/* + setlinebuf(stdout); + setlinebuf(stderr); +*/ seteuid(getuid()); strcpy(fileroot, default_filename); @@ -486,8 +612,9 @@ main(int argc, char **argv) hi_water = 0; local_hi_water = 0; + encrypted_swap = should_encrypt_swap(); - while ((ch = getopt(argc, argv, "EF:L:H:S:P:O:")) != EOF) { + while ((ch = getopt(argc, argv, "EF:L:H:S:P:QO:")) != EOF) { switch((char)ch) { case 'E': @@ -514,6 +641,13 @@ main(int argc, char **argv) priority = atoi(optarg); break; + case 'Q': + /* just query for "encrypted swap" default value */ + fprintf(stdout, + "dynamic_pager: encrypted swap will be %s\n", + encrypted_swap ? "ON": "OFF"); + exit(0); + default: (void)fprintf(stderr, "usage: dynamic_pager [-F filename] [-L low water alert trigger] [-H high water alert trigger] [-S file size] [-P priority]\n"); @@ -530,7 +664,7 @@ main(int argc, char **argv) size_t len; unsigned int size; u_int64_t memsize; - u_int64_t fs_limit; + u_int64_t fs_limit = 0; /* * if we get here, then none of the following options were specified... -L, H, or -S @@ -562,8 +696,32 @@ main(int argc, char **argv) if (q = strrchr(tmp, '/')) *q = 0; - if (statfs(tmp, &sfs) != -1) { - /* + if (statfs(tmp, &sfs) == -1) { + /* + * Setup the swap directory. + */ + if (mkdir(tmp, 0755) == -1) { + (void)fprintf(stderr, "dynamic_pager: cannot create swap directory %s\n", tmp); + exit(EXIT_FAILURE); + } + chown(tmp, 0, 0); + + if (statfs(tmp, &sfs) == -1) { + /* + * We really can't get filesystem status, + * so let's not limit the swap files... + */ + fs_limit = (u_int64_t) -1; + } + } + + /* + * Remove all files in the swap directory. + */ + clean_swap_directory(tmp); + + if (fs_limit != (u_int64_t) -1) { + /* * Limit the maximum size of a swap file to 1/8 the free * space available on the filesystem where the swap files * are to reside. This will allow us to allocate and @@ -571,11 +729,8 @@ main(int argc, char **argv) * free space. */ fs_limit = ((u_int64_t)sfs.f_bfree * (u_int64_t)sfs.f_bsize) / 8; - - } else { - (void)fprintf(stderr, "dynamic_pager: swap directory must exist\n"); - exit(EXIT_FAILURE); } + mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; len = sizeof(u_int64_t); diff --git a/fs_usage.tproj/fs_usage.1 b/fs_usage.tproj/fs_usage.1 index 4479900..6c39c7c 100644 --- a/fs_usage.tproj/fs_usage.1 +++ b/fs_usage.tproj/fs_usage.1 @@ -28,25 +28,24 @@ The output presented by is formatted according to the size of your window. A narrow window will display fewer columns of data. Use a wide window for maximum data display. -You may override the window formatting restrictions by forcing a wide display -with the +You may override the window formatting restrictions +by forcing a wide display with the .Fl w option. -In this case, the data displayed will wrap when the window is not wide enough. +In this case, the data displayed will wrap +when the window is not wide enough. .Pp The options are as follows: .Bl -tag -width Ds +.\" ========== .It Fl e Specifying the .Fl e option generates output that excludes sampling of the running fs_usage tool. -If a list of process ids or commands is also given, then those processes are -also excluded from the sampled output. -.It Fl w -Specifying the -.Fl w -option forces a wider, more detailed output, regardless of the window size. +If a list of process ids or commands is also given, +then those processes are also excluded from the sampled output. +.\" ========== .It Fl f Specifying the .Fl f @@ -65,26 +64,34 @@ Only file system related output is displayed. .Pp .Pa cachehit In addition, display CACHE_HIT output. +.\" ========== +.It Fl w +Specifying the +.Fl w +option forces a wider, more detailed output, +regardless of the window size. +.\" ========== .It pid | cmd The sampled data can be limited to a list of process ids or commands. When a command name is given, all processes with that name will be sampled. Using the .Fl e -option has the opposite effect, excluding sampled data relating to the given -list of process ids or commands. +option has the opposite effect, +excluding sampled data relating to the given list +of process ids or commands. .El .Pp If you set the DYLD_IMAGE_SUFFIX environment variable to .Dq Li _debug , -then an application will use the debug version of all libraries including the -Carbon FileManager. +then an application will use the debug version of all libraries, +including the Carbon FileManager. See .Xr dyld 1 . When .Nm fs_usage -is run against a Carbon Application launched in this environment, then the -high level Carbon FileManager calls will be displayed bracketing the system -calls that they are built on. +is run against a Carbon Application launched in this environment, +then the high-level Carbon FileManager calls +will be displayed bracketing the system calls that they are built on. .Pp The data columns displayed are as follows: .Bl -tag -width Ds @@ -93,11 +100,12 @@ The data columns displayed are as follows: TOD when call occurred. Wide mode will have millisecond granularity. .It CALL -The name of the network or filesystem related call, page-in, page-out or physical disk access. +The name of the network or filesystem related call, page-in, page-out, +or physical disk access. .It FILE DESCRIPTOR Of the form F=x, x is a file descriptor. -Depending on the type of system call, this will be either an input value or a -return value. +Depending on the type of system call, +this will be either an input value or a return value. .It BYTE COUNT Of the form B=x, x is the number of bytes requested by the call. .It [ERRNO] @@ -105,22 +113,24 @@ On error, the errno is displayed in brackets. .It PATHNAME Pathname of the file accessed (up to the last 28 bytes). .It FAULT ADDRESS -Of the form A=0xnnnnnnnn, where 0xnnnnnnnn is the address being faulted. +Of the form A=0xnnnnnnnn, +where 0xnnnnnnnn is the address being faulted. .It DISK BLOCK NUMBER -Of the form D=0xnnnnnnnn, where 0xnnnnnnnn is the block number of the physical -disk block being read or written. +Of the form D=0xnnnnnnnn, +where 0xnnnnnnnn is the block number +of the physical disk block being read or written. .It OFFSET Of the form O=0xnnnnnnnn, where 0xnnnnnnnn is a file offset. .It SELECT RETURN -Of the form S=x, x is the number of ready descriptors returned by the select() -system call. +Of the form S=x, x is the number of ready descriptors returned +by the select() system call. If S=0, the time limit expired. .It TIME INTERVAL(W) The elapsed time spent in the system call. A .Sq Li W -after the elapsed time indicates the process was scheduled out during this file -activity. +after the elapsed time indicates the process was scheduled out +during this file activity. In this case, the elapsed time includes the wait time. .It PROCESS NAME The process that made the system call. @@ -131,10 +141,11 @@ The process that made the system call. fs_usage -w -f filesys Mail .Pp .Nm fs_usage -will display file system related data for all instances of processes named Mail. +will display file system related data +for all instances of processes named Mail. Maximum data output will be displayed in the window. .Sh SEE ALSO -.Xr top 1 , -.Xr sc_usage 1 , +.Xr dyld 1 , .Xr latency 1 , -.Xr dyld 1 +.Xr sc_usage 1 , +.Xr top 1 diff --git a/fs_usage.tproj/fs_usage.c b/fs_usage.tproj/fs_usage.c index 02406aa..137a90e 100644 --- a/fs_usage.tproj/fs_usage.c +++ b/fs_usage.tproj/fs_usage.c @@ -34,6 +34,7 @@ cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c #include #include #include +#include #include #include @@ -44,6 +45,8 @@ cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c #include #include #include +#include +#include #ifndef KERNEL_PRIVATE #define KERNEL_PRIVATE @@ -65,17 +68,25 @@ extern int errno; #define MAXINDEX 2048 +typedef struct LibraryRange { + uint64_t b_address; + uint64_t e_address; +} LibraryRange; + +LibraryRange framework32; +LibraryRange framework64; + + typedef struct LibraryInfo { - unsigned long address; + uint64_t b_address; + uint64_t e_address; char *name; } LibraryInfo; LibraryInfo frameworkInfo[MAXINDEX]; int numFrameworks = 0; -char seg_addr_table[256]="/AppleInternal/Developer/seg_addr_table"; - -char *lookup_name(); +char *lookup_name(uint64_t user_addr); /* @@ -86,12 +97,12 @@ char *lookup_name(); */ #define NUMPARMS 23 #define PATHLENGTH (NUMPARMS*sizeof(long)) -#define MAXCOLS 131 +#define MAXCOLS 132 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80) #define MAXWIDTH MAX_WIDE_MODE_COLS + 64 - struct th_info { + int my_index; int in_filemgr; int thread; int pid; @@ -100,6 +111,10 @@ struct th_info { int arg2; int arg3; int arg4; + int arg5; + int arg6; + int arg7; + int arg8; int child_thread; int waited; double stime; @@ -110,10 +125,17 @@ struct th_info { #define MAX_THREADS 512 struct th_info th_state[MAX_THREADS]; +kd_threadmap *last_map = NULL; +int last_thread = 0; +int map_is_the_same = 0; +int filemgr_in_progress = 0; +int execs_in_progress = 0; +int cur_start = 0; int cur_max = 0; int need_new_map = 1; -int bias_secs; +int bias_secs = 0; +long last_time; int wideflag = 0; int columns = 0; int select_pid_mode = 0; /* Flag set indicates that output is restricted @@ -124,6 +146,12 @@ int one_good_pid = 0; /* Used to fail gracefully when bad pids given */ char *arguments = 0; int argmax = 0; + +#define USLEEP_MIN 1 +#define USLEEP_BEHIND 2 +#define USLEEP_MAX 32 +int usleep_ms = USLEEP_MIN; + /* * Network only or filesystem only output filter * Default of zero means report all activity - no filtering @@ -132,6 +160,7 @@ int argmax = 0; #define NETWORK_FILTER 0x02 #define CACHEHIT_FILTER 0x04 #define EXEC_FILTER 0x08 +#define PATHNAME_FILTER 0x10 #define DEFAULT_DO_NOT_FILTER 0x00 int filter_mode = CACHEHIT_FILTER; @@ -164,14 +193,18 @@ struct diskrec *disk_list = NULL; struct diskio *free_diskios = NULL; struct diskio *busy_diskios = NULL; + + struct diskio *insert_diskio(); struct diskio *complete_diskio(); void free_diskio(); void print_diskio(); -void format_print(); +void format_print(struct th_info *, char *, int, int, int, int, int, int, int, double, double, int, char *, struct diskio *); +void exit_syscall(char *, int, int, int, int, int, int, int, double); char *find_disk_name(); void cache_disk_names(); -int ReadSegAddrTable(); +int ReadSharedCacheMap(const char *, LibraryRange *); +void SortFrameworkAddresses(); void mark_thread_waited(int); int check_filter_mode(struct th_info *, int, int, int, char *); void fs_usage_fd_set(unsigned int, unsigned int); @@ -182,22 +215,30 @@ int get_real_command_name(int, char *, int); void create_map_entry(int, int, char *); void enter_syscall(); -void exit_syscall(); void extend_syscall(); void kill_thread_map(); +#define CLASS_MASK 0xff000000 +#define CSC_MASK 0xffff0000 +#define BSC_INDEX(type) ((type >> 2) & 0x3fff) + + #define TRACE_DATA_NEWTHREAD 0x07000004 #define TRACE_DATA_EXEC 0x07000008 #define TRACE_STRING_NEWTHREAD 0x07010004 #define TRACE_STRING_EXEC 0x07010008 -#define MACH_vmfault 0x01300000 +#define MACH_vmfault 0x01300008 #define MACH_pageout 0x01300004 #define MACH_sched 0x01400000 #define MACH_stkhandoff 0x01400008 #define VFS_LOOKUP 0x03010090 #define BSC_exit 0x040C0004 +#define P_DISKIO 0x03020000 +#define P_DISKIO_DONE 0x03020004 +#define P_DISKIO_MASK (CSC_MASK | 0x4) + #define P_WrData 0x03020000 #define P_RdData 0x03020008 #define P_WrMeta 0x03020020 @@ -211,12 +252,12 @@ void kill_thread_map(); #define P_PgOutAsync 0x03020050 #define P_PgInAsync 0x03020058 -#define P_WrDataDone 0x03020004 -#define P_RdDataDone 0x0302000C -#define P_WrMetaDone 0x03020024 -#define P_RdMetaDone 0x0302002C -#define P_PgOutDone 0x03020044 -#define P_PgInDone 0x0302004C +#define P_WrDataDone 0x03020004 +#define P_RdDataDone 0x0302000C +#define P_WrMetaDone 0x03020024 +#define P_RdMetaDone 0x0302002C +#define P_PgOutDone 0x03020044 +#define P_PgInDone 0x0302004C #define P_WrDataAsyncDone 0x03020014 #define P_RdDataAsyncDone 0x0302001C #define P_WrMetaAsyncDone 0x03020034 @@ -227,185 +268,478 @@ void kill_thread_map(); #define MSC_map_fd 0x010c00ac +#define BSC_BASE 0x040C0000 +#define MSC_BASE 0x010C0000 + // Network related codes -#define BSC_recvmsg 0x040C006C -#define BSC_sendmsg 0x040C0070 -#define BSC_recvfrom 0x040C0074 -#define BSC_accept 0x040C0078 -#define BSC_select 0x040C0174 -#define BSC_socket 0x040C0184 -#define BSC_connect 0x040C0188 -#define BSC_bind 0x040C01A0 -#define BSC_listen 0x040C01A8 -#define BSC_sendto 0x040C0214 -#define BSC_socketpair 0x040C021C - -#define BSC_read 0x040C000C -#define BSC_write 0x040C0010 -#define BSC_open 0x040C0014 -#define BSC_close 0x040C0018 -#define BSC_link 0x040C0024 -#define BSC_unlink 0x040C0028 -#define BSC_chdir 0x040c0030 -#define BSC_fchdir 0x040c0034 -#define BSC_mknod 0x040C0038 -#define BSC_chmod 0x040C003C -#define BSC_chown 0x040C0040 -#define BSC_access 0x040C0084 -#define BSC_chflags 0x040C0088 -#define BSC_fchflags 0x040C008C -#define BSC_sync 0x040C0090 -#define BSC_dup 0x040C00A4 -#define BSC_revoke 0x040C00E0 -#define BSC_symlink 0x040C00E4 -#define BSC_readlink 0x040C00E8 -#define BSC_execve 0x040C00EC -#define BSC_chroot 0x040C00F4 -#define BSC_dup2 0x040C0168 -#define BSC_fsync 0x040C017C -#define BSC_readv 0x040C01E0 -#define BSC_writev 0x040C01E4 -#define BSC_fchown 0x040C01EC -#define BSC_fchmod 0x040C01F0 -#define BSC_rename 0x040C0200 -#define BSC_mkfifo 0x040c0210 -#define BSC_mkdir 0x040C0220 -#define BSC_rmdir 0x040C0224 -#define BSC_utimes 0x040C0228 -#define BSC_futimes 0x040C022C -#define BSC_pread 0x040C0264 -#define BSC_pread_extended 0x040E0264 -#define BSC_pwrite 0x040C0268 -#define BSC_pwrite_extended 0x040E0268 -#define BSC_statfs 0x040C0274 -#define BSC_fstatfs 0x040C0278 -#define BSC_stat 0x040C02F0 -#define BSC_fstat 0x040C02F4 -#define BSC_lstat 0x040C02F8 -#define BSC_pathconf 0x040C02FC -#define BSC_fpathconf 0x040C0300 -#define BSC_getdirentries 0x040C0310 -#define BSC_mmap 0x040c0314 -#define BSC_lseek 0x040c031c -#define BSC_truncate 0x040C0320 -#define BSC_ftruncate 0x040C0324 -#define BSC_undelete 0x040C0334 -#define BSC_statv 0x040C0364 -#define BSC_lstatv 0x040C0368 -#define BSC_fstatv 0x040C036C -#define BSC_mkcomplex 0x040C0360 -#define BSC_getattrlist 0x040C0370 -#define BSC_setattrlist 0x040C0374 -#define BSC_getdirentriesattr 0x040C0378 -#define BSC_exchangedata 0x040C037C -#define BSC_checkuseraccess 0x040C0380 -#define BSC_searchfs 0x040C0384 -#define BSC_delete 0x040C0388 -#define BSC_copyfile 0x040C038C -#define BSC_getxattr 0x040C03A8 -#define BSC_fgetxattr 0x040C03AC -#define BSC_setxattr 0x040C03B0 -#define BSC_fsetxattr 0x040C03B4 -#define BSC_removexattr 0x040C03B8 -#define BSC_fremovexattr 0x040C03BC -#define BSC_listxattr 0x040C03C0 -#define BSC_flistxattr 0x040C03C4 -#define BSC_fsctl 0x040C03C8 -#define BSC_open_extended 0x040C0454 -#define BSC_stat_extended 0x040C045C -#define BSC_lstat_extended 0x040C0460 -#define BSC_fstat_extended 0x040C0464 -#define BSC_chmod_extended 0x040C0468 -#define BSC_fchmod_extended 0x040C046C -#define BSC_access_extended 0x040C0470 -#define BSC_mkfifo_extended 0x040C048C -#define BSC_mkdir_extended 0x040C0490 -#define BSC_load_shared_file 0x040C04A0 -#define BSC_lchown 0x040C05B0 +#define BSC_recvmsg 0x040C006C +#define BSC_sendmsg 0x040C0070 +#define BSC_recvfrom 0x040C0074 +#define BSC_accept 0x040C0078 +#define BSC_select 0x040C0174 +#define BSC_socket 0x040C0184 +#define BSC_connect 0x040C0188 +#define BSC_bind 0x040C01A0 +#define BSC_listen 0x040C01A8 +#define BSC_sendto 0x040C0214 +#define BSC_socketpair 0x040C021C + +#define BSC_read 0x040C000C +#define BSC_write 0x040C0010 +#define BSC_open 0x040C0014 +#define BSC_close 0x040C0018 +#define BSC_link 0x040C0024 +#define BSC_unlink 0x040C0028 +#define BSC_chdir 0x040c0030 +#define BSC_fchdir 0x040c0034 +#define BSC_mknod 0x040C0038 +#define BSC_chmod 0x040C003C +#define BSC_chown 0x040C0040 +#define BSC_access 0x040C0084 +#define BSC_chflags 0x040C0088 +#define BSC_fchflags 0x040C008C +#define BSC_sync 0x040C0090 +#define BSC_dup 0x040C00A4 +#define BSC_ioctl 0x040C00D8 +#define BSC_revoke 0x040C00E0 +#define BSC_symlink 0x040C00E4 +#define BSC_readlink 0x040C00E8 +#define BSC_execve 0x040C00EC +#define BSC_chroot 0x040C00F4 +#define BSC_msync 0x040C0104 +#define BSC_dup2 0x040C0168 +#define BSC_fcntl 0x040C0170 +#define BSC_fsync 0x040C017C +#define BSC_readv 0x040C01E0 +#define BSC_writev 0x040C01E4 +#define BSC_fchown 0x040C01EC +#define BSC_fchmod 0x040C01F0 +#define BSC_rename 0x040C0200 +#define BSC_mkfifo 0x040c0210 +#define BSC_mkdir 0x040C0220 +#define BSC_rmdir 0x040C0224 +#define BSC_utimes 0x040C0228 +#define BSC_futimes 0x040C022C +#define BSC_pread 0x040C0264 +#define BSC_pwrite 0x040C0268 +#define BSC_statfs 0x040C0274 +#define BSC_fstatfs 0x040C0278 +#define BSC_stat 0x040C02F0 +#define BSC_fstat 0x040C02F4 +#define BSC_lstat 0x040C02F8 +#define BSC_pathconf 0x040C02FC +#define BSC_fpathconf 0x040C0300 +#define BSC_getdirentries 0x040C0310 +#define BSC_mmap 0x040c0314 +#define BSC_lseek 0x040c031c +#define BSC_truncate 0x040C0320 +#define BSC_ftruncate 0x040C0324 +#define BSC_undelete 0x040C0334 +#define BSC_statv 0x040C0364 +#define BSC_lstatv 0x040C0368 +#define BSC_fstatv 0x040C036C +#define BSC_mkcomplex 0x040C0360 +#define BSC_getattrlist 0x040C0370 +#define BSC_setattrlist 0x040C0374 +#define BSC_getdirentriesattr 0x040C0378 +#define BSC_exchangedata 0x040C037C +#define BSC_checkuseraccess 0x040C0380 +#define BSC_searchfs 0x040C0384 +#define BSC_delete 0x040C0388 +#define BSC_copyfile 0x040C038C +#define BSC_getxattr 0x040C03A8 +#define BSC_fgetxattr 0x040C03AC +#define BSC_setxattr 0x040C03B0 +#define BSC_fsetxattr 0x040C03B4 +#define BSC_removexattr 0x040C03B8 +#define BSC_fremovexattr 0x040C03BC +#define BSC_listxattr 0x040C03C0 +#define BSC_flistxattr 0x040C03C4 +#define BSC_fsctl 0x040C03C8 +#define BSC_open_extended 0x040C0454 +#define BSC_stat_extended 0x040C045C +#define BSC_lstat_extended 0x040C0460 +#define BSC_fstat_extended 0x040C0464 +#define BSC_chmod_extended 0x040C0468 +#define BSC_fchmod_extended 0x040C046C +#define BSC_access_extended 0x040C0470 +#define BSC_mkfifo_extended 0x040C048C +#define BSC_mkdir_extended 0x040C0490 +#define BSC_load_shared_file 0x040C04A0 +#define BSC_aio_fsync 0x040C04E4 +#define BSC_aio_return 0x040C04E8 +#define BSC_aio_suspend 0x040C04EC +#define BSC_aio_cancel 0x040C04F0 +#define BSC_aio_error 0x040C04F4 +#define BSC_aio_read 0x040C04F8 +#define BSC_aio_write 0x040C04FC +#define BSC_lio_listio 0x040C0500 +#define BSC_lchown 0x040C05B0 + +#define BSC_read_nocancel 0x040c0630 +#define BSC_write_nocancel 0x040c0634 +#define BSC_open_nocancel 0x040c0638 +#define BSC_close_nocancel 0x040c063c +#define BSC_recvmsg_nocancel 0x040c0644 +#define BSC_sendmsg_nocancel 0x040c0648 +#define BSC_recvfrom_nocancel 0x040c064c +#define BSC_accept_nocancel 0x040c0650 +#define BSC_msync_nocancel 0x040c0654 +#define BSC_fcntl_nocancel 0x040c0658 +#define BSC_select_nocancel 0x040c065c +#define BSC_fsync_nocancel 0x040c0660 +#define BSC_connect_nocancel 0x040c0664 +#define BSC_readv_nocancel 0x040c066c +#define BSC_writev_nocancel 0x040c0670 +#define BSC_sendto_nocancel 0x040c0674 +#define BSC_pread_nocancel 0x040c0678 +#define BSC_pwrite_nocancel 0x040c067c +#define BSC_aio_suspend_nocancel 0x40c0694 + +#define BSC_msync_extended 0x040e0104 +#define BSC_pread_extended 0x040e0264 +#define BSC_pwrite_extended 0x040e0268 +#define BSC_mmap_extended 0x040e0314 +#define BSC_mmap_extended2 0x040f0314 // Carbon File Manager support -#define FILEMGR_PBGETCATALOGINFO 0x1e000020 -#define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024 -#define FILEMGR_PBCREATEFILEUNICODE 0x1e000028 -#define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c -#define FILEMGR_PBCREATEFORK 0x1e000030 -#define FILEMGR_PBDELETEFORK 0x1e000034 -#define FILEMGR_PBITERATEFORK 0x1e000038 -#define FILEMGR_PBOPENFORK 0x1e00003c -#define FILEMGR_PBREADFORK 0x1e000040 -#define FILEMGR_PBWRITEFORK 0x1e000044 -#define FILEMGR_PBALLOCATEFORK 0x1e000048 -#define FILEMGR_PBDELETEOBJECT 0x1e00004c -#define FILEMGR_PBEXCHANGEOBJECT 0x1e000050 -#define FILEMGR_PBGETFORKCBINFO 0x1e000054 -#define FILEMGR_PBGETVOLUMEINFO 0x1e000058 -#define FILEMGR_PBMAKEFSREF 0x1e00005c -#define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060 -#define FILEMGR_PBMOVEOBJECT 0x1e000064 -#define FILEMGR_PBOPENITERATOR 0x1e000068 -#define FILEMGR_PBRENAMEUNICODE 0x1e00006c -#define FILEMGR_PBSETCATALOGINFO 0x1e000070 -#define FILEMGR_PBSETVOLUMEINFO 0x1e000074 -#define FILEMGR_FSREFMAKEPATH 0x1e000078 -#define FILEMGR_FSPATHMAKEREF 0x1e00007c - -#define FILEMGR_PBGETCATINFO 0x1e010000 -#define FILEMGR_PBGETCATINFOLITE 0x1e010004 -#define FILEMGR_PBHGETFINFO 0x1e010008 -#define FILEMGR_PBXGETVOLINFO 0x1e01000c -#define FILEMGR_PBHCREATE 0x1e010010 -#define FILEMGR_PBHOPENDF 0x1e010014 -#define FILEMGR_PBHOPENRF 0x1e010018 -#define FILEMGR_PBHGETDIRACCESS 0x1e01001c -#define FILEMGR_PBHSETDIRACCESS 0x1e010020 -#define FILEMGR_PBHMAPID 0x1e010024 -#define FILEMGR_PBHMAPNAME 0x1e010028 -#define FILEMGR_PBCLOSE 0x1e01002c -#define FILEMGR_PBFLUSHFILE 0x1e010030 -#define FILEMGR_PBGETEOF 0x1e010034 -#define FILEMGR_PBSETEOF 0x1e010038 -#define FILEMGR_PBGETFPOS 0x1e01003c -#define FILEMGR_PBREAD 0x1e010040 -#define FILEMGR_PBWRITE 0x1e010044 -#define FILEMGR_PBGETFCBINFO 0x1e010048 -#define FILEMGR_PBSETFINFO 0x1e01004c -#define FILEMGR_PBALLOCATE 0x1e010050 -#define FILEMGR_PBALLOCCONTIG 0x1e010054 -#define FILEMGR_PBSETFPOS 0x1e010058 -#define FILEMGR_PBSETCATINFO 0x1e01005c -#define FILEMGR_PBGETVOLPARMS 0x1e010060 -#define FILEMGR_PBSETVINFO 0x1e010064 -#define FILEMGR_PBMAKEFSSPEC 0x1e010068 -#define FILEMGR_PBHGETVINFO 0x1e01006c -#define FILEMGR_PBCREATEFILEIDREF 0x1e010070 -#define FILEMGR_PBDELETEFILEIDREF 0x1e010074 -#define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078 -#define FILEMGR_PBFLUSHVOL 0x1e01007c -#define FILEMGR_PBHRENAME 0x1e010080 -#define FILEMGR_PBCATMOVE 0x1e010084 -#define FILEMGR_PBEXCHANGEFILES 0x1e010088 -#define FILEMGR_PBHDELETE 0x1e01008c -#define FILEMGR_PBDIRCREATE 0x1e010090 -#define FILEMGR_PBCATSEARCH 0x1e010094 -#define FILEMGR_PBHSETFLOCK 0x1e010098 -#define FILEMGR_PBHRSTFLOCK 0x1e01009c -#define FILEMGR_PBLOCKRANGE 0x1e0100a0 -#define FILEMGR_PBUNLOCKRANGE 0x1e0100a4 +#define FILEMGR_PBGETCATALOGINFO 0x1e000020 +#define FILEMGR_PBGETCATALOGINFOBULK 0x1e000024 +#define FILEMGR_PBCREATEFILEUNICODE 0x1e000028 +#define FILEMGR_PBCREATEDIRECTORYUNICODE 0x1e00002c +#define FILEMGR_PBCREATEFORK 0x1e000030 +#define FILEMGR_PBDELETEFORK 0x1e000034 +#define FILEMGR_PBITERATEFORK 0x1e000038 +#define FILEMGR_PBOPENFORK 0x1e00003c +#define FILEMGR_PBREADFORK 0x1e000040 +#define FILEMGR_PBWRITEFORK 0x1e000044 +#define FILEMGR_PBALLOCATEFORK 0x1e000048 +#define FILEMGR_PBDELETEOBJECT 0x1e00004c +#define FILEMGR_PBEXCHANGEOBJECT 0x1e000050 +#define FILEMGR_PBGETFORKCBINFO 0x1e000054 +#define FILEMGR_PBGETVOLUMEINFO 0x1e000058 +#define FILEMGR_PBMAKEFSREF 0x1e00005c +#define FILEMGR_PBMAKEFSREFUNICODE 0x1e000060 +#define FILEMGR_PBMOVEOBJECT 0x1e000064 +#define FILEMGR_PBOPENITERATOR 0x1e000068 +#define FILEMGR_PBRENAMEUNICODE 0x1e00006c +#define FILEMGR_PBSETCATALOGINFO 0x1e000070 +#define FILEMGR_PBSETVOLUMEINFO 0x1e000074 +#define FILEMGR_FSREFMAKEPATH 0x1e000078 +#define FILEMGR_FSPATHMAKEREF 0x1e00007c + +#define FILEMGR_PBGETCATINFO 0x1e010000 +#define FILEMGR_PBGETCATINFOLITE 0x1e010004 +#define FILEMGR_PBHGETFINFO 0x1e010008 +#define FILEMGR_PBXGETVOLINFO 0x1e01000c +#define FILEMGR_PBHCREATE 0x1e010010 +#define FILEMGR_PBHOPENDF 0x1e010014 +#define FILEMGR_PBHOPENRF 0x1e010018 +#define FILEMGR_PBHGETDIRACCESS 0x1e01001c +#define FILEMGR_PBHSETDIRACCESS 0x1e010020 +#define FILEMGR_PBHMAPID 0x1e010024 +#define FILEMGR_PBHMAPNAME 0x1e010028 +#define FILEMGR_PBCLOSE 0x1e01002c +#define FILEMGR_PBFLUSHFILE 0x1e010030 +#define FILEMGR_PBGETEOF 0x1e010034 +#define FILEMGR_PBSETEOF 0x1e010038 +#define FILEMGR_PBGETFPOS 0x1e01003c +#define FILEMGR_PBREAD 0x1e010040 +#define FILEMGR_PBWRITE 0x1e010044 +#define FILEMGR_PBGETFCBINFO 0x1e010048 +#define FILEMGR_PBSETFINFO 0x1e01004c +#define FILEMGR_PBALLOCATE 0x1e010050 +#define FILEMGR_PBALLOCCONTIG 0x1e010054 +#define FILEMGR_PBSETFPOS 0x1e010058 +#define FILEMGR_PBSETCATINFO 0x1e01005c +#define FILEMGR_PBGETVOLPARMS 0x1e010060 +#define FILEMGR_PBSETVINFO 0x1e010064 +#define FILEMGR_PBMAKEFSSPEC 0x1e010068 +#define FILEMGR_PBHGETVINFO 0x1e01006c +#define FILEMGR_PBCREATEFILEIDREF 0x1e010070 +#define FILEMGR_PBDELETEFILEIDREF 0x1e010074 +#define FILEMGR_PBRESOLVEFILEIDREF 0x1e010078 +#define FILEMGR_PBFLUSHVOL 0x1e01007c +#define FILEMGR_PBHRENAME 0x1e010080 +#define FILEMGR_PBCATMOVE 0x1e010084 +#define FILEMGR_PBEXCHANGEFILES 0x1e010088 +#define FILEMGR_PBHDELETE 0x1e01008c +#define FILEMGR_PBDIRCREATE 0x1e010090 +#define FILEMGR_PBCATSEARCH 0x1e010094 +#define FILEMGR_PBHSETFLOCK 0x1e010098 +#define FILEMGR_PBHRSTFLOCK 0x1e01009c +#define FILEMGR_PBLOCKRANGE 0x1e0100a0 +#define FILEMGR_PBUNLOCKRANGE 0x1e0100a4 #define FILEMGR_CLASS 0x1e +#define FILEMGR_BASE 0x1e000000 + +#define FMT_DEFAULT 0 +#define FMT_FD 1 +#define FMT_FD_IO 2 +#define FMT_FD_2 3 +#define FMT_SOCKET 4 +#define FMT_PGIN 5 +#define FMT_PGOUT 6 +#define FMT_CACHEHIT 7 +#define FMT_DISKIO 8 +#define FMT_LSEEK 9 +#define FMT_PREAD 10 +#define FMT_FTRUNC 11 +#define FMT_TRUNC 12 +#define FMT_SELECT 13 +#define FMT_OPEN 14 +#define FMT_AIO_FSYNC 15 +#define FMT_AIO_RETURN 16 +#define FMT_AIO_SUSPEND 17 +#define FMT_AIO_CANCEL 18 +#define FMT_AIO 19 +#define FMT_LIO_LISTIO 20 +#define FMT_MSYNC 21 +#define FMT_FCNTL 22 +#define FMT_ACCESS 23 +#define FMT_CHMOD 24 +#define FMT_FCHMOD 25 +#define FMT_CHMOD_EXT 26 +#define FMT_FCHMOD_EXT 27 +#define FMT_CHFLAGS 28 +#define FMT_FCHFLAGS 29 +#define FMT_IOCTL 30 +#define FMT_MMAP 31 + +#define MAX_BSD_SYSCALL 512 + +struct bsd_syscall { + char *sc_name; + int sc_format; +} bsd_syscalls[MAX_BSD_SYSCALL]; + + +int bsd_syscall_types[] = { + BSC_recvmsg, + BSC_recvmsg_nocancel, + BSC_sendmsg, + BSC_sendmsg_nocancel, + BSC_recvfrom, + BSC_recvfrom_nocancel, + BSC_accept, + BSC_accept_nocancel, + BSC_select, + BSC_select_nocancel, + BSC_socket, + BSC_connect, + BSC_connect_nocancel, + BSC_bind, + BSC_listen, + BSC_sendto, + BSC_sendto_nocancel, + BSC_socketpair, + BSC_read, + BSC_read_nocancel, + BSC_write, + BSC_write_nocancel, + BSC_open, + BSC_open_nocancel, + BSC_close, + BSC_close_nocancel, + BSC_link, + BSC_unlink, + BSC_chdir, + BSC_fchdir, + BSC_mknod, + BSC_chmod, + BSC_chown, + BSC_access, + BSC_chflags, + BSC_fchflags, + BSC_sync, + BSC_dup, + BSC_revoke, + BSC_symlink, + BSC_readlink, + BSC_execve, + BSC_chroot, + BSC_dup2, + BSC_fsync, + BSC_fsync_nocancel, + BSC_readv, + BSC_readv_nocancel, + BSC_writev, + BSC_writev_nocancel, + BSC_fchown, + BSC_fchmod, + BSC_rename, + BSC_mkfifo, + BSC_mkdir, + BSC_rmdir, + BSC_utimes, + BSC_futimes, + BSC_pread, + BSC_pread_nocancel, + BSC_pwrite, + BSC_pwrite_nocancel, + BSC_statfs, + BSC_fstatfs, + BSC_stat, + BSC_fstat, + BSC_lstat, + BSC_pathconf, + BSC_fpathconf, + BSC_getdirentries, + BSC_mmap, + BSC_lseek, + BSC_truncate, + BSC_ftruncate, + BSC_undelete, + BSC_statv, + BSC_lstatv, + BSC_fstatv, + BSC_mkcomplex, + BSC_getattrlist, + BSC_setattrlist, + BSC_getdirentriesattr, + BSC_exchangedata, + BSC_checkuseraccess, + BSC_searchfs, + BSC_delete, + BSC_copyfile, + BSC_getxattr, + BSC_fgetxattr, + BSC_setxattr, + BSC_fsetxattr, + BSC_removexattr, + BSC_fremovexattr, + BSC_listxattr, + BSC_flistxattr, + BSC_fsctl, + BSC_open_extended, + BSC_stat_extended, + BSC_lstat_extended, + BSC_fstat_extended, + BSC_chmod_extended, + BSC_fchmod_extended, + BSC_access_extended, + BSC_mkfifo_extended, + BSC_mkdir_extended, + BSC_load_shared_file, + BSC_aio_fsync, + BSC_aio_return, + BSC_aio_suspend, + BSC_aio_suspend_nocancel, + BSC_aio_cancel, + BSC_aio_error, + BSC_aio_read, + BSC_aio_write, + BSC_lio_listio, + BSC_lchown, + BSC_msync, + BSC_msync_nocancel, + BSC_fcntl, + BSC_fcntl_nocancel, + BSC_ioctl, + 0 +}; + + +#define MAX_FILEMGR 512 + +struct filemgr_call { + char *fm_name; +} filemgr_calls[MAX_FILEMGR]; + + +int filemgr_call_types[] = { + FILEMGR_PBGETCATALOGINFO, + FILEMGR_PBGETCATALOGINFOBULK, + FILEMGR_PBCREATEFILEUNICODE, + FILEMGR_PBCREATEDIRECTORYUNICODE, + FILEMGR_PBCREATEFORK, + FILEMGR_PBDELETEFORK, + FILEMGR_PBITERATEFORK, + FILEMGR_PBOPENFORK, + FILEMGR_PBREADFORK, + FILEMGR_PBWRITEFORK, + FILEMGR_PBALLOCATEFORK, + FILEMGR_PBDELETEOBJECT, + FILEMGR_PBEXCHANGEOBJECT, + FILEMGR_PBGETFORKCBINFO, + FILEMGR_PBGETVOLUMEINFO, + FILEMGR_PBMAKEFSREF, + FILEMGR_PBMAKEFSREFUNICODE, + FILEMGR_PBMOVEOBJECT, + FILEMGR_PBOPENITERATOR, + FILEMGR_PBRENAMEUNICODE, + FILEMGR_PBSETCATALOGINFO, + FILEMGR_PBSETVOLUMEINFO, + FILEMGR_FSREFMAKEPATH, + FILEMGR_FSPATHMAKEREF, + + FILEMGR_PBGETCATINFO, + FILEMGR_PBGETCATINFOLITE, + FILEMGR_PBHGETFINFO, + FILEMGR_PBXGETVOLINFO, + FILEMGR_PBHCREATE, + FILEMGR_PBHOPENDF, + FILEMGR_PBHOPENRF, + FILEMGR_PBHGETDIRACCESS, + FILEMGR_PBHSETDIRACCESS, + FILEMGR_PBHMAPID, + FILEMGR_PBHMAPNAME, + FILEMGR_PBCLOSE, + FILEMGR_PBFLUSHFILE, + FILEMGR_PBGETEOF, + FILEMGR_PBSETEOF, + FILEMGR_PBGETFPOS, + FILEMGR_PBREAD, + FILEMGR_PBWRITE, + FILEMGR_PBGETFCBINFO, + FILEMGR_PBSETFINFO, + FILEMGR_PBALLOCATE, + FILEMGR_PBALLOCCONTIG, + FILEMGR_PBSETFPOS, + FILEMGR_PBSETCATINFO, + FILEMGR_PBGETVOLPARMS, + FILEMGR_PBSETVINFO, + FILEMGR_PBMAKEFSSPEC, + FILEMGR_PBHGETVINFO, + FILEMGR_PBCREATEFILEIDREF, + FILEMGR_PBDELETEFILEIDREF, + FILEMGR_PBRESOLVEFILEIDREF, + FILEMGR_PBFLUSHVOL, + FILEMGR_PBHRENAME, + FILEMGR_PBCATMOVE, + FILEMGR_PBEXCHANGEFILES, + FILEMGR_PBHDELETE, + FILEMGR_PBDIRCREATE, + FILEMGR_PBCATSEARCH, + FILEMGR_PBHSETFLOCK, + FILEMGR_PBHRSTFLOCK, + FILEMGR_PBLOCKRANGE, + FILEMGR_PBUNLOCKRANGE, + 0 +}; + -#define MAX_PIDS 32 + +#define MAX_PIDS 256 int pids[MAX_PIDS]; int num_of_pids = 0; int exclude_pids = 0; int exclude_default_pids = 1; + struct kinfo_proc *kp_buffer = 0; int kp_nentries = 0; -#define SAMPLE_SIZE 60000 +#define SAMPLE_SIZE 100000 + +int num_cpus; + +#define EVENT_BASE 60000 + +int num_events = EVENT_BASE; #define DBG_ZERO_FILL_FAULT 1 #define DBG_PAGEIN_FAULT 2 @@ -463,6 +797,8 @@ void leave() /* exit under normal conditions -- INT handler */ void set_pidexclude(); void set_remove(); + fflush(0); + set_enable(0); if (exclude_pids == 0) { @@ -489,7 +825,7 @@ void get_screenwidth() columns = size.ws_col; if (columns > MAXWIDTH) - columns = MAXWIDTH; + columns = MAXWIDTH; } } } @@ -511,6 +847,7 @@ exit_usage(char *myname) { fprintf(stderr, " -f Output is based on the mode provided\n"); fprintf(stderr, " mode = \"network\" Show only network related output\n"); fprintf(stderr, " mode = \"filesys\" Show only file system related output\n"); + fprintf(stderr, " mode = \"pathname\" Show only pathname related output\n"); fprintf(stderr, " mode = \"exec\" Show only execs\n"); fprintf(stderr, " mode = \"cachehit\" In addition, show cachehits\n"); fprintf(stderr, " pid selects process(s) to sample\n"); @@ -522,6 +859,815 @@ exit_usage(char *myname) { exit(1); } + +int filemgr_index(type) { + + if (type & 0x10000) + return (((type >> 2) & 0x3fff) + 256); + + return (((type >> 2) & 0x3fff)); +} + + +void init_tables(void) +{ int i; + int type; + int code; + + for (i = 0; i < MAX_THREADS; i++) + th_state[i].my_index = i; + + for (i = 0; i < MAX_BSD_SYSCALL; i++) { + bsd_syscalls[i].sc_name = NULL; + bsd_syscalls[i].sc_format = FMT_DEFAULT; + } + + for (i = 0; i < MAX_FILEMGR; i++) { + filemgr_calls[i].fm_name = NULL; + } + + for (i = 0; (type = bsd_syscall_types[i]); i++) { + + code = BSC_INDEX(type); + + if (code >= MAX_BSD_SYSCALL) { + printf("BSD syscall init (%x): type exceeds table size\n", type); + continue; + } + switch (type) { + + case BSC_recvmsg: + case BSC_recvmsg_nocancel: + bsd_syscalls[code].sc_name = "recvmsg"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_sendmsg: + case BSC_sendmsg_nocancel: + bsd_syscalls[code].sc_name = "sendmsg"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_recvfrom: + case BSC_recvfrom_nocancel: + bsd_syscalls[code].sc_name = "recvfrom"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_sendto: + case BSC_sendto_nocancel: + bsd_syscalls[code].sc_name = "sendto"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_select: + case BSC_select_nocancel: + bsd_syscalls[code].sc_name = "select"; + bsd_syscalls[code].sc_format = FMT_SELECT; + break; + + case BSC_accept: + case BSC_accept_nocancel: + bsd_syscalls[code].sc_name = "accept"; + bsd_syscalls[code].sc_format = FMT_FD_2; + break; + + case BSC_socket: + bsd_syscalls[code].sc_name = "socket"; + bsd_syscalls[code].sc_format = FMT_SOCKET; + break; + + case BSC_connect: + case BSC_connect_nocancel: + bsd_syscalls[code].sc_name = "connect"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_bind: + bsd_syscalls[code].sc_name = "bind"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_listen: + bsd_syscalls[code].sc_name = "listen"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_mmap: + bsd_syscalls[code].sc_name = "mmap"; + bsd_syscalls[code].sc_format = FMT_MMAP; + break; + + case BSC_socketpair: + bsd_syscalls[code].sc_name = "socketpair"; + break; + + case BSC_getxattr: + bsd_syscalls[code].sc_name = "getxattr"; + break; + + case BSC_setxattr: + bsd_syscalls[code].sc_name = "setxattr"; + break; + + case BSC_removexattr: + bsd_syscalls[code].sc_name = "removexattr"; + break; + + case BSC_listxattr: + bsd_syscalls[code].sc_name = "listxattr"; + break; + + case BSC_stat: + bsd_syscalls[code].sc_name = "stat"; + break; + + case BSC_stat_extended: + bsd_syscalls[code].sc_name = "stat_extended"; + break; + + case BSC_execve: + bsd_syscalls[code].sc_name = "execve"; + break; + + case BSC_load_shared_file: + bsd_syscalls[code].sc_name = "load_sf"; + break; + + case BSC_open: + case BSC_open_nocancel: + bsd_syscalls[code].sc_name = "open"; + bsd_syscalls[code].sc_format = FMT_OPEN; + break; + + case BSC_open_extended: + bsd_syscalls[code].sc_name = "open_extended"; + bsd_syscalls[code].sc_format = FMT_OPEN; + break; + + case BSC_dup: + bsd_syscalls[code].sc_name = "dup"; + bsd_syscalls[code].sc_format = FMT_FD_2; + break; + + case BSC_dup2: + bsd_syscalls[code].sc_name = "dup2"; + bsd_syscalls[code].sc_format = FMT_FD_2; + break; + + case BSC_close: + case BSC_close_nocancel: + bsd_syscalls[code].sc_name = "close"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_read: + case BSC_read_nocancel: + bsd_syscalls[code].sc_name = "read"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_write: + case BSC_write_nocancel: + bsd_syscalls[code].sc_name = "write"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_fgetxattr: + bsd_syscalls[code].sc_name = "fgetxattr"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_fsetxattr: + bsd_syscalls[code].sc_name = "fsetxattr"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_fremovexattr: + bsd_syscalls[code].sc_name = "fremovexattr"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_flistxattr: + bsd_syscalls[code].sc_name = "flistxattr"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_fstat: + bsd_syscalls[code].sc_name = "fstat"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_fstat_extended: + bsd_syscalls[code].sc_name = "fstat_extended"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_lstat: + bsd_syscalls[code].sc_name = "lstat"; + break; + + case BSC_lstat_extended: + bsd_syscalls[code].sc_name = "lstat_extended"; + break; + + case BSC_lstatv: + bsd_syscalls[code].sc_name = "lstatv"; + break; + + case BSC_link: + bsd_syscalls[code].sc_name = "link"; + break; + + case BSC_unlink: + bsd_syscalls[code].sc_name = "unlink"; + break; + + case BSC_mknod: + bsd_syscalls[code].sc_name = "mknod"; + break; + + case BSC_chmod: + bsd_syscalls[code].sc_name = "chmod"; + bsd_syscalls[code].sc_format = FMT_CHMOD; + break; + + case BSC_chmod_extended: + bsd_syscalls[code].sc_name = "chmod_extended"; + bsd_syscalls[code].sc_format = FMT_CHMOD_EXT; + break; + + case BSC_fchmod: + bsd_syscalls[code].sc_name = "fchmod"; + bsd_syscalls[code].sc_format = FMT_FCHMOD; + break; + + case BSC_fchmod_extended: + bsd_syscalls[code].sc_name = "fchmod_extended"; + bsd_syscalls[code].sc_format = FMT_FCHMOD_EXT; + break; + + case BSC_chown: + bsd_syscalls[code].sc_name = "chown"; + break; + + case BSC_lchown: + bsd_syscalls[code].sc_name = "lchown"; + break; + + case BSC_fchown: + bsd_syscalls[code].sc_name = "fchown"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_access: + bsd_syscalls[code].sc_name = "access"; + bsd_syscalls[code].sc_format = FMT_ACCESS; + break; + + case BSC_access_extended: + bsd_syscalls[code].sc_name = "access_extended"; + break; + + case BSC_chdir: + bsd_syscalls[code].sc_name = "chdir"; + break; + + case BSC_chroot: + bsd_syscalls[code].sc_name = "chroot"; + break; + + case BSC_utimes: + bsd_syscalls[code].sc_name = "utimes"; + break; + + case BSC_delete: + bsd_syscalls[code].sc_name = "delete"; + break; + + case BSC_undelete: + bsd_syscalls[code].sc_name = "undelete"; + break; + + case BSC_revoke: + bsd_syscalls[code].sc_name = "revoke"; + break; + + case BSC_fsctl: + bsd_syscalls[code].sc_name = "fsctl"; + break; + + case BSC_chflags: + bsd_syscalls[code].sc_name = "chflags"; + bsd_syscalls[code].sc_format = FMT_CHFLAGS; + break; + + case BSC_fchflags: + bsd_syscalls[code].sc_name = "fchflags"; + bsd_syscalls[code].sc_format = FMT_FCHFLAGS; + break; + + case BSC_fchdir: + bsd_syscalls[code].sc_name = "fchdir"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_futimes: + bsd_syscalls[code].sc_name = "futimes"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_sync: + bsd_syscalls[code].sc_name = "sync"; + break; + + case BSC_symlink: + bsd_syscalls[code].sc_name = "symlink"; + break; + + case BSC_readlink: + bsd_syscalls[code].sc_name = "readlink"; + break; + + case BSC_fsync: + case BSC_fsync_nocancel: + bsd_syscalls[code].sc_name = "fsync"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_readv: + case BSC_readv_nocancel: + bsd_syscalls[code].sc_name = "readv"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_writev: + case BSC_writev_nocancel: + bsd_syscalls[code].sc_name = "writev"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_pread: + case BSC_pread_nocancel: + bsd_syscalls[code].sc_name = "pread"; + bsd_syscalls[code].sc_format = FMT_PREAD; + break; + + case BSC_pwrite: + case BSC_pwrite_nocancel: + bsd_syscalls[code].sc_name = "pwrite"; + bsd_syscalls[code].sc_format = FMT_PREAD; + break; + + case BSC_mkdir: + bsd_syscalls[code].sc_name = "mkdir"; + break; + + case BSC_mkdir_extended: + bsd_syscalls[code].sc_name = "mkdir_extended"; + break; + + case BSC_mkfifo: + bsd_syscalls[code].sc_name = "mkfifo"; + break; + + case BSC_mkfifo_extended: + bsd_syscalls[code].sc_name = "mkfifo_extended"; + break; + + case BSC_rmdir: + bsd_syscalls[code].sc_name = "rmdir"; + break; + + case BSC_statfs: + bsd_syscalls[code].sc_name = "statfs"; + break; + + case BSC_fstatfs: + bsd_syscalls[code].sc_name = "fstatfs"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_pathconf: + bsd_syscalls[code].sc_name = "pathconf"; + break; + + case BSC_fpathconf: + bsd_syscalls[code].sc_name = "fpathconf"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_getdirentries: + bsd_syscalls[code].sc_name = "getdirentries"; + bsd_syscalls[code].sc_format = FMT_FD_IO; + break; + + case BSC_lseek: + bsd_syscalls[code].sc_name = "lseek"; + bsd_syscalls[code].sc_format = FMT_LSEEK; + break; + + case BSC_truncate: + bsd_syscalls[code].sc_name = "truncate"; + bsd_syscalls[code].sc_format = FMT_TRUNC; + break; + + case BSC_ftruncate: + bsd_syscalls[code].sc_name = "ftruncate"; + bsd_syscalls[code].sc_format = FMT_FTRUNC; + break; + + case BSC_statv: + bsd_syscalls[code].sc_name = "statv"; + break; + + case BSC_fstatv: + bsd_syscalls[code].sc_name = "fstatv"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_mkcomplex: + bsd_syscalls[code].sc_name = "mkcomplex"; + break; + + case BSC_getattrlist: + bsd_syscalls[code].sc_name = "getattrlist"; + break; + + case BSC_setattrlist: + bsd_syscalls[code].sc_name = "setattrlist"; + break; + + case BSC_getdirentriesattr: + bsd_syscalls[code].sc_name = "getdirentriesattr"; + bsd_syscalls[code].sc_format = FMT_FD; + break; + + case BSC_exchangedata: + bsd_syscalls[code].sc_name = "exchangedata"; + break; + + case BSC_rename: + bsd_syscalls[code].sc_name = "rename"; + break; + + case BSC_copyfile: + bsd_syscalls[code].sc_name = "copyfile"; + break; + + case BSC_checkuseraccess: + bsd_syscalls[code].sc_name = "checkuseraccess"; + break; + + case BSC_searchfs: + bsd_syscalls[code].sc_name = "searchfs"; + break; + + case BSC_aio_fsync: + bsd_syscalls[code].sc_name = "aio_fsync"; + bsd_syscalls[code].sc_format = FMT_AIO_FSYNC; + break; + + case BSC_aio_return: + bsd_syscalls[code].sc_name = "aio_return"; + bsd_syscalls[code].sc_format = FMT_AIO_RETURN; + break; + + case BSC_aio_suspend: + case BSC_aio_suspend_nocancel: + bsd_syscalls[code].sc_name = "aio_suspend"; + bsd_syscalls[code].sc_format = FMT_AIO_SUSPEND; + break; + + case BSC_aio_cancel: + bsd_syscalls[code].sc_name = "aio_cancel"; + bsd_syscalls[code].sc_format = FMT_AIO_CANCEL; + break; + + case BSC_aio_error: + bsd_syscalls[code].sc_name = "aio_error"; + bsd_syscalls[code].sc_format = FMT_AIO; + break; + + case BSC_aio_read: + bsd_syscalls[code].sc_name = "aio_read"; + bsd_syscalls[code].sc_format = FMT_AIO; + break; + + case BSC_aio_write: + bsd_syscalls[code].sc_name = "aio_write"; + bsd_syscalls[code].sc_format = FMT_AIO; + break; + + case BSC_lio_listio: + bsd_syscalls[code].sc_name = "lio_listio"; + bsd_syscalls[code].sc_format = FMT_LIO_LISTIO; + break; + + case BSC_msync: + case BSC_msync_nocancel: + bsd_syscalls[code].sc_name = "msync"; + bsd_syscalls[code].sc_format = FMT_MSYNC; + break; + + case BSC_fcntl: + case BSC_fcntl_nocancel: + bsd_syscalls[code].sc_name = "fcntl"; + bsd_syscalls[code].sc_format = FMT_FCNTL; + break; + + case BSC_ioctl: + bsd_syscalls[code].sc_name = "ioctl"; + bsd_syscalls[code].sc_format = FMT_IOCTL; + break; + } + } + + for (i = 0; (type = filemgr_call_types[i]); i++) { + char * p; + + code = filemgr_index(type); + + if (code >= MAX_FILEMGR) { + printf("FILEMGR call init (%x): type exceeds table size\n", type); + continue; + } + switch (type) { + + case FILEMGR_PBGETCATALOGINFO: + p = "GetCatalogInfo"; + break; + + case FILEMGR_PBGETCATALOGINFOBULK: + p = "GetCatalogInfoBulk"; + break; + + case FILEMGR_PBCREATEFILEUNICODE: + p = "CreateFileUnicode"; + break; + + case FILEMGR_PBCREATEDIRECTORYUNICODE: + p = "CreateDirectoryUnicode"; + break; + + case FILEMGR_PBCREATEFORK: + p = "PBCreateFork"; + break; + + case FILEMGR_PBDELETEFORK: + p = "PBDeleteFork"; + break; + + case FILEMGR_PBITERATEFORK: + p = "PBIterateFork"; + break; + + case FILEMGR_PBOPENFORK: + p = "PBOpenFork"; + break; + + case FILEMGR_PBREADFORK: + p = "PBReadFork"; + break; + + case FILEMGR_PBWRITEFORK: + p = "PBWriteFork"; + break; + + case FILEMGR_PBALLOCATEFORK: + p = "PBAllocateFork"; + break; + + case FILEMGR_PBDELETEOBJECT: + p = "PBDeleteObject"; + break; + + case FILEMGR_PBEXCHANGEOBJECT: + p = "PBExchangeObject"; + break; + + case FILEMGR_PBGETFORKCBINFO: + p = "PBGetForkCBInfo"; + break; + + case FILEMGR_PBGETVOLUMEINFO: + p = "PBGetVolumeInfo"; + break; + + case FILEMGR_PBMAKEFSREF: + p = "PBMakeFSRef"; + break; + + case FILEMGR_PBMAKEFSREFUNICODE: + p = "PBMakeFSRefUnicode"; + break; + + case FILEMGR_PBMOVEOBJECT: + p = "PBMoveObject"; + break; + + case FILEMGR_PBOPENITERATOR: + p = "PBOpenIterator"; + break; + + case FILEMGR_PBRENAMEUNICODE: + p = "PBRenameUnicode"; + break; + + case FILEMGR_PBSETCATALOGINFO: + p = "SetCatalogInfo"; + break; + + case FILEMGR_PBSETVOLUMEINFO: + p = "SetVolumeInfo"; + break; + + case FILEMGR_FSREFMAKEPATH: + p = "FSRefMakePath"; + break; + + case FILEMGR_FSPATHMAKEREF: + p = "FSPathMakeRef"; + break; + + case FILEMGR_PBGETCATINFO: + p = "GetCatInfo"; + break; + + case FILEMGR_PBGETCATINFOLITE: + p = "GetCatInfoLite"; + break; + + case FILEMGR_PBHGETFINFO: + p = "PBHGetFInfo"; + break; + + case FILEMGR_PBXGETVOLINFO: + p = "PBXGetVolInfo"; + break; + + case FILEMGR_PBHCREATE: + p = "PBHCreate"; + break; + + case FILEMGR_PBHOPENDF: + p = "PBHOpenDF"; + break; + + case FILEMGR_PBHOPENRF: + p = "PBHOpenRF"; + break; + + case FILEMGR_PBHGETDIRACCESS: + p = "PBHGetDirAccess"; + break; + + case FILEMGR_PBHSETDIRACCESS: + p = "PBHSetDirAccess"; + break; + + case FILEMGR_PBHMAPID: + p = "PBHMapID"; + break; + + case FILEMGR_PBHMAPNAME: + p = "PBHMapName"; + break; + + case FILEMGR_PBCLOSE: + p = "PBClose"; + break; + + case FILEMGR_PBFLUSHFILE: + p = "PBFlushFile"; + break; + + case FILEMGR_PBGETEOF: + p = "PBGetEOF"; + break; + + case FILEMGR_PBSETEOF: + p = "PBSetEOF"; + break; + + case FILEMGR_PBGETFPOS: + p = "PBGetFPos"; + break; + + case FILEMGR_PBREAD: + p = "PBRead"; + break; + + case FILEMGR_PBWRITE: + p = "PBWrite"; + break; + + case FILEMGR_PBGETFCBINFO: + p = "PBGetFCBInfo"; + break; + + case FILEMGR_PBSETFINFO: + p = "PBSetFInfo"; + break; + + case FILEMGR_PBALLOCATE: + p = "PBAllocate"; + break; + + case FILEMGR_PBALLOCCONTIG: + p = "PBAllocContig"; + break; + + case FILEMGR_PBSETFPOS: + p = "PBSetFPos"; + break; + + case FILEMGR_PBSETCATINFO: + p = "PBSetCatInfo"; + break; + + case FILEMGR_PBGETVOLPARMS: + p = "PBGetVolParms"; + break; + + case FILEMGR_PBSETVINFO: + p = "PBSetVInfo"; + break; + + case FILEMGR_PBMAKEFSSPEC: + p = "PBMakeFSSpec"; + break; + + case FILEMGR_PBHGETVINFO: + p = "PBHGetVInfo"; + break; + + case FILEMGR_PBCREATEFILEIDREF: + p = "PBCreateFileIDRef"; + break; + + case FILEMGR_PBDELETEFILEIDREF: + p = "PBDeleteFileIDRef"; + break; + + case FILEMGR_PBRESOLVEFILEIDREF: + p = "PBResolveFileIDRef"; + break; + + case FILEMGR_PBFLUSHVOL: + p = "PBFlushVol"; + break; + + case FILEMGR_PBHRENAME: + p = "PBHRename"; + break; + + case FILEMGR_PBCATMOVE: + p = "PBCatMove"; + break; + + case FILEMGR_PBEXCHANGEFILES: + p = "PBExchangeFiles"; + break; + + case FILEMGR_PBHDELETE: + p = "PBHDelete"; + break; + + case FILEMGR_PBDIRCREATE: + p = "PBDirCreate"; + break; + + case FILEMGR_PBCATSEARCH: + p = "PBCatSearch"; + break; + + case FILEMGR_PBHSETFLOCK: + p = "PBHSetFlock"; + break; + + case FILEMGR_PBHRSTFLOCK: + p = "PBHRstFLock"; + break; + + case FILEMGR_PBLOCKRANGE: + p = "PBLockRange"; + break; + + case FILEMGR_PBUNLOCKRANGE: + p = "PBUnlockRange"; + break; + + default: + p = NULL; + break; + } + filemgr_calls[code].fm_name = p; + } +} + + + int main(argc, argv) int argc; @@ -530,6 +1676,7 @@ main(argc, argv) char *myname = "fs_usage"; int i; char ch; + struct sigaction osa; void getdivisor(); void argtopid(); void set_remove(); @@ -552,7 +1699,6 @@ main(argc, argv) myname++; } } - while ((ch = getopt(argc, argv, "ewf:")) != EOF) { switch(ch) { @@ -574,6 +1720,8 @@ main(argc, argv) filter_mode &= ~CACHEHIT_FILTER; /* turns on CACHE_HIT */ else if (!strcmp(optarg, "exec")) filter_mode |= EXEC_FILTER; + else if (!strcmp(optarg, "pathname")) + filter_mode |= PATHNAME_FILTER; break; default: @@ -584,6 +1732,19 @@ main(argc, argv) argc -= optind; argv += optind; + /* + * when excluding, fs_usage should be the first in line for pids[] + * + * the !exclude_pids && argc == 0 catches the exclude_default_pids + * case below where exclude_pids is later set and the fs_usage PID + * needs to make it into pids[] + */ + if (exclude_pids || (!exclude_pids && argc == 0)) + { + if (num_of_pids < (MAX_PIDS - 1)) + pids[num_of_pids++] = getpid(); + } + /* If we process any list of pids/cmds, then turn off the defaults */ if (argc > 0) exclude_default_pids = 0; @@ -609,14 +1770,6 @@ main(argc, argv) exclude_pids = 1; } - if (exclude_pids) - { - if (num_of_pids < (MAX_PIDS - 1)) - pids[num_of_pids++] = getpid(); - else - exit_usage(myname); - } - #if 0 for (i = 0; i < num_of_pids; i++) { @@ -630,18 +1783,38 @@ main(argc, argv) /* set up signal handlers */ signal(SIGINT, leave); signal(SIGQUIT, leave); - signal(SIGHUP, leave); + + sigaction(SIGHUP, (struct sigaction *)NULL, &osa); + + if (osa.sa_handler == SIG_DFL) + signal(SIGHUP, leave); signal(SIGTERM, leave); signal(SIGWINCH, sigwinch); - if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0) + /* grab the number of cpus */ + size_t len; + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + mib[2] = 0; + len = sizeof(num_cpus); + sysctl(mib, 2, &num_cpus, &len, NULL, 0); + num_events = EVENT_BASE * num_cpus; + + if ((my_buffer = malloc(num_events * sizeof(kd_buf))) == (char *)0) quit("can't allocate memory for tracing info\n"); - ReadSegAddrTable(); + if (ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_i386.map", &framework32)) + ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64); + else { + ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc.map", &framework32); + ReadSharedCacheMap("/var/db/dyld/dyld_shared_cache_ppc64.map", &framework64); + } + SortFrameworkAddresses(); + cache_disk_names(); set_remove(); - set_numbufs(SAMPLE_SIZE); + set_numbufs(num_events); set_init(); if (exclude_pids == 0) { @@ -666,13 +1839,16 @@ main(argc, argv) getdivisor(); init_arguments_buffer(); + init_tables(); /* main loop */ while (1) { - usleep(1000 * 20); + usleep(1000 * usleep_ms); sample_sc(); + + last_time = time((long *)0); } } @@ -702,23 +1878,60 @@ find_proc_names() } -struct th_info *find_thread(int thread, int type) { - struct th_info *ti; +void destroy_thread(struct th_info *ti) { - for (ti = th_state; ti < &th_state[cur_max]; ti++) { - if (ti->thread == thread) { - if (type == ti->type) - return(ti); - if (ti->in_filemgr) { - if (type == -1) - return(ti); - continue; - } - if (type == 0) - return(ti); - } - } - return ((struct th_info *)0); + ti->child_thread = 0; + ti->thread = 0; + ti->pid = 0; + + if (ti->my_index < cur_start) + cur_start = ti->my_index; + + if (ti->my_index == cur_max) { + while (ti >= &th_state[0]) { + if (ti->thread) + break; + ti--; + } + cur_max = ti->my_index; + } +} + + +struct th_info *find_empty(void) { + struct th_info *ti; + + for (ti = &th_state[cur_start]; ti < &th_state[MAX_THREADS]; ti++, cur_start++) { + if (ti->thread == 0) { + if (cur_start > cur_max) + cur_max = cur_start; + cur_start++; + + return (ti); + } + } + return ((struct th_info *)0); + +} + + +struct th_info *find_thread(int thread, int type) { + struct th_info *ti; + + for (ti = &th_state[0]; ti <= &th_state[cur_max]; ti++) { + if (ti->thread == thread) { + if (type == ti->type) + return(ti); + if (ti->in_filemgr) { + if (type == -1) + return(ti); + continue; + } + if (type == 0) + return(ti); + } + } + return ((struct th_info *)0); } @@ -726,9 +1939,9 @@ void mark_thread_waited(int thread) { struct th_info *ti; - for (ti = th_state; ti < &th_state[cur_max]; ti++) { + for (ti = th_state; ti <= &th_state[cur_max]; ti++) { if (ti->thread == thread) { - ti->waited = 1; + ti->waited = 1; } } } @@ -922,17 +2135,30 @@ sample_sc() quit("trace facility failure, KERN_KDREADTR\n"); count = needed; + if (count > (SAMPLE_SIZE / 8)) { + if (usleep_ms > USLEEP_BEHIND) + usleep_ms = USLEEP_BEHIND; + else if (usleep_ms > USLEEP_MIN) + usleep_ms /= 2; + + } else if (count < (SAMPLE_SIZE / 16)) { + if (usleep_ms < USLEEP_MAX) + usleep_ms *= 2; + } + if (bufinfo.flags & KDBG_WRAPPED) { - fprintf(stderr, "fs_usage: buffer overrun, events generated too quickly\n"); + fprintf(stderr, "fs_usage: buffer overrun, events generated too quickly: %d\n", count); - for (i = 0; i < cur_max; i++) { + for (i = 0; i <= cur_max; i++) { th_state[i].thread = 0; th_state[i].pid = 0; th_state[i].pathptr = (long *)NULL; th_state[i].pathname[0] = 0; } cur_max = 0; + cur_start = 0; need_new_map = 1; + map_is_the_same = 0; set_enable(0); set_enable(1); @@ -943,7 +2169,8 @@ sample_sc() #endif for (i = 0; i < count; i++) { int debugid, thread; - int type, n; + int type; + int index; long *sargptr; uint64_t now; long long l_usecs; @@ -961,64 +2188,37 @@ sample_sc() if (i == 0) { + curr_time = time((long *)0); /* * Compute bias seconds after each trace buffer read. * This helps resync timestamps with the system clock * in the event of a system sleep. */ - l_usecs = (long long)(now / divisor); - secs = l_usecs / 1000000; - curr_time = time((long *)0); - bias_secs = curr_time - secs; + if (bias_secs == 0 || curr_time < last_time || curr_time > (last_time + 2)) { + l_usecs = (long long)(now / divisor); + secs = l_usecs / 1000000; + bias_secs = curr_time - secs; + } + } + + if ((type & P_DISKIO_MASK) == P_DISKIO) { + insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now); + continue; + } + if ((type & P_DISKIO_MASK) == P_DISKIO_DONE) { + if ((dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now))) { + print_diskio(dio); + free_diskio(dio); + } + continue; } - switch (type) { - case P_RdMeta: - case P_WrMeta: - case P_RdData: - case P_WrData: - case P_PgIn: - case P_PgOut: - case P_RdMetaAsync: - case P_WrMetaAsync: - case P_RdDataAsync: - case P_WrDataAsync: - case P_PgInAsync: - case P_PgOutAsync: - insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now); - continue; - - case P_RdMetaDone: - case P_WrMetaDone: - case P_RdDataDone: - case P_WrDataDone: - case P_PgInDone: - case P_PgOutDone: - case P_RdMetaAsyncDone: - case P_WrMetaAsyncDone: - case P_RdDataAsyncDone: - case P_WrDataAsyncDone: - case P_PgInAsyncDone: - case P_PgOutAsyncDone: - if ((dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now))) { - print_diskio(dio); - free_diskio(dio); - } - continue; - - case TRACE_DATA_NEWTHREAD: - for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) { - if (ti->thread == 0) - break; - } - if (ti == &th_state[MAX_THREADS]) - continue; - if (n >= cur_max) - cur_max = n + 1; + if ((ti = find_empty()) == NULL) + continue; ti->thread = thread; ti->child_thread = kd[i].arg1; @@ -1032,23 +2232,14 @@ sample_sc() continue; create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1); - if (ti == &th_state[cur_max - 1]) - cur_max--; - ti->child_thread = 0; - ti->thread = 0; - ti->pid = 0; + destroy_thread(ti); + continue; case TRACE_DATA_EXEC: - for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) { - if (ti->thread == 0) - break; - } - if (ti == &th_state[MAX_THREADS]) - continue; - if (n >= cur_max) - cur_max = n + 1; + if ((ti = find_empty()) == NULL) + continue; ti->thread = thread; ti->pid = kd[i].arg1; @@ -1064,10 +2255,7 @@ sample_sc() { create_map_entry(thread, ti->pid, (char *)&kd[i].arg1); - if (ti == &th_state[cur_max - 1]) - cur_max--; - ti->thread = 0; - ti->pid = 0; + destroy_thread(ti); } continue; @@ -1075,6 +2263,11 @@ sample_sc() kill_thread_map(thread); continue; + case BSC_mmap: + if (kd[i].arg4 & MAP_ANON) + continue; + break; + case MACH_sched: case MACH_stkhandoff: mark_thread_waited(thread); @@ -1084,7 +2277,7 @@ sample_sc() if ((ti = find_thread(thread, 0)) == (struct th_info *)0) continue; - if (!ti->pathptr) { + if (ti->pathptr == NULL) { sargptr = ti->pathname; *sargptr++ = kd[i].arg2; *sargptr++ = kd[i].arg3; @@ -1093,26 +2286,25 @@ sample_sc() * NULL terminate the 'string' */ *sargptr = 0; - ti->pathptr = sargptr; } else { sargptr = ti->pathptr; /* - We don't want to overrun our pathname buffer if the - kernel sends us more VFS_LOOKUP entries than we can - handle. - */ + * We don't want to overrun our pathname buffer if the + * kernel sends us more VFS_LOOKUP entries than we can + * handle. + */ if (sargptr >= &ti->pathname[NUMPARMS]) { continue; } - /* - We need to detect consecutive vfslookup entries. - So, if we get here and find a START entry, - fake the pathptr so we can bypass all further - vfslookup entries. - */ + /* + * We need to detect consecutive vfslookup entries. + * So, if we get here and find a START entry, + * fake the pathptr so we can bypass all further + * vfslookup entries. + */ if (debugid & DBG_FUNC_START) { ti->pathptr = &ti->pathname[NUMPARMS]; continue; @@ -1125,830 +2317,107 @@ sample_sc() * NULL terminate the 'string' */ *sargptr = 0; - ti->pathptr = sargptr; } continue; } if (debugid & DBG_FUNC_START) { - char *p; - - switch (type) { - case FILEMGR_PBGETCATALOGINFO: - p = "GetCatalogInfo"; - break; - case FILEMGR_PBGETCATALOGINFOBULK: - p = "GetCatalogInfoBulk"; - break; - case FILEMGR_PBCREATEFILEUNICODE: - p = "CreateFileUnicode"; - break; - case FILEMGR_PBCREATEDIRECTORYUNICODE: - p = "CreateDirectoryUnicode"; - break; - case FILEMGR_PBCREATEFORK: - p = "PBCreateFork"; - break; - case FILEMGR_PBDELETEFORK: - p = "PBDeleteFork"; - break; - case FILEMGR_PBITERATEFORK: - p = "PBIterateFork"; - break; - case FILEMGR_PBOPENFORK: - p = "PBOpenFork"; - break; - case FILEMGR_PBREADFORK: - p = "PBReadFork"; - break; - case FILEMGR_PBWRITEFORK: - p = "PBWriteFork"; - break; - case FILEMGR_PBALLOCATEFORK: - p = "PBAllocateFork"; - break; - case FILEMGR_PBDELETEOBJECT: - p = "PBDeleteObject"; - break; - case FILEMGR_PBEXCHANGEOBJECT: - p = "PBExchangeObject"; - break; - case FILEMGR_PBGETFORKCBINFO: - p = "PBGetForkCBInfo"; - break; - case FILEMGR_PBGETVOLUMEINFO: - p = "PBGetVolumeInfo"; - break; - case FILEMGR_PBMAKEFSREF: - p = "PBMakeFSRef"; - break; - case FILEMGR_PBMAKEFSREFUNICODE: - p = "PBMakeFSRefUnicode"; - break; - case FILEMGR_PBMOVEOBJECT: - p = "PBMoveObject"; - break; - case FILEMGR_PBOPENITERATOR: - p = "PBOpenIterator"; - break; - case FILEMGR_PBRENAMEUNICODE: - p = "PBRenameUnicode"; - break; - case FILEMGR_PBSETCATALOGINFO: - p = "SetCatalogInfo"; - break; - case FILEMGR_PBSETVOLUMEINFO: - p = "SetVolumeInfo"; - break; - case FILEMGR_FSREFMAKEPATH: - p = "FSRefMakePath"; - break; - case FILEMGR_FSPATHMAKEREF: - p = "FSPathMakeRef"; - break; - // SPEC based calls - case FILEMGR_PBGETCATINFO: - p = "GetCatInfo"; - break; - case FILEMGR_PBGETCATINFOLITE: - p = "GetCatInfoLite"; - break; - case FILEMGR_PBHGETFINFO: - p = "PBHGetFInfo"; - break; - case FILEMGR_PBXGETVOLINFO: - p = "PBXGetVolInfo"; - break; - case FILEMGR_PBHCREATE: - p = "PBHCreate"; - break; - case FILEMGR_PBHOPENDF: - p = "PBHOpenDF"; - break; - case FILEMGR_PBHOPENRF: - p = "PBHOpenRF"; - break; - case FILEMGR_PBHGETDIRACCESS: - p = "PBHGetDirAccess"; - break; - case FILEMGR_PBHSETDIRACCESS: - p = "PBHSetDirAccess"; - break; - case FILEMGR_PBHMAPID: - p = "PBHMapID"; - break; - case FILEMGR_PBHMAPNAME: - p = "PBHMapName"; - break; - case FILEMGR_PBCLOSE: - p = "PBClose"; - break; - case FILEMGR_PBFLUSHFILE: - p = "PBFlushFile"; - break; - case FILEMGR_PBGETEOF: - p = "PBGetEOF"; - break; - case FILEMGR_PBSETEOF: - p = "PBSetEOF"; - break; - case FILEMGR_PBGETFPOS: - p = "PBGetFPos"; - break; - case FILEMGR_PBREAD: - p = "PBRead"; - break; - case FILEMGR_PBWRITE: - p = "PBWrite"; - break; - case FILEMGR_PBGETFCBINFO: - p = "PBGetFCBInfo"; - break; - case FILEMGR_PBSETFINFO: - p = "PBSetFInfo"; - break; - case FILEMGR_PBALLOCATE: - p = "PBAllocate"; - break; - case FILEMGR_PBALLOCCONTIG: - p = "PBAllocContig"; - break; - case FILEMGR_PBSETFPOS: - p = "PBSetFPos"; - break; - case FILEMGR_PBSETCATINFO: - p = "PBSetCatInfo"; - break; - case FILEMGR_PBGETVOLPARMS: - p = "PBGetVolParms"; - break; - case FILEMGR_PBSETVINFO: - p = "PBSetVInfo"; - break; - case FILEMGR_PBMAKEFSSPEC: - p = "PBMakeFSSpec"; - break; - case FILEMGR_PBHGETVINFO: - p = "PBHGetVInfo"; - break; - case FILEMGR_PBCREATEFILEIDREF: - p = "PBCreateFileIDRef"; - break; - case FILEMGR_PBDELETEFILEIDREF: - p = "PBDeleteFileIDRef"; - break; - case FILEMGR_PBRESOLVEFILEIDREF: - p = "PBResolveFileIDRef"; - break; - case FILEMGR_PBFLUSHVOL: - p = "PBFlushVol"; - break; - case FILEMGR_PBHRENAME: - p = "PBHRename"; - break; - case FILEMGR_PBCATMOVE: - p = "PBCatMove"; - break; - case FILEMGR_PBEXCHANGEFILES: - p = "PBExchangeFiles"; - break; - case FILEMGR_PBHDELETE: - p = "PBHDelete"; - break; - case FILEMGR_PBDIRCREATE: - p = "PBDirCreate"; - break; - case FILEMGR_PBCATSEARCH: - p = "PBCatSearch"; - break; - case FILEMGR_PBHSETFLOCK: - p = "PBHSetFlock"; - break; - case FILEMGR_PBHRSTFLOCK: - p = "PBHRstFLock"; - break; - case FILEMGR_PBLOCKRANGE: - p = "PBLockRange"; - break; - case FILEMGR_PBUNLOCKRANGE: - p = "PBUnlockRange"; - break; - default: - p = (char *)0; - break; - } - enter_syscall(thread, type, &kd[i], p, (double)now); + char * p; + + if ((type & CLASS_MASK) == FILEMGR_BASE) { + + index = filemgr_index(type); + + if (index >= MAX_FILEMGR) + continue; + + if ((p = filemgr_calls[index].fm_name) == NULL) + continue; + } else + p = NULL; + + enter_syscall(thread, type, &kd[i], p, (double)now); continue; } - + switch (type) { - - case BSC_pread_extended: - case BSC_pwrite_extended: - extend_syscall(thread, type, &kd[i], (double)now); - case MACH_pageout: - if (kd[i].arg2) - exit_syscall("PAGE_OUT_D", thread, type, 0, kd[i].arg1, 0, 4, (double)now); - else - exit_syscall("PAGE_OUT_V", thread, type, 0, kd[i].arg1, 0, 4, (double)now); - break; + case MACH_pageout: + if (kd[i].arg2) + exit_syscall("PAGE_OUT_D", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now); + else + exit_syscall("PAGE_OUT_V", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now); + continue; + + case MACH_vmfault: + if (kd[i].arg4 == DBG_PAGEIN_FAULT) + exit_syscall("PAGE_IN", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now); + else if (kd[i].arg4 == DBG_CACHE_HIT_FAULT) + exit_syscall("CACHE_HIT", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_CACHEHIT, (double)now); + else { + if ((ti = find_thread(thread, type))) { + destroy_thread(ti); + } + } + continue; + + case MSC_map_fd: + exit_syscall("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_FD, (double)now); + continue; + + case BSC_mmap_extended: + case BSC_mmap_extended2: + case BSC_msync_extended: + case BSC_pread_extended: + case BSC_pwrite_extended: + extend_syscall(thread, type, &kd[i]); + continue; + } - case MACH_vmfault: - if (kd[i].arg2 == DBG_PAGEIN_FAULT) - exit_syscall("PAGE_IN", thread, type, kd[i].arg4, kd[i].arg1, 0, 6, (double)now); - else if (kd[i].arg2 == DBG_CACHE_HIT_FAULT) - exit_syscall("CACHE_HIT", thread, type, 0, kd[i].arg1, 0, 2, (double)now); - else { - if ((ti = find_thread(thread, type))) { - if (ti == &th_state[cur_max - 1]) - cur_max--; - ti->thread = 0; - } - } - break; + if ((type & CSC_MASK) == BSC_BASE) { - case MSC_map_fd: - exit_syscall("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; + index = BSC_INDEX(type); - case BSC_mmap: - exit_syscall("mmap", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_recvmsg: - exit_syscall("recvmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; + if (index >= MAX_BSD_SYSCALL) + continue; - case BSC_sendmsg: - exit_syscall("sendmsg", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; + if (bsd_syscalls[index].sc_name == NULL) + continue; - case BSC_recvfrom: - exit_syscall("recvfrom", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; + if (type == BSC_execve) + execs_in_progress--; - case BSC_accept: - exit_syscall("accept", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); - break; - - case BSC_select: - exit_syscall("select", thread, type, kd[i].arg1, kd[i].arg2, 0, 8, (double)now); - break; - - case BSC_socket: - exit_syscall("socket", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); - break; + exit_syscall(bsd_syscalls[index].sc_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, + bsd_syscalls[index].sc_format, (double)now); - case BSC_connect: - exit_syscall("connect", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_bind: - exit_syscall("bind", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_listen: - exit_syscall("listen", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_sendto: - exit_syscall("sendto", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; - - case BSC_socketpair: - exit_syscall("socketpair", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_getxattr: - exit_syscall("getxattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_setxattr: - exit_syscall("setxattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_removexattr: - exit_syscall("removexattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_listxattr: - exit_syscall("listxattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_stat: - exit_syscall("stat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_stat_extended: - exit_syscall("stat_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_execve: - exit_syscall("execve", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_load_shared_file: - exit_syscall("load_sf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_open: - exit_syscall("open", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); - break; - - case BSC_open_extended: - exit_syscall("open_extended", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); - break; - - case BSC_dup: - exit_syscall("dup", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); - break; - - case BSC_dup2: - exit_syscall("dup2", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now); - break; - - case BSC_close: - exit_syscall("close", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_read: - exit_syscall("read", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; - - case BSC_write: - exit_syscall("write", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; - - case BSC_fgetxattr: - exit_syscall("fgetxattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fsetxattr: - exit_syscall("fsetxattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fremovexattr: - exit_syscall("fremovexattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_flistxattr: - exit_syscall("flistxattr", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fstat: - exit_syscall("fstat", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fstat_extended: - exit_syscall("fstat_extended", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_lstat: - exit_syscall("lstat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_lstat_extended: - exit_syscall("lstat_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_link: - exit_syscall("link", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_unlink: - exit_syscall("unlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_mknod: - exit_syscall("mknod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_chmod: - exit_syscall("chmod", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_chmod_extended: - exit_syscall("chmod_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_chown: - exit_syscall("chown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_lchown: - exit_syscall("lchown", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_access: - exit_syscall("access", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_access_extended: - exit_syscall("access_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_chdir: - exit_syscall("chdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_chroot: - exit_syscall("chroot", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_utimes: - exit_syscall("utimes", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_delete: - exit_syscall("delete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_undelete: - exit_syscall("undelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_revoke: - exit_syscall("revoke", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_fsctl: - exit_syscall("fsctl", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_chflags: - exit_syscall("chflags", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_fchflags: - exit_syscall("fchflags", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fchdir: - exit_syscall("fchdir", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_futimes: - exit_syscall("futimes", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_sync: - exit_syscall("sync", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_symlink: - exit_syscall("symlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_readlink: - exit_syscall("readlink", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_fsync: - exit_syscall("fsync", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_readv: - exit_syscall("readv", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; - - case BSC_writev: - exit_syscall("writev", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; - - case BSC_pread: - exit_syscall("pread", thread, type, kd[i].arg1, kd[i].arg2, 1, 9, (double)now); - break; - - case BSC_pwrite: - exit_syscall("pwrite", thread, type, kd[i].arg1, kd[i].arg2, 1, 9, (double)now); - break; - - case BSC_fchown: - exit_syscall("fchown", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fchmod: - exit_syscall("fchmod", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_fchmod_extended: - exit_syscall("fchmod_extended", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_mkdir: - exit_syscall("mkdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_mkdir_extended: - exit_syscall("mkdir_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_mkfifo: - exit_syscall("mkfifo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_mkfifo_extended: - exit_syscall("mkfifo_extended", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_rmdir: - exit_syscall("rmdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_statfs: - exit_syscall("statfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_fstatfs: - exit_syscall("fstatfs", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_pathconf: - exit_syscall("pathconf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_fpathconf: - exit_syscall("fpathconf", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_getdirentries: - exit_syscall("getdirentries", thread, type, kd[i].arg1, kd[i].arg2, 1, 1, (double)now); - break; - - case BSC_lseek: - exit_syscall("lseek", thread, type, kd[i].arg1, kd[i].arg3, 1, 5, (double)now); - break; - - case BSC_truncate: - exit_syscall("truncate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_ftruncate: - exit_syscall("ftruncate", thread, type, kd[i].arg1, kd[i].arg2, 1, 3, (double)now); - break; - - case BSC_statv: - exit_syscall("statv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_lstatv: - exit_syscall("lstatv", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_fstatv: - exit_syscall("fstatv", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now); - break; - - case BSC_mkcomplex: - exit_syscall("mkcomplex", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_getattrlist: - exit_syscall("getattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_setattrlist: - exit_syscall("setattrlist", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_getdirentriesattr: - exit_syscall("getdirentriesattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 1, (double)now); - break; - - - case BSC_exchangedata: - exit_syscall("exchangedata", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_rename: - exit_syscall("rename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - - case BSC_copyfile: - exit_syscall("copyfile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; + continue; + } + if ((type & CLASS_MASK) == FILEMGR_BASE) { + + index = filemgr_index(type); - case BSC_checkuseraccess: - exit_syscall("checkuseraccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; + if (index >= MAX_FILEMGR) + continue; - case BSC_searchfs: - exit_syscall("searchfs", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; + if (filemgr_calls[index].fm_name == NULL) + continue; - case FILEMGR_PBGETCATALOGINFO: - exit_syscall("GetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETCATALOGINFOBULK: - exit_syscall("GetCatalogInfoBulk", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCREATEFILEUNICODE: - exit_syscall("CreateFileUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCREATEDIRECTORYUNICODE: - exit_syscall("CreateDirectoryUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCREATEFORK: - exit_syscall("PBCreateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBDELETEFORK: - exit_syscall("PBDeleteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBITERATEFORK: - exit_syscall("PBIterateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBOPENFORK: - exit_syscall("PBOpenFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBREADFORK: - exit_syscall("PBReadFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBWRITEFORK: - exit_syscall("PBWriteFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBALLOCATEFORK: - exit_syscall("PBAllocateFork", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBDELETEOBJECT: - exit_syscall("PBDeleteObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBEXCHANGEOBJECT: - exit_syscall("PBExchangeObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETFORKCBINFO: - exit_syscall("PBGetForkCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETVOLUMEINFO: - exit_syscall("PBGetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBMAKEFSREF: - exit_syscall("PBMakeFSRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBMAKEFSREFUNICODE: - exit_syscall("PBMakeFSRefUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBMOVEOBJECT: - exit_syscall("PBMoveObject", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBOPENITERATOR: - exit_syscall("PBOpenIterator", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBRENAMEUNICODE: - exit_syscall("PBRenameUnicode", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETCATALOGINFO: - exit_syscall("PBSetCatalogInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETVOLUMEINFO: - exit_syscall("PBSetVolumeInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_FSREFMAKEPATH: - exit_syscall("FSRefMakePath", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_FSPATHMAKEREF: - exit_syscall("FSPathMakeRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETCATINFO: - exit_syscall("GetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETCATINFOLITE: - exit_syscall("GetCatInfoLite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHGETFINFO: - exit_syscall("PBHGetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBXGETVOLINFO: - exit_syscall("PBXGetVolInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHCREATE: - exit_syscall("PBHCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHOPENDF: - exit_syscall("PBHOpenDF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHOPENRF: - exit_syscall("PBHOpenRF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHGETDIRACCESS: - exit_syscall("PBHGetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHSETDIRACCESS: - exit_syscall("PBHSetDirAccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHMAPID: - exit_syscall("PBHMapID", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHMAPNAME: - exit_syscall("PBHMapName", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCLOSE: - exit_syscall("PBClose", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBFLUSHFILE: - exit_syscall("PBFlushFile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETEOF: - exit_syscall("PBGetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETEOF: - exit_syscall("PBSetEOF", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETFPOS: - exit_syscall("PBGetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBREAD: - exit_syscall("PBRead", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBWRITE: - exit_syscall("PBWrite", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETFCBINFO: - exit_syscall("PBGetFCBInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETFINFO: - exit_syscall("PBSetFInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBALLOCATE: - exit_syscall("PBAllocate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBALLOCCONTIG: - exit_syscall("PBAllocContig", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETFPOS: - exit_syscall("PBSetFPos", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETCATINFO: - exit_syscall("PBSetCatInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBGETVOLPARMS: - exit_syscall("PBGetVolParms", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBSETVINFO: - exit_syscall("PBSetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBMAKEFSSPEC: - exit_syscall("PBMakeFSSpec", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHGETVINFO: - exit_syscall("PBHGetVInfo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCREATEFILEIDREF: - exit_syscall("PBCreateFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBDELETEFILEIDREF: - exit_syscall("PBDeleteFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBRESOLVEFILEIDREF: - exit_syscall("PBResolveFileIDRef", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBFLUSHVOL: - exit_syscall("PBFlushVol", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHRENAME: - exit_syscall("PBHRename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCATMOVE: - exit_syscall("PBCatMove", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBEXCHANGEFILES: - exit_syscall("PBExchangeFiles", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHDELETE: - exit_syscall("PBHDelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBDIRCREATE: - exit_syscall("PBDirCreate", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBCATSEARCH: - exit_syscall("PBCatSearch", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHSETFLOCK: - exit_syscall("PBHSetFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBHRSTFLOCK: - exit_syscall("PBHRstFLock", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBLOCKRANGE: - exit_syscall("PBLockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - case FILEMGR_PBUNLOCKRANGE: - exit_syscall("PBUnlockRange", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now); - break; - default: - break; + exit_syscall(filemgr_calls[index].fm_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, + FMT_DEFAULT, (double)now); } } fflush(0); } + + + void -enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) +enter_syscall_now(int thread, int type, kd_buf *kd, char *name, double now) { struct th_info *ti; - int i; int secs; int usecs; long long l_usecs; @@ -1961,205 +2430,42 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) int argsclen = 0; char buf[MAXWIDTH]; - switch (type) { - - case MACH_pageout: - case MACH_vmfault: - case MSC_map_fd: - case BSC_mmap: - case BSC_recvmsg: - case BSC_sendmsg: - case BSC_recvfrom: - case BSC_accept: - case BSC_select: - case BSC_socket: - case BSC_connect: - case BSC_bind: - case BSC_listen: - case BSC_sendto: - case BSC_socketpair: - case BSC_execve: - case BSC_getxattr: - case BSC_fgetxattr: - case BSC_setxattr: - case BSC_fsetxattr: - case BSC_removexattr: - case BSC_fremovexattr: - case BSC_listxattr: - case BSC_flistxattr: - case BSC_open_extended: - case BSC_stat_extended: - case BSC_lstat_extended: - case BSC_fstat_extended: - case BSC_chmod_extended: - case BSC_fchmod_extended: - case BSC_access_extended: - case BSC_mkfifo_extended: - case BSC_mkdir_extended: - case BSC_stat: - case BSC_load_shared_file: - case BSC_open: - case BSC_dup: - case BSC_dup2: - case BSC_close: - case BSC_read: - case BSC_write: - case BSC_fstat: - case BSC_lstat: - case BSC_link: - case BSC_unlink: - case BSC_mknod: - case BSC_chmod: - case BSC_chown: - case BSC_lchown: - case BSC_access: - case BSC_chflags: - case BSC_fchflags: - case BSC_fchdir: - case BSC_futimes: - case BSC_chdir: - case BSC_utimes: - case BSC_chroot: - case BSC_undelete: - case BSC_delete: - case BSC_revoke: - case BSC_fsctl: - case BSC_copyfile: - case BSC_sync: - case BSC_symlink: - case BSC_readlink: - case BSC_fsync: - case BSC_readv: - case BSC_writev: - case BSC_pread: - case BSC_pwrite: - case BSC_fchown: - case BSC_fchmod: - case BSC_rename: - case BSC_mkdir: - case BSC_mkfifo: - case BSC_rmdir: - case BSC_statfs: - case BSC_fstatfs: - case BSC_pathconf: - case BSC_fpathconf: - case BSC_getdirentries: - case BSC_lseek: - case BSC_truncate: - case BSC_ftruncate: - case BSC_statv: - case BSC_lstatv: - case BSC_fstatv: - case BSC_mkcomplex: - case BSC_getattrlist: - case BSC_setattrlist: - case BSC_getdirentriesattr: - case BSC_exchangedata: - case BSC_checkuseraccess: - case BSC_searchfs: - case FILEMGR_PBGETCATALOGINFO: - case FILEMGR_PBGETCATALOGINFOBULK: - case FILEMGR_PBCREATEFILEUNICODE: - case FILEMGR_PBCREATEDIRECTORYUNICODE: - case FILEMGR_PBCREATEFORK: - case FILEMGR_PBDELETEFORK: - case FILEMGR_PBITERATEFORK: - case FILEMGR_PBOPENFORK: - case FILEMGR_PBREADFORK: - case FILEMGR_PBWRITEFORK: - case FILEMGR_PBALLOCATEFORK: - case FILEMGR_PBDELETEOBJECT: - case FILEMGR_PBEXCHANGEOBJECT: - case FILEMGR_PBGETFORKCBINFO: - case FILEMGR_PBGETVOLUMEINFO: - case FILEMGR_PBMAKEFSREF: - case FILEMGR_PBMAKEFSREFUNICODE: - case FILEMGR_PBMOVEOBJECT: - case FILEMGR_PBOPENITERATOR: - case FILEMGR_PBRENAMEUNICODE: - case FILEMGR_PBSETCATALOGINFO: - case FILEMGR_PBSETVOLUMEINFO: - case FILEMGR_FSREFMAKEPATH: - case FILEMGR_FSPATHMAKEREF: - - case FILEMGR_PBGETCATINFO: - case FILEMGR_PBGETCATINFOLITE: - case FILEMGR_PBHGETFINFO: - case FILEMGR_PBXGETVOLINFO: - case FILEMGR_PBHCREATE: - case FILEMGR_PBHOPENDF: - case FILEMGR_PBHOPENRF: - case FILEMGR_PBHGETDIRACCESS: - case FILEMGR_PBHSETDIRACCESS: - case FILEMGR_PBHMAPID: - case FILEMGR_PBHMAPNAME: - case FILEMGR_PBCLOSE: - case FILEMGR_PBFLUSHFILE: - case FILEMGR_PBGETEOF: - case FILEMGR_PBSETEOF: - case FILEMGR_PBGETFPOS: - case FILEMGR_PBREAD: - case FILEMGR_PBWRITE: - case FILEMGR_PBGETFCBINFO: - case FILEMGR_PBSETFINFO: - case FILEMGR_PBALLOCATE: - case FILEMGR_PBALLOCCONTIG: - case FILEMGR_PBSETFPOS: - case FILEMGR_PBSETCATINFO: - case FILEMGR_PBGETVOLPARMS: - case FILEMGR_PBSETVINFO: - case FILEMGR_PBMAKEFSSPEC: - case FILEMGR_PBHGETVINFO: - case FILEMGR_PBCREATEFILEIDREF: - case FILEMGR_PBDELETEFILEIDREF: - case FILEMGR_PBRESOLVEFILEIDREF: - case FILEMGR_PBFLUSHVOL: - case FILEMGR_PBHRENAME: - case FILEMGR_PBCATMOVE: - case FILEMGR_PBEXCHANGEFILES: - case FILEMGR_PBHDELETE: - case FILEMGR_PBDIRCREATE: - case FILEMGR_PBCATSEARCH: - case FILEMGR_PBHSETFLOCK: - case FILEMGR_PBHRSTFLOCK: - case FILEMGR_PBLOCKRANGE: - case FILEMGR_PBUNLOCKRANGE: - - if ((ti = find_thread(thread, BSC_execve))) { - if (ti->pathptr) { - exit_syscall("execve", thread, BSC_execve, 0, 0, 0, 0, (double)now); - } - } - for (i = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, i++) { - if (ti->thread == 0) - break; - } - if (ti == &th_state[MAX_THREADS]) - return; - if (i >= cur_max) - cur_max = i + 1; + if (execs_in_progress) { + if ((ti = find_thread(thread, BSC_execve))) { + if (ti->pathptr) { + exit_syscall("execve", thread, BSC_execve, 0, 0, 0, 0, FMT_DEFAULT, (double)now); + execs_in_progress--; + } + } + } + if ((ti = find_empty()) == NULL) + return; - if ((type >> 24) == FILEMGR_CLASS) { - ti->in_filemgr = 1; + if ((type & CLASS_MASK) == FILEMGR_BASE) { + + filemgr_in_progress++; + ti->in_filemgr = 1; - l_usecs = (long long)(now / divisor); - secs = l_usecs / 1000000; - curr_time = bias_secs + secs; + l_usecs = (long long)(now / divisor); + secs = l_usecs / 1000000; + curr_time = bias_secs + secs; - sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11])); - tsclen = strlen(buf); + sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11])); + tsclen = strlen(buf); - if (columns > MAXCOLS || wideflag) { - usecs = l_usecs - (long long)((long long)secs * 1000000); - sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000); - tsclen = strlen(buf); - } + if (columns > MAXCOLS || wideflag) { + usecs = l_usecs - (long long)((long long)secs * 1000000); + sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000); + tsclen = strlen(buf); + } - /* Print timestamp column */ - printf("%s", buf); + /* + * Print timestamp column + */ + printf("%s", buf); - map = find_thread_map(thread); - if (map) { + map = find_thread_map(thread); + if (map) { sprintf(buf, " %-25.25s ", name); nmclen = strlen(buf); printf("%s", buf); @@ -2168,55 +2474,81 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) argsclen = strlen(buf); /* - Calculate white space out to command - */ + * Calculate white space out to command + */ + if (columns > MAXCOLS || wideflag) { + clen = columns - (tsclen + nmclen + argsclen + 20); + } else + clen = columns - (tsclen + nmclen + argsclen + 12); + + if (clen > 0) { + printf("%s", buf); /* print the kdargs */ + memset(buf, ' ', clen); + buf[clen] = '\0'; + printf("%s", buf); + } + else if ((argsclen + clen) > 0) { + /* + * no room so wipe out the kdargs + */ + memset(buf, ' ', (argsclen + clen)); + buf[argsclen + clen] = '\0'; + printf("%s", buf); + } if (columns > MAXCOLS || wideflag) - { - clen = columns - (tsclen + nmclen + argsclen + 20); - } + printf("%-20.20s\n", map->command); else - clen = columns - (tsclen + nmclen + argsclen + 12); - - if(clen > 0) - { - printf("%s", buf); /* print the kdargs */ - memset(buf, ' ', clen); - buf[clen] = '\0'; - printf("%s", buf); - } - else if ((argsclen + clen) > 0) - { - /* no room so wipe out the kdargs */ - memset(buf, ' ', (argsclen + clen)); - buf[argsclen + clen] = '\0'; - printf("%s", buf); - } + printf("%-12.12s\n", map->command); + } else + printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4); + } + ti->thread = thread; + ti->waited = 0; + ti->type = type; + ti->stime = now; + ti->arg1 = kd->arg1; + ti->arg2 = kd->arg2; + ti->arg3 = kd->arg3; + ti->arg4 = kd->arg4; + ti->pathptr = (long *)NULL; + ti->pathname[0] = 0; +} - if (columns > MAXCOLS || wideflag) - printf("%-20.20s\n", map->command); - else - printf("%-12.12s\n", map->command); - } else - printf(" %-24.24s (%5d, %#x, 0x%x, 0x%x)\n", name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4); - } else { - ti->in_filemgr = 0; - } - ti->thread = thread; - ti->waited = 0; - ti->type = type; - ti->stime = now; - ti->arg1 = kd->arg1; - ti->arg2 = kd->arg2; - ti->arg3 = kd->arg3; - ti->arg4 = kd->arg4; - ti->pathptr = (long *)NULL; - ti->pathname[0] = 0; - break; - default: - break; +void +enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) +{ + int index; + + if (type == MACH_pageout || type == MACH_vmfault || type == MSC_map_fd) { + enter_syscall_now(thread, type, kd, name, now); + return; + } + if ((type & CSC_MASK) == BSC_BASE) { + + index = BSC_INDEX(type); + + if (index >= MAX_BSD_SYSCALL) + return; + + if (type == BSC_execve) + execs_in_progress++; + + if (bsd_syscalls[index].sc_name) + enter_syscall_now(thread, type, kd, name, now); + + return; + } + if ((type & CLASS_MASK) == FILEMGR_BASE) { + + index = filemgr_index(type); + + if (index >= MAX_FILEMGR) + return; + + if (filemgr_calls[index].fm_name) + enter_syscall_now(thread, type, kd, name, now); } - fflush (0); } /* @@ -2228,22 +2560,50 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now) */ void -extend_syscall(int thread, int type, kd_buf *kd, char *name, double now) +extend_syscall(int thread, int type, kd_buf *kd) { struct th_info *ti; switch (type) { + case BSC_mmap_extended: + if ((ti = find_thread(thread, BSC_mmap)) == (struct th_info *)0) + return; + ti->arg8 = ti->arg3; /* save protection */ + ti->arg1 = kd->arg1; /* the fd */ + ti->arg3 = kd->arg2; /* bottom half address */ + ti->arg5 = kd->arg3; /* bottom half size */ + break; + case BSC_mmap_extended2: + if ((ti = find_thread(thread, BSC_mmap)) == (struct th_info *)0) + return; + ti->arg2 = kd->arg1; /* top half address */ + ti->arg4 = kd->arg2; /* top half size */ + ti->arg6 = kd->arg3; /* top half file offset */ + ti->arg7 = kd->arg4; /* bottom half file offset */ + break; + case BSC_msync_extended: + if ((ti = find_thread(thread, BSC_msync)) == (struct th_info *)0) { + if ((ti = find_thread(thread, BSC_msync_nocancel)) == (struct th_info *)0) + return; + } + ti->arg4 = kd->arg1; /* top half address */ + ti->arg5 = kd->arg2; /* top half size */ + break; case BSC_pread_extended: - if ((ti = find_thread(thread, BSC_pread)) == (struct th_info *)0) - return; + if ((ti = find_thread(thread, BSC_pread)) == (struct th_info *)0) { + if ((ti = find_thread(thread, BSC_pread_nocancel)) == (struct th_info *)0) + return; + } ti->arg1 = kd->arg1; /* the fd */ ti->arg2 = kd->arg2; /* nbytes */ ti->arg3 = kd->arg3; /* top half offset */ ti->arg4 = kd->arg4; /* bottom half offset */ break; case BSC_pwrite_extended: - if ((ti = find_thread(thread, BSC_pwrite)) == (struct th_info *)0) - return; + if ((ti = find_thread(thread, BSC_pwrite)) == (struct th_info *)0) { + if ((ti = find_thread(thread, BSC_pwrite_nocancel)) == (struct th_info *)0) + return; + } ti->arg1 = kd->arg1; /* the fd */ ti->arg2 = kd->arg2; /* nbytes */ ti->arg3 = kd->arg3; /* top half offset */ @@ -2254,200 +2614,903 @@ extend_syscall(int thread, int type, kd_buf *kd, char *name, double now) } } + void -exit_syscall(char *sc_name, int thread, int type, int error, int retval, - int has_fd, int has_ret, double now) +exit_syscall(char *sc_name, int thread, int type, int arg1, int arg2, int arg3, int arg4, + int format, double now) { - struct th_info *ti; + struct th_info *ti; - if ((ti = find_thread(thread, type)) == (struct th_info *)0) - return; + if ((ti = find_thread(thread, type)) == (struct th_info *)0) + return; + + if (check_filter_mode(ti, type, arg1, arg2, sc_name)) + format_print(ti, sc_name, thread, type, arg1, arg2, arg3, arg4, format, now, ti->stime, ti->waited, (char *)ti->pathname, NULL); - if (check_filter_mode(ti, type, error, retval, sc_name)) - format_print(ti, sc_name, thread, type, error, retval, has_fd, has_ret, now, ti->stime, ti->waited, (char *)ti->pathname, NULL); + if ((type & CLASS_MASK) == FILEMGR_BASE) { + ti->in_filemgr = 0; - if (ti == &th_state[cur_max - 1]) - cur_max--; - ti->thread = 0; + if (filemgr_in_progress > 0) + filemgr_in_progress--; + } + destroy_thread(ti); } +void +get_mode_nibble(char * buf, int smode, int special, char x_on, char x_off) +{ + if (smode & 04) + buf[0] = 'r'; + if (smode & 02) + buf[1] = 'w'; + if (smode & 01) { + if (special) + buf[2] = x_on; + else + buf[2] = 'x'; + } else { + if (special) + buf[2] = x_off; + } +} + void -format_print(struct th_info *ti, char *sc_name, int thread, int type, int error, int retval, - int has_fd, int has_ret, double now, double stime, int waited, char *pathname, struct diskio *dio) +get_mode_string(int mode, char *buf) { - int secs; - int usecs; - int nopadding; - long long l_usecs; - long curr_time; - char *command_name; - kd_threadmap *map; - kd_threadmap *find_thread_map(); - int len = 0; - int clen = 0; - char *framework_name; - char buf[MAXWIDTH]; - - command_name = ""; - - if (dio) - command_name = dio->issuing_command; - else { - if ((map = find_thread_map(thread))) - command_name = map->command; - } - - l_usecs = (long long)(now / divisor); - secs = l_usecs / 1000000; - curr_time = bias_secs + secs; - sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11])); - clen = strlen(buf); - - if (columns > MAXCOLS || wideflag) { - nopadding = 0; - usecs = l_usecs - (long long)((long long)secs * 1000000); - sprintf(&buf[clen], ".%03ld", (long)usecs / 1000); - clen = strlen(buf); - - if ((type >> 24) != FILEMGR_CLASS) { - if (find_thread(thread, -1)) { - sprintf(&buf[clen], " "); - clen = strlen(buf); - nopadding = 1; - } - } - } else - nopadding = 1; + memset(buf, '-', 9); + buf[9] = '\0'; + + get_mode_nibble(&buf[6], mode, (mode & 01000), 't', 'T'); + get_mode_nibble(&buf[3], (mode>>3), (mode & 02000), 's', 'S'); + get_mode_nibble(&buf[0], (mode>>6), (mode & 04000), 's', 'S'); +} + + +int clip_64bit(char *s, uint64_t value) +{ + int clen = 0; + + if ( (value & 0xff00000000000000LL) ) + clen = printf("%s0x%16.16qx", s, value); + else if ( (value & 0x00ff000000000000LL) ) + clen = printf("%s0x%14.14qx ", s, value); + else if ( (value & 0x0000ff0000000000LL) ) + clen = printf("%s0x%12.12qx ", s, value); + else if ( (value & 0x000000ff00000000LL) ) + clen = printf("%s0x%10.10qx ", s, value); + else + clen = printf("%s0x%8.8qx ", s, value); + + return (clen); +} + + +void +format_print(struct th_info *ti, char *sc_name, int thread, int type, int arg1, int arg2, int arg3, int arg4, + int format, double now, double stime, int waited, char *pathname, struct diskio *dio) +{ + int secs; + int usecs; + int nopadding = 0; + long long l_usecs; + long curr_time; + char *command_name; + kd_threadmap *map; + kd_threadmap *find_thread_map(); + int in_filemgr = 0; + int len = 0; + int clen = 0; + int tlen = 0; + int class; + uint64_t user_addr; + uint64_t user_size; + char *framework_name; + char *p1; + char *p2; + char buf[MAXWIDTH]; + command_name = ""; + int need_msec_update = 0; + static char timestamp[32]; + static int last_timestamp = 0; + static int timestamp_len = 0; + static int last_msec = 0; + + + class = type >> 24; + + if (dio) + command_name = dio->issuing_command; + else { + if (map_is_the_same && thread == last_thread) + map = last_map; + else { + if ((map = find_thread_map(thread))) { + last_map = map; + last_thread = thread; + map_is_the_same = 1; + } + } + if (map) + command_name = map->command; + } + l_usecs = (long long)(now / divisor); + secs = l_usecs / 1000000; + curr_time = bias_secs + secs; + + if (last_timestamp != curr_time) { + timestamp_len = sprintf(timestamp, "%-8.8s", &(ctime(&curr_time)[11])); + last_timestamp = curr_time; + need_msec_update = 1; + } + if (columns > MAXCOLS || wideflag) { + int msec; - if (((type >> 24) == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag)) - sprintf(&buf[clen], " %-18.18s", sc_name); - else - sprintf(&buf[clen], " %-15.15s", sc_name); + tlen = timestamp_len; + nopadding = 0; + msec = (l_usecs - (long long)((long long)secs * 1000000)) / 1000; - clen = strlen(buf); + if (msec != last_msec || need_msec_update) { + sprintf(×tamp[tlen], ".%03ld", (long)msec); + last_msec = msec; + } + tlen += 4; + + timestamp[tlen] = '\0'; + + if (filemgr_in_progress) { + if (class != FILEMGR_CLASS) { + if (find_thread(thread, -1)) { + in_filemgr = 1; + } + } + } + } else + nopadding = 1; + + if ((class == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag)) + clen = printf("%s %-20.20s", timestamp, sc_name); + else if (in_filemgr) + clen = printf("%s %-15.15s", timestamp, sc_name); + else + clen = printf("%s %-17.17s", timestamp, sc_name); - framework_name = (char *)0; - - if (columns > MAXCOLS || wideflag) { - if (has_ret == 7) { - sprintf(&buf[clen], " D=0x%8.8x", dio->blkno); - - clen = strlen(buf); - - if (dio->io_errno) - sprintf(&buf[clen], " [%3d] ", dio->io_errno); - else - sprintf(&buf[clen], " B=0x%-6x /dev/%s", dio->iosize, find_disk_name(dio->dev)); - } else { + framework_name = (char *)0; + + if (columns > MAXCOLS || wideflag) { - off_t offset_reassembled = 0LL; + off_t offset_reassembled = 0LL; - if (has_fd == 2 && error == 0) - sprintf(&buf[clen], " F=%-3d", retval); - else if (has_fd == 1) - sprintf(&buf[clen], " F=%-3d", ti->arg1); - else if (has_ret != 2 && has_ret != 6) - sprintf(&buf[clen], " "); - - clen = strlen(buf); - - if (has_ret == 2 || has_ret == 6) - framework_name = lookup_name(retval); - - if (error && has_ret != 6) - sprintf(&buf[clen], "[%3d] ", error); - else if (has_ret == 3) - sprintf(&buf[clen], "O=0x%8.8x", ti->arg3); - else if (has_ret == 5) - sprintf(&buf[clen], "O=0x%8.8x", retval); - else if (has_ret == 2) - sprintf(&buf[clen], " A=0x%8.8x ", retval); - else if (has_ret == 6) - sprintf(&buf[clen], " A=0x%8.8x B=0x%-8x", retval, error); - else if (has_ret == 1) - sprintf(&buf[clen], " B=0x%-6x", retval); - else if (has_ret == 4) - sprintf(&buf[clen], "B=0x%-8x", retval); - else if (has_ret == 8) /* BSC_select */ - sprintf(&buf[clen], " S=%-3d ", retval); - else if (has_ret == 9) /* BSC_pread, BSC_pwrite */ - { - sprintf(&buf[clen], "B=0x%-8x", retval); - clen = strlen(buf); - offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg4); - if ((offset_reassembled >> 32) != 0) - sprintf(&buf[clen], "O=0x%16.16qx", (off_t)offset_reassembled); - else - sprintf(&buf[clen], "O=0x%8.8qx", (off_t)offset_reassembled); - } - else - sprintf(&buf[clen], " "); - } - clen = strlen(buf); - } - printf("%s", buf); - - /* - Calculate space available to print pathname - */ - if (columns > MAXCOLS || wideflag) - clen = columns - (clen + 13 + 20); - else - clen = columns - (clen + 13 + 12); - - if ((type >> 24) != FILEMGR_CLASS && !nopadding) - clen -= 3; - - if (framework_name) - sprintf(&buf[0], " %s ", framework_name); - else - sprintf(&buf[0], " %s ", pathname); - len = strlen(buf); - - if (clen > len) - { - /* - Add null padding if column length - is wider than the pathname length. - */ - memset(&buf[len], ' ', clen - len); - buf[clen] = '\0'; - printf("%s", buf); - } - else if (clen == len) - { - printf("%s", buf); - } - else if ((clen > 0) && (clen < len)) - { - /* This prints the tail end of the pathname */ - buf[len-clen] = ' '; - printf("%s", &buf[len - clen]); - } - - usecs = (unsigned long)((now - stime) / divisor); - secs = usecs / 1000000; - usecs -= secs * 1000000; - - if ((type >> 24) != FILEMGR_CLASS && !nopadding) - printf(" "); + switch (format) { + + case FMT_DEFAULT: + /* + * pathname based system calls or + * calls with no fd or pathname (i.e. sync) + */ + if (arg1) + clen += printf(" [%3d] ", arg1); + else + clen += printf(" "); + break; + + case FMT_FD: + /* + * fd based system call... no I/O + */ + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d", ti->arg1); + break; + + case FMT_FD_2: + /* + * accept, dup, dup2 + */ + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d F=%-3d", ti->arg1, arg2); + break; + + case FMT_FD_IO: + /* + * system calls with fd's that return an I/O completion count + */ + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d B=0x%-6x", ti->arg1, arg2); + break; + + case FMT_PGIN: + /* + * pagein + */ + user_addr = ((uint64_t)arg2 << 32) | (uint32_t)arg3; + framework_name = lookup_name(user_addr); + clen += clip_64bit(" A=", user_addr); + break; + + case FMT_CACHEHIT: + /* + * cache hit + */ + user_addr = ((uint64_t)arg2 << 32) | (uint32_t)arg3; + + framework_name = lookup_name(user_addr); + clen += clip_64bit(" A=", user_addr); + break; + + case FMT_PGOUT: + /* + * pageout + */ + clen += printf(" B=0x%-8x", arg2); + break; + + case FMT_DISKIO: + /* + * physical disk I/O + */ + if (dio->io_errno) + clen += printf(" D=0x%8.8x [%3d]", dio->blkno, dio->io_errno); + else + clen += printf(" D=0x%8.8x B=0x%-6x /dev/%s", dio->blkno, dio->iosize, find_disk_name(dio->dev)); + break; + + case FMT_MSYNC: + { + /* + * msync + */ + int mlen = 0; + + buf[0] = '\0'; + + if (ti->arg3 & MS_ASYNC) + mlen += sprintf(&buf[mlen], "MS_ASYNC | "); + else + mlen += sprintf(&buf[mlen], "MS_SYNC | "); + + if (ti->arg3 & MS_INVALIDATE) + mlen += sprintf(&buf[mlen], "MS_INVALIDATE | "); + if (ti->arg3 & MS_KILLPAGES) + mlen += sprintf(&buf[mlen], "MS_KILLPAGES | "); + if (ti->arg3 & MS_DEACTIVATE) + mlen += sprintf(&buf[mlen], "MS_DEACTIVATE | "); + + if (ti->arg3 & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE | MS_KILLPAGES | MS_DEACTIVATE)) + mlen += sprintf(&buf[mlen], "UNKNOWN | "); + + if (mlen) + buf[mlen - 3] = '\0'; + + if (arg1) + clen += printf(" [%3d]", arg1); + + user_addr = (((off_t)(unsigned int)(ti->arg4)) << 32) | (unsigned int)(ti->arg1); + clen += clip_64bit(" A=", user_addr); + + user_size = (((off_t)(unsigned int)(ti->arg5)) << 32) | (unsigned int)(ti->arg2); + + clen += printf(" B=0x%-16qx <%s>", user_size, buf); + + break; + } + + case FMT_FCNTL: + { + /* + * fcntl + */ + char *p = NULL; + + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d", ti->arg1); + + switch(ti->arg2) { + + case F_DUPFD: + p = "DUPFD"; + break; + + case F_GETFD: + p = "GETFD"; + break; + + case F_SETFD: + p = "SETFD"; + break; + + case F_GETFL: + p = "GETFL"; + break; + + case F_SETFL: + p = "SETFL"; + break; + + case F_GETOWN: + p = "GETOWN"; + break; + + case F_SETOWN: + p = "SETOWN"; + break; + + case F_GETLK: + p = "GETLK"; + break; + + case F_SETLK: + p = "SETLK"; + break; + + case F_SETLKW: + p = "SETLKW"; + break; + + case F_PREALLOCATE: + p = "PREALLOCATE"; + break; + + case F_SETSIZE: + p = "SETSIZE"; + break; + + case F_RDADVISE: + p = "RDADVISE"; + break; + + case F_GETPATH: + p = "GETPATH"; + break; + + case F_FULLFSYNC: + p = "FULLFSYNC"; + break; + + case F_PATHPKG_CHECK: + p = "PATHPKG_CHECK"; + break; + + case F_NOCACHE: + if (ti->arg3) + p = "CACHING OFF"; + else + p = "CACHING ON"; + break; + + } + if (p) + clen += printf(" <%s>", p); + else + clen += printf(" ", ti->arg2); + + break; + } + + case FMT_IOCTL: + { + /* + * fcntl + */ + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d", ti->arg1); + + clen += printf(" ", ti->arg2); + + break; + } + + case FMT_SELECT: + /* + * select + */ + if (arg1) + clen += printf(" [%3d]", arg1); + else + clen += printf(" S=%-3d", arg2); + + break; + + case FMT_LSEEK: + case FMT_PREAD: + /* + * pread, pwrite, lseek + */ + clen += printf(" F=%-3d", ti->arg1); + + if (arg1) + clen += printf("[%3d] ", arg1); + else { + if (format == FMT_PREAD) + clen += printf(" B=0x%-8x ", arg2); + else + clen += printf(" "); + } + if (format == FMT_PREAD) + offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg4); + else +#ifdef __ppc__ + offset_reassembled = (((off_t)(unsigned int)(arg2)) << 32) | (unsigned int)(arg3); +#else + offset_reassembled = (((off_t)(unsigned int)(arg3)) << 32) | (unsigned int)(arg2); +#endif + clen += clip_64bit("O=", offset_reassembled); + + if (format == FMT_LSEEK) { + char *mode; + + if (ti->arg4 == SEEK_SET) + mode = "SEEK_SET"; + else if (ti->arg4 == SEEK_CUR) + mode = "SEEK_CUR"; + else if (ti->arg4 == SEEK_END) + mode = "SEEK_END"; + else + mode = "UNKNOWN"; + + clen += printf(" <%s>", mode); + } + break; + + case FMT_MMAP: + /* + * mmap + */ + clen += printf(" F=%-3d ", ti->arg1); + + if (arg1) + clen += printf("[%3d] ", arg1); + else { + + user_addr = (((off_t)(unsigned int)(ti->arg2)) << 32) | (unsigned int)(ti->arg3); + + clen += clip_64bit("A=", user_addr); + + offset_reassembled = (((off_t)(unsigned int)(ti->arg6)) << 32) | (unsigned int)(ti->arg7); + + clen += clip_64bit("O=", offset_reassembled); + + user_size = (((off_t)(unsigned int)(ti->arg4)) << 32) | (unsigned int)(ti->arg5); + + clen += printf("B=0x%-16qx", user_size); + + clen += printf(" <"); + + if (ti->arg8 & PROT_READ) + clen += printf("READ"); + + if (ti->arg8 & PROT_WRITE) + clen += printf("|WRITE"); + + if (ti->arg8 & PROT_EXEC) + clen += printf("|EXEC"); + + clen += printf(">"); + } + break; + + case FMT_TRUNC: + case FMT_FTRUNC: + /* + * ftruncate, truncate + */ + if (format == FMT_FTRUNC) + clen += printf(" F=%-3d", ti->arg1); + else + clen += printf(" "); + + if (arg1) + clen += printf("[%3d]", arg1); + +#ifdef __ppc__ + offset_reassembled = (((off_t)(unsigned int)(ti->arg2)) << 32) | (unsigned int)(ti->arg3); +#else + offset_reassembled = (((off_t)(unsigned int)(ti->arg3)) << 32) | (unsigned int)(ti->arg2); +#endif + clen += clip_64bit(" O=", offset_reassembled); + + nopadding = 1; + break; + + case FMT_FCHFLAGS: + case FMT_CHFLAGS: + { + /* + * fchflags, chflags + */ + int mlen = 0; + + if (format == FMT_FCHFLAGS) { + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d", ti->arg1); + } else { + if (arg1) + clen += printf(" [%3d] ", arg1); + } + buf[mlen++] = ' '; + buf[mlen++] = '<'; + + if (ti->arg2 & UF_NODUMP) + mlen += sprintf(&buf[mlen], "UF_NODUMP | "); + if (ti->arg2 & UF_IMMUTABLE) + mlen += sprintf(&buf[mlen], "UF_IMMUTABLE | "); + if (ti->arg2 & UF_APPEND) + mlen += sprintf(&buf[mlen], "UF_APPEND | "); + if (ti->arg2 & UF_OPAQUE) + mlen += sprintf(&buf[mlen], "UF_OPAQUE | "); + if (ti->arg2 & SF_ARCHIVED) + mlen += sprintf(&buf[mlen], "SF_ARCHIVED | "); + if (ti->arg2 & SF_IMMUTABLE) + mlen += sprintf(&buf[mlen], "SF_IMMUTABLE | "); + if (ti->arg2 & SF_APPEND) + mlen += sprintf(&buf[mlen], "SF_APPEND | "); + + if (ti->arg2 == 0) + mlen += sprintf(&buf[mlen], "CLEAR_ALL_FLAGS | "); + else if (ti->arg2 & ~(UF_NODUMP | UF_IMMUTABLE | UF_APPEND | SF_ARCHIVED | SF_IMMUTABLE | SF_APPEND)) + mlen += sprintf(&buf[mlen], "UNKNOWN | "); + + if (mlen >= 3) + mlen -= 3; + + buf[mlen++] = '>'; + buf[mlen] = '\0'; + + if (mlen < 21) { + memset(&buf[mlen], ' ', 21 - mlen); + mlen = 21; + } + clen += printf("%s", buf); + + nopadding = 1; + break; + } + + case FMT_FCHMOD: + case FMT_FCHMOD_EXT: + case FMT_CHMOD: + case FMT_CHMOD_EXT: + { + /* + * fchmod, fchmod_extended, chmod, chmod_extended + */ + int mode; + + if (format == FMT_FCHMOD || format == FMT_FCHMOD_EXT) { + if (arg1) + clen += printf(" F=%-3d[%3d] ", ti->arg1, arg1); + else + clen += printf(" F=%-3d ", ti->arg1); + } else { + if (arg1) + clen += printf(" [%3d] ", arg1); + else + clen += printf(" "); + } + if (format == FMT_FCHMOD || format == FMT_CHMOD) + mode = ti->arg2; + else + mode = ti->arg4; + + get_mode_string(mode, &buf[0]); + + if (arg1 == 0) + clen += printf("<%s> ", buf); + else + clen += printf("<%s>", buf); + break; + } + + case FMT_ACCESS: + { + /* + * access + */ + char mode[4]; + + memset(mode, '_', 4); + mode[4] = '\0'; + + if (ti->arg2 & R_OK) + mode[0] = 'R'; + if (ti->arg2 & W_OK) + mode[1] = 'W'; + if (ti->arg2 & X_OK) + mode[2] = 'X'; + if (ti->arg2 == F_OK) + mode[3] = 'F'; + + if (arg1) + clen += printf(" [%3d] (%s) ", arg1, mode); + else + clen += printf(" (%s) ", mode); + + nopadding = 1; + break; + } + + case FMT_OPEN: + { + /* + * open + */ + char mode[7]; + + memset(mode, '_', 6); + mode[6] = '\0'; + + if (ti->arg2 & O_RDWR) { + mode[0] = 'R'; + mode[1] = 'W'; + } else if (ti->arg2 & O_WRONLY) + mode[1] = 'W'; + else + mode[0] = 'R'; + + if (ti->arg2 & O_CREAT) + mode[2] = 'C'; + + if (ti->arg2 & O_APPEND) + mode[3] = 'A'; + + if (ti->arg2 & O_TRUNC) + mode[4] = 'T'; + + if (ti->arg2 & O_EXCL) + mode[5] = 'E'; + + if (arg1) + clen += printf(" [%3d] (%s) ", arg1, mode); + else + clen += printf(" F=%-3d (%s) ", arg2, mode); + + nopadding = 1; + break; + } + + case FMT_SOCKET: + { + /* + * socket + * + */ + char *domain; + char *type; + + switch (ti->arg1) { + + case AF_UNIX: + domain = "AF_UNIX"; + break; + + case AF_INET: + domain = "AF_INET"; + break; + + case AF_ISO: + domain = "AF_ISO"; + break; + + case AF_NS: + domain = "AF_NS"; + break; + + case AF_IMPLINK: + domain = "AF_IMPLINK"; + break; + + default: + domain = "UNKNOWN"; + break; + } + + switch (ti->arg2) { + + case SOCK_STREAM: + type = "SOCK_STREAM"; + break; + + case SOCK_DGRAM: + type = "SOCK_DGRAM"; + break; + + case SOCK_RAW: + type = "SOCK_RAW"; + break; + + case SOCK_SEQPACKET: + type = "SOCK_SEQPACKET"; + break; + + case SOCK_RDM: + type = "SOCK_RDM"; + break; + + default: + type = "UNKNOWN"; + break; + } + + if (arg1) + clen += printf(" [%3d] <%s, %s, 0x%x>", arg1, domain, type, ti->arg3); + else + clen += printf(" F=%-3d <%s, %s, 0x%x>", arg2, domain, type, ti->arg3); + break; + } + + case FMT_AIO_FSYNC: + { + /* + * aio_fsync [errno] AIOCBP OP + */ + char *op; + + if (ti->arg1 == O_SYNC || ti->arg1 == 0) + op = "AIO_FSYNC"; +#if O_DSYNC + else if (ti->arg1 == O_DSYNC) + op = "AIO_DSYNC"; +#endif + else + op = "UNKNOWN"; + + if (arg1) + clen += printf(" [%3d] P=0x%8.8x <%s>", arg1, ti->arg2, op); + else + clen += printf(" P=0x%8.8x <%s>", ti->arg2, op); + break; + } + + case FMT_AIO_RETURN: + /* + * aio_return [errno] AIOCBP IOSIZE + */ + if (arg1) + clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg1); + else + clen += printf(" P=0x%8.8x B=0x%-8x", ti->arg1, arg2); + break; + + case FMT_AIO_SUSPEND: + /* + * aio_suspend [errno] NENTS + */ + if (arg1) + clen += printf(" [%3d] N=%d", arg1, ti->arg2); + else + clen += printf(" N=%d", ti->arg2); + break; + + case FMT_AIO_CANCEL: + /* + * aio_cancel [errno] FD or AIOCBP (if non-null) + */ + if (ti->arg2) { + if (arg1) + clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg2); + else + clen += printf(" P=0x%8.8x", ti->arg2); + } else { + if (arg1) + clen += printf(" F=%-3d[%3d]", ti->arg1, arg1); + else + clen += printf(" F=%-3d", ti->arg1); + } + break; + + case FMT_AIO: + /* + * aio_error, aio_read, aio_write [errno] AIOCBP + */ + if (arg1) + clen += printf(" [%3d] P=0x%8.8x", arg1, ti->arg1); + else + clen += printf(" P=0x%8.8x", ti->arg1); + break; + + case FMT_LIO_LISTIO: + { + /* + * lio_listio [errno] NENTS MODE + */ + char *op; + + if (ti->arg1 == LIO_NOWAIT) + op = "LIO_NOWAIT"; + else if (ti->arg1 == LIO_WAIT) + op = "LIO_WAIT"; + else + op = "UNKNOWN"; + + if (arg1) + clen += printf(" [%3d] N=%d <%s>", arg1, ti->arg3, op); + else + clen += printf(" N=%d <%s>", ti->arg3, op); + break; + } + + } + } + + /* + * Calculate space available to print pathname + */ + if (columns > MAXCOLS || wideflag) + clen = columns - (clen + 14 + 20); + else + clen = columns - (clen + 14 + 12); + + if (class != FILEMGR_CLASS && !nopadding) + clen -= 3; + + if (framework_name) + len = sprintf(&buf[0], " %s ", framework_name); + else if (*pathname != '\0') + len = sprintf(&buf[0], " %s ", pathname); + else + len = 0; + + if (clen > len) { + /* + * Add null padding if column length + * is wider than the pathname length. + */ + memset(&buf[len], ' ', clen - len); + buf[clen] = '\0'; + + pathname = buf; + + } else if (clen == len) { + pathname = buf; + + } else if ((clen > 0) && (clen < len)) { + /* + * This prints the tail end of the pathname + */ + buf[len-clen] = ' '; + + pathname = &buf[len - clen]; + + } else { + pathname = ""; + } + + /* + * fudge some additional system call overhead + * that currently isn't tracked... this also + * insures that we see a minimum of 1 us for + * an elapsed time + */ + usecs = (unsigned long)(((now - stime) + (divisor-1)) / divisor); + secs = usecs / 1000000; + usecs -= secs * 1000000; + + if (class != FILEMGR_CLASS && !nopadding) + p1 = " "; + else + p1 = ""; - printf(" %2ld.%06ld", (unsigned long)secs, (unsigned long)usecs); - - if (waited) - printf(" W"); - else - printf(" "); - - if (columns > MAXCOLS || wideflag) - printf(" %-20.20s", command_name); - else - printf(" %-12.12s", command_name); - - printf("\n"); - fflush (0); + if (waited) + p2 = " W"; + else + p2 = " "; + + if (columns > MAXCOLS || wideflag) + printf("%s%s %3ld.%06ld%s %-20.20s\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name); + else + printf("%s%s %3ld.%06ld%s %-12.12s\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name); } int @@ -2458,9 +3521,9 @@ char *s; set_enable(0); /* - This flag is turned off when calling - quit() due to a set_remove() failure. - */ + * This flag is turned off when calling + * quit() due to a set_remove() failure. + */ if (set_remove_flag) set_remove(); @@ -2609,11 +3672,11 @@ void create_map_entry(int thread, int pid, char *command) if (!map) { - /* If reach here, then this is a new thread and + /* + * If reach here, then this is a new thread and * there are no invalid entries to reuse * Double the size of the thread map table. */ - n = total_threads * 2; mapptr = (kd_threadmap *) realloc(mapptr, n * sizeof(kd_threadmap)); bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap)); @@ -2632,10 +3695,10 @@ void create_map_entry(int thread, int pid, char *command) map->valid = 1; map->thread = thread; /* - The trace entry that returns the command name will hold - at most, MAXCOMLEN chars, and in that case, is not - guaranteed to be null terminated. - */ + * The trace entry that returns the command name will hold + * at most, MAXCOMLEN chars, and in that case, is not + * guaranteed to be null terminated. + */ (void)strncpy (map->command, command, MAXCOMLEN); map->command[MAXCOMLEN] = '\0'; @@ -2703,6 +3766,9 @@ kill_thread_map(int thread) kd_threadmap *map; fd_threadmap *fdmap; + if (thread == last_thread) + map_is_the_same = 0; + if ((map = find_thread_map(thread))) { map->valid = 0; map->thread = 0; @@ -2743,7 +3809,8 @@ argtopid(str) if(kp_buffer[i].kp_proc.p_stat == 0) continue; else { - if(!strcmp(str, kp_buffer[i].kp_proc.p_comm)) + if(!strncmp(str, kp_buffer[i].kp_proc.p_comm, + sizeof(kp_buffer[i].kp_proc.p_comm) -1)) pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid; } } @@ -2756,29 +3823,29 @@ argtopid(str) -char *lookup_name(unsigned long addr) +char *lookup_name(uint64_t user_addr) { register int i; register int start, last; - - - if (numFrameworks == 0 || addr < frameworkInfo[0].address || addr > frameworkInfo[numFrameworks].address) - return (0); - - start = 0; - last = numFrameworks; - - for (i = numFrameworks / 2; i >= 0 && i < numFrameworks; ) { - - if (addr >= frameworkInfo[i].address && addr < frameworkInfo[i+1].address) - return(frameworkInfo[i].name); - - if (addr >= frameworkInfo[i].address) { - start = i; - i = start + ((last - i) / 2); - } else { - last = i; - i = start + ((i - start) / 2); + + if (numFrameworks && ((user_addr >= framework32.b_address && user_addr < framework32.e_address) || + (user_addr >= framework64.b_address && user_addr < framework64.e_address))) { + + start = 0; + last = numFrameworks; + + for (i = numFrameworks / 2; i >= 0 && i < numFrameworks; ) { + + if (user_addr >= frameworkInfo[i].b_address && user_addr < frameworkInfo[i].e_address) + return(frameworkInfo[i].name); + + if (user_addr >= frameworkInfo[i].b_address) { + start = i; + i = start + ((last - i) / 2); + } else { + last = i; + i = start + ((i - start) / 2); + } } } return (0); @@ -2793,167 +3860,178 @@ static int compareFrameworkAddress(const void *aa, const void *bb) LibraryInfo *a = (LibraryInfo *)aa; LibraryInfo *b = (LibraryInfo *)bb; - if (a->address < b->address) return -1; - if (a->address == b->address) return 0; + if (a->b_address < b->b_address) return -1; + if (a->b_address == b->b_address) return 0; return 1; } -int scanline(char *inputstring,char **argv) +int scanline(char *inputstring, char **argv, int maxtokens) { int n = 0; - char **ap = argv, *p, *val; + char **ap = argv, *p, *val; - for (p = inputstring; p != NULL; ) + for (p = inputstring; n < maxtokens && p != NULL; ) { while ((val = strsep(&p, " \t")) != NULL && *val == '\0'); *ap++ = val; - n++; + n++; } *ap = 0; return n; } -int ReadSegAddrTable() +int ReadSharedCacheMap(const char *path, LibraryRange *lr) { - char buf[1024]; + char buf[1024]; + + FILE *fd; + uint64_t b_frameworkAddress, b_frameworkDataAddress; + uint64_t e_frameworkAddress, e_frameworkDataAddress; + char frameworkName[256]; + char *tokens[64]; + int ntokens; + char *substring,*ptr; - FILE *fd; - unsigned long frameworkAddress, frameworkDataAddress, previousFrameworkAddress; - char frameworkName[256]; - char *tokens[64]; - int ntokens; - char *substring,*ptr; - int founddylib = 0; + bzero(buf, sizeof(buf)); + bzero(tokens, sizeof(tokens)); + + lr->b_address = 0; + lr->e_address = 0; - bzero(buf, sizeof(buf)); - bzero(tokens, sizeof(tokens)); - numFrameworks = 0; + if ((fd = fopen(path, "r")) == 0) + { + return 0; + } + while (fgets(buf, 1023, fd)) { + if (strncmp(buf, "mapping", 7)) + break; + } + buf[strlen(buf)-1] = 0; + + frameworkName[0] = 0; - if ((fd = fopen(seg_addr_table, "r")) == 0) - { - return 0; - } - fgets(buf, 1023, fd); + for (;;) { + b_frameworkAddress = 0; + b_frameworkDataAddress = 0; + e_frameworkAddress = 0; + e_frameworkDataAddress = 0; - if (*buf == '#') - { - founddylib = 0; - frameworkName[0] = 0; - previousFrameworkAddress = 0; - - while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2)) - { - /* - * Get rid of EOL - */ - buf[strlen(buf)-1] = 0; - - if (strncmp(buf, "# dyld:", 7) == 0) { - /* - * the next line in the file will contain info about dyld + /* + * Extract lib name from path name */ - founddylib = 1; - continue; - } - /* - * This is a split library line: parse it into 3 tokens - */ - ntokens = scanline(buf, tokens); + if ((substring = strrchr(buf, '.'))) + { + /* + * There is a ".": name is whatever is between the "/" around the "." + */ + while ( *substring != '/') { /* find "/" before "." */ + substring--; + } + substring++; + strncpy(frameworkName, substring, 256); /* copy path from "/" */ + frameworkName[255] = 0; + substring = frameworkName; + + while ( *substring != '/' && *substring) /* find "/" after "." and stop string there */ + substring++; + *substring = 0; + } + else + { + /* + * No ".": take segment after last "/" + */ + ptr = buf; + substring = ptr; + + while (*ptr) + { + if (*ptr == '/') + substring = ptr + 1; + ptr++; + } + strncpy(frameworkName, substring, 256); + frameworkName[255] = 0; + } + while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2)) + { + /* + * Get rid of EOL + */ + buf[strlen(buf)-1] = 0; - if (ntokens < 3) - continue; + ntokens = scanline(buf, tokens, 64); - frameworkAddress = strtoul(tokens[0], 0, 16); - frameworkDataAddress = strtoul(tokens[1], 0, 16); + if (ntokens < 4) + continue; - if (founddylib) { - /* - * dyld entry is of a different form from the std split library - * it consists of a base address and a size instead of a code - * and data base address + if (strncmp(tokens[0], "__TEXT", 6) == 0) { + b_frameworkAddress = strtoull(tokens[1], 0, 16); + e_frameworkAddress = strtoull(tokens[3], 0, 16); + } else if (strncmp(tokens[0], "__DATA", 6) == 0) { + b_frameworkDataAddress = strtoull(tokens[1], 0, 16); + e_frameworkDataAddress = strtoull(tokens[3], 0, 16); + } else if (strncmp(tokens[0], "__LINKEDIT", 10) == 0) + break; + } + /* + * Make sure that we have 2 addresses */ - frameworkInfo[numFrameworks].address = frameworkAddress; - frameworkInfo[numFrameworks+1].address = frameworkAddress + frameworkDataAddress; + if (b_frameworkAddress && b_frameworkDataAddress) { - frameworkInfo[numFrameworks].name = (char *)"dylib"; - frameworkInfo[numFrameworks+1].name = (char *)0; + frameworkInfo[numFrameworks].b_address = b_frameworkAddress; + frameworkInfo[numFrameworks].e_address = e_frameworkAddress; - numFrameworks += 2; - founddylib = 0; + frameworkInfo[numFrameworks+1].b_address = b_frameworkDataAddress; + frameworkInfo[numFrameworks+1].e_address = e_frameworkDataAddress; - continue; - } - - /* - * Make sure that we have 2 addresses and a path - */ - if (!frameworkAddress) - continue; - if (!frameworkDataAddress) - continue; - if (*tokens[2] != '/') - continue; - if (frameworkAddress == previousFrameworkAddress) - continue; - previousFrameworkAddress = frameworkAddress; - - /* - * Extract lib name from path name - */ - if ((substring = strrchr(tokens[2], '.'))) - { - /* - * There is a ".": name is whatever is between the "/" around the "." - */ - while ( *substring != '/') { /* find "/" before "." */ - substring--; - } - substring++; - strcpy(frameworkName, substring); /* copy path from "/" */ - substring = frameworkName; + frameworkInfo[numFrameworks].name = (char *)malloc(strlen(frameworkName) + 1); + strcpy(frameworkInfo[numFrameworks].name, frameworkName); + frameworkInfo[numFrameworks+1].name = frameworkInfo[numFrameworks].name; - while ( *substring != '/' && *substring) /* find "/" after "." and stop string there */ - substring++; - *substring = 0; - } - else - { - /* - * No ".": take segment after last "/" - */ - ptr = tokens[2]; - substring = ptr; + numFrameworks += 2; +#if 0 + printf("%s: %qx-%qx %qx-%qx\n", frameworkName, b_frameworkAddress, e_frameworkAddress, b_frameworkDataAddress, e_frameworkDataAddress); +#endif + if (lr->b_address == 0) + lr->b_address = b_frameworkAddress; - while (*ptr) - { - if (*ptr == '/') - substring = ptr + 1; - ptr++; + if (b_frameworkAddress < lr->b_address) + lr->b_address = b_frameworkAddress; + + if (b_frameworkDataAddress < lr->b_address) + lr->b_address = b_frameworkDataAddress; + + if (e_frameworkAddress > lr->e_address) + lr->e_address = e_frameworkAddress; + + if (e_frameworkDataAddress > lr->e_address) + lr->e_address = e_frameworkDataAddress; } - strcpy(frameworkName, substring); - } - frameworkInfo[numFrameworks].address = frameworkAddress; - frameworkInfo[numFrameworks+1].address = frameworkDataAddress; + if (fgets(buf, 1023, fd) == 0) + break; - frameworkInfo[numFrameworks].name = (char *)malloc(strlen(frameworkName) + 1); - strcpy(frameworkInfo[numFrameworks].name, frameworkName); - frameworkInfo[numFrameworks+1].name = frameworkInfo[numFrameworks].name; + buf[strlen(buf)-1] = 0; + } + fclose(fd); - numFrameworks += 2; - } - } - frameworkInfo[numFrameworks].address = frameworkInfo[numFrameworks - 1].address + 0x800000; - frameworkInfo[numFrameworks].name = (char *)0; + return 1; +} - fclose(fd); - qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress); +void +SortFrameworkAddresses() +{ + + frameworkInfo[numFrameworks].b_address = frameworkInfo[numFrameworks - 1].b_address + 0x800000; + frameworkInfo[numFrameworks].e_address = frameworkInfo[numFrameworks].b_address; + frameworkInfo[numFrameworks].name = (char *)0; - return 1; + qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress); } @@ -3075,8 +4153,8 @@ void print_diskio(struct diskio *dio) p = " "; break; } - if (check_filter_mode(NULL, dio->type,0, 0, p)) - format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 7, dio->completed_time, dio->issued_time, 1, "", dio); + if (check_filter_mode(NULL, dio->type, 0, 0, p)) + format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 0, FMT_DISKIO, dio->completed_time, dio->issued_time, 1, "", dio); } @@ -3096,7 +4174,7 @@ void cache_disk_names() if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4)) continue; - sprintf(nbuf, "%s/%s", "/dev", dir->d_name); + snprintf(nbuf, MAXPATHLEN, "%s/%s", "/dev", dir->d_name); if (stat(nbuf, &st) < 0) continue; @@ -3158,7 +4236,7 @@ fs_usage_fd_set(thread, fd) } /* If the map is not big enough, then reallocate it */ - while (fdmap->fd_setsize < fd) + while (fdmap->fd_setsize <= fd) { fprintf(stderr, "reallocating bitmap for threadid %d, fd = %d, setsize = %d\n", thread, fd, fdmap->fd_setsize); @@ -3233,28 +4311,38 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc unsigned int fd; if (filter_mode == DEFAULT_DO_NOT_FILTER) - return(1); + return(1); - if (!strcmp (sc_name, "CACHE_HIT")) { + if (sc_name[0] == 'C' && !strcmp (sc_name, "CACHE_HIT")) { if (filter_mode & CACHEHIT_FILTER) /* Do not print if cachehit filter is set */ return(0); - return (1); + return(1); } if (filter_mode & EXEC_FILTER) { - if (!strcmp (sc_name, "execve")) - return(1); - return(0); + if (type == BSC_execve) + return(1); + return(0); } + + if (filter_mode & PATHNAME_FILTER) + { + if (ti && ti->pathname[0]) + return(1); + if (type == BSC_close || type == BSC_close_nocancel) + return(1); + return(0); + } + if ( !(filter_mode & (FILESYS_FILTER | NETWORK_FILTER))) return(1); if (ti == (struct th_info *)0) { - if(filter_mode & FILESYS_FILTER) + if (filter_mode & FILESYS_FILTER) ret = 1; else ret = 0; @@ -3263,6 +4351,7 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc switch (type) { case BSC_close: + case BSC_close_nocancel: fd = ti->arg1; network_fd_isset = fs_usage_fd_isset(ti->thread, fd); if (error == 0) @@ -3280,6 +4369,8 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc break; case BSC_read: case BSC_write: + case BSC_read_nocancel: + case BSC_write_nocancel: /* we don't care about error in this case */ fd = ti->arg1; network_fd_isset = fs_usage_fd_isset(ti->thread, fd); @@ -3292,6 +4383,7 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc ret = 1; break; case BSC_accept: + case BSC_accept_nocancel: case BSC_socket: fd = retval; if (error == 0) @@ -3306,6 +4398,11 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc case BSC_connect: case BSC_bind: case BSC_listen: + case BSC_sendto_nocancel: + case BSC_recvfrom_nocancel: + case BSC_recvmsg_nocancel: + case BSC_sendmsg_nocancel: + case BSC_connect_nocancel: fd = ti->arg1; if (error == 0) fs_usage_fd_set(ti->thread, fd); @@ -3313,6 +4410,7 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc ret = 1; break; case BSC_select: + case BSC_select_nocancel: case BSC_socketpair: /* Cannot determine info about file descriptors */ if (filter_mode & NETWORK_FILTER) diff --git a/getconf.tproj/confstr.gperf b/getconf.tproj/confstr.gperf index 929a8fd..4e79502 100644 --- a/getconf.tproj/confstr.gperf +++ b/getconf.tproj/confstr.gperf @@ -52,6 +52,9 @@ _POSIX_V6_LPBIG_OFFBIG_CFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _POSIX_V6_LPBIG_OFFBIG_LDFLAGS, _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _POSIX_V6_LPBIG_OFFBIG_LIBS, _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _POSIX_V6_WIDTH_RESTRICTED_ENVS, _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS +DARWIN_USER_DIR, _CS_DARWIN_USER_DIR +DARWIN_USER_TEMP_DIR, _CS_DARWIN_USER_TEMP_DIR +DARWIN_USER_CACHE_DIR, _CS_DARWIN_USER_CACHE_DIR %% int find_confstr(const char *name, int *key) diff --git a/getconf.tproj/getconf.1 b/getconf.tproj/getconf.1 index 5702f8b..d28bccb 100644 --- a/getconf.tproj/getconf.1 +++ b/getconf.tproj/getconf.1 @@ -145,6 +145,10 @@ Several of the .Xr confstr 3 variables provide information on the necessary compiler and linker flags to use the standard programming environments described above. +.Pp +Many of these values are also available through the +.Xr sysctl 8 +mechanism. .Sh DIAGNOSTICS .Ex -std Use of a @@ -191,7 +195,8 @@ if the system supports that environment. .Sh SEE ALSO .Xr pathconf 2 , .Xr confstr 3 , -.Xr sysconf 3 +.Xr sysconf 3 , +.Xr sysctl 8 .Sh STANDARDS The .Nm diff --git a/getconf.tproj/getconf.c b/getconf.tproj/getconf.c index 8b636dd..9cb0b7d 100644 --- a/getconf.tproj/getconf.c +++ b/getconf.tproj/getconf.c @@ -96,12 +96,6 @@ main(int argc, char **argv) } if (argv[optind + 1] == NULL) { /* confstr or sysconf */ -#ifdef APPLE_GETCONF_SPEC - if ((valid = find_progenv(name, &alt_path)) != 0) { - printf(valid > 0 ? "defined\n" : "undefined\n"); - return 0; - } -#endif /* APPLE_GETCONF_SPEC */ if ((valid = find_limit(name, &limitval)) != 0) { if (valid > 0) printf("%" PRIdMAX "\n", limitval); @@ -146,13 +140,15 @@ do_confstr(const char *name, int key) { size_t len; + errno = 0; len = confstr(key, 0, 0); - if (len == (size_t)-1) - err(EX_OSERR, "confstr: %s", name); - - if (len == 0) - printf("undefined\n"); - else { + if (len == 0) { + if (errno != 0) { + err(EX_OSERR, "confstr: %s", name); + } else { + printf("undefined\n"); + } + } else { char buf[len + 1]; confstr(key, buf, len); diff --git a/getconf.tproj/limits.gperf b/getconf.tproj/limits.gperf index e395c1a..bf19282 100644 --- a/getconf.tproj/limits.gperf +++ b/getconf.tproj/limits.gperf @@ -122,7 +122,7 @@ find_limit(const char *name, intmax_t *value) } #ifdef APPLE_GETCONF_UNDERSCORE if(*name == '_') - alt = name + 1; + alt = (char *)name + 1; else { if((alt = (char *)alloca(strlen(name) + 2)) == NULL) return 0; diff --git a/getconf.tproj/pathconf.gperf b/getconf.tproj/pathconf.gperf index 1b20649..ebb317f 100644 --- a/getconf.tproj/pathconf.gperf +++ b/getconf.tproj/pathconf.gperf @@ -35,6 +35,7 @@ POSIX_REC_INCR_XFER_SIZE, _PC_REC_INCR_XFER_SIZE POSIX_REC_MAX_XFER_SIZE, _PC_REC_MAX_XFER_SIZE POSIX_REC_MIN_XFER_SIZE, _PC_REC_MIN_XFER_SIZE POSIX_REC_XFER_ALIGN, _PC_REC_XFER_ALIGN +POSIX2_SYMLINKS, _PC_2_SYMLINKS SYMLINK_MAX, _PC_SYMLINK_MAX TRUSTEDBSD_ACL_EXTENDED, _PC_ACL_EXTENDED TRUSTEDBSD_ACL_PATH_MAX, _PC_ACL_PATH_MAX @@ -67,7 +68,7 @@ find_pathconf(const char *name, int *key) } #ifdef APPLE_GETCONF_UNDERSCORE if(*name == '_') - alt = name + 1; + alt = (char *)name + 1; else { if((alt = (char *)alloca(strlen(name) + 2)) == NULL) return 0; diff --git a/getconf.tproj/progenv.gperf b/getconf.tproj/progenv.gperf index d257c6b..4f2319f 100644 --- a/getconf.tproj/progenv.gperf +++ b/getconf.tproj/progenv.gperf @@ -32,6 +32,9 @@ static const struct map *in_word_set(const char *str); */ #if defined(__alpha__) || defined(__sparc64__) #define have_LP64_OFF64 NULL +#elif defined(__APPLE__) +#define have_LP64_OFF64 NULL +#define have_LPBIG_OFFBIG NULL #endif #if defined(__i386__) || defined(__powerpc__) @@ -44,11 +47,11 @@ struct map { const char *name; const char *alt_path; int valid; }; POSIX_V6_ILP32_OFF32, notdef POSIX_V6_ILP32_OFFBIG, have_ILP32_OFFBIG POSIX_V6_LP64_OFF64, have_LP64_OFF64 -POSIX_V6_LPBIG_OFFBIG, notdef +POSIX_V6_LPBIG_OFFBIG, have_LPBIG_OFFBIG _POSIX_V6_ILP32_OFF32, notdef _POSIX_V6_ILP32_OFFBIG, have_ILP32_OFFBIG _POSIX_V6_LP64_OFF64, have_LP64_OFF64 -_POSIX_V6_LPBIG_OFFBIG, notdef +_POSIX_V6_LPBIG_OFFBIG, have_LPBIG_OFFBIG %% int find_progenv(const char *name, const char **alt_path) diff --git a/getconf.tproj/sysconf.gperf b/getconf.tproj/sysconf.gperf index 35c825e..95283a8 100644 --- a/getconf.tproj/sysconf.gperf +++ b/getconf.tproj/sysconf.gperf @@ -110,6 +110,7 @@ _POSIX_SHELL, _SC_SHELL _POSIX_SPAWN, _SC_SPAWN _POSIX_SPIN_LOCKS, _SC_SPIN_LOCKS _POSIX_SPORADIC_SERVER, _SC_SPORADIC_SERVER +_POSIX_SS_REPL_MAX, _SC_SS_REPL_MAX _POSIX_SYNCHRONIZED_IO, _SC_SYNCHRONIZED_IO _POSIX_THREADS, _SC_THREADS _POSIX_THREAD_ATTR_STACKADDR, _SC_THREAD_ATTR_STACKADDR @@ -122,17 +123,21 @@ _POSIX_THREAD_PROCESS_SHARED, _SC_THREAD_PROCESS_SHARED _POSIX_THREAD_SAFE_FUNCTIONS, _SC_THREAD_SAFE_FUNCTIONS _POSIX_THREAD_SPORADIC_SERVER, _SC_THREAD_SPORADIC_SERVER _POSIX_TIMEOUTS, _SC_TIMEOUTS +_POSIX_TIMERS, _SC_TIMERS _POSIX_TRACE, _SC_TRACE _POSIX_TRACE_EVENT_FILTER, _SC_TRACE_EVENT_FILTER +_POSIX_TRACE_EVENT_NAME_MAX, _SC_TRACE_EVENT_NAME_MAX _POSIX_TRACE_INHERIT, _SC_TRACE_INHERIT _POSIX_TRACE_LOG, _SC_TRACE_LOG -_POSIX_TIMERS, _SC_TIMERS +_POSIX_TRACE_NAME_MAX, _SC_TRACE_NAME_MAX +_POSIX_TRACE_SYS_MAX, _SC_TRACE_SYS_MAX +_POSIX_TRACE_USER_EVENT_MAX, _SC_TRACE_USER_EVENT_MAX _POSIX_TYPED_MEMORY_OBJECTS, _SC_TYPED_MEMORY_OBJECTS -_POSIX_VERSION, _SC_VERSION _POSIX_V6_ILP32_OFF32, _SC_V6_ILP32_OFF32 _POSIX_V6_ILP32_OFFBIG, _SC_V6_ILP32_OFFBIG _POSIX_V6_LP64_OFF64, _SC_V6_LP64_OFF64 -_POSIX_V6_LP64_OFFBIG, _SC_V6_LP64_OFFBIG +_POSIX_V6_LPBIG_OFFBIG, _SC_V6_LPBIG_OFFBIG +_POSIX_VERSION, _SC_VERSION _XOPEN_CRYPT, _SC_XOPEN_CRYPT _XOPEN_ENH_I18N, _SC_XOPEN_ENH_I18N _XOPEN_LEGACY, _SC_XOPEN_LEGACY @@ -162,7 +167,7 @@ find_sysconf(const char *name, int *key) } #ifdef APPLE_GETCONF_UNDERSCORE if(*name == '_') - alt = name + 1; + alt = (char *)name + 1; else { if((alt = (char *)alloca(strlen(name) + 2)) == NULL) return 0; diff --git a/getty.tproj/Makefile b/getty.tproj/Makefile index f7c2acc..6f3af4e 100644 --- a/getty.tproj/Makefile +++ b/getty.tproj/Makefile @@ -14,10 +14,10 @@ PROJECT_TYPE = Tool HFILES = extern.h gettytab.h pathnames.h -CFILES = init.c main.c subr.c +CFILES = chat.c init.c main.c subr.c OTHERSRCS = Makefile.preamble Makefile Makefile.postamble getty.8\ - gettytab.5 ttys.5 + gettytab.5 ttys.5 com.apple.getty.plist MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/getty.tproj/Makefile.postamble b/getty.tproj/Makefile.postamble index 03f6b6e..2dc7cb8 100644 --- a/getty.tproj/Makefile.postamble +++ b/getty.tproj/Makefile.postamble @@ -71,7 +71,7 @@ # the top-level: #OPTIMIZATION_CFLAG = -O #DEBUG_SYMBOLS_CFLAG = -g -#WARNING_CFLAGS = -Wall +WARNING_CFLAGS = -Wall -Werror #DEBUG_BUILD_CFLAGS = -DDEBUG #PROFILE_BUILD_CFLAGS = -pg -DPROFILE @@ -108,9 +108,18 @@ # owned by the top-level Makefile API and no context has been set up for where # derived files should go. +LAUNCHD_PLIST_DIR = $(DSTROOT)/System/Library/LaunchDaemons +LAUNCHD_PLIST = com.apple.getty.plist + +Embedded = $(shell tconf --test TARGET_OS_EMBEDDED) + after_install: mkdir -p $(DSTROOT)/usr/share/man/man5 install -c -m 444 gettytab.5 $(DSTROOT)/usr/share/man/man5 install -c -m 444 ttys.5 $(DSTROOT)/usr/share/man/man5 mkdir -p $(DSTROOT)/usr/share/man/man8 install -c -m 444 getty.8 $(DSTROOT)/usr/share/man/man8 +ifeq "$(Embedded)" "YES" + install -d $(LAUNCHD_PLIST_DIR) + install -c -m 644 $(LAUNCHD_PLIST) $(LAUNCHD_PLIST_DIR)/$(LAUNCHD_PLIST) +endif diff --git a/getty.tproj/Makefile.preamble b/getty.tproj/Makefile.preamble index 5741d84..4493da0 100644 --- a/getty.tproj/Makefile.preamble +++ b/getty.tproj/Makefile.preamble @@ -17,7 +17,7 @@ ## (e.g. change -O to -O2), see Makefile.postamble. # Flags passed to compiler (in addition to -g, -O, etc) -OTHER_CFLAGS = +OTHER_CFLAGS = -fno-builtin-puts # Flags passed to ld (in addition to -ObjC, etc.) OTHER_LDFLAGS = # Flags passed to libtool when building libraries diff --git a/getty.tproj/chat.c b/getty.tproj/chat.c new file mode 100644 index 0000000..147ef84 --- /dev/null +++ b/getty.tproj/chat.c @@ -0,0 +1,490 @@ +/*- + * Copyright (c) 1997 + * David L Nugent . + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. This work was done expressly for inclusion into FreeBSD. Other use + * is permitted provided this notation is included. + * 4. Absolutely no warranty of function or purpose is made by the authors. + * 5. Modifications may be freely made to this file providing the above + * conditions are met. + * + * Modem chat module - send/expect style functions for getty + * For semi-intelligent modem handling. + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: src/libexec/getty/chat.c,v 1.11 2005/04/06 17:42:24 stefanf Exp $"; +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "gettytab.h" +#include "extern.h" + +#define PAUSE_CH (unsigned char)'\xff' /* pause kludge */ + +#define CHATDEBUG_RECEIVE 0x01 +#define CHATDEBUG_SEND 0x02 +#define CHATDEBUG_EXPECT 0x04 +#define CHATDEBUG_MISC 0x08 + +#define CHATDEBUG_DEFAULT 0 +#define CHAT_DEFAULT_TIMEOUT 10 + + +static int chat_debug = CHATDEBUG_DEFAULT; +static int chat_alarm = CHAT_DEFAULT_TIMEOUT; /* Default */ + +static volatile int alarmed = 0; + + +static void chat_alrm(int); +static int chat_unalarm(void); +static int getdigit(unsigned char **, int, int); +static char **read_chat(char **); +static char *cleanchr(char **, unsigned char); +static char *cleanstr(const char *, int); +static const char *result(int); +static int chat_expect(const char *); +static int chat_send(char const *); + + +/* + * alarm signal handler + * handle timeouts in read/write + * change stdin to non-blocking mode to prevent + * possible hang in read(). + */ + +static void +chat_alrm(int signo) +{ + int on = 1; + + alarm(1); + alarmed = 1; + signal(SIGALRM, chat_alrm); + ioctl(STDIN_FILENO, FIONBIO, &on); +} + + +/* + * Turn back on blocking mode reset by chat_alrm() + */ + +static int +chat_unalarm(void) +{ + int off = 0; + return ioctl(STDIN_FILENO, FIONBIO, &off); +} + + +/* + * convert a string of a given base (octal/hex) to binary + */ + +static int +getdigit(unsigned char **ptr, int base, int max) +{ + int i, val = 0; + unsigned char * q; + + static const char xdigits[] = "0123456789abcdef"; + + for (i = 0, q = *ptr; i++ < max; ++q) { + int sval; + const char * s = strchr(xdigits, tolower(*q)); + + if (s == NULL || (sval = s - xdigits) >= base) + break; + val = (val * base) + sval; + } + *ptr = q; + return val; +} + + +/* + * read_chat() + * Convert a whitespace delimtied string into an array + * of strings, being expect/send pairs + */ + +static char ** +read_chat(char **chatstr) +{ + char *str = *chatstr; + char **res = NULL; + + if (str != NULL) { + char *tmp = NULL; + int l; + + if ((l=strlen(str)) > 0 && (tmp=malloc(l + 1)) != NULL && + (res=malloc((l / 2 + 1) * sizeof(char *))) != NULL) { + static char ws[] = " \t"; + char * p; + + for (l = 0, p = strtok(strcpy(tmp, str), ws); + p != NULL; + p = strtok(NULL, ws)) + { + unsigned char *q, *r; + + /* Read escapes */ + for (q = r = (unsigned char *)p; *r; ++q) + { + if (*q == '\\') + { + /* handle special escapes */ + switch (*++q) + { + case 'a': /* bell */ + *r++ = '\a'; + break; + case 'r': /* cr */ + *r++ = '\r'; + break; + case 'n': /* nl */ + *r++ = '\n'; + break; + case 'f': /* ff */ + *r++ = '\f'; + break; + case 'b': /* bs */ + *r++ = '\b'; + break; + case 'e': /* esc */ + *r++ = 27; + break; + case 't': /* tab */ + *r++ = '\t'; + break; + case 'p': /* pause */ + *r++ = PAUSE_CH; + break; + case 's': + case 'S': /* space */ + *r++ = ' '; + break; + case 'x': /* hexdigit */ + ++q; + *r++ = getdigit(&q, 16, 2); + --q; + break; + case '0': /* octal */ + ++q; + *r++ = getdigit(&q, 8, 3); + --q; + break; + default: /* literal */ + *r++ = *q; + break; + case 0: /* not past eos */ + --q; + break; + } + } else { + /* copy standard character */ + *r++ = *q; + } + } + + /* Remove surrounding quotes, if any + */ + if (*p == '"' || *p == '\'') { + q = (unsigned char*)strrchr(p+1, *p); + if (q != NULL && *q == *p && q[1] == '\0') { + *q = '\0'; + strcpy(p, p+1); + } + } + + res[l++] = p; + } + res[l] = NULL; + *chatstr = tmp; + return res; + } + free(tmp); + } + return res; +} + + +/* + * clean a character for display (ctrl/meta character) + */ + +static char * +cleanchr(char **buf, unsigned char ch) +{ + int l; + static char tmpbuf[5]; + char * tmp = buf ? *buf : tmpbuf; + + if (ch & 0x80) { + strcpy(tmp, "M-"); + l = 2; + ch &= 0x7f; + } else + l = 0; + + if (ch < 32) { + tmp[l++] = '^'; + tmp[l++] = ch + '@'; + } else if (ch == 127) { + tmp[l++] = '^'; + tmp[l++] = '?'; + } else + tmp[l++] = ch; + tmp[l] = '\0'; + + if (buf) + *buf = tmp + l; + return tmp; +} + + +/* + * clean a string for display (ctrl/meta characters) + */ + +static char * +cleanstr(const char *s, int l) +{ + static char * tmp = NULL; + static int tmplen = 0; + + if (tmplen < l * 4 + 1) + tmp = realloc(tmp, tmplen = l * 4 + 1); + + if (tmp == NULL) { + tmplen = 0; + return (char *)"(mem alloc error)"; + } else { + int i = 0; + char * p = tmp; + + while (i < l) + cleanchr(&p, s[i++]); + *p = '\0'; + } + + return tmp; +} + + +/* + * return result as a pseudo-english word + */ + +static const char * +result(int r) +{ + static const char * results[] = { + "OK", "MEMERROR", "IOERROR", "TIMEOUT" + }; + return results[r & 3]; +} + + +/* + * chat_expect() + * scan input for an expected string + */ + +static int +chat_expect(const char *str) +{ + int len, r = 0; + + if (chat_debug & CHATDEBUG_EXPECT) + syslog(LOG_DEBUG, "chat_expect '%s'", cleanstr(str, strlen(str))); + + if ((len = strlen(str)) > 0) { + int i = 0; + char * got; + + if ((got = malloc(len + 1)) == NULL) + r = 1; + else { + + memset(got, 0, len+1); + alarm(chat_alarm); + alarmed = 0; + + while (r == 0 && i < len) { + if (alarmed) + r = 3; + else { + unsigned char ch; + + if (read(STDIN_FILENO, &ch, 1) == 1) { + + if (chat_debug & CHATDEBUG_RECEIVE) + syslog(LOG_DEBUG, "chat_recv '%s' m=%d", + cleanchr(NULL, ch), i); + + if (ch == str[i]) + got[i++] = ch; + else if (i > 0) { + int j = 1; + + /* See if we can resync on a + * partial match in our buffer + */ + while (j < i && memcmp(got + j, str, i - j) != 0) + j++; + if (j < i) + memcpy(got, got + j, i - j); + i -= j; + } + } else + r = alarmed ? 3 : 2; + } + } + alarm(0); + chat_unalarm(); + alarmed = 0; + free(got); + } + } + + if (chat_debug & CHATDEBUG_EXPECT) + syslog(LOG_DEBUG, "chat_expect %s", result(r)); + + return r; +} + + +/* + * chat_send() + * send a chat string + */ + +static int +chat_send(char const *str) +{ + int r = 0; + + if (chat_debug && CHATDEBUG_SEND) + syslog(LOG_DEBUG, "chat_send '%s'", cleanstr(str, strlen(str))); + + if (*str) { + alarm(chat_alarm); + alarmed = 0; + while (r == 0 && *str) + { + unsigned char ch = (unsigned char)*str++; + + if (alarmed) + r = 3; + else if (ch == PAUSE_CH) + usleep(500000); /* 1/2 second */ + else { + usleep(10000); /* be kind to modem */ + if (write(STDOUT_FILENO, &ch, 1) != 1) + r = alarmed ? 3 : 2; + } + } + alarm(0); + chat_unalarm(); + alarmed = 0; + } + + if (chat_debug & CHATDEBUG_SEND) + syslog(LOG_DEBUG, "chat_send %s", result(r)); + + return r; +} + + +/* + * getty_chat() + * + * Termination codes: + * -1 - no script supplied + * 0 - script terminated correctly + * 1 - invalid argument, expect string too large, etc. + * 2 - error on an I/O operation or fatal error condition + * 3 - timeout waiting for a simple string + * + * Parameters: + * char *scrstr - unparsed chat script + * timeout - seconds timeout + * debug - debug value (bitmask) + */ + +int +getty_chat(char *scrstr, int timeout, int debug) +{ + int r = -1; + + chat_alarm = timeout ? timeout : CHAT_DEFAULT_TIMEOUT; + chat_debug = debug; + + if (scrstr != NULL) { + char **script; + + if (chat_debug & CHATDEBUG_MISC) + syslog(LOG_DEBUG, "getty_chat script='%s'", scrstr); + + if ((script = read_chat(&scrstr)) != NULL) { + int i = r = 0; + int off = 0; + sig_t old_alarm; + + /* + * We need to be in raw mode for all this + * Rely on caller... + */ + + old_alarm = signal(SIGALRM, chat_alrm); + chat_unalarm(); /* Force blocking mode at start */ + + /* + * This is the send/expect loop + */ + while (r == 0 && script[i] != NULL) + if ((r = chat_expect(script[i++])) == 0 && script[i] != NULL) + r = chat_send(script[i++]); + + signal(SIGALRM, old_alarm); + free(script); + free(scrstr); + + /* + * Ensure stdin is in blocking mode + */ + ioctl(STDIN_FILENO, FIONBIO, &off); + } + + if (chat_debug & CHATDEBUG_MISC) + syslog(LOG_DEBUG, "getty_chat %s", result(r)); + + } + return r; +} diff --git a/getty.tproj/com.apple.getty.plist b/getty.tproj/com.apple.getty.plist new file mode 100644 index 0000000..0e6c035 --- /dev/null +++ b/getty.tproj/com.apple.getty.plist @@ -0,0 +1,18 @@ + + + + + Label + com.apple.getty + ProgramArguments + + /usr/libexec/getty + std.9600 + console + + SessionCreate + + KeepAlive + + + diff --git a/getty.tproj/extern.h b/getty.tproj/extern.h index f8e759a..76fdf44 100644 --- a/getty.tproj/extern.h +++ b/getty.tproj/extern.h @@ -1,26 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ /* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -54,27 +31,30 @@ * SUCH DAMAGE. * * from: @(#)extern.h 8.1 (Berkeley) 6/4/93 - * $Id: extern.h,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $ + * $FreeBSD: src/libexec/getty/extern.h,v 1.9 2005/04/06 17:42:24 stefanf Exp $ */ struct delayval; +struct termios; -int adelay __P((int, struct delayval *)); -char *autobaud __P((void)); -int delaybits __P((void)); -void edithost __P((char *)); -void gendefaults __P((void)); -int getent __P((char *, char *)); -int getflag __P((char *)); -long getnum __P((char *)); -char *getstr __P((char *, char **)); -void gettable __P((char *, char *)); -void makeenv __P((char *[])); -char *portselector __P((void)); -void set_ttydefaults __P((int)); -void setchars __P((void)); -void setdefaults __P((void)); -void setflags __P((int)); -int speed __P((int)); +extern char hostname[]; +extern int hopcount; +extern struct termios tmode, omode; +extern struct gettyflags gettyflags[]; +extern struct gettynums gettynums[]; +extern struct gettystrs gettystrs[]; -int login_tty __P((int)); /* From libutil. */ +int adelay(int, struct delayval *); +const char *autobaud(void); +int delaybits(void); +void edithost(const char *); +void gendefaults(void); +void gettable(const char *, char *); +void makeenv(char *[]); +const char *portselector(void); +void set_ttydefaults(int); +void setchars(void); +void setdefaults(void); +void set_flags(int); +int speed(int); +int getty_chat(char *, int, int); diff --git a/getty.tproj/getty.8 b/getty.tproj/getty.8 index a97f053..159b14a 100644 --- a/getty.tproj/getty.8 +++ b/getty.tproj/getty.8 @@ -30,26 +30,25 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)getty.8 8.1 (Berkeley) 6/4/93 -.\" $Id: getty.8,v 1.1 1999/05/02 04:21:29 wsanchez Exp $ -.\" +.\" $FreeBSD: src/libexec/getty/getty.8,v 1.16 2005/01/18 09:29:39 ru Exp $ +.\" " .Dd June 4, 1993 .Dt GETTY 8 -.Os BSD 4 +.Os .Sh NAME .Nm getty .Nd set terminal mode .Sh SYNOPSIS -.Nm getty -.Oo +.Nm +.Oo .Ar type .Op Ar tty .Oc .Sh DESCRIPTION The -.Nm getty -program -is called by -.Xr init 8 +.Nm +utility is called by +.Xr launchd 8 to open and initialize the tty line, read a login name, and invoke .Xr login 1 . .Pp @@ -59,16 +58,16 @@ is the special device file in .Pa /dev to open for the terminal (for example, ``ttyh0''). If there is no argument or the argument is -.Ql Fl , +.Sq Fl , the tty line is assumed to be open as file descriptor 0. .Pp The .Ar type argument can be used to make -.Nm getty +.Nm treat the terminal line specially. This argument is used as an index into the -.Nm gettytab 5 +.Xr gettytab 5 database, to determine the characteristics of the line. If there is no argument, or there is no such table, the .Em default @@ -77,7 +76,7 @@ If there is no .Pa /etc/gettytab a set of system defaults is used. If indicated by the table located, -.Nm getty +.Nm will clear the terminal screen, print a banner heading, and prompt for a login name. @@ -85,24 +84,29 @@ Usually either the banner or the login prompt will include the system hostname. .Pp Most of the default actions of -.Nm getty +.Nm can be circumvented, or modified, by a suitable -.Nm gettytab +.Pa gettytab table. .Pp The -.Nm getty -program -can be set to timeout after some interval, +.Nm +utility can be set to timeout after some interval, which will cause dial up lines to hang up if the login name is not entered reasonably quickly. +.Sh FILES +.Bl -tag -width /etc/gettytab -compact +.It Pa /etc/gettytab +.It Pa /etc/ttys +.El .Sh DIAGNOSTICS .Bl -diag .It "ttyxx: No such device or address." .It "ttyxx: No such file or address." +.Pp A terminal which is turned on in the -.Xr ttys +.Pa ttys file cannot be opened, likely because the requisite lines are either not configured into the system, the associated device was not attached during boot-time system configuration, @@ -110,19 +114,15 @@ or the special file in .Pa /dev does not exist. .El -.Sh FILES -.Bl -tag -width /etc/gettytab -compact -.It Pa /etc/gettytab -.El .Sh SEE ALSO -.Xr gettytab 5 , -.Xr init 8 , .Xr login 1 , .Xr ioctl 2 , .Xr tty 4 , -.Xr ttys 5 +.Xr gettytab 5 , +.Xr ttys 5 , +.Xr launchd 8 .Sh HISTORY A -.Nm getty -program appeared in +.Nm +utility appeared in .At v6 . diff --git a/getty.tproj/gettytab.5 b/getty.tproj/gettytab.5 index 38e9a96..c2efc88 100644 --- a/getty.tproj/gettytab.5 +++ b/getty.tproj/gettytab.5 @@ -30,19 +30,19 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)gettytab.5 8.4 (Berkeley) 4/19/94 -.\" $Id: gettytab.5,v 1.1 1999/05/02 04:21:29 wsanchez Exp $ -.\" +.\" $FreeBSD: src/libexec/getty/gettytab.5,v 1.41 2005/01/18 09:29:39 ru Exp $ +.\" " .Dd April 19, 1994 .Dt GETTYTAB 5 -.Os BSD 4.2 +.Os .Sh NAME .Nm gettytab .Nd terminal configuration data base .Sh SYNOPSIS -.Nm gettytab +.Nm .Sh DESCRIPTION The -.Nm gettytab +.Nm file is a simplified version of the .Xr termcap 5 @@ -51,17 +51,17 @@ used to describe terminal lines. The initial terminal login process .Xr getty 8 accesses the -.Nm gettytab +.Nm file each time it starts, allowing simpler reconfiguration of terminal characteristics. Each entry in the data base is used to describe one class of terminals. .Pp There is a default terminal class, -.Em default , +.Va default , that is used to set global defaults for all other classes. (That is, the -.Em default +.Va default entry is read, then the entry for the class required is used to override particular settings.) .Sh CAPABILITIES @@ -69,13 +69,15 @@ Refer to .Xr termcap 5 for a description of the file layout. The -.Em default +.Va default column below lists defaults obtained if there is no entry in the table obtained, nor one in the special -.Em default +.Va default table. -.Bl -column Namexx /usr/bin/login Default -.It Sy Name Type Default Description +.Bl -column Name Type /usr/bin/login +.It Sy "Name Type Default Description +.It "ac str unused expect-send chat script for modem answer" +.It "al str unused user to auto-login instead of prompting" .It "ap bool false terminal uses any parity" .It "bk str 0377 alternate end of line character (input break)" .It "c0 num unused tty control flags to write messages" @@ -83,17 +85,25 @@ table. .It "c2 num unused tty control flags to leave terminal as" .It "ce bool false use crt erase algorithm" .It "ck bool false use crt kill algorithm" -.It "cl str" Ta Dv NULL Ta +.It "cl str" Ta Dv NULL Ta .No "screen clear sequence" .It "co bool false console - add" .Ql \en after login prompt +.It "ct num 10 chat timeout for" +.Va \&ac +and +.Va \&ic +scripts +.It "dc num 0 chat debug bitmask" +.It "de num 0 delay secs and flush input before writing first prompt" +.It "df str %+ the" Xr strftime 3 "format used for \&%d in the banner message" .It "ds str" Ta So Li ^Y Sc Ta .No "delayed suspend character" .It "dx bool false set" .Dv DECCTLQ .It "ec bool false leave echo" -.Tn OFF +.Em OFF .It "ep bool false terminal uses even parity" .It "er str" Ta So Li ^? Sc Ta .No "erase character" @@ -101,7 +111,7 @@ after login prompt .No "end of text" .Pq Dv EOF character -.It "ev str" Ta Dv NULL Ta +.It "ev str" Ta Dv NULL Ta .No "initial environment" .It "f0 num unused tty mode flags to write messages" .It "f1 num unused tty mode flags to read login name" @@ -109,15 +119,18 @@ character .It "fl str" Ta So Li ^O Sc Ta .No "output flush character" .It "hc bool false do" -.Tn NOT +.Em NOT hangup line on last close -.It "he str" Ta Dv NULL Ta +.It "he str" Ta Dv NULL Ta .No "hostname editing string" .It "hn str hostname hostname" .It "ht bool false terminal has real tabs" +.It "hw bool false do cts/rts hardware flow control" .It "i0 num unused tty input flags to write messages" .It "i1 num unused tty input flags to read login name" .It "i2 num unused tty input flags to leave terminal as" +.It "ic str unused expect-send chat script for modem initialization" +.It "if str unused display named file before prompt, like /etc/issue" .It "ig bool false ignore garbage characters in login name" .It "im str" Ta Dv NULL Ta .No "initial (banner) message" @@ -129,13 +142,13 @@ hangup line on last close .It "l0 num unused tty local flags to write messages" .It "l1 num unused tty local flags to read login name" .It "l2 num unused tty local flags to leave terminal as" -.It "lc bool false terminal has lower case" .It "lm str login: login prompt" .It "ln str" Ta So Li ^V Sc Ta .No "``literal next'' character" .It "lo str" Ta Pa /usr/bin/login Ta .No "program to exec when name obtained" .It "mb bool false do flow control based on carrier" +.It "nc bool false terminal does not supply carrier (set clocal)" .It "nl bool false terminal has (or might have) a newline character" .It "np bool false terminal uses no parity (i.e. 8-bit characters)" .It "nx str default next table (for auto speed selection)" @@ -149,6 +162,10 @@ hangup line on last close .It "pe bool false use printer (hard copy) erase algorithm" .It "pf num 0 delay" between first prompt and following flush (seconds) +.It "pl bool false start PPP login program unconditionally if" +.Va \&pp +is specified +.It "pp str unused PPP login program" .It "ps bool false line connected to a" .Tn MICOM port selector @@ -156,8 +173,10 @@ port selector .No "quit character" .It "rp str" Ta So Li ^R Sc Ta .No "line retype character" +.It "rt num unused ring timeout when using" +.Va \&ac .It "rw bool false do" -.Tn NOT +.Em NOT use raw for input, use cbreak .It "sp num unused line speed (input and output)" .It "su str" Ta So Li ^Z Sc Ta @@ -170,21 +189,24 @@ use raw for input, use cbreak .It "we str" Ta So Li ^W Sc Ta .No "word erase character" .It "xc bool false do -.Tn NOT +.Em NOT echo control chars as .Ql ^X .It "xf str" Ta So Li ^S Sc Ta Dv XOFF (stop output) character .It "xn str" Ta So Li ^Q Sc Ta Dv XON (start output) character +.It "Lo str C the locale name used for \&%d in the banner message" .El .Pp -The following capabilities are no longer supported by getty(8): -.Bl -column Namexx /usr/bin/login Default +The following capabilities are no longer supported by +.Xr getty 8 : +.Bl -column Name Type /usr/bin/login .It "bd num 0 backspace delay" .It "cb bool false use crt backspace mode" .It "cd num 0 carriage-return delay" .It "fd num 0 form-feed (vertical motion) delay" +.It "lc bool false terminal has lower case" .It "nd num 0 newline (line-feed) delay" .It "uc bool false terminal is known upper case only" .El @@ -201,48 +223,51 @@ are derived from the boolean flags specified. If the derivation should prove inadequate, any (or all) of these three may be overridden with one of the -.Em \&c0 , -.Em \&c1 , -.Em \&c2 , -.Em \&i0 , -.Em \&i1 , -.Em \&i2 , -.Em \&l0 , -.Em \&l1 , -.Em \&l2 , -.Em \&o0 , -.Em \&o1 , +.Va \&c0 , +.Va \&c1 , +.Va \&c2 , +.Va \&i0 , +.Va \&i1 , +.Va \&i2 , +.Va \&l0 , +.Va \&l1 , +.Va \&l2 , +.Va \&o0 , +.Va \&o1 , or -.Em \&o2 +.Va \&o2 numeric specifications, which can be used to specify (usually in octal, with a leading '0') the exact values of the flags. These flags correspond to the termios -.Em c_cflag , -.Em c_iflag , -.Em c_lflag , +.Va c_cflag , +.Va c_iflag , +.Va c_lflag , and -.Em c_oflag -fields, respectively. Each these sets must be completely specified to be -effective. +.Va c_oflag +fields, respectively. +Each of these sets must be completely specified to be effective. +.Pp The -.Em \&f0 , -.Em \&f1 , +.Va \&f0 , +.Va \&f1 , and -.Em \&f2 +.Va \&f2 are excepted for backwards compatibility with a previous incarnation of -the TTY sub-system. In these flags the bottom 16 bits of the (32 bits) +the TTY sub-system. +In these flags the bottom 16 bits of the (32 bits) value contain the sgttyb -.Em sg_flags +.Va sg_flags field, while the top 16 bits represent the local mode word. .Pp Should -.Xr getty +.Xr getty 8 receive a null character (presumed to indicate a line break) it will restart using the table indicated by the -.Em nx -entry. If there is none, it will re-use its original table. +.Va \&nx +entry. +If there is none, it will re-use its original table. .Pp Delays are specified in milliseconds, the nearest possible delay available in the tty driver will be used. @@ -251,96 +276,249 @@ with values 0, 1, 2, and 3 are interpreted as choosing that particular delay algorithm from the driver. .Pp The -.Em \&cl +.Va \&cl screen clear string may be preceded by a (decimal) number of milliseconds of delay required (a la termcap). This delay is simulated by repeated use of the pad character -.Em \&pc . +.Va \&pc . .Pp -The initial message, and login message, -.Em \&im +The initial message, login message, and initial file; +.Va \&im , +.Va \&lm and -.Em \&lm -may include the character sequence -.Em \&%h -or -.Em \&%t -to obtain -the hostname or tty name respectively. -.Pf ( Em %% -obtains a single '%' character.) -The hostname is normally obtained from the system, -but may be set by the -.Em \&hn +.Va \&if +may include any of the following character sequences, which expand to +information about the environment in which +.Xr getty 8 +is running. +.Pp +.Bl -tag -offset indent -width \&%xxxxxxxxxxxxxx +.It \&%d +The current date and time formatted according to the +.Va \&Lo +and +.Va \&df +strings. +.It \&%h +The hostname of the machine, which is normally obtained from the +system using +.Xr gethostname 3 , +but may also be overridden by the +.Va \&hn table entry. -In either case it may be edited with -.Em \&he . -The -.Em \&he -string is a sequence of characters, each character that -is neither '@' nor '#' is copied into the final hostname. +In either case it may be edited with the +.Va \&he +string. A '@' in the -.Em \&he -string, causes one character from the real hostname to +.Va \&he +string causes one character from the real hostname to be copied to the final hostname. A '#' in the -.Em \&he -string, causes the next character of the real hostname +.Va \&he +string causes the next character of the real hostname to be skipped. +Each character that +is neither '@' nor '#' is copied into the final hostname. Surplus '@' and '#' characters are ignored. +.It \&%t +The tty name. +.It "\&%m, \&%r, \&%s, \&%v" +The type of machine, release of the operating system, name of the +operating system, and version of the kernel, respectively, as +returned by +.Xr uname 3 . +.It \&%% +A +.Dq % +character. +.El .Pp When getty execs the login process, given in the -.Em \&lo +.Va \&lo string (usually .Dq Pa /usr/bin/login ) , it will have set the environment to include the terminal type, as indicated by the -.Em \&tt +.Va \&tt string (if it exists). The -.Em \&ev +.Va \&ev string, can be used to enter additional data into the environment. It is a list of comma separated strings, each of which will presumably be of the form -.Em name=value . +.Li name=value . .Pp If a non-zero timeout is specified, with -.Em \&to , +.Va \&to , then getty will exit within the indicated number of seconds, either having received a login name and passed control to -.Xr login , +.Xr login 1 , or having received an alarm signal, and exited. This may be useful to hangup dial in lines. .Pp Output from -.Xr getty +.Xr getty 8 is even parity unless -.Em \&op +.Va \&op or -.Em \&np +.Va \&np is specified. The -.Em \&op +.Va \&op string may be specified with -.Em \&ap +.Va \&ap to allow any parity on input, but generate odd parity output. Note: this only applies while getty is being run, terminal driver limitations prevent a more complete implementation. -.Xr Getty -does not check parity of input characters in +The +.Xr getty 8 +utility does not check parity of input characters in .Dv RAW mode. +.Pp +If a +.Va \&pp +string is specified and a PPP link bring-up sequence is recognized, +getty will invoke the program referenced by the +.Va \&pp +option. +This can be used to handle incoming PPP calls. +If the +.Va \&pl +option is true as well, +.Xr getty 8 +will skip the user name prompt and the PPP detection phase, and will +invoke the program specified by +.Va \&pp +instantly. +.Pp +.Nm Getty +provides some basic intelligent modem handling by providing a chat +script feature available via two capabilities: +.Pp +.Bl -tag -offset indent -width \&xxxxxxxx -compact +.It ic +Chat script to initialize modem. +.It ac +Chat script to answer a call. +.El +.Pp +A chat script is a set of expect/send string pairs. +When a chat string starts, +.Nm getty +will wait for the first string, and if it finds it, will send the +second, and so on. +Strings specified are separated by one or more tabs or spaces. +Strings may contain standard ASCII characters and special 'escapes', +which consist of a backslash character followed by one or more +characters which are interpreted as follows: +.Pp +.Bl -tag -offset indent -width \&xxxxxxxx -compact +.It \ea +bell character. +.It \eb +backspace. +.It \en +newline. +.It \ee +escape. +.It \ef +formfeed. +.It \ep +half-second pause. +.It \er +carriage return. +.It \eS , \es +space character. +.It \et +tab. +.It \exNN +hexadecimal byte value. +.It \e0NNN +octal byte value. +.El +.Pp +Note that the +.Ql \ep +sequence is only valid for send strings and causes a half-second +pause between sending the previous and next characters. +Hexadecimal values are, at most, 2 hex digits long, and octal +values are a maximum of 3 octal digits. +.Pp +The +.Va \&ic +chat sequence is used to initialize a modem or similar device. +A typical example of an init chat script for a modem with a +hayes compatible command set might look like this: +.Pp +.Dl :ic="" ATE0Q0V1\er OK\er ATS0=0\er OK\er: +.Pp +This script waits for nothing (which always succeeds), sends +a sequence to ensure that the modem is in the correct mode +(suppress command echo, send responses in verbose mode), +and then disables auto-answer. +It waits for an "OK" response before it terminates. +The init sequence is used to check modem responses to ensure that +the modem is functioning correctly. +If the init script fails to complete, +.Nm getty +considers this to be fatal, and results in an error logged via +.Xr syslogd 8 , +and exiting. +.Pp +Similarly, an answer chat script is used to manually answer the +phone in response to (usually) a "RING". +When run with an answer script, +.Nm getty +opens the port in non-blocking mode, clears any extraneous input +and waits for data on the port. +As soon as any data is available, the answer chat script is +started and scanned for a string, and responds according to +the answer chat script. +With a hayes compatible modem, this would normally look something +like: +.Pp +.Dl :ac=RING\er ATA\er CONNECT: +.Pp +This causes the modem to answer the call via the "ATA" command, +then scans input for a "CONNECT" string. +If this is received before a +.Va \&ct +timeout, then a normal login sequence commences. +.Pp +The +.Va \&ct +capability specifies a timeout for all send and expect strings. +This timeout is set individually for each expect wait and send +string and must be at least as long as the time it takes for +a connection to be established between a remote and local +modem (usually around 10 seconds). +.Pp +In most situations, you will want to flush any additional +input after the connection has been detected, and the +.Va \&de +capability may be used to do that, as well as delay for a +short time after the connection has been established during +which all of the connection data has been sent by the modem. .Sh SEE ALSO .Xr login 1 , +.Xr gethostname 3 , +.Xr uname 3 , .Xr termcap 5 , -.Xr getty 8 . +.Xr getty 8 , +.Xr telnetd 8 +.Sh HISTORY +The +.Nm +file format appeared in +.Bx 4.2 . .Sh BUGS The special characters (erase, kill, etc.) are reset to system defaults by @@ -356,17 +534,13 @@ of the delay algorithms are not implemented. The terminal driver should support sane delay settings. .Pp The -.Em \&he +.Va \&he capability is stupid. .Pp The -.Xr termcap +.Xr termcap 5 format is horrid, something more rational should have been chosen. .Pp This should be converted to use .Xr termios 4 . -.Sh HISTORY -The -.Nm gettytab -file format appeared in 4.2BSD. diff --git a/getty.tproj/gettytab.h b/getty.tproj/gettytab.h index 2fcd79c..3addfe3 100644 --- a/getty.tproj/gettytab.h +++ b/getty.tproj/gettytab.h @@ -1,26 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ /* * Copyright (c) 1983, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -54,27 +31,27 @@ * SUCH DAMAGE. * * from: @(#)gettytab.h 8.2 (Berkeley) 3/30/94 - * $Id: gettytab.h,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $ + * $FreeBSD: src/libexec/getty/gettytab.h,v 1.14 2003/06/10 18:30:41 yar Exp $ */ /* * Getty description definitions. */ struct gettystrs { - char *field; /* name to lookup in gettytab */ + const char *field; /* name to lookup in gettytab */ char *defalt; /* value we find by looking in defaults */ char *value; /* value that we find there */ }; struct gettynums { - char *field; /* name to lookup */ + const char *field; /* name to lookup */ long defalt; /* number we find in defaults */ long value; /* number we find there */ int set; /* we actually got this one */ }; struct gettyflags { - char *field; /* name to lookup */ + const char *field; /* name to lookup */ char invrt; /* name existing in gettytab --> false */ char defalt; /* true/false in defaults */ char value; /* true/false flag */ @@ -108,6 +85,13 @@ struct gettyflags { #define FL gettystrs[21].value #define WE gettystrs[22].value #define LN gettystrs[23].value +#define Lo gettystrs[24].value +#define PP gettystrs[25].value +#define IF gettystrs[26].value +#define IC gettystrs[27].value +#define AC gettystrs[28].value +#define AL gettystrs[29].value +#define DF gettystrs[30].value /* * Numeric definitions. @@ -152,6 +136,11 @@ struct gettyflags { #define O1set gettynums[23].set #define O2 gettynums[24].value #define O2set gettynums[24].set +#define DE gettynums[25].value +#define RTset gettynums[26].set +#define RT gettynums[26].value +#define CT gettynums[27].value +#define DC gettynums[28].value /* * Boolean values. @@ -181,14 +170,8 @@ struct gettyflags { #define AB gettyflags[19].value #define DX gettyflags[20].value #define NP gettyflags[21].value +#define NPset gettyflags[21].set #define MB gettyflags[22].value - -int getent __P((char *, char *)); -long getnum __P((char *)); -int getflag __P((char *)); -char *getstr __P((char *, char **)); - -extern struct gettyflags gettyflags[]; -extern struct gettynums gettynums[]; -extern struct gettystrs gettystrs[]; -extern int hopcount; +#define HW gettyflags[23].value +#define NC gettyflags[24].value +#define PL gettyflags[25].value diff --git a/getty.tproj/init.c b/getty.tproj/init.c index 99c980a..7982b5c 100644 --- a/getty.tproj/init.c +++ b/getty.tproj/init.c @@ -1,26 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. @@ -55,8 +32,11 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)init.c 8.1 (Berkeley) 6/4/93";*/ -static char rcsid[] = "$Id: init.c,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $"; +#if 0 +static char sccsid[] = "@(#)from: init.c 8.1 (Berkeley) 6/4/93"; +#endif +static const char rcsid[] = + "$FreeBSD: src/libexec/getty/init.c,v 1.16 2005/04/06 17:42:24 stefanf Exp $"; #endif /* not lint */ /* @@ -66,36 +46,46 @@ static char rcsid[] = "$Id: init.c,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $" */ #include #include "gettytab.h" +#include "extern.h" #include "pathnames.h" -extern struct termios tmode; -extern char hostname[]; +static char loginmsg[] = "login: "; +static char nullstr[] = ""; +static char loginprg[] = _PATH_LOGIN; +static char datefmt[] = "%+"; struct gettystrs gettystrs[] = { { "nx" }, /* next table */ { "cl" }, /* screen clear characters */ { "im" }, /* initial message */ - { "lm", "login: " }, /* login message */ - { "er", &tmode.c_cc[VERASE] }, /* erase character */ - { "kl", &tmode.c_cc[VKILL] }, /* kill character */ - { "et", &tmode.c_cc[VEOF] }, /* eof chatacter (eot) */ - { "pc", "" }, /* pad character */ + { "lm", loginmsg }, /* login message */ + { "er", (char*)&omode.c_cc[VERASE] }, /* erase character */ + { "kl", (char*)&omode.c_cc[VKILL] }, /* kill character */ + { "et", (char*)&omode.c_cc[VEOF] }, /* eof chatacter (eot) */ + { "pc", nullstr }, /* pad character */ { "tt" }, /* terminal type */ { "ev" }, /* enviroment */ - { "lo", _PATH_LOGIN }, /* login program */ + { "lo", loginprg }, /* login program */ { "hn", hostname }, /* host name */ { "he" }, /* host name edit */ - { "in", &tmode.c_cc[VINTR] }, /* interrupt char */ - { "qu", &tmode.c_cc[VQUIT] }, /* quit char */ - { "xn", &tmode.c_cc[VSTART] }, /* XON (start) char */ - { "xf", &tmode.c_cc[VSTOP] }, /* XOFF (stop) char */ - { "bk", &tmode.c_cc[VEOL] }, /* brk char (alt \n) */ - { "su", &tmode.c_cc[VSUSP] }, /* suspend char */ - { "ds", &tmode.c_cc[VDSUSP] }, /* delayed suspend */ - { "rp", &tmode.c_cc[VREPRINT] },/* reprint char */ - { "fl", &tmode.c_cc[VDISCARD] },/* flush output */ - { "we", &tmode.c_cc[VWERASE] }, /* word erase */ - { "ln", &tmode.c_cc[VLNEXT] }, /* literal next */ + { "in", (char*)&omode.c_cc[VINTR] }, /* interrupt char */ + { "qu", (char*)&omode.c_cc[VQUIT] }, /* quit char */ + { "xn", (char*)&omode.c_cc[VSTART] }, /* XON (start) char */ + { "xf", (char*)&omode.c_cc[VSTOP] }, /* XOFF (stop) char */ + { "bk", (char*)&omode.c_cc[VEOL] }, /* brk char (alt \n) */ + { "su", (char*)&omode.c_cc[VSUSP] }, /* suspend char */ + { "ds", (char*)&omode.c_cc[VDSUSP] }, /* delayed suspend */ + { "rp", (char*)&omode.c_cc[VREPRINT] },/* reprint char */ + { "fl", (char*)&omode.c_cc[VDISCARD] },/* flush output */ + { "we", (char*)&omode.c_cc[VWERASE] }, /* word erase */ + { "ln", (char*)&omode.c_cc[VLNEXT] }, /* literal next */ + { "Lo" }, /* locale for strftime() */ + { "pp" }, /* ppp login program */ + { "if" }, /* sysv-like 'issue' filename */ + { "ic" }, /* modem init-chat */ + { "ac" }, /* modem answer-chat */ + { "al" }, /* user to auto-login */ + { "df", datefmt}, /* format for strftime() */ { 0 } }; @@ -125,8 +115,13 @@ struct gettynums gettynums[] = { { "o0" }, /* output o_flags */ { "o1" }, /* input o_flags */ { "o2" }, /* user mode o_flags */ - { 0 } + { "de" }, /* delay before sending 1st prompt */ + { "rt" }, /* reset timeout */ + { "ct" }, /* chat script timeout */ + { "dc" }, /* debug chat script value */ + { 0 } }; + struct gettyflags gettyflags[] = { { "ht", 0 }, /* has tabs */ @@ -152,5 +147,8 @@ struct gettyflags gettyflags[] = { { "dx", 0 }, /* set decctlq */ { "np", 0 }, /* no parity at all (8bit chars) */ { "mb", 0 }, /* do MDMBUF flow control */ + { "hw", 0 }, /* do CTSRTS flow control */ + { "nc", 0 }, /* set clocal (no carrier) */ + { "pl", 0 }, /* use PPP instead of login(1) */ { 0 } }; diff --git a/getty.tproj/main.c b/getty.tproj/main.c index 3eaa6da..c25373c 100644 --- a/getty.tproj/main.c +++ b/getty.tproj/main.c @@ -1,29 +1,7 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ /*- * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. + * Portions copyright (c) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,39 +32,50 @@ * SUCH DAMAGE. */ +#include #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/*static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";*/ -static char rcsid[] = "$Id: main.c,v 1.3 2004/08/26 00:32:22 lindak Exp $"; +#if 0 +static char sccsid[] = "@(#)from: main.c 8.1 (Berkeley) 6/20/93"; +#endif +static const char rcsid[] = + "$FreeBSD: src/libexec/getty/main.c,v 1.47 2005/04/06 17:42:24 stefanf Exp $"; #endif /* not lint */ #include -#include -#include #include +#include #include +#include +#include #include -#include -#include -#include + #include +#include #include +#include +#include #include #include #include #include #include +#include #include #include +#ifdef __APPLE__ +#include +#endif + #include "gettytab.h" -#include "pathnames.h" #include "extern.h" +#include "pathnames.h" /* * Set the amount of running time that getty should accumulate @@ -94,23 +83,37 @@ static char rcsid[] = "$Id: main.c,v 1.3 2004/08/26 00:32:22 lindak Exp $"; */ #define GETTY_TIMEOUT 60 /* seconds */ -struct termios tmode, omode; +#undef CTRL +#define CTRL(x) (x&037) + +/* defines for auto detection of incoming PPP calls (->PAP/CHAP) */ + +#define PPP_FRAME 0x7e /* PPP Framing character */ +#define PPP_STATION 0xff /* "All Station" character */ +#define PPP_ESCAPE 0x7d /* Escape Character */ +#define PPP_CONTROL 0x03 /* PPP Control Field */ +#define PPP_CONTROL_ESCAPED 0x23 /* PPP Control Field, escaped */ +#define PPP_LCP_HI 0xc0 /* LCP protocol - high byte */ +#define PPP_LCP_LOW 0x21 /* LCP protocol - low byte */ + +/* original mode; flags've been reset using values from */ +struct termios omode; +/* current mode */ +struct termios tmode; int crmod, digit, lower, upper; char hostname[MAXHOSTNAMELEN]; -struct utsname kerninfo; -char name[MAXLOGNAME+1]; +char name[MAXLOGNAME*3]; char dev[] = _PATH_DEV; char ttyn[32]; -char *portselector(); -char *ttyname(); #define OBUFSIZ 128 #define TABBUFSIZ 512 char defent[TABBUFSIZ]; char tabent[TABBUFSIZ]; +const char *tname; char *env[128]; @@ -137,68 +140,71 @@ char partab[] = { #define KILL tmode.c_cc[VKILL] #define EOT tmode.c_cc[VEOF] +#define puts Gputs + +static void defttymode(void); +static void dingdong(int); +static void dogettytab(void); +static int getname(void); +static void interrupt(int); +static void oflush(void); +static void prompt(void); +static void putchr(int); +static void putf(const char *); +static void putpad(const char *); +static void puts(const char *); +static void timeoverrun(int); +static char *getline(int); +static void setttymode(int); +static int opentty(const char *, int); + jmp_buf timeout; static void -dingdong() +dingdong(int signo __unused) { - alarm(0); - signal(SIGALRM, SIG_DFL); longjmp(timeout, 1); } jmp_buf intrupt; static void -interrupt() +interrupt(int signo __unused) { - - signal(SIGINT, interrupt); longjmp(intrupt, 1); } /* * Action to take when getty is running too long. */ -void -timeoverrun(signo) - int signo; +static void +timeoverrun(int signo __unused) { - syslog(LOG_ERR, "getty exiting due to excessive running time\n"); + syslog(LOG_ERR, "getty exiting due to excessive running time"); exit(1); } -static int getname __P((void)); -static void oflush __P((void)); -static void prompt __P((void)); -static void putchr __P((int)); -static void putf __P((char *)); -static void putpad __P((char *)); -static void puts __P((char *)); - int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { - extern char **environ; - char *tname; - long allflags; - int repcnt = 0; + extern char **environ; + int first_sleep = 1, first_time = 1; struct rlimit limit; - int ttyopenmode; + int rval; +#ifdef __APPLE__ + int ttyopenmode = O_RDWR; +#endif signal(SIGINT, SIG_IGN); -/* - signal(SIGQUIT, SIG_DFL); -*/ - openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH); - gethostname(hostname, sizeof(hostname)); + signal(SIGQUIT, SIG_IGN); + + openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH); + gethostname(hostname, sizeof(hostname) - 1); + hostname[sizeof(hostname) - 1] = '\0'; if (hostname[0] == '\0') strcpy(hostname, "Amnesiac"); - uname(&kerninfo); /* * Limit running time to deal with broken or dead lines. @@ -208,134 +214,225 @@ main(argc, argv) limit.rlim_cur = GETTY_TIMEOUT; (void)setrlimit(RLIMIT_CPU, &limit); + gettable("default", defent); + gendefaults(); + tname = "default"; + if (argc > 1) + tname = argv[1]; + /* * The following is a work around for vhangup interactions * which cause great problems getting window systems started. * If the tty line is "-", we do the old style getty presuming - * that the file descriptors are already set up for us. + * that the file descriptors are already set up for us. * J. Gettys - MIT Project Athena. */ if (argc <= 2 || strcmp(argv[2], "-") == 0) - strcpy(ttyn, ttyname(0)); +#ifdef __APPLE__ + { + // + char* n = ttyname(STDIN_FILENO); + if (n) { + strlcpy(ttyn, n, sizeof(ttyn)); + } else { + syslog(LOG_ERR, "ttyname %m"); + exit(1); + } + } +#else + strcpy(ttyn, ttyname(STDIN_FILENO)); +#endif else { - int i; - strcpy(ttyn, dev); strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); if (strcmp(argv[0], "+") != 0) { chown(ttyn, 0, 0); chmod(ttyn, 0600); revoke(ttyn); + + /* + * Do the first scan through gettytab. + * Terminal mode parameters will be wrong until + * defttymode() called, but they're irrelevant for + * the initial setup of the terminal device. + */ + dogettytab(); + +#if defined(__APPLE__) && !TARGET_OS_EMBEDDED + if (strncmp(ttyn, _PATH_CONSOLE, sizeof(ttyn)) == 0) + ttyopenmode |= O_POPUP; +#endif /* - * Delay the open so DTR stays down long enough to be detected. + * Init or answer modem sequence has been specified. */ - sleep(2); + if (IC || AC) { #ifdef __APPLE__ - ttyopenmode = ((strcmp(ttyn, _PATH_CONSOLE)==0) - ? (O_RDWR |O_POPUP): O_RDWR); -#else /* __APPLE __ */ - ttyopenmode = O_RDWR; -#endif /* __APPLE__ */ - - while ((i = open(ttyn, ttyopenmode)) == -1) { - if (repcnt % 10 == 0) { - syslog(LOG_ERR, "%s: %m", ttyn); - closelog(); + if (!opentty(ttyn, ttyopenmode)) +#else + if (!opentty(ttyn, O_RDWR|O_NONBLOCK)) +#endif + exit(1); + defttymode(); + setttymode(1); + } + + if (IC) { + if (getty_chat(IC, CT, DC) > 0) { + syslog(LOG_ERR, "modem init problem on %s", ttyn); + (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); + exit(1); } - repcnt++; - sleep(60); } - login_tty(i); - } - } - /* Start with default tty settings */ - if (tcgetattr(0, &tmode) < 0) { - syslog(LOG_ERR, "%s: %m", ttyn); - exit(1); + if (AC) { + int i, rfds; + struct timeval to; + + rfds = 1 << 0; /* FD_SET */ + to.tv_sec = RT; + to.tv_usec = 0; + i = select(32, (fd_set*)&rfds, (fd_set*)NULL, + (fd_set*)NULL, RT ? &to : NULL); + if (i < 0) { + syslog(LOG_ERR, "select %s: %m", ttyn); + } else if (i == 0) { + syslog(LOG_NOTICE, "recycle tty %s", ttyn); + (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); + exit(0); /* recycle for init */ + } + i = getty_chat(AC, CT, DC); + if (i > 0) { + syslog(LOG_ERR, "modem answer problem on %s", ttyn); + (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); + exit(1); + } + } else { /* maybe blocking open */ +#ifdef __APPLE__ + if (!opentty(ttyn, ttyopenmode | (NC ? O_NONBLOCK : 0 ))) +#else + if (!opentty(ttyn, O_RDWR | (NC ? O_NONBLOCK : 0 ))) +#endif + exit(1); + } + } } - omode = tmode; - gettable("default", defent); - gendefaults(); - tname = "default"; - if (argc > 1) - tname = argv[1]; + defttymode(); for (;;) { - int off; - - gettable(tname, tabent); - if (OPset || EPset || APset) - APset++, OPset++, EPset++; - setdefaults(); - off = 0; - ioctl(0, TIOCFLUSH, &off); /* clear out the crap */ - ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ - ioctl(0, FIOASYNC, &off); /* ditto for async mode */ - - if (IS) - cfsetispeed(&tmode, IS); - else if (SP) - cfsetispeed(&tmode, SP); - if (OS) - cfsetospeed(&tmode, OS); - else if (SP) - cfsetospeed(&tmode, SP); - setflags(0); - setchars(); - if (tcsetattr(0, TCSANOW, &tmode) < 0) { - syslog(LOG_ERR, "%s: %m", ttyn); - exit(1); + + /* + * if a delay was specified then sleep for that + * number of seconds before writing the initial prompt + */ + if (first_sleep && DE) { + sleep(DE); + /* remove any noise */ + (void)tcflush(STDIN_FILENO, TCIOFLUSH); } - if (AB) { - extern char *autobaud(); + first_sleep = 0; + setttymode(0); + if (AB) { tname = autobaud(); + dogettytab(); continue; } if (PS) { tname = portselector(); + dogettytab(); continue; } if (CL && *CL) putpad(CL); edithost(HE); - if (IM && *IM) + + /* if this is the first time through this, and an + issue file has been given, then send it */ + if (first_time && IF) { + int fd; + + if ((fd = open(IF, O_RDONLY)) != -1) { + char * cp; + + while ((cp = getline(fd)) != NULL) { + putf(cp); + } + close(fd); + } + } + first_time = 0; + + if (IM && *IM && !(PL && PP)) putf(IM); if (setjmp(timeout)) { - tmode.c_ispeed = tmode.c_ospeed = 0; - (void)tcsetattr(0, TCSANOW, &tmode); + cfsetispeed(&tmode, B0); + cfsetospeed(&tmode, B0); + (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); exit(1); } if (TO) { signal(SIGALRM, dingdong); alarm(TO); } - if (getname()) { - register int i; + + rval = 0; + if (AL) { + const char *p = AL; + char *q = name; + + while (*p && q < &name[sizeof name - 1]) { + if (isupper(*p)) + upper = 1; + else if (islower(*p)) + lower = 1; + else if (isdigit(*p)) + digit = 1; + *q++ = *p++; + } + } else if (!(PL && PP)) + rval = getname(); + if (rval == 2 || (PL && PP)) { + oflush(); + alarm(0); + limit.rlim_max = RLIM_INFINITY; + limit.rlim_cur = RLIM_INFINITY; + (void)setrlimit(RLIMIT_CPU, &limit); + execle(PP, "ppplogin", ttyn, (char *) 0, env); + syslog(LOG_ERR, "%s: %m", PP); + exit(1); + } else if (rval || AL) { + int i; oflush(); alarm(0); signal(SIGALRM, SIG_DFL); + if (name[0] == '\0') + continue; if (name[0] == '-') { puts("user names may not start with '-'."); continue; } - if (!(upper || lower || digit)) - continue; - setflags(2); + if (!(upper || lower || digit)) { + if (AL) { + syslog(LOG_ERR, + "invalid auto-login name: %s", AL); + exit(1); + } else + continue; + } + set_flags(2); if (crmod) { tmode.c_iflag |= ICRNL; tmode.c_oflag |= ONLCR; } -#if XXX +#if REALLY_OLD_TTYS if (upper || UC) tmode.sg_flags |= LCASE; if (lower || LC) tmode.sg_flags &= ~LCASE; #endif - if (tcsetattr(0, TCSANOW, &tmode) < 0) { - syslog(LOG_ERR, "%s: %m", ttyn); + if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) { + syslog(LOG_ERR, "tcsetattr %s: %m", ttyn); exit(1); } signal(SIGINT, SIG_DFL); @@ -346,24 +443,120 @@ main(argc, argv) limit.rlim_max = RLIM_INFINITY; limit.rlim_cur = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &limit); - execle(LO, "login", "-p1", name, (char *) 0, env); +#ifdef __APPLE__ + // + execle(LO, "login", AL ? "-fp1" : "-p1", name, +#else + execle(LO, "login", AL ? "-fp" : "-p", name, +#endif + (char *) 0, env); syslog(LOG_ERR, "%s: %m", LO); exit(1); } alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGINT, SIG_IGN); - if (NX && *NX) + if (NX && *NX) { tname = NX; + dogettytab(); + } + } +} + +static int +opentty(const char *tty, int flags) +{ + int i; + int failopenlogged = 0; + + while ((i = open(tty, flags)) == -1) + { + if (!failopenlogged) { + syslog(LOG_ERR, "open %s: %m", tty); + failopenlogged = 1; + } + sleep(60); + } + if (login_tty(i) < 0) { +#ifndef __APPLE__ + if (daemon(0,0) < 0) { + syslog(LOG_ERR,"daemon: %m"); + close(i); + return 0; + } +#endif + if (login_tty(i) < 0) { + syslog(LOG_ERR, "login_tty %s: %m", tty); + close(i); + return 0; + } + } + return 1; +} + +static void +defttymode() +{ + + /* Start with default tty settings. */ + if (tcgetattr(STDIN_FILENO, &tmode) < 0) { + syslog(LOG_ERR, "tcgetattr %s: %m", ttyn); + exit(1); + } + omode = tmode; /* fill c_cc for dogettytab() */ + dogettytab(); + /* + * Don't rely on the driver too much, and initialize crucial + * things according to . Avoid clobbering + * the c_cc[] settings however, the console drivers might wish + * to leave their idea of the preferred VERASE key value + * there. + */ + tmode.c_iflag = TTYDEF_IFLAG; + tmode.c_oflag = TTYDEF_OFLAG; + tmode.c_lflag = TTYDEF_LFLAG; + tmode.c_cflag = TTYDEF_CFLAG; + if (NC) + tmode.c_cflag |= CLOCAL; + omode = tmode; +} + +static void +setttymode(int raw) +{ + int off = 0; + + (void)tcflush(STDIN_FILENO, TCIOFLUSH); /* clear out the crap */ + ioctl(STDIN_FILENO, FIONBIO, &off); /* turn off non-blocking mode */ + ioctl(STDIN_FILENO, FIOASYNC, &off); /* ditto for async mode */ + + if (IS) + cfsetispeed(&tmode, speed(IS)); + else if (SP) + cfsetispeed(&tmode, speed(SP)); + if (OS) + cfsetospeed(&tmode, speed(OS)); + else if (SP) + cfsetospeed(&tmode, speed(SP)); + set_flags(0); + setchars(); + if (raw) + cfmakeraw(&tmode); + if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) { + syslog(LOG_ERR, "tcsetattr %s: %m", ttyn); + exit(1); } } + static int -getname() +getname(void) { - register int c; - register char *np; - char cs; + int c; + char *np; + unsigned char cs; + int ppp_state = 0; + int ppp_connection = 0; /* * Interrupt may happen if we use CBREAK mode @@ -373,14 +566,14 @@ getname() return (0); } signal(SIGINT, interrupt); - setflags(1); + set_flags(1); prompt(); + oflush(); if (PF > 0) { - oflush(); sleep(PF); PF = 0; } - if (tcsetattr(0, TCSANOW, &tmode) < 0) { + if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) { syslog(LOG_ERR, "%s: %m", ttyn); exit(1); } @@ -392,8 +585,36 @@ getname() exit(0); if ((c = cs&0177) == 0) return (0); - if (c == EOT) - exit(1); + + /* PPP detection state machine.. + Look for sequences: + PPP_FRAME, PPP_STATION, PPP_ESCAPE, PPP_CONTROL_ESCAPED or + PPP_FRAME, PPP_STATION, PPP_CONTROL (deviant from RFC) + See RFC1662. + Derived from code from Michael Hancock, + and Erik 'PPP' Olson, + */ + + if (PP && (cs == PPP_FRAME)) { + ppp_state = 1; + } else if (ppp_state == 1 && cs == PPP_STATION) { + ppp_state = 2; + } else if (ppp_state == 2 && cs == PPP_ESCAPE) { + ppp_state = 3; + } else if ((ppp_state == 2 && cs == PPP_CONTROL) + || (ppp_state == 3 && cs == PPP_CONTROL_ESCAPED)) { + ppp_state = 4; + } else if (ppp_state == 4 && cs == PPP_LCP_HI) { + ppp_state = 5; + } else if (ppp_state == 5 && cs == PPP_LCP_LOW) { + ppp_connection = 1; + break; + } else { + ppp_state = 0; + } + + if (c == EOT || c == CTRL('d')) + exit(0); if (c == '\r' || c == '\n' || np >= &name[sizeof name-1]) { putf("\r\n"); break; @@ -402,7 +623,7 @@ getname() lower = 1; else if (isupper(c)) upper = 1; - else if (c == ERASE || c == '#' || c == '\b') { + else if (c == ERASE || c == '\b' || c == 0177) { if (np > name) { np--; if (cfgetospeed(&tmode) >= 1200) @@ -411,8 +632,7 @@ getname() putchr(cs); } continue; - } else if (c == KILL || c == '@') { - putchr(cs); + } else if (c == KILL || c == CTRL('u')) { putchr('\r'); if (cfgetospeed(&tmode) < 1200) putchr('\n'); @@ -420,10 +640,11 @@ getname() else if (np > name) puts(" \r"); prompt(); + digit = lower = upper = 0; np = name; continue; } else if (isdigit(c)) - digit++; + digit = 1; if (IG && (c <= ' ' || c > 0176)) continue; *np++ = c; @@ -433,18 +654,17 @@ getname() *np = 0; if (c == '\r') crmod = 1; - if (upper && !lower && !LC || UC) + if ((upper && !lower && !LC) || UC) for (np = name; *np; np++) if (isupper(*np)) *np = tolower(*np); - return (1); + return (1 + ppp_connection); } static void -putpad(s) - register char *s; +putpad(const char *s) { - register pad = 0; + int pad = 0; speed_t ospeed = cfgetospeed(&tmode); if (isdigit(*s)) { @@ -479,8 +699,7 @@ putpad(s) } static void -puts(s) - register char *s; +puts(const char *s) { while (*s) putchr(*s++); @@ -490,8 +709,7 @@ char outbuf[OBUFSIZ]; int obufcnt = 0; static void -putchr(cc) - int cc; +putchr(int cc) { char c; @@ -510,7 +728,7 @@ putchr(cc) } static void -oflush() +oflush(void) { if (obufcnt) write(STDOUT_FILENO, outbuf, obufcnt); @@ -518,7 +736,7 @@ oflush() } static void -prompt() +prompt(void) { putf(LM); @@ -526,14 +744,43 @@ prompt() putchr('\n'); } + +static char * +getline(int fd) +{ + int i = 0; + static char linebuf[512]; + + /* + * This is certainly slow, but it avoids having to include + * stdio.h unnecessarily. Issue files should be small anyway. + */ + while (i < (sizeof linebuf - 3) && read(fd, linebuf+i, 1)==1) { + if (linebuf[i] == '\n') { + /* Don't rely on newline mode, assume raw */ + linebuf[i++] = '\r'; + linebuf[i++] = '\n'; + linebuf[i] = '\0'; + return linebuf; + } + ++i; + } + linebuf[i] = '\0'; + return i ? linebuf : 0; +} + static void -putf(cp) - register char *cp; +putf(const char *cp) { extern char editedhost[]; time_t t; char *slash, db[100]; + static struct utsname kerninfo; + + if (!*kerninfo.sysname) + uname(&kerninfo); + while (*cp) { if (*cp != '%') { putchr(*cp++); @@ -554,11 +801,11 @@ putf(cp) break; case 'd': { - static char fmt[] = "%l:% %P on %A, %d %B %Y"; - - fmt[4] = 'M'; /* I *hate* SCCS... */ + t = (time_t)0; (void)time(&t); - (void)strftime(db, sizeof(db), fmt, localtime(&t)); + if (Lo) + (void)setlocale(LC_TIME, Lo); + (void)strftime(db, sizeof(db), DF, localtime(&t)); puts(db); break; @@ -586,3 +833,25 @@ putf(cp) cp++; } } + +/* + * Read a gettytab database entry and perform necessary quirks. + */ +static void +dogettytab() +{ + + /* Read the database entry. */ + gettable(tname, tabent); + + /* + * Avoid inheriting the parity values from the default entry + * if any of them is set in the current entry. + * Mixing different parity settings is unreasonable. + */ + if (OPset || EPset || APset || NPset) + OPset = EPset = APset = NPset = 1; + + /* Fill in default values for unset capabilities. */ + setdefaults(); +} diff --git a/getty.tproj/pathnames.h b/getty.tproj/pathnames.h index 909042a..2c64fd1 100644 --- a/getty.tproj/pathnames.h +++ b/getty.tproj/pathnames.h @@ -1,26 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -54,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)pathnames.h 8.1 (Berkeley) 6/4/93 - * $Id: pathnames.h,v 1.1.1.2 2000/01/11 02:10:14 wsanchez Exp $ + * $FreeBSD: src/libexec/getty/pathnames.h,v 1.7 1999/08/28 00:09:36 peter Exp $ */ #include diff --git a/getty.tproj/subr.c b/getty.tproj/subr.c index 83fe9b4..5c3fb85 100644 --- a/getty.tproj/subr.c +++ b/getty.tproj/subr.c @@ -1,26 +1,3 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. @@ -55,87 +32,161 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)subr.c 8.1 (Berkeley) 6/4/93";*/ -static char rcsid[] = "$Id: subr.c,v 1.2 2004/09/30 22:57:04 lindak Exp $"; +#if 0 +static char sccsid[] = "@(#)from: subr.c 8.1 (Berkeley) 6/4/93"; +#endif +static const char rcsid[] = + "$FreeBSD: src/libexec/getty/subr.c,v 1.19 2004/06/25 10:11:28 phk Exp $"; #endif /* not lint */ /* * Melbourne getty. */ -#define COMPAT_43_TTY 1 +#ifdef DEBUG +#include +#endif #include -#include #include #include +#include #include +#include +#include +#include #include "gettytab.h" #include "pathnames.h" #include "extern.h" -extern struct termios tmode, omode; -static void compatflags __P((long)); /* * Get a table entry. */ void -gettable(name, buf) - char *name, *buf; +gettable(const char *name, char *buf) { - register struct gettystrs *sp; - register struct gettynums *np; - register struct gettyflags *fp; + struct gettystrs *sp; + struct gettynums *np; + struct gettyflags *fp; long n; - char *dba[2]; + int l; + char *p; + char *msg = NULL; + const char *dba[2]; + + static int firsttime = 1; + dba[0] = _PATH_GETTYTAB; dba[1] = 0; - if (cgetent(&buf, dba, name) != 0) + if (firsttime) { + /* + * we need to strdup() anything in the strings array + * initially in order to simplify things later + */ + for (sp = gettystrs; sp->field; sp++) + if (sp->value != NULL) { + /* handle these ones more carefully */ + if (sp >= &gettystrs[4] && sp <= &gettystrs[6]) + l = 2; + else + l = strlen(sp->value) + 1; + if ((p = malloc(l)) != NULL) { + strncpy(p, sp->value, l); + p[l-1] = '\0'; + } + /* + * replace, even if NULL, else we'll + * have problems with free()ing static mem + */ + sp->value = p; + } + firsttime = 0; + } + + switch (cgetent(&buf, (char **)dba, (char *)name)) { + case 1: + msg = "%s: couldn't resolve 'tc=' in gettytab '%s'"; + case 0: + break; + case -1: + msg = "%s: unknown gettytab entry '%s'"; + break; + case -2: + msg = "%s: retrieving gettytab entry '%s': %m"; + break; + case -3: + msg = "%s: recursive 'tc=' reference gettytab entry '%s'"; + break; + default: + msg = "%s: unexpected cgetent() error for entry '%s'"; + break; + } + + if (msg != NULL) { + syslog(LOG_ERR, msg, "getty", name); return; + } + + for (sp = gettystrs; sp->field; sp++) { + if ((l = cgetstr(buf, (char*)sp->field, &p)) >= 0) { + if (sp->value) { + /* prefer existing value */ + if (strcmp(p, sp->value) != 0) + free(sp->value); + else { + free(p); + p = sp->value; + } + } + sp->value = p; + } else if (l == -1) { + free(sp->value); + sp->value = NULL; + } + } - for (sp = gettystrs; sp->field; sp++) - cgetstr(buf, sp->field, &sp->value); for (np = gettynums; np->field; np++) { - if (cgetnum(buf, np->field, &n) == -1) + if (cgetnum(buf, (char*)np->field, &n) == -1) np->set = 0; else { np->set = 1; np->value = n; } } + for (fp = gettyflags; fp->field; fp++) { - if (cgetcap(buf, fp->field, ':') == NULL) + if (cgetcap(buf, (char *)fp->field, ':') == NULL) fp->set = 0; else { fp->set = 1; fp->value = 1 ^ fp->invrt; } } + #ifdef DEBUG - printf("name=\"%s\", buf=\"%s\"\n", name, buf); + printf("name=\"%s\", buf=\"%s\"\r\n", name, buf); for (sp = gettystrs; sp->field; sp++) - printf("cgetstr: %s=%s\n", sp->field, sp->value); + printf("cgetstr: %s=%s\r\n", sp->field, sp->value); for (np = gettynums; np->field; np++) - printf("cgetnum: %s=%d\n", np->field, np->value); + printf("cgetnum: %s=%d\r\n", np->field, np->value); for (fp = gettyflags; fp->field; fp++) - printf("cgetflags: %s='%c' set='%c'\n", fp->field, + printf("cgetflags: %s='%c' set='%c'\r\n", fp->field, fp->value + '0', fp->set + '0'); - exit(1); #endif /* DEBUG */ } void -gendefaults() +gendefaults(void) { - register struct gettystrs *sp; - register struct gettynums *np; - register struct gettyflags *fp; + struct gettystrs *sp; + struct gettynums *np; + struct gettyflags *fp; for (sp = gettystrs; sp->field; sp++) if (sp->value) - sp->defalt = sp->value; + sp->defalt = strdup(sp->value); for (np = gettynums; np->field; np++) if (np->set) np->defalt = np->value; @@ -147,15 +198,16 @@ gendefaults() } void -setdefaults() +setdefaults(void) { - register struct gettystrs *sp; - register struct gettynums *np; - register struct gettyflags *fp; + struct gettystrs *sp; + struct gettynums *np; + struct gettyflags *fp; for (sp = gettystrs; sp->field; sp++) if (!sp->value) - sp->value = sp->defalt; + sp->value = !sp->defalt ? sp->defalt + : strdup(sp->defalt); for (np = gettynums; np->field; np++) if (!np->set) np->value = np->defalt; @@ -172,18 +224,28 @@ charnames[] = { static char * charvars[] = { - &tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR], - &tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP], - &tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP], - &tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD], - &tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0 + (char*)&tmode.c_cc[VERASE], + (char*)&tmode.c_cc[VKILL], + (char*)&tmode.c_cc[VINTR], + (char*)&tmode.c_cc[VQUIT], + (char*)&tmode.c_cc[VSTART], + (char*)&tmode.c_cc[VSTOP], + (char*)&tmode.c_cc[VEOF], + (char*)&tmode.c_cc[VEOL], + (char*)&tmode.c_cc[VSUSP], + (char*)&tmode.c_cc[VDSUSP], + (char*)&tmode.c_cc[VREPRINT], + (char*)&tmode.c_cc[VDISCARD], + (char*)&tmode.c_cc[VWERASE], + (char*)&tmode.c_cc[VLNEXT], + 0 }; void -setchars() +setchars(void) { - register int i; - register char *p; + int i; + const char *p; for (i = 0; charnames[i]; i++) { p = *charnames[i]; @@ -194,34 +256,16 @@ setchars() } } +/* Macros to clear/set/test flags. */ +#define SET(t, f) (t) |= (f) +#define CLR(t, f) (t) &= ~(f) +#define ISSET(t, f) ((t) & (f)) + void -setflags(n) - int n; +set_flags(int n) { - register tcflag_t iflag, oflag, cflag, lflag; + tcflag_t iflag, oflag, cflag, lflag; -#ifdef COMPAT_43 - switch (n) { - case 0: - if (F0set) { - compatflags(F0); - return; - } - break; - case 1: - if (F1set) { - compatflags(F1); - return; - } - break; - default: - if (F2set) { - compatflags(F2); - return; - } - break; - } -#endif switch (n) { case 0: @@ -253,31 +297,33 @@ setflags(n) break; } -#define BIC(v,c) (v) &= ~(c) -#define BIS(v,s) (v) |= (s) -#define BICS(v,c,s) BIC(v,c),BIS(v,s) - iflag = omode.c_iflag; oflag = omode.c_oflag; cflag = omode.c_cflag; lflag = omode.c_lflag; if (NP) { - BIC(iflag, ISTRIP|INPCK|IGNPAR); - BICS(cflag, CSIZE|PARENB|PARODD, CS8); - } else if (OP && !EP) { - BIS(iflag, ISTRIP|INPCK|IGNPAR); - BICS(cflag, CSIZE, PARENB|PARODD|CS7); - if (AP) - BIC(iflag, INPCK); - } else if (EP && !OP) { - BIS(iflag, ISTRIP|INPCK|IGNPAR); - BICS(cflag, CSIZE|PARODD, PARENB|CS7); - if (AP) - BIC(iflag, INPCK); - } else if (AP || EP && OP) { - BICS(iflag, INPCK|IGNPAR, ISTRIP); - BICS(cflag, CSIZE|PARODD, PARENB|CS7); + CLR(cflag, CSIZE|PARENB); + SET(cflag, CS8); + CLR(iflag, ISTRIP|INPCK|IGNPAR); + } else if (AP || EP || OP) { + CLR(cflag, CSIZE); + SET(cflag, CS7|PARENB); + SET(iflag, ISTRIP); + if (OP && !EP) { + SET(iflag, INPCK|IGNPAR); + SET(cflag, PARODD); + if (AP) + CLR(iflag, INPCK); + } else if (EP && !OP) { + SET(iflag, INPCK|IGNPAR); + CLR(cflag, PARODD); + if (AP) + CLR(iflag, INPCK); + } else if (AP || (EP && OP)) { + CLR(iflag, INPCK|IGNPAR); + CLR(cflag, PARODD); + } } /* else, leave as is */ #if 0 @@ -286,66 +332,87 @@ setflags(n) #endif if (HC) - cflag |= HUPCL; + SET(cflag, HUPCL); + else + CLR(cflag, HUPCL); + + if (MB) + SET(cflag, MDMBUF); + else + CLR(cflag, MDMBUF); + + if (HW) + SET(cflag, CRTSCTS); else - cflag &= ~HUPCL; + CLR(cflag, CRTSCTS); if (NL) { - iflag |= ICRNL; - oflag |= ONLCR; + SET(iflag, ICRNL); + SET(oflag, ONLCR|OPOST); + } else { + CLR(iflag, ICRNL); + CLR(oflag, ONLCR); } + if (!HT) + SET(oflag, OXTABS|OPOST); + else + CLR(oflag, OXTABS); + #ifdef XXX_DELAY - f |= delaybits(); + SET(f, delaybits()); #endif if (n == 1) { /* read mode flags */ if (RW) { iflag = 0; - oflag = 0; - cflag = CREAD|CS8; + CLR(oflag, OPOST); + CLR(cflag, CSIZE|PARENB); + SET(cflag, CS8); lflag = 0; } else { - lflag &= ~ICANON; + CLR(lflag, ICANON); } goto out; } - if (HT) - oflag &= ~OXTABS; - else - oflag |= OXTABS; - if (n == 0) goto out; #if 0 if (CB) - f |= CRTBS; + SET(f, CRTBS); #endif if (CE) - lflag |= ECHOE; + SET(lflag, ECHOE); + else + CLR(lflag, ECHOE); if (CK) - lflag |= ECHOKE; + SET(lflag, ECHOKE); + else + CLR(lflag, ECHOKE); if (PE) - lflag |= ECHOPRT; + SET(lflag, ECHOPRT); + else + CLR(lflag, ECHOPRT); if (EC) - lflag |= ECHO; + SET(lflag, ECHO); + else + CLR(lflag, ECHO); if (XC) - lflag |= ECHOCTL; + SET(lflag, ECHOCTL); + else + CLR(lflag, ECHOCTL); if (DX) - lflag |= IXANY; - - if (MB) - cflag |= MDMBUF; + SET(lflag, IXANY); else - cflag &= ~MDMBUF; + CLR(lflag, IXANY); out: tmode.c_iflag = iflag; @@ -354,140 +421,6 @@ out: tmode.c_lflag = lflag; } -#ifdef COMPAT_43 -/* - * Old TTY => termios, snatched from - */ -void -compatflags(flags) -register long flags; -{ - register tcflag_t iflag, oflag, cflag, lflag; - - iflag = (BRKINT|ICRNL|IMAXBEL|IXON|IXANY); - oflag = (OPOST|ONLCR|OXTABS); - cflag = (CREAD); - lflag = (ICANON|ISIG|IEXTEN); - - if (flags & TANDEM) - iflag |= IXOFF; - else - iflag &= ~IXOFF; - if (flags & ECHO) - lflag |= ECHO; - else - lflag &= ~ECHO; - if (flags & CRMOD) { - iflag |= ICRNL; - oflag |= ONLCR; - } else { - iflag &= ~ICRNL; - oflag &= ~ONLCR; - } - if (flags & XTABS) - oflag |= OXTABS; - else - oflag &= ~OXTABS; - - if (flags & RAW) { - iflag &= IXOFF; - lflag &= ~(ISIG|ICANON|IEXTEN); - } else { - iflag |= BRKINT|IXON|IMAXBEL; - lflag |= ISIG|IEXTEN; - if (flags & CBREAK) - lflag &= ~ICANON; - else - lflag |= ICANON; - } - - switch (flags & ANYP) { - case EVENP: - iflag |= INPCK; - cflag &= ~PARODD; - break; - case ODDP: - iflag |= INPCK; - cflag |= PARODD; - break; - default: - iflag &= ~INPCK; - break; - } - - if (flags & (RAW|LITOUT|PASS8)) { - cflag &= ~(CSIZE|PARENB); - cflag |= CS8; - if ((flags & (RAW|PASS8)) == 0) - iflag |= ISTRIP; - else - iflag &= ~ISTRIP; - if ((flags & (RAW|LITOUT)) == 0) - oflag |= OPOST; - else - oflag &= ~OPOST; - } else { - cflag &= ~CSIZE; - cflag |= CS7|PARENB; - iflag |= ISTRIP; - oflag |= OPOST; - } - - if (flags & PRTERA) - lflag |= ECHOPRT; - else - lflag &= ~ECHOPRT; - if (flags & CRTERA) - lflag |= ECHOE; - else - lflag &= ~ECHOE; - if (flags & MDMBUF) - cflag |= MDMBUF; - else - cflag &= ~MDMBUF; - if (flags & NOHANG) - cflag &= ~HUPCL; - else - cflag |= HUPCL; - if (flags & CRTKIL) - lflag |= ECHOKE; - else - lflag &= ~ECHOKE; - if (flags & CTLECH) - lflag |= ECHOCTL; - else - lflag &= ~ECHOCTL; - if ((flags & DECCTQ) == 0) - lflag |= IXANY; - else - lflag &= ~IXANY; - lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); - lflag |= flags & (TOSTOP|FLUSHO|PENDIN|NOFLSH); - - if (flags & (RAW|LITOUT|PASS8)) { - cflag &= ~(CSIZE|PARENB); - cflag |= CS8; - if ((flags & (RAW|PASS8)) == 0) - iflag |= ISTRIP; - else - iflag &= ~ISTRIP; - if ((flags & (RAW|LITOUT)) == 0) - oflag |= OPOST; - else - oflag &= ~OPOST; - } else { - cflag &= ~CSIZE; - cflag |= CS7|PARENB; - iflag |= ISTRIP; - oflag |= OPOST; - } - - tmode.c_iflag = iflag; - tmode.c_oflag = oflag; - tmode.c_cflag = cflag; - tmode.c_lflag = lflag; -} -#endif #ifdef XXX_DELAY struct delayval { @@ -528,17 +461,17 @@ struct delayval ffdelay[] = { }; struct delayval tbdelay[] = { - { 1, TAB1 }, - { 2, TAB2 }, + { 1, TAB1 }, + { 2, TAB2 }, { 3, XTABS }, /* this is expand tabs */ - { 100, TAB1 }, - { 0, TAB2 }, + { 100, TAB1 }, + { 0, TAB2 }, }; int -delaybits() +delaybits(void) { - register int f; + int f; f = adelay(CD, crdelay); f |= adelay(ND, nldelay); @@ -549,9 +482,7 @@ delaybits() } int -adelay(ms, dp) - register ms; - register struct delayval *dp; +adelay(int ms, struct delayval *dp) { if (ms == 0) return (0); @@ -561,14 +492,13 @@ adelay(ms, dp) } #endif -char editedhost[32]; +char editedhost[MAXHOSTNAMELEN]; void -edithost(pat) - register char *pat; +edithost(const char *pat) { - register char *host = HN; - register char *res = editedhost; + const char *host = HN; + char *res = editedhost; if (!pat) pat = ""; @@ -603,22 +533,64 @@ edithost(pat) editedhost[sizeof editedhost - 1] = '\0'; } +static struct speedtab { + int speed; + int uxname; +} speedtab[] = { + { 50, B50 }, + { 75, B75 }, + { 110, B110 }, + { 134, B134 }, + { 150, B150 }, + { 200, B200 }, + { 300, B300 }, + { 600, B600 }, + { 1200, B1200 }, + { 1800, B1800 }, + { 2400, B2400 }, + { 4800, B4800 }, + { 9600, B9600 }, + { 19200, EXTA }, + { 19, EXTA }, /* for people who say 19.2K */ + { 38400, EXTB }, + { 38, EXTB }, + { 7200, EXTB }, /* alternative */ + { 57600, B57600 }, + { 115200, B115200 }, + { 230400, B230400 }, + { 0 } +}; + +int +speed(int val) +{ + struct speedtab *sp; + + if (val <= B230400) + return (val); + + for (sp = speedtab; sp->speed; sp++) + if (sp->speed == val) + return (sp->uxname); + + return (B300); /* default in impossible cases */ +} + void -makeenv(env) - char *env[]; +makeenv(char *env[]) { static char termbuf[128] = "TERM="; - register char *p, *q; - register char **ep; + char *p, *q; + char **ep; ep = env; if (TT && *TT) { - strcat(termbuf, TT); + strlcat(termbuf, TT, sizeof(termbuf)); *ep++ = termbuf; } - if (p = EV) { + if ((p = EV)) { q = p; - while (q = strchr(q, ',')) { + while ((q = strchr(q, ','))) { *q++ = '\0'; *ep++ = p; p = q; @@ -636,8 +608,8 @@ makeenv(env) * The routine below returns the terminal type mapped from derived speed. */ struct portselect { - char *ps_baud; - char *ps_type; + const char *ps_baud; + const char *ps_type; } portspeeds[] = { { "B110", "std.110" }, { "B134", "std.134" }, @@ -652,11 +624,12 @@ struct portselect { { 0 } }; -char * -portselector() +const char * +portselector(void) { - char c, baud[20], *type = "default"; - register struct portselect *ps; + char c, baud[20]; + const char *type = "default"; + struct portselect *ps; int len; alarm(5*60); @@ -685,17 +658,15 @@ portselector() * portselector. Selection is done by looking at how the character '\r' * is garbled at the different speeds. */ -#include - -char * -autobaud() +const char * +autobaud(void) { int rfds; struct timeval timeout; - char c, *type = "9600-baud"; - int null = 0; + char c; + const char *type = "9600-baud"; - ioctl(0, TIOCFLUSH, &null); + (void)tcflush(0, TCIOFLUSH); rfds = 1 << 0; timeout.tv_sec = 5; timeout.tv_usec = 0; @@ -708,7 +679,7 @@ autobaud() timeout.tv_usec = 20; (void) select(32, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &timeout); - ioctl(0, TIOCFLUSH, &null); + (void)tcflush(0, TCIOFLUSH); switch (c & 0377) { case 0200: /* 300-baud */ diff --git a/getty.tproj/ttys.5 b/getty.tproj/ttys.5 index 3a2fc45..9a0a77c 100644 --- a/getty.tproj/ttys.5 +++ b/getty.tproj/ttys.5 @@ -30,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)ttys.5 8.1 (Berkeley) 6/4/93 -.\" $Id: ttys.5,v 1.1 1999/05/02 04:21:29 wsanchez Exp $ -.\" -.Dd June 4, 1993 +.\" $FreeBSD: src/libexec/getty/ttys.5,v 1.18 2005/06/14 08:40:10 ru Exp $ +.\" " +.Dd May 27, 2005 .Dt TTYS 5 .Os .Sh NAME @@ -40,14 +40,14 @@ .Nd terminal initialization information .Sh DESCRIPTION The file -.Nm ttys +.Nm contains information that is used by various routines to initialize and control the use of terminal special files. This information is read with the .Xr getttyent 3 library routines. -There is one line in the -.Nm ttys +There is one line in the +.Nm file per special device file. Fields are separated by tabs and/or spaces. Fields comprised of more than one word should be enclosed in double @@ -56,9 +56,11 @@ Blank lines and comments may appear anywhere in the file; comments are delimited by hash marks (``#'') and new lines. Any unspecified fields will default to null. .Pp -The first field is the +The first field is normally the name of the terminal special file as it is found in .Pa /dev . +However, it can be any arbitrary string +when the associated command is not related to a tty. .Pp The second field of the file is the command to execute for the line, usually @@ -76,7 +78,7 @@ tty line, normally the one found in the .Xr termcap 5 data base file. The environment variable -.Dv TERM +.Ev TERM is initialized with the value by either .Xr getty 8 @@ -86,13 +88,13 @@ or The remaining fields set flags in the .Fa ty_status entry (see -.Xr getttyent 3 ) -or specify a window system process that -.Xr init 8 +.Xr getttyent 3 ) , +specify a window system process that +.Xr launchd 8 will maintain for the terminal line. .Pp As flag values, the strings ``on'' and ``off'' specify that -.Xr init +.Xr launchd 8 should (should not) execute the command given in the second field, while ``secure'' (if ``on'' is also specified) allows users with a uid of 0 to login on @@ -113,30 +115,43 @@ These flag fields should not be quoted. .Pp The string ``window='' may be followed by a quoted command string which -.Xr init +.Xr launchd 8 will execute .Em before starting the command specified by the second field. +.Sh FILES +.Bl -tag -width /etc/ttys -compact +.It Pa /etc/ttys +.El +.Sh NUMERIC SEQUENCES +Numeric sequences of terminals can be represented in a more compact format. +A matching pair of square bracket may enclose two numbers (the start and +stop values), separated by a hyphen. +The numbers are assumed to be decimal, unless prefixed with ``0x'', in which +case they are interpreted as hexadecimal. +The number of characters (not including any ``0x'') in the starting value gives +the minimum width; sequence values are zero padded up to this width. +Thus ``tty[00-07]'' represents the eight terminals ``tty00'' through ``tty07''. .Sh EXAMPLES .Bd -literal # root login on console at 1200 baud console "/usr/libexec/getty std.1200" vt100 on secure # dialup at 1200 baud, no root logins -ttyd0 "/usr/libexec/getty d1200" dialup on # 555-1234 +ttyd0 "/usr/libexec/getty d1200" dialup on # 555-1234 # Mike's terminal: hp2621 -ttyh0 "/usr/libexec/getty std.9600" hp2621-nl on # 457 Evans +ttyh0 "/usr/libexec/getty std.9600" hp2621-nl on # 457 Evans # John's terminal: vt100 -ttyh1 "/usr/libexec/getty std.9600" vt100 on # 459 Evans +ttyh1 "/usr/libexec/getty std.9600" vt100 on # 459 Evans # terminal emulate/window system -ttyv0 "/usr/new/xterm -L :0" vs100 on window="/usr/new/Xvs100 0" +ttyv0 "/usr/X11/bin/xterm -display :0" xterm on window="/usr/X11/bin/X :0" +# the sequence of eight terminals tty00 through tty07 +tty[00-07] "/usr/libexec/getty std.9600" vt100 on # Network pseudo ttys -- don't enable getty -ttyp0 none network -ttyp1 none network off +ttyp0 none network +ttyp1 none network off +# All sixteen of a pseudo tty sequence +ttyq[0x0-0xf] none network .Ed -.Sh FILES -.Bl -tag -width /etc/ttys -compact -.It Pa /etc/ttys -.El .Sh SEE ALSO .Xr login 1 , .Xr getttyent 3 , @@ -144,8 +159,8 @@ ttyp1 none network off .Xr gettytab 5 , .Xr termcap 5 , .Xr getty 8 , -.Xr init 8 , -.Xr ttyflags 8 +.Xr launchd 8 +.\" .Xr ttyflags 8 .Sh HISTORY A .Nm diff --git a/hostinfo.tproj/hostinfo.c b/hostinfo.tproj/hostinfo.c index 5ea6c5c..65cd143 100644 --- a/hostinfo.tproj/hostinfo.c +++ b/hostinfo.tproj/hostinfo.c @@ -51,9 +51,9 @@ int slots[1024]; int main(int argc, char *argv[]) { kern_return_t ret; - int size; + unsigned int size, count; char *cpu_name, *cpu_subname; - int i, count; + int i; int mib[2]; size_t len; uint64_t memsize; diff --git a/iostat.tproj/iostat.8 b/iostat.tproj/iostat.8 index 4428877..a1487e7 100644 --- a/iostat.tproj/iostat.8 +++ b/iostat.tproj/iostat.8 @@ -69,8 +69,8 @@ .Tn I/O statistics .Sh SYNOPSIS -.Nm -.Op Fl CdKIoT?\& +.Nm iostat +.Op Fl CUdKIoT?\& .Op Fl c Ar count .Op Fl n Ar devs .Op Fl w Ar wait @@ -87,6 +87,16 @@ averaged over that time. .Pp The options are as follows: .Bl -tag -width flag +.\" ========== +.It Fl ?\& +Display a usage statement and exit. +.\" ========== +.It Fl C +Display CPU statistics. +This is on by default, unless +.Fl d +is specified. +.\" ========== .It Fl c Repeat the display .Ar count @@ -94,35 +104,37 @@ times. If no .Ar wait interval is specified, the default is 1 second. -.It Fl C -Display CPU statistics. -This is on by default, unless -.Fl d -is specified. +.\" ========== .It Fl d Display only device statistics. If this flag is turned on, only device statistics will be displayed, unless .Fl C or +.Fl U +or .Fl T -is also specfied to enable the display of CPU or TTY statistics. +is also specfied to enable the display of CPU, load average or TTY statistics. +.\" ========== .It Fl I Display total statstics for a given time period, rather than average statistics for each second during that time period. +.\" ========== .It Fl K In the blocks transferred display (-o), display block count in kilobytes rather then the device native block size. +.\" ========== .It Fl n Display up to .Ar devs number of devices. -.Nm +.Nm iostat will display fewer devices if there aren't .Ar devs devices present. +.\" ========== .It Fl o Display old-style -.Nm +.Nm iostat device statistics. Sectors per second, transfers per second, and miliseconds per seek are displayed. @@ -130,11 +142,19 @@ If .Fl I is specified, total blocks/sectors, total transfers, and miliseconds per seek are displayed. +.\" ========== .It Fl T Display TTY statistics. This is on by default, unless .Fl d is specified. +.\" ========== +.It Fl U +Display system load averages. +This is on by default, unless +.Fl d +is specified. +.\" ========== .It Fl w Pause .Ar wait @@ -142,8 +162,6 @@ seconds between each display. If no repeat .Ar count is specified, the default is infinity. -.It Fl ?\& -Display a usage statement and exit. .El .Pp .Nm Iostat @@ -159,20 +177,20 @@ characters written to terminals .It devices Device operations. The header of the field is the device name and unit number. -.Nm +.Nm iostat will display as many devices as will fit in a standard 80 column screen, or the maximum number of devices in the system, whichever is smaller. If .Fl n is specified on the command line, -.Nm +.Nm iostat will display the smaller of the requested number of devices, and the maximum number of devices in the system. To force -.Nm +.Nm iostat to display specific drives, their names may be supplied on the command line. -.Nm +.Nm iostat will not display more devices than will fit in an 80 column screen, unless the .Fl n @@ -180,11 +198,11 @@ argument is given on the command line to specify a maximum number of devices to display, or the list of specified devices exceeds 80 columns. If fewer devices are specified on the command line than will fit in an 80 column screen, -.Nm +.Nm iostat will show only the specified devices. .Pp The standard -.Nm +.Nm iostat device display shows the following statistics: .Pp .Bl -tag -width indent -compact @@ -197,7 +215,7 @@ megabytes per second .El .Pp The standard -.Nm +.Nm iostat device display, with the .Fl I flag specified, shows the following statistics: @@ -212,7 +230,7 @@ total number of megabytes transferred .El .Pp The old-style -.Nm +.Nm iostat display (using .Fl o ) shows the following statistics: @@ -227,7 +245,7 @@ average milliseconds per transaction .El .Pp The old-style -.Nm +.Nm iostat display, with the .Fl I flag specified, shows the following statistics: @@ -281,12 +299,12 @@ flags are given, the TTY and CPU displays will be displayed. .Xr netstat 1 , .Xr nfsstat 1 , .Xr ps 1 , -.Xr pstat 8 , +.Xr pstat 8 .Pp The sections starting with ``Interpreting system activity'' in .%T "Installing and Operating 4.3BSD" . .Sh HISTORY This version of -.Nm +.Nm iostat first appeared in .Nm FreeBSD 3.0 . diff --git a/iostat.tproj/iostat.c b/iostat.tproj/iostat.c index f6764e2..ea2cb74 100644 --- a/iostat.tproj/iostat.c +++ b/iostat.tproj/iostat.c @@ -132,7 +132,7 @@ #include #include #include - +#include /* host_statistics */ #include #include #include @@ -169,8 +169,9 @@ static mach_port_t masterPort; static int num_devices; static int maxshowdevs; -static int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0; +static int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Uflag = 0, Kflag = 0; static volatile sig_atomic_t phdr_flag = 0; +static IONotificationPortRef notifyPort; /* local function declarations */ static void usage(void); @@ -178,12 +179,17 @@ static void phdr(int signo); static void do_phdr(); static void devstats(int perf_select, long double etime, int havelast); static void cpustats(void); +static void loadstats(void); static int readvar(const char *name, void *ptr, size_t len); static int record_all_devices(void); +static void record_drivelist(void* context, io_iterator_t drivelist); +static void remove_drivelist(void* context, io_iterator_t drivelist); static int record_one_device(char *name); static int record_device(io_registry_entry_t drive); +static int compare_drivestats(const void* pa, const void* pb); + static long double compute_etime(struct timeval cur_time, struct timeval prev_time); @@ -196,7 +202,7 @@ usage(void) * This isn't mentioned in the man page, or the usage statement, * but it is supported. */ - fprintf(stderr, "usage: iostat [-CdIKoT?] [-c count] [-n devs]\n" + fprintf(stderr, "usage: iostat [-CUdIKoT?] [-c count] [-n devs]\n" "\t [-w wait] [drives]\n"); } @@ -210,9 +216,11 @@ main(int argc, char **argv) int num_devices_specified; int havelast = 0; + CFRunLoopSourceRef rls; + maxshowdevs = 3; - while ((c = getopt(argc, argv, "c:CdIKM:n:oTw:?")) != -1) { + while ((c = getopt(argc, argv, "c:CdIKM:n:oTUw:?")) != -1) { switch(c) { case 'c': cflag++; @@ -245,6 +253,9 @@ main(int argc, char **argv) case 'T': Tflag++; break; + case 'U': + Uflag++; + break; case 'w': wflag++; waittime = atoi(optarg); @@ -271,13 +282,18 @@ main(int argc, char **argv) */ IOMasterPort(bootstrap_port, &masterPort); + notifyPort = IONotificationPortCreate(masterPort); + rls = IONotificationPortGetRunLoopSource(notifyPort); + CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); + /* - * Make sure Tflag and/or Cflag are set if dflag == 0. If dflag is + * Make sure Tflag, Cflag and Uflag are set if dflag == 0. If dflag is * greater than 0, they may be 0 or non-zero. */ if (dflag == 0) { Cflag = 1; Tflag = 1; + Uflag = 1; } /* @@ -391,16 +407,12 @@ main(int argc, char **argv) } } - if (phdr_flag) { + if (!--headercount || phdr_flag) { phdr_flag = 0; + headercount = 20; do_phdr(); } - if (!--headercount) { - do_phdr(); - headercount = 20; - } - last_time = cur_time; gettimeofday(&cur_time, NULL); @@ -427,13 +439,21 @@ main(int argc, char **argv) if (Cflag > 0) cpustats(); + if (Uflag > 0) + loadstats(); + printf("\n"); fflush(stdout); if (count >= 0 && --count <= 0) break; - sleep(waittime); + /* + * Instead of sleep(waittime), wait in + * the RunLoop for IONotifications. + */ + CFRunLoopRunInMode(kCFRunLoopDefaultMode, (CFTimeInterval)waittime, 1); + havelast = 1; } @@ -455,7 +475,7 @@ do_phdr() if (Tflag > 0) (void)printf(" tty"); - for (i = 0; (i < num_devices); i++){ + for (i = 0; i < num_devices && i < maxshowdevs; i++){ if (oflag > 0) (void)printf("%12.6s ", drivestat[i].name); else @@ -463,14 +483,17 @@ do_phdr() } if (Cflag > 0) - (void)printf(" cpu\n"); + (void)printf(" cpu"); + + if (Uflag > 0) + (void)printf(" load average\n"); else (void)printf("\n"); if (Tflag > 0) (void)printf(" tin tout"); - for (i=0; i < num_devices; i++){ + for (i=0; i < num_devices && i < maxshowdevs; i++){ if (oflag > 0) { if (Iflag == 0) (void)printf(" sps tps msps "); @@ -478,14 +501,17 @@ do_phdr() (void)printf(" blk xfr msps "); } else { if (Iflag == 0) - printf(" KB/t tps MB/s "); + printf(" KB/t tps MB/s "); else - printf(" KB/t xfrs MB "); + printf(" KB/t xfrs MB "); } } if (Cflag > 0) - (void)printf(" us sy id\n"); + (void)printf(" us sy id"); + + if (Uflag > 0) + (void)printf(" 1m 5m 15m\n"); else printf("\n"); } @@ -507,7 +533,7 @@ devstats(int perf_select, long double etime, int havelast) kern_return_t status; int i; - for (i = 0; i < num_devices; i++) { + for (i = 0; i < num_devices && i < maxshowdevs; i++) { /* * If the drive goes away, we may not get any properties @@ -523,7 +549,7 @@ devstats(int perf_select, long double etime, int havelast) kCFAllocatorDefault, kNilOptions); if (status != KERN_SUCCESS) - err(1, "device has no properties"); + continue; /* get statistics from properties */ statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, @@ -627,7 +653,7 @@ devstats(int perf_select, long double etime, int havelast) ms_per_transaction); } else { if (Iflag == 0) - printf(" %5.2Lf %3.0Lf %5.2Lf ", + printf(" %7.2Lf %3.0Lf %5.2Lf ", kb_per_transfer, transfers_per_second, mb_per_second); @@ -635,7 +661,7 @@ devstats(int perf_select, long double etime, int havelast) interval_mb = interval_bytes; interval_mb /= 1024 * 1024; - printf(" %5.2Lf %3.1qu %5.2Lf ", + printf(" %7.2Lf %3.1qu %5.2Lf ", kb_per_transfer, interval_transfers, interval_mb); @@ -684,15 +710,24 @@ cpustats(void) /* * Print times. */ - printf("%3.0f", - rint(100. * cur.load.cpu_ticks[CPU_STATE_USER] - / (time ? time : 1))); - printf("%3.0f", - rint(100. * cur.load.cpu_ticks[CPU_STATE_SYSTEM] - / (time ? time : 1))); - printf("%3.0f", - rint(100. * cur.load.cpu_ticks[CPU_STATE_IDLE] - / (time ? time : 1))); +#define PTIME(kind) { \ + double cpu = rint(100. * cur.load.cpu_ticks[kind] / (time ? time : 1));\ + printf("%*.0f", (100 == cpu) ? 4 : 3, cpu); \ +} + PTIME(CPU_STATE_USER); + PTIME(CPU_STATE_SYSTEM); + PTIME(CPU_STATE_IDLE); +} + +static void +loadstats(void) +{ + double loadavg[3]; + + if(getloadavg(loadavg,3)!=3) + errx(1, "couldn't fetch load average"); + + printf(" %4.2f %4.2f %4.2f",loadavg[0],loadavg[1],loadavg[2]); } static int @@ -760,9 +795,7 @@ static int record_all_devices(void) { io_iterator_t drivelist; - io_registry_entry_t drive; CFMutableDictionaryRef match; - int error, ndrives; kern_return_t status; /* @@ -770,7 +803,10 @@ record_all_devices(void) */ match = IOServiceMatching("IOMedia"); CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); - status = IOServiceGetMatchingServices(masterPort, match, &drivelist); + + CFRetain(match); + status = IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, match, &record_drivelist, NULL, &drivelist); + if (status != KERN_SUCCESS) errx(1, "couldn't match whole IOMedia devices"); @@ -782,19 +818,72 @@ record_all_devices(void) * * XXX What about RAID devices? */ - error = 1; - ndrives = 0; - while ((drive = IOIteratorNext(drivelist)) - && (ndrives < maxshowdevs)) { - if (!record_device(drive)) { - error = 0; - ndrives++; + + record_drivelist(NULL, drivelist); + + + status = IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, match, &remove_drivelist, NULL, &drivelist); + + if (status != KERN_SUCCESS) + errx(1, "couldn't match whole IOMedia device removal"); + + remove_drivelist(NULL, drivelist); + + return(0); +} + +static void record_drivelist(void* context, io_iterator_t drivelist) +{ + io_registry_entry_t drive; + while ((drive = IOIteratorNext(drivelist))) { + if (num_devices < MAXDRIVES) { + record_device(drive); + phdr_flag = 1; } IOObjectRelease(drive); } - IOObjectRelease(drivelist); + qsort(drivestat, num_devices, sizeof(struct drivestats), &compare_drivestats); +} + +static void remove_drivelist(void* context, io_iterator_t drivelist) +{ + io_registry_entry_t drive; + while ((drive = IOIteratorNext(drivelist))) { + kern_return_t status; + char bsdname[MAXDRIVENAME]; + CFDictionaryRef properties; + CFStringRef name; + + /* get drive properties */ + status = IORegistryEntryCreateCFProperties(drive, + (CFMutableDictionaryRef *)&properties, + kCFAllocatorDefault, + kNilOptions); + if (status != KERN_SUCCESS) continue; - return(error); + /* get name from properties */ + name = (CFStringRef)CFDictionaryGetValue(properties, + CFSTR(kIOBSDNameKey)); + CFRelease(properties); + if (!name) continue; + + if (CFStringGetCString(name, bsdname, MAXDRIVENAME, CFStringGetSystemEncoding())) { + int i; + for (i = 0; i < num_devices; ++i) { + if (strcmp(bsdname,drivestat[i].name) == 0) { + if (i < MAXDRIVES-1) { + memmove(&drivestat[i], &drivestat[i+1], sizeof(struct drivestats)*(MAXDRIVES-i)); + } + --num_devices; + phdr_flag = 1; + qsort(drivestat, num_devices, sizeof(struct drivestats), &compare_drivestats); + break; + } + } + } + + IOObjectRelease(drive); + } } /* @@ -820,7 +909,7 @@ record_one_device(char *name) /* * Get the first match (should only be one) */ - if ((drive = IOIteratorNext(drivelist)) == NULL) + if (!(drive = IOIteratorNext(drivelist))) errx(1, "'%s' not found", name); if (!IOObjectConformsTo(drive, "IOMedia")) errx(1, "'%s' is not a storage device", name); @@ -869,14 +958,21 @@ record_device(io_registry_entry_t drive) /* get name from properties */ name = (CFStringRef)CFDictionaryGetValue(properties, CFSTR(kIOBSDNameKey)); - CFStringGetCString(name, drivestat[num_devices].name, - MAXDRIVENAME, CFStringGetSystemEncoding()); + if (name) + CFStringGetCString(name, drivestat[num_devices].name, + MAXDRIVENAME, CFStringGetSystemEncoding()); + else { + errx(1, "device does not have a BSD name"); + } /* get blocksize from properties */ number = (CFNumberRef)CFDictionaryGetValue(properties, CFSTR(kIOMediaPreferredBlockSizeKey)); - CFNumberGetValue(number, kCFNumberSInt64Type, - &drivestat[num_devices].blocksize); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &drivestat[num_devices].blocksize); + else + errx(1, "device does not have a preferred block size"); /* clean up, return success */ CFRelease(properties); @@ -888,3 +984,11 @@ record_device(io_registry_entry_t drive) IOObjectRelease(parent); return(1); } + +static int +compare_drivestats(const void* pa, const void* pb) +{ + struct drivestats* a = (struct drivestats*)pa; + struct drivestats* b = (struct drivestats*)pb; + return strcmp(a->name, b->name); +} diff --git a/kdump.tproj/Makefile b/kdump.tproj/Makefile deleted file mode 100644 index 23bdd7d..0000000 --- a/kdump.tproj/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# -# Generated by the Apple Project Builder. -# -# NOTE: Do NOT change this file -- Project Builder maintains it. -# -# Put all of your customizations in files called Makefile.preamble -# and Makefile.postamble (both optional), and Makefile will include them. -# - -NAME = kdump - -PROJECTVERSION = 2.8 -PROJECT_TYPE = Tool - -CFILES = kdump.c - -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kdump.1\ - mkioctls syscalls.c - - -MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles -CODE_GEN_STYLE = DYNAMIC -MAKEFILE = tool.make -NEXTSTEP_INSTALLDIR = /usr/bin -WINDOWS_INSTALLDIR = /usr/bin -PDO_UNIX_INSTALLDIR = /usr/bin -LIBS = -DEBUG_LIBS = $(LIBS) -PROF_LIBS = $(LIBS) - - -HEADER_PATHS = -I../ktrace.tproj -I$(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders -NEXTSTEP_PB_CFLAGS = -DMACH_USER_API -WINDOWS_PB_CFLAGS = -DMACH_USER_API -PDO_UNIX_PB_CFLAGS = -DMACH_USER_API - - -NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc -WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc -PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc -NEXTSTEP_JAVA_COMPILER = /usr/bin/javac -WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe -PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac - -include $(MAKEFILEDIR)/platform.make - --include Makefile.preamble - -include $(MAKEFILEDIR)/$(MAKEFILE) - --include Makefile.postamble - --include Makefile.dependencies diff --git a/kdump.tproj/Makefile.postamble b/kdump.tproj/Makefile.postamble deleted file mode 100644 index 1e2ae06..0000000 --- a/kdump.tproj/Makefile.postamble +++ /dev/null @@ -1,8 +0,0 @@ -VPATH += :../ktrace.tproj - -ioctl.c: mkioctls - $(SHELL) mkioctls -s /usr/include > $(SFILE_DIR)/ioctl.c - -install-man-page: - install -d $(DSTROOT)/usr/share/man/man1 - install -c -m 444 kdump.1 $(DSTROOT)/usr/share/man/man1/kdump.1 diff --git a/kdump.tproj/Makefile.preamble b/kdump.tproj/Makefile.preamble deleted file mode 100644 index 1bf99f7..0000000 --- a/kdump.tproj/Makefile.preamble +++ /dev/null @@ -1,7 +0,0 @@ -KTRACE_CFILES = subr.c -GENERATED_CFILES = ioctl.c -OTHER_INITIAL_DEPENDS = $(GENERATED_CFILES) -OTHER_OFILES = $(GENERATED_CFILES:.c=.o) $(KTRACE_CFILES:.c=.o) -OTHER_GENERATED_OFILES = $(VERS_OFILE) -AFTER_INSTALL += install-man-page --include ../Makefile.include diff --git a/kdump.tproj/PB.project b/kdump.tproj/PB.project deleted file mode 100644 index 1fbdcd4..0000000 --- a/kdump.tproj/PB.project +++ /dev/null @@ -1,42 +0,0 @@ -{ - APPCLASS = NSApplication; - FILESTABLE = { - FRAMEWORKS = (); - HEADERSEARCH = (../ktrace.tproj); - H_FILES = (); - M_FILES = (); - OTHER_LIBS = (); - OTHER_LINKED = (kdump.c); - OTHER_SOURCES = ( - Makefile.preamble, - Makefile, - Makefile.postamble, - kdump.1, - mkioctls, - syscalls.c - ); - }; - LANGUAGE = English; - LOCALIZABLE_FILES = {}; - NEXTSTEP_BUILDTOOL = make; - NEXTSTEP_COMPILEROPTIONS = "-DMACH_USER_API"; - NEXTSTEP_INSTALLDIR = /usr/bin; - NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; - NEXTSTEP_MAINNIB = kdump; - NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; - PDO_UNIX_BUILDTOOL = make; - PDO_UNIX_COMPILEROPTIONS = "-DMACH_USER_API"; - PDO_UNIX_INSTALLDIR = /usr/bin; - PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; - PDO_UNIX_MAINNIB = kdump; - PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; - PROJECTNAME = kdump; - PROJECTTYPE = Tool; - PROJECTVERSION = 2.8; - WINDOWS_BUILDTOOL = make; - WINDOWS_COMPILEROPTIONS = "-DMACH_USER_API"; - WINDOWS_INSTALLDIR = /usr/bin; - WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; - WINDOWS_MAINNIB = kdump; - WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; -} diff --git a/kdump.tproj/kdump.1 b/kdump.tproj/kdump.1 deleted file mode 100644 index ab9c37a..0000000 --- a/kdump.tproj/kdump.1 +++ /dev/null @@ -1,102 +0,0 @@ -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)kdump.1 8.1 (Berkeley) 6/6/93 -.\" $FreeBSD: src/usr.bin/kdump/kdump.1,v 1.5.2.2 2001/08/16 13:16:51 ru Exp $ -.\" -.Dd June 6, 1993 -.Dt KDUMP 1 -.Os -.Sh NAME -.Nm kdump -.Nd display kernel trace data -.Sh SYNOPSIS -.Nm -.Op Fl dnlRT -.Op Fl f Ar file -.Op Fl m Ar maxdata -.Op Fl t Op cnisuw -.Sh DESCRIPTION -The -.Nm -command displays the kernel trace files produced with -.Xr ktrace 1 -in human readable format. -By default, the file -.Pa ktrace.out -in the current directory is displayed. -.Pp -The options are as follows: -.Bl -tag -width Fl -.It Fl d -Display all numbers in decimal. -.It Fl f Ar file -Display the specified file instead of -.Pa ktrace.out . -.It Fl l -Loop reading the trace file, once the end-of-file is reached, waiting for -more data. -.It Fl m Ar maxdata -Display at most -.Ar maxdata -bytes when decoding -.Tn I/O . -.It Fl n -Suppress ad hoc translations. -Normally -.Nm -tries to decode many system calls into a more human readable format. -For example, -.Xr ioctl 2 -values are replaced with the macro name and -.Va errno -values are replaced with the -.Xr strerror 3 -string. -Suppressing this feature yields a more consistent output format and is -easily amenable to further processing. -.It Fl R -Display relative timestamps (time since previous entry). -.It Fl T -Display absolute timestamps for each entry (seconds since epoch). -.It Fl t Ar cnisuw -See the -.Fl t -option of -.Xr ktrace 1 . -.El -.Sh SEE ALSO -.Xr ktrace 1 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.4 . diff --git a/kdump.tproj/kdump.c b/kdump.tproj/kdump.c deleted file mode 100644 index bcb3698..0000000 --- a/kdump.tproj/kdump.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include - -#ifndef lint -__unused static const char copyright[] = -"@(#) Copyright (c) 1988, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -__unused static char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; -#endif -__unused static const char rcsid[] = - "$FreeBSD: src/usr.bin/kdump/kdump.c,v 1.17 1999/12/29 05:05:33 peter Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ktrace.h" - -#define ERESTART -1 -#define EJUSTRETURN -2 -int timestamp, decimal, fancy = 1, tail, maxdata; -char *tracefile = DEF_TRACEFILE; -struct ktr_header ktr_header; - -#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) - -/* Forward declarations */ -void usage(void); -int fread_tail(char *buf, int size, int num); -void dumpheader(struct ktr_header *kth); -void dumpheader(struct ktr_header *kth); -void ktrsyscall(struct ktr_syscall *ktr); -void ktrsysret(struct ktr_sysret *ktr); -void ktrnamei(char *cp, int len); -void ktrgenio(struct ktr_genio *ktr, int len); -void ktrpsig(struct ktr_psig *psig); -void ktrcsw(struct ktr_csw *cs); -void ktruser(int len, unsigned char *p); - -int -main(int argc, char *argv[]) -{ - int ch, ktrlen, size; - void *m; - int trpoints = ALL_POINTS; - - (void) setlocale(LC_CTYPE, ""); - - while ((ch = getopt(argc,argv,"f:dlm:nRTt:")) != -1) - switch((char)ch) { - case 'f': - tracefile = optarg; - break; - case 'd': - decimal = 1; - break; - case 'l': - tail = 1; - break; - case 'm': - maxdata = atoi(optarg); - break; - case 'n': - fancy = 0; - break; - case 'R': - timestamp = 2; /* relative timestamp */ - break; - case 'T': - timestamp = 1; - break; - case 't': - trpoints = getpoints(optarg); - if (trpoints < 0) - errx(1, "unknown trace point in %s", optarg); - break; - default: - usage(); - } - - if (argc > optind) - usage(); - - m = (void *)malloc(size = 1025); - if (m == NULL) - errx(1, "%s", strerror(ENOMEM)); - if (!freopen(tracefile, "r", stdin)) - err(1, "%s", tracefile); - while (fread_tail((char *)&ktr_header, sizeof(struct ktr_header), 1)) { - if (trpoints & (1< size) { - m = (void *)realloc(m, ktrlen+1); - if (m == NULL) - errx(1, "%s", strerror(ENOMEM)); - size = ktrlen; - } - if (ktrlen && fread_tail(m, ktrlen, 1) == 0) - errx(1, "data too short"); - if ((trpoints & (1<ktr_type) { - case KTR_SYSCALL: - type = "CALL"; - break; - case KTR_SYSRET: - type = "RET "; - break; - case KTR_NAMEI: - type = "NAMI"; - break; - case KTR_GENIO: - type = "GIO "; - break; - case KTR_PSIG: - type = "PSIG"; - break; - case KTR_CSW: - type = "CSW"; - break; - case KTR_USER: - type = "USER"; - break; - default: - (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); - type = unknown; - } - - (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, kth->ktr_comm); - if (timestamp) { - if (timestamp == 2) { - temp = kth->ktr_time; - timevalsub(&kth->ktr_time, &prevtime); - prevtime = temp; - } - (void)printf("%ld.%06d ", - kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); - } - (void)printf("%s ", type); -} - -#include -#include "syscalls.c" -int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); - -static char *ptrace_ops[] = { - "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", - "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", - "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH", - "PT_SIGEXC", "PT_THUPDATE", "PT_ATTACHEXC", -}; - -void -ktrsyscall(struct ktr_syscall *ktr) -{ - register_t narg = ktr->ktr_narg; - unsigned long long *ip; - char *ioctlname(); - - if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) - (void)printf("[%d]", ktr->ktr_code); - else - (void)printf("%s", syscallnames[ktr->ktr_code]); - ip = &ktr->ktr_args[0]; - if (narg) { - char c = '('; - if (fancy) { - if (ktr->ktr_code == SYS_ioctl) { - char *cp; - if (decimal) - (void)printf("(%ld", (long)*ip); - else - (void)printf("(%#lx", (long)*ip); - ip++; - narg--; - if ((cp = ioctlname(*ip)) != NULL) - (void)printf(",%s", cp); - else { - if (decimal) - (void)printf(",%ld", (long)*ip); - else - (void)printf(",%#lx ", (long)*ip); - } - c = ','; - ip++; - narg--; - } else if (ktr->ktr_code == SYS_ptrace) { - if (*ip < sizeof(ptrace_ops) / - sizeof(ptrace_ops[0]) && *ip >= 0) - (void)printf("(%s", ptrace_ops[*ip]); -#ifdef PT_FORCEQUOTA - else if (*ip == PT_FORCEQUOTA) - (void)printf("(%s", "PT_FORCEQUOTA"); -#endif -#ifdef PT_DENY_ATTACH - else if (*ip == PT_DENY_ATTACH) - (void)printf("(%s", "PT_DENY_ATTACH"); -#endif -#ifdef PT_FIRSTMACH - else if (*ip == PT_FIRSTMACH) - (void)printf("(%s", "PT_FIRSTMACH"); -#endif - else - (void)printf("(%ld", (long)*ip); - c = ','; - ip++; - narg--; - } - } - while (narg) { - if (decimal) - (void)printf("%c%ld", c, (long)*ip); - else - (void)printf("%c%#lx", c, (long)*ip); - c = ','; - ip++; - narg--; - } - (void)putchar(')'); - } - (void)putchar('\n'); -} - -void -ktrsysret(struct ktr_sysret *ktr) -{ - register_t ret = ktr->ktr_retval; - int error = ktr->ktr_error; - int code = ktr->ktr_code; - - if (code >= nsyscalls || code < 0) - (void)printf("[%d] ", code); - else - (void)printf("%s ", syscallnames[code]); - - if (error == 0) { - if (fancy) { - (void)printf("%d", ret); - if (ret < 0 || ret > 9) - (void)printf("/%#lx", (long)ret); - } else { - if (decimal) - (void)printf("%ld", (long)ret); - else - (void)printf("%#lx", (long)ret); - } - } else if (error == ERESTART) - (void)printf("RESTART"); - else if (error == EJUSTRETURN) - (void)printf("JUSTRETURN"); - else { - (void)printf("-1 errno %d", ktr->ktr_error); - if (fancy) - (void)printf(" %s", strerror(ktr->ktr_error)); - } - (void)putchar('\n'); -} - -void -ktrnamei(char *cp, int len) -{ - (void)printf("\"%.*s\"\n", len, cp); -} - -void -ktrgenio(struct ktr_genio *ktr, int len) -{ - int datalen = len - sizeof (struct ktr_genio); - char *dp = (char *)ktr + sizeof (struct ktr_genio); - char *cp; - int col = 0; - int width; - char visbuf[5]; - static int screenwidth = 0; - - if (screenwidth == 0) { - struct winsize ws; - - if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && - ws.ws_col > 8) - screenwidth = ws.ws_col; - else - screenwidth = 80; - } - printf("fd %d %s %d byte%s\n", ktr->ktr_fd, - ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, - datalen == 1 ? "" : "s"); - if (maxdata && datalen > maxdata) - datalen = maxdata; - (void)printf(" \""); - col = 8; - for (;datalen > 0; datalen--, dp++) { - (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); - cp = visbuf; - /* - * Keep track of printables and - * space chars (like fold(1)). - */ - if (col == 0) { - (void)putchar('\t'); - col = 8; - } - switch(*cp) { - case '\n': - col = 0; - (void)putchar('\n'); - continue; - case '\t': - width = 8 - (col&07); - break; - default: - width = strlen(cp); - } - if (col + width > (screenwidth-2)) { - (void)printf("\\\n\t"); - col = 8; - } - col += width; - do { - (void)putchar(*cp++); - } while (*cp); - } - if (col == 0) - (void)printf(" "); - (void)printf("\"\n"); -} - -char *signames[] = { - "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", /* 1 - 6 */ - "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ - "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ - "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ - "XFSZ", "VTALRM", "PROF", "WINCH", "INFO", "USR1", /* 25 - 30 */ - "USR2", NULL, /* 31 - 32 */ -}; - -void -ktrpsig(struct ktr_psig *psig) -{ - (void)printf("SIG%s ", signames[psig->signo]); - if (psig->action == SIG_DFL) - (void)printf("SIG_DFL\n"); - else - (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", - (u_long)psig->action, psig->mask, psig->code); -} - -void -ktrcsw(struct ktr_csw *cs) -{ - (void)printf("%s %s\n", cs->out ? "stop" : "resume", - cs->user ? "user" : "kernel"); -} - -void -ktruser(int len, unsigned char *p) -{ - (void)printf("%d ", len); - while (len--) - (void)printf(" %02x", *p++); - (void)printf("\n"); - -} - -void -usage(void) -{ - (void)fprintf(stderr, - "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]]\n"); - exit(1); -} diff --git a/kdump.tproj/mkioctls b/kdump.tproj/mkioctls deleted file mode 100644 index f98139a..0000000 --- a/kdump.tproj/mkioctls +++ /dev/null @@ -1,97 +0,0 @@ -set -e - -# $FreeBSD: src/usr.bin/kdump/mkioctls,v 1.15.2.3 2001/04/07 11:09:28 ru Exp $ - -if [ "x$1" = "x-s" ]; then - use_switch=1 - shift -else - use_switch=0 -fi - -if [ -z "$1" ]; then - echo "usage: sh $0 [-s] include-dir" - exit 1 -fi - -LC_ALL=C; export LC_ALL - -# Build a list of headers that have ioctls in them. -# XXX should we use an ANSI cpp? -# XXX netipx conflicts with netns (leave out netns). -ioctl_includes=` - cd $1 - find * -name '*.h' | - egrep -v '^(netns)/' | - egrep -v 'if_atm' | - egrep -v 'disklabel' | - egrep -v 'if_ppp' | - egrep -v 'bpf' | - egrep -v '^(netiso)/' | - egrep -v '^(netccitt)/' | - xargs egrep -l \ -'^#[ ]*define[ ]+[A-Za-z_][A-Za-z0-9_]*[ ]+_IO[^a-z0-9_]' | - sed -e 's/^/#include /' -` - -echo "/* XXX obnoxious prerequisites. */" -echo "#define COMPAT_43_TTY 1" -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "#include " -echo "" -echo "$ioctl_includes" -echo "" - -echo "$ioctl_includes" | - cc -no-cpp-precomp -E -I$1 -dM - | - awk -v use_switch="$use_switch" ' -BEGIN { - print "char *" - print "ioctlname(register_t val)" - print "{" - print "" - if (use_switch) - print "\tswitch(val) {" -} - -/^#[ ]*define[ ]+[A-Za-z_][A-Za-z0-9_]*[ ]+_IO/ { - - # find where the name starts - for (i = 1; i <= NF; i++) - if ($i ~ /define/) - break; - ++i; - # - if ($i == "SIOCADDRT" || $i == "SIOCDELRT") { - printf("#if 0\n"); - } - if (use_switch) - printf("\tcase %s:\n\t\treturn(\"%s\");\n", $i, $i); - else - printf("\tif (val == %s)\n\t\treturn(\"%s\");\n", $i, $i); - if ($i == "SIOCADDRT" || $i == "SIOCDELRT") { - printf("#endif\n"); - } - -} -END { - if (use_switch) - print "\t}" - print "\n\treturn(NULL);" - print "}" -} -' diff --git a/kdump.tproj/syscalls.c b/kdump.tproj/syscalls.c deleted file mode 100644 index 8794bae..0000000 --- a/kdump.tproj/syscalls.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * - * System call switch table. - * - * DO NOT EDIT-- this file is automatically generated. - * created from syscalls.master - */ - -const char *syscallnames[] = { - "syscall", /* 0 = syscall indirect syscall */ - "exit", /* 1 = exit */ - "fork", /* 2 = fork */ - "read", /* 3 = read */ - "write", /* 4 = write */ - "open", /* 5 = open */ - "close", /* 6 = close */ - "wait4", /* 7 = wait4 */ - "#8", /* 8 = old creat */ - "link", /* 9 = link */ - "unlink", /* 10 = unlink */ - "#11", /* 11 = old execv */ - "chdir", /* 12 = chdir */ - "fchdir", /* 13 = fchdir */ - "mknod", /* 14 = mknod */ - "chmod", /* 15 = chmod */ - "chown", /* 16 = chown */ - "obreak", /* 17 = obreak old break */ -#if COMPAT_GETFSSTAT - "ogetfsstat", /* 18 = ogetfsstat */ -#else - "getfsstat", /* 18 = getfsstat */ -#endif - "#19", /* 19 = old lseek */ - "getpid", /* 20 = getpid */ - "#21", /* 21 = old mount */ - "#22", /* 22 = old umount */ - "setuid", /* 23 = setuid */ - "getuid", /* 24 = getuid */ - "geteuid", /* 25 = geteuid */ - "ptrace", /* 26 = ptrace */ - "recvmsg", /* 27 = recvmsg */ - "sendmsg", /* 28 = sendmsg */ - "recvfrom", /* 29 = recvfrom */ - "accept", /* 30 = accept */ - "getpeername", /* 31 = getpeername */ - "getsockname", /* 32 = getsockname */ - "access", /* 33 = access */ - "chflags", /* 34 = chflags */ - "fchflags", /* 35 = fchflags */ - "sync", /* 36 = sync */ - "kill", /* 37 = kill */ - "#38", /* 38 = old stat */ - "getppid", /* 39 = getppid */ - "#40", /* 40 = old lstat */ - "dup", /* 41 = dup */ - "pipe", /* 42 = pipe */ - "getegid", /* 43 = getegid */ - "profil", /* 44 = profil */ - "ktrace", /* 45 = ktrace */ - "sigaction", /* 46 = sigaction */ - "getgid", /* 47 = getgid */ - "sigprocmask", /* 48 = sigprocmask */ - "getlogin", /* 49 = getlogin */ - "setlogin", /* 50 = setlogin */ - "acct", /* 51 = acct */ - "sigpending", /* 52 = sigpending */ - "sigaltstack", /* 53 = sigaltstack */ - "ioctl", /* 54 = ioctl */ - "reboot", /* 55 = reboot */ - "revoke", /* 56 = revoke */ - "symlink", /* 57 = symlink */ - "readlink", /* 58 = readlink */ - "execve", /* 59 = execve */ - "umask", /* 60 = umask */ - "chroot", /* 61 = chroot */ - "#62", /* 62 = old fstat */ - "#63", /* 63 = used internally , reserved */ - "#64", /* 64 = old getpagesize */ - "msync", /* 65 = msync */ - "vfork", /* 66 = vfork */ - "#67", /* 67 = old vread */ - "#68", /* 68 = old vwrite */ - "sbrk", /* 69 = sbrk */ - "sstk", /* 70 = sstk */ - "#71", /* 71 = old mmap */ - "ovadvise", /* 72 = ovadvise old vadvise */ - "munmap", /* 73 = munmap */ - "mprotect", /* 74 = mprotect */ - "madvise", /* 75 = madvise */ - "#76", /* 76 = old vhangup */ - "#77", /* 77 = old vlimit */ - "mincore", /* 78 = mincore */ - "getgroups", /* 79 = getgroups */ - "setgroups", /* 80 = setgroups */ - "getpgrp", /* 81 = getpgrp */ - "setpgid", /* 82 = setpgid */ - "setitimer", /* 83 = setitimer */ - "#84", /* 84 = old wait */ - "swapon", /* 85 = swapon */ - "getitimer", /* 86 = getitimer */ - "#87", /* 87 = old gethostname */ - "#88", /* 88 = old sethostname */ - "getdtablesize", /* 89 = getdtablesize */ - "dup2", /* 90 = dup2 */ - "#91", /* 91 = old getdopt */ - "fcntl", /* 92 = fcntl */ - "select", /* 93 = select */ - "#94", /* 94 = old setdopt */ - "fsync", /* 95 = fsync */ - "setpriority", /* 96 = setpriority */ - "socket", /* 97 = socket */ - "connect", /* 98 = connect */ - "#99", /* 99 = old accept */ - "getpriority", /* 100 = getpriority */ - "#101", /* 101 = old send */ - "#102", /* 102 = old recv */ -#ifdef __ppc__ - "#103", /* 103 = old sigreturn */ -#else - "sigreturn", /* 103 = sigreturn */ -#endif - "bind", /* 104 = bind */ - "setsockopt", /* 105 = setsockopt */ - "listen", /* 106 = listen */ - "#107", /* 107 = old vtimes */ - "#108", /* 108 = old sigvec */ - "#109", /* 109 = old sigblock */ - "#110", /* 110 = old sigsetmask */ - "sigsuspend", /* 111 = sigsuspend */ - "#112", /* 112 = old sigstack */ - "#113", /* 113 = old recvmsg */ - "#114", /* 114 = old sendmsg */ - "#115", /* 115 = old vtrace */ -#ifdef __ppc__ - "ppc_gettimeofday", /* 116 = ppc_gettimeofday */ -#else - "gettimeofday", /* 116 = gettimeofday */ -#endif - "getrusage", /* 117 = getrusage */ - "getsockopt", /* 118 = getsockopt */ - "#119", /* 119 = old resuba */ - "readv", /* 120 = readv */ - "writev", /* 121 = writev */ - "settimeofday", /* 122 = settimeofday */ - "fchown", /* 123 = fchown */ - "fchmod", /* 124 = fchmod */ - "#125", /* 125 = old recvfrom */ - "#126", /* 126 = old setreuid */ - "#127", /* 127 = old setregid */ - "rename", /* 128 = rename */ - "#129", /* 129 = old truncate */ - "#130", /* 130 = old ftruncate */ - "flock", /* 131 = flock */ - "mkfifo", /* 132 = mkfifo */ - "sendto", /* 133 = sendto */ - "shutdown", /* 134 = shutdown */ - "socketpair", /* 135 = socketpair */ - "mkdir", /* 136 = mkdir */ - "rmdir", /* 137 = rmdir */ - "utimes", /* 138 = utimes */ - "futimes", /* 139 = futimes */ - "adjtime", /* 140 = adjtime */ - "#141", /* 141 = old getpeername */ - "#142", /* 142 = old gethostid */ - "#143", /* 143 = old sethostid */ - "#144", /* 144 = old getrlimit */ - "#145", /* 145 = old setrlimit */ - "#146", /* 146 = old killpg */ - "setsid", /* 147 = setsid */ - "#148", /* 148 = old setquota */ - "#149", /* 149 = old qquota */ - "#150", /* 150 = old getsockname */ - "getpgid", /* 151 = getpgid */ - "setprivexec", /* 152 = setprivexec */ - "pread", /* 153 = pread */ - "pwrite", /* 154 = pwrite */ -#if NFSSERVER - "nfssvc", /* 155 = nfssvc */ -#else - "#155", /* 155 = */ -#endif - "#156", /* 156 = old getdirentries */ - "statfs", /* 157 = statfs */ - "fstatfs", /* 158 = fstatfs */ - "unmount", /* 159 = unmount */ - "#160", /* 160 = old async_daemon */ -#if NFSCLIENT - "getfh", /* 161 = getfh */ -#else - "#161", /* 161 = */ -#endif - "#162", /* 162 = old getdomainname */ - "#163", /* 163 = old setdomainname */ - "#164", /* 164 = */ - "quotactl", /* 165 = quotactl */ - "#166", /* 166 = old exportfs */ - "mount", /* 167 = mount */ - "#168", /* 168 = old ustat */ - "#169", /* 169 = */ - "table", /* 170 = table old table */ - "#171", /* 171 = old wait3 */ - "#172", /* 172 = old rpause */ - "waitid", /* 173 = waitid */ - "#174", /* 174 = old getdents */ - "#175", /* 175 = old gc_control */ - "add_profil", /* 176 = add_profil */ - "#177", /* 177 = */ - "#178", /* 178 = */ - "#179", /* 179 = */ - "kdebug_trace", /* 180 = kdebug_trace */ - "setgid", /* 181 = setgid */ - "setegid", /* 182 = setegid */ - "seteuid", /* 183 = seteuid */ -#ifdef __ppc__ - "sigreturn", /* 184 = sigreturn */ -#else - "#184", /* 184 = */ -#endif - "#185", /* 185 = */ - "#186", /* 186 = */ - "#187", /* 187 = */ - "stat", /* 188 = stat */ - "fstat", /* 189 = fstat */ - "lstat", /* 190 = lstat */ - "pathconf", /* 191 = pathconf */ - "fpathconf", /* 192 = fpathconf */ -#if COMPAT_GETFSSTAT - "getfsstat", /* 193 = getfsstat */ -#else - "#193", /* 193 = */ -#endif - "getrlimit", /* 194 = getrlimit */ - "setrlimit", /* 195 = setrlimit */ - "getdirentries", /* 196 = getdirentries */ - "mmap", /* 197 = mmap */ - "#198", /* 198 = __syscall */ - "lseek", /* 199 = lseek */ - "truncate", /* 200 = truncate */ - "ftruncate", /* 201 = ftruncate */ - "__sysctl", /* 202 = __sysctl */ - "mlock", /* 203 = mlock */ - "munlock", /* 204 = munlock */ - "undelete", /* 205 = undelete */ -#ifdef __ppc__ - "ATsocket", /* 206 = ATsocket */ - "ATgetmsg", /* 207 = ATgetmsg */ - "ATputmsg", /* 208 = ATputmsg */ - "ATPsndreq", /* 209 = ATPsndreq */ - "ATPsndrsp", /* 210 = ATPsndrsp */ - "ATPgetreq", /* 211 = ATPgetreq */ - "ATPgetrsp", /* 212 = ATPgetrsp */ - "#213", /* 213 = Reserved for AppleTalk */ -#else - "ATsocket", /* 206 = ATsocket */ - "ATgetmsg", /* 207 = ATgetmsg */ - "ATputmsg", /* 208 = ATputmsg */ - "ATPsndreq", /* 209 = ATPsndreq */ - "ATPsndrsp", /* 210 = ATPsndrsp */ - "ATPgetreq", /* 211 = ATPgetreq */ - "ATPgetrsp", /* 212 = ATPgetrsp */ - "#213", /* 213 = Reserved for AppleTalk */ -#endif /* __ppc__ */ - "kqueue_from_portset_np", /* 214 = kqueue_from_portset_np */ - "kqueue_portset_np", /* 215 = kqueue_portset_np */ - "mkcomplex", /* 216 = mkcomplex soon to be obsolete */ - "statv", /* 217 = statv soon to be obsolete */ - "lstatv", /* 218 = lstatv soon to be obsolete */ - "fstatv", /* 219 = fstatv soon to be obsolete */ - "getattrlist", /* 220 = getattrlist */ - "setattrlist", /* 221 = setattrlist */ - "getdirentriesattr", /* 222 = getdirentriesattr */ - "exchangedata", /* 223 = exchangedata */ -#ifdef __APPLE_API_OBSOLETE - "checkuseraccess", /* 224 = checkuseraccess */ -#else - "#224", /* 224 = HFS checkuseraccess check access to a file */ -#endif /* __APPLE_API_OBSOLETE */ - "searchfs", /* 225 = searchfs */ - "delete", /* 226 = delete private delete ( Carbon semantics ) */ - "copyfile", /* 227 = copyfile */ - "#228", /* 228 = */ - "#229", /* 229 = */ - "poll", /* 230 = poll */ - "watchevent", /* 231 = watchevent */ - "waitevent", /* 232 = waitevent */ - "modwatch", /* 233 = modwatch */ - "getxattr", /* 234 = getxattr */ - "fgetxattr", /* 235 = fgetxattr */ - "setxattr", /* 236 = setxattr */ - "fsetxattr", /* 237 = fsetxattr */ - "removexattr", /* 238 = removexattr */ - "fremovexattr", /* 239 = fremovexattr */ - "listxattr", /* 240 = listxattr */ - "flistxattr", /* 241 = flistxattr */ - "fsctl", /* 242 = fsctl */ - "#243", /* 243 = */ - "#244", /* 244 = */ - "#245", /* 245 = */ - "#246", /* 246 = */ -#if NFSCLIENT - "nfsclnt", /* 247 = nfsclnt */ - "fhopen", /* 248 = fhopen */ -#else - "#247", /* 247 = */ - "#248", /* 248 = */ -#endif - "#249", /* 249 = */ - "minherit", /* 250 = minherit */ - "semsys", /* 251 = semsys */ - "msgsys", /* 252 = msgsys */ - "shmsys", /* 253 = shmsys */ - "semctl", /* 254 = semctl */ - "semget", /* 255 = semget */ - "semop", /* 256 = semop */ - "#257", /* 257 = */ - "msgctl", /* 258 = msgctl */ - "msgget", /* 259 = msgget */ - "msgsnd", /* 260 = msgsnd */ - "msgrcv", /* 261 = msgrcv */ - "shmat", /* 262 = shmat */ - "shmctl", /* 263 = shmctl */ - "shmdt", /* 264 = shmdt */ - "shmget", /* 265 = shmget */ - "shm_open", /* 266 = shm_open */ - "shm_unlink", /* 267 = shm_unlink */ - "sem_open", /* 268 = sem_open */ - "sem_close", /* 269 = sem_close */ - "sem_unlink", /* 270 = sem_unlink */ - "sem_wait", /* 271 = sem_wait */ - "sem_trywait", /* 272 = sem_trywait */ - "sem_post", /* 273 = sem_post */ - "sem_getvalue", /* 274 = sem_getvalue */ - "sem_init", /* 275 = sem_init */ - "sem_destroy", /* 276 = sem_destroy */ - "open_extended", /* 277 = open_extended */ - "umask_extended", /* 278 = umask_extended */ - "stat_extended", /* 279 = stat_extended */ - "lstat_extended", /* 280 = lstat_extended */ - "fstat_extended", /* 281 = fstat_extended */ - "chmod_extended", /* 282 = chmod_extended */ - "fchmod_extended", /* 283 = fchmod_extended */ - "access_extended", /* 284 = access_extended */ - "settid", /* 285 = settid */ - "gettid", /* 286 = gettid */ - "setsgroups", /* 287 = setsgroups */ - "getsgroups", /* 288 = getsgroups */ - "setwgroups", /* 289 = setwgroups */ - "getwgroups", /* 290 = getwgroups */ - "mkfifo_extended", /* 291 = mkfifo_extended */ - "mkdir_extended", /* 292 = mkdir_extended */ - "identitysvc", /* 293 = identitysvc */ - "#294", /* 294 = */ - "#295", /* 295 = */ - "load_shared_file", /* 296 = load_shared_file */ - "reset_shared_file", /* 297 = reset_shared_file */ - "new_system_shared_regions", /* 298 = new_system_shared_regions */ - "shared_region_map_file_np", /* 299 = shared_region_map_file_np */ - "shared_region_make_private_np", /* 300 = shared_region_make_private_np */ - "#301", /* 301 = */ - "#302", /* 302 = */ - "#303", /* 303 = */ - "#304", /* 304 = */ - "#305", /* 305 = */ - "#306", /* 306 = */ - "#307", /* 307 = */ - "#308", /* 308 = */ - "#309", /* 309 = */ - "getsid", /* 310 = getsid */ - "#311", /* 311 = */ - "#312", /* 312 = */ - "aio_fsync", /* 313 = aio_fsync */ - "aio_return", /* 314 = aio_return */ - "aio_suspend", /* 315 = aio_suspend */ - "aio_cancel", /* 316 = aio_cancel */ - "aio_error", /* 317 = aio_error */ - "aio_read", /* 318 = aio_read */ - "aio_write", /* 319 = aio_write */ - "lio_listio", /* 320 = lio_listio */ - "#321", /* 321 = */ - "#322", /* 322 = */ - "#323", /* 323 = */ - "mlockall", /* 324 = mlockall */ - "munlockall", /* 325 = munlockall */ - "#326", /* 326 = */ - "issetugid", /* 327 = issetugid */ - "__pthread_kill", /* 328 = __pthread_kill */ - "pthread_sigmask", /* 329 = pthread_sigmask */ - "sigwait", /* 330 = sigwait */ - "__disable_threadsignal", /* 331 = __disable_threadsignal */ - "__pthread_markcancel", /* 332 = __pthread_markcancel */ - "__pthread_canceled", /* 333 = __pthread_canceled */ - "__semwait_signal", /* 334 = __semwait_signal */ - "utrace", /* 335 = utrace */ - "#336", /* 336 = */ - "#337", /* 337 = */ - "#338", /* 338 = */ - "#339", /* 339 = */ - "#340", /* 340 = */ - "#341", /* 341 = */ - "#342", /* 342 = */ - "#343", /* 343 = */ - "#344", /* 344 = */ - "#345", /* 345 = */ - "#346", /* 346 = */ - "#347", /* 347 = */ - "#348", /* 348 = */ - "#349", /* 349 = */ - "audit", /* 350 = audit */ - "auditon", /* 351 = auditon */ - "#352", /* 352 = */ - "getauid", /* 353 = getauid */ - "setauid", /* 354 = setauid */ - "getaudit", /* 355 = getaudit */ - "setaudit", /* 356 = setaudit */ - "getaudit_addr", /* 357 = getaudit_addr */ - "setaudit_addr", /* 358 = setaudit_addr */ - "auditctl", /* 359 = auditctl */ - "#360", /* 360 = */ - "#361", /* 361 = */ - "kqueue", /* 362 = kqueue */ - "kevent", /* 363 = kevent */ - "lchown", /* 364 = lchown */ - "#365", /* 365 = */ - "#366", /* 366 = */ - "#367", /* 367 = */ - "#368", /* 368 = */ - "#369", /* 369 = */ -}; diff --git a/kgmon.tproj/Makefile.postamble b/kgmon.tproj/Makefile.postamble deleted file mode 100644 index 069e5cc..0000000 --- a/kgmon.tproj/Makefile.postamble +++ /dev/null @@ -1,117 +0,0 @@ -############################################################################### -# NeXT Makefile.postamble Template -# Copyright 1993, NeXT Computer, Inc. -# -# This Makefile is used for configuring the standard app makefiles associated -# with ProjectBuilder. -# -# Use this template to set attributes for a project, sub-project, bundle, or -# palette. Each node in the project's tree of sub-projects and bundles -# should have it's own Makefile.preamble and Makefile.postamble. Additional -# rules (e.g., after_install) that are defined by the developer should be -# defined in this file. -# -############################################################################### -# -# Here are the variables exported by the common "app" makefiles that can be -# used in any customizations you make to the template below: -# -# PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app) -# OFILE_DIR - Directory into which .o object files are generated. -# (Note that this name is calculated based on the target -# architectures specified in Project Builder). -# DERIVED_SRC_DIR - Directory used for all other derived files -# ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations -# -# NAME - name of application, bundle, subproject, palette, etc. -# LANGUAGE - langage in which the project is written (default "English") -# ENGLISH - boolean flag set iff $(LANGUAGE) = "English" -# JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese" -# LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project -# GLOBAL_RESOURCES - non-localized resources of project -# PROJECTVERSION - version of ProjectBuilder that output Makefile -# APPICON - application icon file -# DOCICONS - dock icon files -# ICONSECTIONS - Specifies icon sections when linking executable -# -# CLASSES - Class implementation files in project. -# HFILES - Header files in project. -# MFILES - Other Objective-C source files in project. -# CFILES - Other C source files in project. -# PSWFILES - .psw files in the project -# PSWMFILES - .pswm files in the project -# SUBPROJECTS - Subprojects of this project -# BUNDLES - Bundle subprojects of this project -# OTHERSRCS - Other miscellaneous sources of this project -# OTHERLINKED - Source files not matching a standard source extention -# -# LIBS - Libraries to link with when making app target -# DEBUG_LIBS - Libraries to link with when making debug target -# PROF_LIBS - Libraries to link with when making profile target -# OTHERLINKEDOFILES - Other relocatable files to (always) link in. -# -# APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles -# MAKEFILEDIR - Directory in which to find $(MAKEFILE) -# MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make) -# INSTALLDIR - Directory app will be installed into by 'install' target - - -# Change defaults assumed by the standard app makefiles here. Edit the -# following default values as appropriate. (Note that if no Makefile.postamble -# exists, these values will have defaults set in common.make). - -# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if -# you would like changes to them to invalidate previous builds. The project -# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build. -#MAKEFILES = Makefile - -# Optimization flag passed to compiler: -#OPTIMIZATION_CFLAG = -O - -# Flags always passed to compiler: -#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall - -# Flags passed to compiler in normal 'app' compiles: -#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG) - -# Flags passed to compiler in 'debug' compiles: -#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG - -# Flags passed to compiler in 'profile' compiles -#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE - -# Flags passed to yacc -#YFLAGS = -d - -# Ownership and permissions of files installed by 'install' target -# -# This program may safely be run setuid-root to allow non-root -# users to start, stop, and reset profiling buffers. -# -#INSTALL_AS_USER = root # User to chown app to -#INSTALL_AS_GROUP = wheel # Group to chgrp app to -#INSTALL_PERMISSIONS = 4555 # If set, 'install' chmod's executable to this - -# Options to strip for bundles, apps with bundles, and apps without bundles, -# respectively. -#RELOCATABLE_STRIP_OPTS = -x -u -#DYLD_APP_STRIP_OPTS = -A -n -#APP_STRIP_OPTS = -#TOOL_STRIP_OPTS = -#LIBRARY_STRIP_OPTS = -x -S # Note: -S strips debugging symbols -# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but -# developers doing their own dynamic loading should set this to -# $(DYLD_APP_STRIP_OPTS)). - - -######################################################################### -# Put rules to extend the behavior of the standard Makefiles here. Typical -# user-defined rules are before_install and after_install (please don't -# redefine things like install or app, as they are owned by the top-level -# Makefile API), which are rules that get invoked before and after the install -# target runs. Such rules should be specified with the '::' syntax rather than -# a single colon. - -after_install: - mkdir -p $(DSTROOT)/usr/share/man/man8 - install -c -m 444 kgmon.8 $(DSTROOT)/usr/share/man/man8 diff --git a/kgmon.tproj/Makefile.preamble b/kgmon.tproj/Makefile.preamble deleted file mode 100644 index e371f9d..0000000 --- a/kgmon.tproj/Makefile.preamble +++ /dev/null @@ -1,113 +0,0 @@ -############################################################################### -# NeXT Makefile.preamble Template -# Copyright 1993, NeXT Computer, Inc. -# -# This Makefile is used for configuring the standard app makefiles associated -# with ProjectBuilder. -# -# Use this template to set attributes for a project, sub-project, bundle, or -# palette. Each node in the project's tree of sub-projects and bundles -# should have it's own Makefile.preamble and Makefile.postamble. -# -############################################################################### -## Configure the flags passed to $(CC) here. These flags will also be -## inherited by all nested sub-projects and bundles. Put your -I, -D, -U, and -## -L flags here. To change the default flags that get passed to ${CC} -## (e.g. change -O to -O2), see Makefile.postamble. - -# Flags passed to compiler (in addition to -g, -O, etc) -OTHER_CFLAGS = -# Flags passed to ld (in addition to -ObjC, etc.) -OTHER_LDFLAGS = - -BUNDLELDFLAGS = # use iff project is a bundle -PALETTELDFLAGS = # use iff project is a palette - -## Specify which headers in this project should be published to the outside -## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be -## prepended by DSTROOT, below. Any subset of these public headers can be -## precompiled automatically after installation, with extra user-defined flags. -PUBLIC_HEADER_DIR = -PUBLIC_HEADERS = -PUBLIC_PRECOMPILED_HEADERS = -PUBLIC_PRECOMPILED_HEADERS_CFLAGS = - -## Configure what is linked in at each level here. Libraries are only used in -## the final 'app' linking step. Final 'app' linking is only done via the -## 'app', 'debug', and 'profile' targets when they are invoked for -## the top-level app. - -# Additional relocatables to be linked in at this level -OTHER_OFILES = -# Additional libs to link apps against ('app' target) -#OTHER_LIBS = -# Additional libs to link apps against ('debug' target) -OTHER_DEBUG_LIBS = -# Additional libs to link apps against ('profile' target) -OTHER_PROF_LIBS = - -# More 'app' libraries when $(JAPANESE) = "YES" -OTHER_JAPANESE_LIBS = -# More 'debug' libraries when $(JAPANESE) = "YES" -OTHER_JAPANESE_DEBUG_LIBS = -# More 'profile' libs when $(JAPANESE) = "YES" -OTHER_JAPANESE_PROF_LIBS = - -# If this is a bundle, and you *know* the enclosing application will not -# be linking with a library which you require in your bundle code, then -# mention it here so that it gets linked into the bundle. Note that this -# is wasteful but sometimes necessary. -BUNDLE_LIBS = - -## Configure how things get built here. Additional dependencies, sourcefiles, -## derived files, and build order should be specified here. - -# Other dependencies of this project -OTHER_PRODUCT_DEPENDS = -# Built *before* building subprojects/bundles -OTHER_INITIAL_TARGETS = -# Other source files maintained by .pre/postamble -OTHER_SOURCEFILES = -# Additional files to be removed by `make clean' -OTHER_GARBAGE = -# Precompiled headers to be built before any compilation occurs (e.g., draw.p) -PRECOMPS = - -# Targets to be built before installation -OTHER_INSTALL_DEPENDS = - -# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) -# passed from ProjectBuilder. -DSTROOT = - -# Set the following to "YES" if you want the old behavior of recursively -# cleaning all nested subprojects during 'make clean'. -CLEAN_ALL_SUBPROJECTS = - -## Add more obscure source files here to cause them to be automatically -## processed by the appropriate tool. Note that these files should also be -## added to "Supporting Files" in ProjectBuilder. The desired .o files that -## result from these files should also be added to OTHER_OFILES above so they -## will be linked in. - -# .msg files that should have msgwrap run on them -MSGFILES = -# .defs files that should have mig run on them -DEFSFILES = -# .mig files (no .defs files) that should have mig run on them -MIGFILES = - -## Add additional Help directories here (add them to the project as "Other -## Resources" in Project Builder) so that they will be compressed into .store -## files and copied into the app wrapper. If the help directories themselves -## need to also be in the app wrapper, then a cp command will need to be added -## in an after_install target. -OTHER_HELP_DIRS = - -# Don't add more rules here unless you want the first one to be the default -# target for make! Put all your targets in Makefile.postamble. - -# To include a version string, project source must exist in a directory named -# $(NAME).%d[.%d][.%d] and the following line must be uncommented. -OTHER_GENERATED_OFILES = $(VERS_OFILE) - diff --git a/kgmon.tproj/kgmon.8 b/kgmon.tproj/kgmon.8 deleted file mode 100644 index 060ed2e..0000000 --- a/kgmon.tproj/kgmon.8 +++ /dev/null @@ -1,122 +0,0 @@ -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)kgmon.8 8.1 (Berkeley) 6/6/93 -.\" -.Dd June 6, 1993 -.Dt KGMON 8 -.Os BSD 4.2 -.Sh NAME -.Nm kgmon -.Nd generate a dump of the operating system's profile buffers -.Sh SYNOPSIS -.Nm kgmon -.Op Fl bhpr -.Op Fl M core -.Op Fl N system -.Sh DESCRIPTION -.Nm Kgmon -is a tool used when profiling the operating system. -When no arguments are supplied, -.Nm kgmon -indicates the state of operating system profiling as running, -off, or not configured. -(see -.Xr config 8 ) -If the -.Fl p -flag is specified, -.Nm kgmon -extracts profile data from the operating system and produces a -.Pa gmon.out -file suitable for later analysis by -.Xr gprof 1 . -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl b -Resume the collection of profile data. -.It Fl h -Stop the collection of profile data. -.It Fl p -Dump the contents of the profile buffers into a -.Pa gmon.out -file. -.It Fl r -Reset all the profile buffers. -If the -.Fl p -flag is also specified, the -.Pa gmon.out -file is generated before the buffers are reset. -.It Fl M -Extract values associated with the name list from the specified core -instead of the default ``/dev/kmem''. -.It Fl N -Extract the name list from the specified system instead of the -default ``/vmunix''. -.El -.Pp -If neither -.Fl b -nor -.Fl h -is specified, the state of profiling collection remains unchanged. -For example, if the -.Fl p -flag is specified and profile data is being collected, -profiling will be momentarily suspended, -the operating system profile buffers will be dumped, -and profiling will be immediately resumed. -.Sh FILES -.Bl -tag -width /dev/kmemx -compact -.It Pa /vmunix -the default system -.It Pa /dev/kmem -the default memory -.El -.Sh SEE ALSO -.Xr gprof 1 , -.Xr config 8 -.Sh DIAGNOSTICS -Users with only read permission on -.Pa /dev/kmem -cannot change the state -of profiling collection. -They can get a -.Pa gmon.out -file with the warning that the data may be -inconsistent if profiling is in progress. -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.2 . diff --git a/kgmon.tproj/kgmon.c b/kgmon.tproj/kgmon.c deleted file mode 100644 index 47161c0..0000000 --- a/kgmon.tproj/kgmon.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1983, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1983, 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct nlist nl[] = { -#define N_GMONPARAM 0 - { "__gmonparam" }, -#define N_PROFHZ 1 - { "_profhz" }, - 0, -}; - -struct kvmvars { - kvm_t *kd; - struct gmonparam gpm; -}; - -int bflag, hflag, kflag, rflag, pflag; -int debug = 0; -void setprof __P((struct kvmvars *kvp, int state)); -void dumpstate __P((struct kvmvars *kvp)); -void reset __P((struct kvmvars *kvp)); - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind; - int ch, mode, disp, accessmode; - struct kvmvars kvmvars; - char *system, *kmemf; - - seteuid(getuid()); - kmemf = NULL; - system = NULL; - while ((ch = getopt(argc, argv, "M:N:bhpr")) != EOF) { - switch((char)ch) { - - case 'M': - kmemf = optarg; - kflag = 1; - break; - - case 'N': - system = optarg; - break; - - case 'b': - bflag = 1; - break; - - case 'h': - hflag = 1; - break; - - case 'p': - pflag = 1; - break; - - case 'r': - rflag = 1; - break; - - default: - (void)fprintf(stderr, - "usage: kgmon [-bhrp] [-M core] [-N system]\n"); - exit(1); - } - } - argc -= optind; - argv += optind; - -#define BACKWARD_COMPATIBILITY -#ifdef BACKWARD_COMPATIBILITY - if (*argv) { - system = *argv; - if (*++argv) { - kmemf = *argv; - ++kflag; - } - } -#endif - if (system == NULL) - system = _PATH_UNIX; - accessmode = openfiles(system, kmemf, &kvmvars); - mode = getprof(&kvmvars); - if (hflag) - disp = GMON_PROF_OFF; - else if (bflag) - disp = GMON_PROF_ON; - else - disp = mode; - if (pflag) - dumpstate(&kvmvars); - if (rflag) - reset(&kvmvars); - if (accessmode == O_RDWR) - setprof(&kvmvars, disp); - (void)fprintf(stdout, "kgmon: kernel profiling is %s.\n", - disp == GMON_PROF_OFF ? "off" : "running"); - return (0); -} - -/* - * Check that profiling is enabled and open any ncessary files. - */ -openfiles(system, kmemf, kvp) - char *system; - char *kmemf; - struct kvmvars *kvp; -{ - int mib[3], state, size, openmode; - char errbuf[_POSIX2_LINE_MAX]; - - if (!kflag) { - mib[0] = CTL_KERN; - mib[1] = KERN_PROF; - mib[2] = GPROF_STATE; - size = sizeof state; - if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) { - (void)fprintf(stderr, - "kgmon: profiling not defined in kernel.\n"); - exit(20); - } - if (!(bflag || hflag || rflag || - (pflag && state == GMON_PROF_ON))) - return (O_RDONLY); - (void)seteuid(0); - if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) - return (O_RDWR); - (void)seteuid(getuid()); - kern_readonly(state); - return (O_RDONLY); - } - openmode = (bflag || hflag || pflag || rflag) ? O_RDWR : O_RDONLY; - kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf); - if (kvp->kd == NULL) { - if (openmode == O_RDWR) { - openmode = O_RDONLY; - kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, - errbuf); - } - if (kvp->kd == NULL) { - (void)fprintf(stderr, "kgmon: kvm_openfiles: %s\n", - errbuf); - exit(2); - } - kern_readonly(GMON_PROF_ON); - } - if (kvm_nlist(kvp->kd, nl) < 0) { - (void)fprintf(stderr, "kgmon: %s: no namelist\n", system); - exit(3); - } - if (!nl[N_GMONPARAM].n_value) { - (void)fprintf(stderr, - "kgmon: profiling not defined in kernel.\n"); - exit(20); - } - return (openmode); -} - -/* - * Suppress options that require a writable kernel. - */ -kern_readonly(mode) - int mode; -{ - - (void)fprintf(stderr, "kgmon: kernel read-only: "); - if (pflag && mode == GMON_PROF_ON) - (void)fprintf(stderr, "data may be inconsistent\n"); - if (rflag) - (void)fprintf(stderr, "-r supressed\n"); - if (bflag) - (void)fprintf(stderr, "-b supressed\n"); - if (hflag) - (void)fprintf(stderr, "-h supressed\n"); - rflag = bflag = hflag = 0; -} - -/* - * Get the state of kernel profiling. - */ -getprof(kvp) - struct kvmvars *kvp; -{ - int mib[3], size; - - if (kflag) { - size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm, - sizeof kvp->gpm); - } else { - mib[0] = CTL_KERN; - mib[1] = KERN_PROF; - mib[2] = GPROF_GMONPARAM; - size = sizeof kvp->gpm; - if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) - size = 0; - } - if (size != sizeof kvp->gpm) { - (void)fprintf(stderr, "kgmon: cannot get gmonparam: %s\n", - kflag ? kvm_geterr(kvp->kd) : strerror(errno)); - exit (4); - } - return (kvp->gpm.state); -} - -/* - * Enable or disable kernel profiling according to the state variable. - */ -void -setprof(kvp, state) - struct kvmvars *kvp; - int state; -{ - struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value; - int mib[3], sz, oldstate; - - sz = sizeof(state); - if (!kflag) { - mib[0] = CTL_KERN; - mib[1] = KERN_PROF; - mib[2] = GPROF_STATE; - if (sysctl(mib, 3, &oldstate, &sz, NULL, 0) < 0) - goto bad; - if (oldstate == state) - return; - (void)seteuid(0); - if (sysctl(mib, 3, NULL, NULL, &state, sz) >= 0) { - (void)seteuid(getuid()); - return; - } - (void)seteuid(getuid()); - } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, sz) - == sz) - return; -bad: - (void)fprintf(stderr, "kgmon: warning: cannot turn profiling %s\n", - state == GMON_PROF_OFF ? "off" : "on"); -} - -/* - * Build the gmon.out file. - */ -void -dumpstate(kvp) - struct kvmvars *kvp; -{ - register FILE *fp; - struct rawarc rawarc; - struct tostruct *tos; - u_long frompc, addr; - u_short *froms, *tickbuf; - int mib[3], i; - struct gmonhdr h; - int fromindex, endfrom, toindex; - - setprof(kvp, GMON_PROF_OFF); - fp = fopen("gmon.out", "w"); - if (fp == 0) { - perror("gmon.out"); - return; - } - - /* - * Build the gmon header and write it to a file. - */ - bzero(&h, sizeof(h)); - h.lpc = kvp->gpm.lowpc; - h.hpc = kvp->gpm.highpc; - h.ncnt = kvp->gpm.kcountsize + sizeof(h); - h.version = GMONVERSION; - h.profrate = getprofhz(kvp); - fwrite((char *)&h, sizeof(h), 1, fp); - - /* - * Write out the tick buffer. - */ - mib[0] = CTL_KERN; - mib[1] = KERN_PROF; - if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) { - fprintf(stderr, "kgmon: cannot allocate kcount space\n"); - exit (5); - } - if (kflag) { - i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, - kvp->gpm.kcountsize); - } else { - mib[2] = GPROF_COUNT; - i = kvp->gpm.kcountsize; - if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) - i = 0; - } - if (i != kvp->gpm.kcountsize) { - (void)fprintf(stderr, "kgmon: read ticks: read %u, got %d: %s", - kvp->gpm.kcountsize, i, - kflag ? kvm_geterr(kvp->kd) : strerror(errno)); - exit(6); - } - if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) { - perror("kgmon: writing tocks to gmon.out"); - exit(7); - } - free(tickbuf); - - /* - * Write out the arc info. - */ - if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) { - fprintf(stderr, "kgmon: cannot allocate froms space\n"); - exit (8); - } - if (kflag) { - i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, - kvp->gpm.fromssize); - } else { - mib[2] = GPROF_FROMS; - i = kvp->gpm.fromssize; - if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) - i = 0; - } - if (i != kvp->gpm.fromssize) { - (void)fprintf(stderr, "kgmon: read froms: read %u, got %d: %s", - kvp->gpm.fromssize, i, - kflag ? kvm_geterr(kvp->kd) : strerror(errno)); - exit(9); - } - if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) { - fprintf(stderr, "kgmon: cannot allocate tos space\n"); - exit(10); - } - if (kflag) { - i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, - kvp->gpm.tossize); - } else { - mib[2] = GPROF_TOS; - i = kvp->gpm.tossize; - if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) - i = 0; - } - if (i != kvp->gpm.tossize) { - (void)fprintf(stderr, "kgmon: read tos: read %u, got %d: %s", - kvp->gpm.tossize, i, - kflag ? kvm_geterr(kvp->kd) : strerror(errno)); - exit(11); - } - if (debug) - (void)fprintf(stderr, "kgmon: lowpc 0x%x, textsize 0x%x\n", - kvp->gpm.lowpc, kvp->gpm.textsize); - endfrom = kvp->gpm.fromssize / sizeof(*froms); - for (fromindex = 0; fromindex < endfrom; ++fromindex) { - if (froms[fromindex] == 0) - continue; - frompc = (u_long)kvp->gpm.lowpc + - (fromindex * kvp->gpm.hashfraction * sizeof(*froms)); - for (toindex = froms[fromindex]; toindex != 0; - toindex = tos[toindex].link) { - if (debug) - (void)fprintf(stderr, - "%s: [mcleanup] frompc 0x%x selfpc 0x%x count %d\n", - "kgmon", frompc, tos[toindex].selfpc, - tos[toindex].count); - rawarc.raw_frompc = frompc; - rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; - rawarc.raw_count = tos[toindex].count; - fwrite((char *)&rawarc, sizeof(rawarc), 1, fp); - } - } - fclose(fp); -} - -/* - * Get the profiling rate. - */ -int -getprofhz(kvp) - struct kvmvars *kvp; -{ - int mib[2], size, profrate; - struct clockinfo clockrate; - - if (kflag) { - profrate = 1; - if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, - sizeof profrate) != sizeof profrate) - (void)fprintf(stderr, "kgmon: get clockrate: %s\n", - kvm_geterr(kvp->kd)); - return (profrate); - } - mib[0] = CTL_KERN; - mib[1] = KERN_CLOCKRATE; - clockrate.profhz = 1; - size = sizeof clockrate; - if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) - (void)fprintf(stderr, "kgmon: get clockrate: %s\n", - strerror(errno)); - return (clockrate.profhz); -} - -/* - * Reset the kernel profiling date structures. - */ -void -reset(kvp) - struct kvmvars *kvp; -{ - char *zbuf; - u_long biggest; - int mib[3]; - - setprof(kvp, GMON_PROF_OFF); - - biggest = kvp->gpm.kcountsize; - if (kvp->gpm.fromssize > biggest) - biggest = kvp->gpm.fromssize; - if (kvp->gpm.tossize > biggest) - biggest = kvp->gpm.tossize; - if ((zbuf = (char *)malloc(biggest)) == NULL) { - fprintf(stderr, "kgmon: cannot allocate zbuf space\n"); - exit(12); - } - bzero(zbuf, biggest); - if (kflag) { - if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, - kvp->gpm.kcountsize) != kvp->gpm.kcountsize) { - (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", - kvm_geterr(kvp->kd)); - exit(13); - } - if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, - kvp->gpm.fromssize) != kvp->gpm.fromssize) { - (void)fprintf(stderr, "kgmon: froms zero: %s\n", - kvm_geterr(kvp->kd)); - exit(14); - } - if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, - kvp->gpm.tossize) != kvp->gpm.tossize) { - (void)fprintf(stderr, "kgmon: tos zero: %s\n", - kvm_geterr(kvp->kd)); - exit(15); - } - return; - } - (void)seteuid(0); - mib[0] = CTL_KERN; - mib[1] = KERN_PROF; - mib[2] = GPROF_COUNT; - if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) { - (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", - strerror(errno)); - exit(13); - } - mib[2] = GPROF_FROMS; - if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) { - (void)fprintf(stderr, "kgmon: froms zero: %s\n", - strerror(errno)); - exit(14); - } - mib[2] = GPROF_TOS; - if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) { - (void)fprintf(stderr, "kgmon: tos zero: %s\n", - strerror(errno)); - exit(15); - } - (void)seteuid(getuid()); - free(zbuf); -} diff --git a/ktrace.tproj/Makefile b/ktrace.tproj/Makefile deleted file mode 100644 index 5991b29..0000000 --- a/ktrace.tproj/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# Generated by the NeXT Project Builder. -# -# NOTE: Do NOT change this file -- Project Builder maintains it. -# -# Put all of your customizations in files called Makefile.preamble -# and Makefile.postamble (both optional), and Makefile will include them. -# - -NAME = ktrace - -PROJECTVERSION = 2.8 -PROJECT_TYPE = Tool - -HFILES = ktrace.h - -CFILES = ktrace.c subr.c - -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble ktrace.1 - -HEADER_PATHS = -I$(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders - -MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles -CODE_GEN_STYLE = DYNAMIC -MAKEFILE = tool.make -NEXTSTEP_INSTALLDIR = /usr/bin -WINDOWS_INSTALLDIR = /usr/bin -PDO_UNIX_INSTALLDIR = /usr/bin -LIBS = -DEBUG_LIBS = $(LIBS) -PROF_LIBS = $(LIBS) - - -NEXTSTEP_PB_CFLAGS = -DMACH_USER_API -WINDOWS_PB_CFLAGS = -DMACH_USER_API -PDO_UNIX_PB_CFLAGS = -DMACH_USER_API - - -NEXTSTEP_BUILD_OUTPUT_DIR = /$(USER)/BUILD - -NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc -WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc -PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc -NEXTSTEP_JAVA_COMPILER = /usr/bin/javac -WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe -PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac - -include $(MAKEFILEDIR)/platform.make - --include Makefile.preamble - -include $(MAKEFILEDIR)/$(MAKEFILE) - --include Makefile.postamble - --include Makefile.dependencies diff --git a/ktrace.tproj/Makefile.postamble b/ktrace.tproj/Makefile.postamble deleted file mode 100644 index f7143e4..0000000 --- a/ktrace.tproj/Makefile.postamble +++ /dev/null @@ -1,4 +0,0 @@ -install-man-page: - install -d $(DSTROOT)/usr/share/man/man1 - install -c -m 444 ktrace.1 $(DSTROOT)/usr/share/man/man1/ktrace.1 - diff --git a/ktrace.tproj/Makefile.preamble b/ktrace.tproj/Makefile.preamble deleted file mode 100644 index de796ce..0000000 --- a/ktrace.tproj/Makefile.preamble +++ /dev/null @@ -1,3 +0,0 @@ -OTHER_GENERATED_OFILES = $(VERS_OFILE) -AFTER_INSTALL += install-man-page - diff --git a/ktrace.tproj/PB.project b/ktrace.tproj/PB.project deleted file mode 100644 index 1a3d2e9..0000000 --- a/ktrace.tproj/PB.project +++ /dev/null @@ -1,38 +0,0 @@ -{ - APPCLASS = NSApplication; - FILESTABLE = { - CLASSES = (); - FRAMEWORKS = (); - HEADERSEARCH = (); - H_FILES = (ktrace.h); - M_FILES = (); - OTHER_LIBS = (); - OTHER_LINKED = (ktrace.c, subr.c); - OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, ktrace.1); - SUBPROJECTS = (); - }; - LANGUAGE = English; - LOCALIZABLE_FILES = {}; - NEXTSTEP_BUILDDIR = "/$(USER)/BUILD"; - NEXTSTEP_BUILDTOOL = /bin/gnumake; - NEXTSTEP_COMPILEROPTIONS = "-DMACH_USER_API"; - NEXTSTEP_INSTALLDIR = /usr/bin; - NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; - NEXTSTEP_MAINNIB = ktrace; - NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; - PDO_UNIX_BUILDTOOL = make; - PDO_UNIX_COMPILEROPTIONS = "-DMACH_USER_API"; - PDO_UNIX_INSTALLDIR = /usr/bin; - PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; - PDO_UNIX_MAINNIB = ktrace; - PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; - PROJECTNAME = ktrace; - PROJECTTYPE = Tool; - PROJECTVERSION = 2.8; - WINDOWS_BUILDTOOL = make; - WINDOWS_COMPILEROPTIONS = "-DMACH_USER_API"; - WINDOWS_INSTALLDIR = /usr/bin; - WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; - WINDOWS_MAINNIB = ktrace; - WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; -} diff --git a/ktrace.tproj/ktrace.1 b/ktrace.tproj/ktrace.1 deleted file mode 100644 index 082e34b..0000000 --- a/ktrace.tproj/ktrace.1 +++ /dev/null @@ -1,172 +0,0 @@ -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)ktrace.1 8.1 (Berkeley) 6/6/93 -.\" $FreeBSD: src/usr.bin/ktrace/ktrace.1,v 1.8.2.5 2001/08/16 13:16:53 ru Exp $ -.\" -.Dd June 6, 1993 -.Dt KTRACE 1 -.Os -.Sh NAME -.Nm ktrace -.Nd enable kernel process tracing -.Sh SYNOPSIS -.Nm -.Op Fl aCcdi -.Op Fl f Ar trfile -.Op Fl g Ar pgrp | Fl p Ar pid -.Op Fl t Ar trstr -.Nm -.Op Fl adi -.Op Fl f Ar trfile -.Op Fl t Ar trstr -.Ar command -.Sh DESCRIPTION -The -.Nm -command enables kernel trace logging for the specified processes. -Kernel trace data is logged to the file -.Pa ktrace.out . -The kernel operations that are traced include system calls, namei -translations, signal processing, and -.Tn I/O . -.Pp -Once tracing is enabled on a process, trace data will be logged until -either the process exits or the trace point is cleared. -A traced process can generate enormous amounts of log data quickly; -It is strongly suggested that users memorize how to disable tracing before -attempting to trace a process. -The following command is sufficient to disable tracing on all user owned -processes, and, if executed by root, all processes: -.Pp -.Dl \&$ ktrace -C -.Pp -The trace file is not human readable; use -.Xr kdump 1 -to decode it. -.Pp -The options are as follows: -.Bl -tag -width indent -.It Fl a -Append to the trace file instead of recreating it. -.It Fl C -Disable tracing on all user owned processes, and, if executed by root, all -processes in the system. -.It Fl c -Clear the trace points associated with the specified file or processes. -.It Fl d -Descendants; perform the operation for all current children of the -designated processes. -.It Fl f Ar file -Log trace records to -.Ar file -instead of -.Pa ktrace.out . -.It Fl g Ar pgid -Enable (disable) tracing on all processes in the process group (only one -.Fl g -flag is permitted). -.It Fl i -Inherit; pass the trace flags to all future children of the designated -processes. -.It Fl p Ar pid -Enable (disable) tracing on the indicated process id (only one -.Fl p -flag is permitted). -.It Fl t Ar trstr -The string argument represents the kernel trace points, one per letter. -The following table equates the letters with the tracepoints: -.Pp -.Bl -tag -width flag -compact -.It Cm c -trace system calls -.It Cm n -trace namei translations -.It Cm i -trace -.Tn I/O -.It Cm s -trace signal processing -.It Cm u -userland traces -.It Cm w -context switches -.El -.It Ar command -Execute -.Ar command -with the specified trace flags. -.El -.Pp -The -.Fl p , -.Fl g , -and -.Ar command -options are mutually exclusive. -.Sh EXAMPLES -# trace all kernel operations of process id 34 -.Dl $ ktrace -p 34 -.Pp -# trace all kernel operations of processes in process group 15 and -# pass the trace flags to all current and future children -.Dl $ ktrace -idg 15 -.Pp -# disable all tracing of process 65 -.Dl $ ktrace -cp 65 -.Pp -# disable tracing signals on process 70 and all current children -.Dl $ ktrace -t s -cdp 70 -.Pp -# enable tracing of -.Tn I/O -on process 67 -.Dl $ ktrace -ti -p 67 -.Pp -# run the command "w", tracing only system calls -.Dl $ ktrace -tc w -.Pp -# disable all tracing to the file "tracedata" -.Dl $ ktrace -c -f tracedata -.Pp -# disable tracing of all processes owned by the user -.Dl $ ktrace -C -.Sh SEE ALSO -.Xr kdump 1 -.Sh BUGS -Only works if -.Ar file -is a regular file. -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.4 . diff --git a/ktrace.tproj/ktrace.c b/ktrace.tproj/ktrace.c deleted file mode 100644 index 50e3b2f..0000000 --- a/ktrace.tproj/ktrace.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#ifndef lint -__unused static char copyright[] = -"@(#) Copyright (c) 1988, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -__unused static char sccsid[] = "@(#)ktrace.c 8.1 (Berkeley) 6/6/93"; -#endif -__unused static const char rcsid[] = - "$FreeBSD: src/usr.bin/ktrace/ktrace.c,v 1.12.2.3 2001/07/11 00:29:27 mikeh Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ktrace.h" - -void no_ktrace __P((int)); -void usage __P((void)); -int rpid(char *p); - -int -main(int argc, char *argv[]) -{ - enum { NOTSET, CLEAR, CLEARALL } clear; - int append; - int ch; - int fd; - int inherit; - int ops; - int pid = 1; /* protected by pidset */ - int pidset; - int trpoints; - char *tracefile; - mode_t omask; - struct stat sb; - - clear = NOTSET; - append = ops = pidset = inherit = 0; - trpoints = DEF_POINTS; - tracefile = DEF_TRACEFILE; - while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != -1) - switch((char)ch) { - case 'a': - append = 1; - break; - case 'C': - clear = CLEARALL; - pidset = 1; - break; - case 'c': - clear = CLEAR; - break; - case 'd': - ops |= KTRFLAG_DESCEND; - break; - case 'f': - tracefile = optarg; - break; - case 'g': - pid = -rpid(optarg); - pidset = 1; - break; - case 'i': - inherit = 1; - break; - case 'p': - pid = rpid(optarg); - pidset = 1; - break; - case 't': - trpoints = getpoints(optarg); - if (trpoints < 0) { - warnx("unknown facility in %s", optarg); - usage(); - } - break; - default: - usage(); - } - argv += optind; - argc -= optind; - - if (pidset && *argv || !pidset && !*argv) - usage(); - - if (inherit) - trpoints |= KTRFAC_INHERIT; - - (void)signal(SIGSYS, no_ktrace); - if (clear != NOTSET) { - if (clear == CLEARALL) { - ops = KTROP_CLEAR | KTRFLAG_DESCEND; - trpoints = ALL_POINTS; - pid = 1; - } else - ops |= pidset ? KTROP_CLEAR : KTROP_CLEARFILE; - - if (ktrace(tracefile, ops, trpoints, pid) < 0) - err(1, "%s", tracefile); - exit(0); - } - - omask = umask(S_IRWXG|S_IRWXO); - if (append) { - if ((fd = open(tracefile, O_CREAT | O_WRONLY, DEFFILEMODE)) < 0) - err(1, "%s", tracefile); - if (fstat(fd, &sb) != 0 || sb.st_uid != getuid()) - errx(1, "Refuse to append to %s not owned by you.", - tracefile); - } else { - if (unlink(tracefile) == -1 && errno != ENOENT) - err(1, "unlink %s", tracefile); - if ((fd = open(tracefile, O_CREAT | O_EXCL | O_WRONLY, - DEFFILEMODE)) < 0) - err(1, "%s", tracefile); - } - (void)umask(omask); - (void)close(fd); - - if (*argv) { - if (ktrace(tracefile, ops, trpoints, getpid()) < 0) - err(1, "%s", tracefile); - execvp(argv[0], &argv[0]); - err(1, "exec of '%s' failed", argv[0]); - } - else if (ktrace(tracefile, ops, trpoints, pid) < 0) - err(1, "%s", tracefile); - exit(0); -} - -int -rpid(char *p) -{ - static int first; - - if (first++) { - warnx("only one -g or -p flag is permitted."); - usage(); - } - if (!*p) { - warnx("illegal process id."); - usage(); - } - return(atoi(p)); -} - -void -usage(void) -{ - (void)fprintf(stderr, "%s\n%s\n", -"usage: ktrace [-aCcdi] [-f trfile] [-g pgrp | -p pid] [-t cnisuw]", -" ktrace [-adi] [-f trfile] [-t cnisuw] command"); - exit(1); -} - -void -no_ktrace(int sig) -{ - (void)fprintf(stderr, -"error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'options KTRACE'\n"); - exit(1); -} diff --git a/ktrace.tproj/ktrace.h b/ktrace.tproj/ktrace.h deleted file mode 100644 index 2d96f7e..0000000 --- a/ktrace.tproj/ktrace.h +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ktrace.h 8.1 (Berkeley) 6/6/93 - */ - -#define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ - KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER) - -#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW) - -#define DEF_TRACEFILE "ktrace.out" - -/* - * External function declarations - */ -/* subr.c */ -int getpoints(char *s); -void timevaladd(struct timeval *t1, struct timeval *t2); -void timevalsub(struct timeval *t1, struct timeval *t2); -void timevalfix(struct timeval *t1); diff --git a/ktrace.tproj/subr.c b/ktrace.tproj/subr.c deleted file mode 100644 index be7da68..0000000 --- a/ktrace.tproj/subr.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)subr.c 8.1 (Berkeley) 6/6/93"; -#endif -static const char rcsid[] = - "$FreeBSD: src/usr.bin/ktrace/subr.c,v 1.6 1999/08/28 01:02:34 peter Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "ktrace.h" - -int -getpoints(char *s) -{ - int facs = 0; - - while (*s) { - switch(*s) { - case 'c': - facs |= KTRFAC_SYSCALL | KTRFAC_SYSRET; - break; - case 'n': - facs |= KTRFAC_NAMEI; - break; - case 'i': - facs |= KTRFAC_GENIO; - break; - case 's': - facs |= KTRFAC_PSIG; - break; - case 'u': - facs |= KTRFAC_USER; - break; - case 'w': - facs |= KTRFAC_CSW; - break; - case '+': - facs |= DEF_POINTS; - break; - default: - return (-1); - } - s++; - } - return (facs); -} - -void -timevaladd(struct timeval *t1, struct timeval *t2) -{ - t1->tv_sec += t2->tv_sec; - t1->tv_usec += t2->tv_usec; - timevalfix(t1); -} - -void -timevalsub(struct timeval *t1, struct timeval *t2) -{ - t1->tv_sec -= t2->tv_sec; - t1->tv_usec -= t2->tv_usec; - timevalfix(t1); -} - -void -timevalfix(struct timeval *t1) -{ - if (t1->tv_usec < 0) { - t1->tv_sec--; - t1->tv_usec += 1000000; - } - if (t1->tv_usec >= 1000000) { - t1->tv_sec++; - t1->tv_usec -= 1000000; - } -} diff --git a/latency.tproj/latency.1 b/latency.tproj/latency.1 index 94ce927..8978522 100644 --- a/latency.tproj/latency.1 +++ b/latency.tproj/latency.1 @@ -9,8 +9,8 @@ .Sh SYNOPSIS .Nm latency .Op Fl rt -.Op Fl c Ar codefile -.Op Fl l Ar logfile +.Op Fl c Ar code_file +.Op Fl l Ar log_file .Op Fl st Ar threshold .Op Fl it Ar threshold .Op Fl s Ar sleep_in_usecs @@ -19,57 +19,58 @@ .Sh DESCRIPTION The .Nm latency -utility provides scheduling and interrupt latency statistics. -It requires root privileges due to the kernel tracing facility it uses to -operate. +utility provides scheduling and interrupt-latency statistics. +Due to the kernel tracing facility it uses to operate, +the command requires root privileges. .Pp The arguments are as follows: .Bl -tag -width Ds -.It Fl rt -Set real time scheduling policy. -Default policy is timeshare. -.It Fl c +.\" ========== +.It Fl c Ar code_file When the .Fl c -option is specified, it takes a path to a -.Ar codefile +option is specified, it takes a path to a code file that contains the mappings for the system calls. -This option overrides the default location of the system call codefile which is -found in /usr/share/misc/trace.codes. -.It Fl l -Specifies a -.Ar logfile -that is written to when either the interrupt or scheduling latency is exceeded. -.It Fl st -Set the scheduler latency threshold in microseconds. -If latency exceeds this, and a logfile has been specified, a record of what -occurred during this time is recorded. -.It Fl it -Set the interrupt latency threshold in microseconds. -If latency exceeds this, and a logfile has been specified, a record of what -occurred during this time is recorded. -.It Fl s -The -.Fl s -option sets the timer. -It takes microseconds as an argument, the default timer is set to 1000 -microseconds. -.It Fl d -The -.Fl d -option sets the decrementer. -It takes microseconds as an argument. -The decrementer is set back to the system default on exit. -.It Fl n +This option overrides the default location of the system call code file, +which is found in /usr/share/misc/trace.codes. +.\" ========== +.It Fl d Ar decrementer_in_usecs +Sets the decrementer, using a value expressed in microseconds. +On exit, the decrementer is set back to the system default value. +.\" ========== +.It Fl it Ar threshold +Set the interrupt latency threshold, +expressed in microseconds. +If the latency exceeds this value, +and a log file has been specified, +a record of what occurred during this time is recorded. +.\" ========== +.It Fl l Ar log_file +Specifies a log file that is written to when +either the interrupt or scheduling latency is exceeded. +.\" ========== +.It Fl n Ar kernel By default, .Nm latency acts on the default /mach_kernel. This option allows you to specify an alternate booted kernel. +.\" ========== +.It Fl rt +Sets the real-time scheduling policy. +Default policy is timeshare. +.\" ========== +.It Fl s Ar sleep_in_usecs +Sets the timer, taking an argument expressed in microseconds. +The default timer is set to 1000 microseconds. +.\" ========== +.It Fl st Ar threshold +Set the scheduler latency threshold in microseconds. +If latency exceeds this, and a log file has been specified, +a record of what occurred during this time is recorded. .El .Pp The data columns displayed are as follows: -.Bl -tag -width LAST_PATHNAME_WAITED_FOR -compact -.Pp +.Bl -tag -width LAST_PATHNAME_WAITED_FOR .It SCHEDULER The number of context switches that fall within the described delay. .It INTERRUPTS @@ -91,6 +92,6 @@ The threshold for the scheduler is set to 20000 microseconds. The threshold for interrupts is set to 1000 microseconds. Latencies that exceed these thresholds will be logged in /var/tmp/latency.log. .Sh SEE ALSO -.Xr top 1 , .Xr fs_usage 1 , -.Xr sc_usage 1 +.Xr sc_usage 1 , +.Xr top 1 diff --git a/latency.tproj/latency.c b/latency.tproj/latency.c index 0b6da26..d24fb57 100644 --- a/latency.tproj/latency.c +++ b/latency.tproj/latency.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -141,7 +142,7 @@ int need_new_map = 0; int total_threads = 0; kd_threadmap *mapptr = 0; -#define MAX_ENTRIES 1024 +#define MAX_ENTRIES 4096 struct ct { int type; char name[32]; @@ -172,7 +173,7 @@ int cur_max = 0; #define INTERRUPT 0x01050000 #define DECR_TRAP 0x01090000 #define DECR_SET 0x01090004 -#define MACH_vmfault 0x01300000 +#define MACH_vmfault 0x01300008 #define MACH_sched 0x01400000 #define MACH_stkhandoff 0x01400008 #define VFS_LOOKUP 0x03010090 @@ -1633,6 +1634,7 @@ exit_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, double t struct th_info *ti; int cpunum; char *p; + uint64_t user_addr; cpunum = CPU_NUMBER(kd->timestamp); @@ -1650,9 +1652,11 @@ exit_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, double t if ((p = find_code(type))) { if (type == INTERRUPT) { fprintf(fp, "INTERRUPT %-8x %d %s\n", thread, cpunum, command); - } else if (type == MACH_vmfault && kd->arg2 <= DBG_CACHE_HIT_FAULT) { - fprintf(fp, "%-28.28s %-8.8s %-8x %-8x %d %s\n", - p, fault_name[kd->arg2], kd->arg1, + } else if (type == MACH_vmfault && kd->arg4 <= DBG_CACHE_HIT_FAULT) { + user_addr = ((uint64_t)kd->arg1 << 32) | (uint32_t)kd->arg2; + + fprintf(fp, "%-28.28s %-8.8s %-16qx %-8x %d %s\n", + p, fault_name[kd->arg4], user_addr, thread, cpunum, command); } else { fprintf(fp, "%-28.28s %-8x %-8x %-8x %d %s\n", @@ -2076,7 +2080,7 @@ void init_code_file() return; } for (i = 0; i < MAX_ENTRIES; i++) { - n = fscanf(fp, "%x%s\n", &code, name); + n = fscanf(fp, "%x%127s\n", &code, name); if (n != 2) break; @@ -2103,7 +2107,11 @@ do_kernel_nm() bzero(tmpstr, 1024); /* Build the temporary nm file path */ - sprintf(tmp_nm_file, "/tmp/knm.out.%d", getpid()); + strcpy(tmp_nm_file,"/tmp/knm.out.XXXXXX"); + if (!mktemp(tmp_nm_file)) { + fprintf(stderr, "Error in mktemp call\n"); + return; + } /* Build the nm command and create a tmp file with the output*/ sprintf (tmpstr, "/usr/bin/nm -f -n -s __TEXT __text %s > %s", diff --git a/login.tproj/Makefile b/login.tproj/Makefile index 5784e64..3f17ae0 100644 --- a/login.tproj/Makefile +++ b/login.tproj/Makefile @@ -12,6 +12,8 @@ NAME = login PROJECTVERSION = 2.8 PROJECT_TYPE = Tool +Embedded=$(shell tconf --test TARGET_OS_EMBEDDED) + HFILES = pathnames.h CFILES = klogin.c login.c @@ -25,7 +27,9 @@ MAKEFILE = tool.make NEXTSTEP_INSTALLDIR = /usr/bin WINDOWS_INSTALLDIR = /usr/bin PDO_UNIX_INSTALLDIR = /usr/bin +ifeq "$(Embedded)" "NO" LIBS = -lbsm -lpam -lpam_misc +endif DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) diff --git a/login.tproj/Makefile.preamble b/login.tproj/Makefile.preamble index 802d9eb..9862638 100644 --- a/login.tproj/Makefile.preamble +++ b/login.tproj/Makefile.preamble @@ -1,5 +1,7 @@ CLEAN_ALL_SUBPROJECTS = YES OTHER_GENERATED_OFILES = $(VERS_OFILE) -OTHER_CFLAGS = -DUSE_PAM -no-cpp-precomp +ifeq "$(shell tconf --test TARGET_OS_EMBEDDED)" "NO" +OTHER_CFLAGS = -DUSE_PAM -DUSE_BSM -no-cpp-precomp +endif AFTER_INSTALL = after_install diff --git a/login.tproj/login.1 b/login.tproj/login.1 index 1d30551..a49fcb7 100644 --- a/login.tproj/login.1 +++ b/login.tproj/login.1 @@ -39,9 +39,14 @@ .Nd log into the computer .Sh SYNOPSIS .Nm login -.Op Fl fp +.Op Fl pq .Op Fl h Ar hostname .Op Ar user +.Nm login +.Fl f +.Op Fl lpq +.Op Fl h Ar hostname +.Op Ar user Op Ar prog Op Ar args... .Sh DESCRIPTION The .Nm login @@ -55,6 +60,7 @@ Authentication of users is done via passwords. .Pp The options are as follows: .Bl -tag -width Ds +.\" ========== .It Fl f The .Fl f @@ -63,6 +69,13 @@ authentication has already been done and that no password need be requested. This option may only be used by the super-user or when an already logged in user is logging in as themselves. +.Pp +With the +.Fl f +option, an alternate program (and any arguments) may be run instead of the +user's default shell. +The program and arguments follows the user name. +.\" ========== .It Fl h The .Fl h @@ -70,6 +83,16 @@ option specifies the host from which the connection was received. It is used by various daemons such as .Xr telnetd 8 . This option may only be used by the super-user. +.\" ========== +.It Fl l +Tells the program executed by +.Nm login +that this is not a login session (by convention, a login session is +signalled to the program with a hyphen as the first character of +.Em argv[0] ; +this option disables that), and prevents it from chdir(2)ing to the user's home directory. +The default is to add the hyphen (this is a login session). +.\" ========== .It Fl p By default, .Nm login @@ -77,6 +100,11 @@ discards any previous environment. The .Fl p option disables this behavior. +.\" ========== +.It Fl q +This forces quiet logins, as if a +.Pa .hushlogin +is present. .El .Pp If the file @@ -94,15 +122,18 @@ displays the system copyright notice, the date and time the user last logged in, the message of the day as well as other information. If the file .Dq Pa .hushlogin -exists in the user's home directory, all of these messages are suppressed. +exists in the user's home directory or +.Fl q +is specified, all of these messages are suppressed. This is to simplify logins for non-human users, such as .Xr uucp 1 . .Nm Login -then records an entry in the -.Xr wtmp 5 -and -.Xr utmp 5 -files and executes the user's command interpreter. +then records an entry in +.Xr utmpx 5 +and the like, and executes the user's command interpreter (or the program +specified on the command line if +.Fl f +is specified). .Pp Login enters information into the environment (see .Xr environ 7 ) @@ -123,12 +154,8 @@ utility. message-of-the-day .It Pa /etc/nologin disallows logins -.It Pa /var/run/utmp +.It Pa /var/run/utmpx current logins -.It Pa /var/log/lastlog -last login account records -.It Pa /var/log/wtmp -login account records .It Pa /var/mail/user system mailboxes .It Pa \&.hushlogin @@ -139,8 +166,8 @@ makes login quieter .Xr passwd 1 , .Xr rlogin 1 , .Xr getpass 3 , -.Xr utmp 5 , -.Xr environ 7 , +.Xr utmpx 5 , +.Xr environ 7 .Sh HISTORY A .Nm login diff --git a/login.tproj/login.c b/login.tproj/login.c index 09909c9..76fbc6f 100644 --- a/login.tproj/login.c +++ b/login.tproj/login.c @@ -1,23 +1,22 @@ /* - * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999, 2004, 2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -85,7 +84,11 @@ static char copyright[] = #include #include #include +#ifdef USE_PAM +#include +#else /* !USE_PAM */ #include +#endif /* USE_PAM */ #include #include @@ -93,14 +96,22 @@ static char copyright[] = #include #include +#include + +#ifdef USE_BSM #include #include +#endif #ifdef USE_PAM #include #include #endif +#include + +#include + #include "pathnames.h" void badlogin __P((char *)); @@ -120,7 +131,9 @@ void au_success(); void au_fail(char *, int); +#ifndef USE_PAM extern void login __P((struct utmp *)); +#endif /* !USE_PAM */ static void bail(int, int); static void refused(const char *, const char *, int); @@ -151,11 +164,14 @@ static int pam_err; static int pam_silent = PAM_SILENT; static int pam_cred_established; static int pam_session_established; +static struct lastlogx lastlog; #endif /* USE_PAM */ int hflag; +#ifdef USE_BSM #define NA_EVENT_STR_SIZE 25 au_tid_t tid; +#endif int main(argc, argv) @@ -165,8 +181,11 @@ main(argc, argv) extern char **environ; struct group *gr; struct stat st; +#ifndef USE_PAM struct utmp utmp; - int ask, ch, cnt, oflag = 0, fflag, pflag, quietlog, rootlogin = 0; +#endif /* USE_PAM */ + int ask, ch, cnt, oflag = 0, fflag, lflag, pflag; + int quietlog = 0, rootlogin = 0; uid_t uid; uid_t euid; gid_t egid; @@ -194,8 +213,11 @@ main(argc, argv) /* * -p is used by getty to tell login not to destroy the environment * -f is used to skip a second login authentication + * -l is used to indicate a login session to the command that + * follows username * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp + * -q is used to force hushlogin */ domain = NULL; if (gethostname(localhost, sizeof(localhost)) < 0) @@ -206,9 +228,9 @@ main(argc, argv) euid = geteuid(); egid = getegid(); - fflag = hflag = pflag = 0; + fflag = hflag = lflag = pflag = 0; uid = getuid(); - while ((ch = getopt(argc, argv, "1fh:p")) != EOF) + while ((ch = getopt(argc, argv, "1fh:lpq")) != EOF) switch (ch) { case '1': oflag = 1; @@ -225,22 +247,30 @@ main(argc, argv) *p = 0; hostname = optarg; break; + case 'l': + lflag = 1; + break; case 'p': pflag = 1; break; + case 'q': + quietlog = 1; + break; case '?': default: if (!uid) syslog(LOG_ERR, "invalid flag %c", ch); (void)fprintf(stderr, - "usage: login [-fp] [-h hostname] [username]\n"); + "usage: login [-pq] [-h hostname] [username]\n"); + (void)fprintf(stderr, + " login -f [-lpq] [-h hostname] [username [prog [arg ...]]]\n"); exit(1); } argc -= optind; argv += optind; if (*argv) { - username = *argv; + username = *argv++; ask = 0; } else ask = 1; @@ -258,6 +288,7 @@ main(argc, argv) else tty = ttyn; +#ifdef USE_BSM /* Set the terminal id */ audit_set_terminal_id(&tid); if (fstat(STDIN_FILENO, &st) < 0) { @@ -270,31 +301,32 @@ main(argc, argv) } else { tid.port = 0; } +#endif #ifdef USE_PAM pam_err = pam_start("login", username, &conv, &pamh); if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM Error", 1); exit(1); } pam_err = pam_set_item(pamh, PAM_TTY, tty); if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM Error", 1); exit(1); } pam_err = pam_set_item(pamh, PAM_RHOST, hostname); if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM Error", 1); exit(1); } pam_err = pam_set_item(pamh, PAM_USER_PROMPT, "login: "); if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM Error", 1); exit(1); } @@ -345,7 +377,7 @@ main(argc, argv) pam_err = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); } if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM error", 1); exit(1); } @@ -355,16 +387,20 @@ main(argc, argv) if( (pam_err == PAM_SUCCESS) && username && *username) pwd = getpwnam(username); + /* get lastlog info before PAM make a new entry */ + if (!quietlog) + getlastlogxbyname(username, &lastlog); + pam_err = pam_open_session(pamh, 0); if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM error", 1); exit(1); } pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED); if( pam_err != PAM_SUCCESS ) { - fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, pam_err)); + fprintf(stderr, "login: PAM Error (line %d): %s\n", __LINE__, pam_strerror(pamh, pam_err)); au_fail("PAM error", 1); exit(1); } @@ -485,6 +521,11 @@ main(argc, argv) endpwent(); + if (!pwd) { + fprintf(stderr, "login: Unable to find user: %s\n", username); + exit(1); + } + /* if user not super-user, check for disabled logins */ if (!rootlogin) checknologin(); @@ -496,27 +537,30 @@ main(argc, argv) setegid(pwd->pw_gid); seteuid(rootlogin ? 0 : pwd->pw_uid); - /* First do a stat in case the homedir is automounted */ - stat(pwd->pw_dir,&st); - - if (!*pwd->pw_dir || chdir(pwd->pw_dir) < 0) { - printf("No home directory %s!\n", pwd->pw_dir); - if (chdir("/")) { - refused("Cannot find root directory", "HOMEDIR", 1); - } - pwd->pw_dir = strdup("/"); - if (pwd->pw_dir == NULL) { - syslog(LOG_NOTICE, "strdup(): %m"); - bail(SLEEP_EXIT, 1); + if (!lflag) { + /* First do a stat in case the homedir is automounted */ + stat(pwd->pw_dir,&st); + + if (!*pwd->pw_dir || chdir(pwd->pw_dir) < 0) { + printf("No home directory %s!\n", pwd->pw_dir); + if (chdir("/")) + refused("Cannot find root directory", "HOMEDIR", 1); + pwd->pw_dir = strdup("/"); + if (pwd->pw_dir == NULL) { + syslog(LOG_NOTICE, "strdup(): %m"); + bail(SLEEP_EXIT, 1); + } + printf("Logging in with home = \"/\".\n"); } - printf("Logging in with home = \"/\".\n"); } seteuid(euid); setegid(egid); - quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; + if (!quietlog) + quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; /* Nothing else left to fail -- really log in. */ +#ifndef USE_PAM memset((void *)&utmp, 0, sizeof(utmp)); (void)time(&utmp.ut_time); (void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); @@ -524,6 +568,7 @@ main(argc, argv) (void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); login(&utmp); +#endif /* USE_PAM */ dolastlog(quietlog); @@ -542,6 +587,16 @@ main(argc, argv) bail(SLEEP_EXIT, 1); } +#if TARGET_OS_EMBEDDED + /* on embedded, allow a shell to live in /var/debug_mount/bin/sh */ +#define _PATH_DEBUGSHELL "/var/debug_mount/bin/sh" + if (stat(pwd->pw_shell, &st) != 0) { + if (stat(_PATH_DEBUGSHELL, &st) == 0) { + pwd->pw_shell = strdup(_PATH_DEBUGSHELL); + } + } +#endif + /* Destroy environment unless user has requested its preservation. */ if (!pflag) { environ = malloc(sizeof(char *)); @@ -565,6 +620,10 @@ main(argc, argv) for( cnt = 0; pmenv && pmenv[cnt]; cnt++ ) putenv(pmenv[cnt]); + /* Ignore SIGHUP so that the parent's call to waitpid will + succeed and the tty ownership can be reset. */ + (void)signal(SIGHUP, SIG_IGN); + pid = fork(); if ( pid < 0 ) { err(1, "fork"); @@ -578,6 +637,9 @@ main(argc, argv) exit(0); } + /* Restore the default SIGHUP handler for the child. */ + (void)signal(SIGHUP, SIG_DFL); + #endif if (tty[sizeof("tty")-1] == 'd') @@ -610,10 +672,6 @@ main(argc, argv) (void)signal(SIGINT, SIG_DFL); (void)signal(SIGTSTP, SIG_IGN); - tbuf[0] = '-'; - (void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? - p + 1 : pwd->pw_shell); - if (setlogin(pwd->pw_name) < 0) syslog(LOG_ERR, "setlogin() failure: %m"); @@ -623,8 +681,67 @@ main(argc, argv) else (void) setuid(pwd->pw_uid); - execlp(pwd->pw_shell, tbuf, 0); - err(1, "%s", pwd->pw_shell); + /* Re-enable crash reporter */ + do { + kern_return_t kr; + mach_port_t bp, ep, mts; + thread_state_flavor_t flavor = 0; + +#if defined(__ppc__) + flavor = PPC_THREAD_STATE64; +#elif defined(__i386__) + flavor = x86_THREAD_STATE; +#endif + + mts = mach_task_self(); + + kr = task_get_bootstrap_port(mts, &bp); + if (kr != KERN_SUCCESS) { + syslog(LOG_ERR, "task_get_bootstrap_port() failure: %s (%d)", + bootstrap_strerror(kr), kr); + break; + } + + const char* bs = "com.apple.ReportCrash"; + kr = bootstrap_look_up(bp, (char*)bs, &ep); + if (kr != KERN_SUCCESS) { + syslog(LOG_ERR, "bootstrap_look_up(%s) failure: %s (%d)", + bs, bootstrap_strerror(kr), kr); + break; + } + + kr = task_set_exception_ports(mts, EXC_MASK_CRASH, ep, EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, flavor); + if (kr != KERN_SUCCESS) { + syslog(LOG_ERR, "task_set_exception_ports() failure: %d", kr); + break; + } + } while (0); + + if (fflag && *argv) { + char *arg0 = *argv; + if (lflag) + (void)strlcpy(tbuf, (p = strrchr(*argv, '/')) ? + p + 1 : *argv, sizeof(tbuf)); + else { + tbuf[0] = '-'; + (void)strlcpy(tbuf + 1, (p = strrchr(*argv, '/')) ? + p + 1 : *argv, sizeof(tbuf) - 1); + } + *argv = tbuf; + execvp(arg0, argv); + err(1, "%s", arg0); + } else { + if (lflag) + (void)strlcpy(tbuf, (p = strrchr(pwd->pw_shell, '/')) ? + p + 1 : pwd->pw_shell, sizeof(tbuf)); + else { + tbuf[0] = '-'; + (void)strlcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ? + p + 1 : pwd->pw_shell, sizeof(tbuf) - 1); + } + execlp(pwd->pw_shell, tbuf, (char *)NULL); + err(1, "%s", pwd->pw_shell); + } } #ifdef KERBEROS @@ -641,6 +758,7 @@ main(argc, argv) */ void au_success() { +#ifdef USE_BSM token_t *tok; int aufd; au_mask_t aumask; @@ -697,6 +815,7 @@ void au_success() fprintf(stderr, "login: Audit Record was not committed.\n"); exit(1); } +#endif } /* @@ -708,6 +827,7 @@ void au_success() */ void au_fail(char *errmsg, int na) { +#ifdef USE_BSM token_t *tok; int aufd; long au_cond; @@ -767,6 +887,7 @@ void au_fail(char *errmsg, int na) fprintf(stderr, "login: Audit Error: au_close() was not committed\n"); exit(1); } +#endif } void @@ -864,6 +985,22 @@ void dolastlog(quiet) int quiet; { +#ifdef USE_PAM + if (quiet) + return; + if (*lastlog.ll_line) { + (void)printf("Last login: %.*s ", + 24-5, (char *)ctime(&lastlog.ll_tv.tv_sec)); + if (*lastlog.ll_host != '\0') + (void)printf("from %.*s\n", + (int)sizeof(lastlog.ll_host), + lastlog.ll_host); + else + (void)printf("on %.*s\n", + (int)sizeof(lastlog.ll_line), + lastlog.ll_line); + } +#else /* !USE_PAM */ struct lastlog ll; int fd; @@ -903,6 +1040,7 @@ dolastlog(quiet) (void)write(fd, (char *)&ll, sizeof(ll)); (void)close(fd); } +#endif /* USE_PAM */ } void @@ -1005,8 +1143,9 @@ pam_cleanup() void bail(int sec, int eval) { - +#ifdef USE_PAM pam_cleanup(); +#endif (void)sleep(sec); exit(eval); } diff --git a/makekey.tproj/makekey.8 b/makekey.tproj/makekey.8 index c6ded2d..ee98c57 100644 --- a/makekey.tproj/makekey.8 +++ b/makekey.tproj/makekey.8 @@ -41,19 +41,19 @@ .Nm makekey .Sh DESCRIPTION .Nm Makekey -encrypts a key and salt which it reads from the standard input -and writes the result to the standard output. -The key is expected to be -ten bytes; the salt is expected to be two bytes. +encrypts a key and salt which it reads from the standard input, +writing the result to the standard output. +The key and salt values are expected to be ten and two bytes, +respectively, in length. See .Xr crypt 3 for more information on what characters the key and salt can contain and how the encrypted value is calculated. .Sh SEE ALSO -.Xr login 1 , .Xr crypt 1 , +.Xr login 1 , .Xr crypt 3 .Sh HISTORY A -.Nm +.Nm makekey command appeared in Version 7 AT&T UNIX. diff --git a/makekey.tproj/makekey.c b/makekey.tproj/makekey.c index 487cfaa..ae9ca17 100644 --- a/makekey.tproj/makekey.c +++ b/makekey.tproj/makekey.c @@ -54,14 +54,15 @@ * SUCH DAMAGE. */ +#include #ifndef lint -static char copyright[] = +__unused static char copyright[] = "@(#) Copyright (c) 1990, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)makekey.c 8.1 (Berkeley) 6/4/93"; +__unused static char sccsid[] = "@(#)makekey.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint */ #include diff --git a/mkfile.tproj/mkfile.8 b/mkfile.tproj/mkfile.8 index beed0c1..59c772b 100644 --- a/mkfile.tproj/mkfile.8 +++ b/mkfile.tproj/mkfile.8 @@ -44,4 +44,4 @@ re-exported before the client will be able to access it. This action may only be done when the client is not running. .SH "SEE ALSO" .TP -chmod(2), stat(2), exportfs(8), sticky(8) +chmod(2), stat(2), sticky(8) diff --git a/mkfile.tproj/mkfile.c b/mkfile.tproj/mkfile.c index 4aff548..0965ef5 100644 --- a/mkfile.tproj/mkfile.c +++ b/mkfile.tproj/mkfile.c @@ -41,6 +41,7 @@ #include #include #include +#include #define BF_SZ 512 /* Size of write chunks */ @@ -142,9 +143,12 @@ create_file(file_name, size, empty, verbose) char buff[BF_SZ]; int fd, bytes_written = BF_SZ; quad_t i; - mode_t mode; + mode_t mode = S_IRUSR | S_IWUSR; - if ((fd = open(file_name, O_RDWR | O_CREAT | O_TRUNC )) == -1) + /* If superuser, then set sticky bit */ + if (!geteuid()) mode |= S_ISVTX; + + if ((fd = open(file_name, O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) err(1, NULL); @@ -176,17 +180,11 @@ create_file(file_name, size, empty, verbose) } } + if (fchmod(fd, mode)) /* Change permissions */ + err_rm(file_name, NULL); - mode = S_IRUSR | S_IWUSR; - /* If superuser, then set sticky bit */ - if (! geteuid()) - mode |= S_ISVTX; - - if (fchmod(fd, mode)) /* Change permissions */ - err_rm(file_name, NULL); - - if ((close(fd)) == -1) - err_rm(file_name, NULL); + if ((close(fd)) == -1) + err_rm(file_name, NULL); if (verbose) (void)fprintf(stderr, "%s %qd bytes\n", file_name, size); diff --git a/pt_chown.tproj/Makefile b/newgrp.tproj/Makefile similarity index 77% rename from pt_chown.tproj/Makefile rename to newgrp.tproj/Makefile index 9503386..da34f45 100644 --- a/pt_chown.tproj/Makefile +++ b/newgrp.tproj/Makefile @@ -7,27 +7,29 @@ # and Makefile.postamble (both optional), and Makefile will include them. # -NAME = pt_chown +NAME = newgrp -PROJECTVERSION = 1.1 +PROJECTVERSION = 2.8 PROJECT_TYPE = Tool -CFILES = pt_chown.c +CFILES = newgrp.c -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble +OTHERSRCS = Makefile Makefile.preamble Makefile.postamble newgrp.1 +NEXTSTEP_PB_CFLAGS += -D__FBSDID=__RCSID MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles CODE_GEN_STYLE = DYNAMIC MAKEFILE = tool.make -NEXTSTEP_INSTALLDIR = /usr/libexec -WINDOWS_INSTALLDIR = /usr/libexec -PDO_UNIX_INSTALLDIR = /usr/libexec -LIBS = +NEXTSTEP_INSTALLDIR = /usr/bin DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) + + +NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(NAME)/Build + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc diff --git a/newgrp.tproj/Makefile.postamble b/newgrp.tproj/Makefile.postamble new file mode 100644 index 0000000..d153ad1 --- /dev/null +++ b/newgrp.tproj/Makefile.postamble @@ -0,0 +1,6 @@ +INSTALL_AS_USER = root +INSTALL_PERMISSIONS = 4555 + +after_install: + mkdir -p "$(DSTROOT)/usr/share/man/man1" + install -c -m 644 newgrp.1 "$(DSTROOT)/usr/share/man/man1/newgrp.1" diff --git a/newgrp.tproj/Makefile.preamble b/newgrp.tproj/Makefile.preamble new file mode 100644 index 0000000..053d503 --- /dev/null +++ b/newgrp.tproj/Makefile.preamble @@ -0,0 +1,2 @@ + +AFTER_INSTALL = after_install diff --git a/newgrp.tproj/PB.project b/newgrp.tproj/PB.project new file mode 100644 index 0000000..3901822 --- /dev/null +++ b/newgrp.tproj/PB.project @@ -0,0 +1,27 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + FRAMEWORKS = (); + H_FILES = (); + OTHER_LINKED = (newgrp.c); + OTHER_SOURCES = (Makefile, Makefile.preamble, Makefile.postamble, newgrp.1); + SUBPROJECTS = (); + }; + LANGUAGE = English; + LOCALIZABLE_FILES = {}; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDDIR = "/tmp/$(NAME)/Build"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_INSTALLDIR = /usr/bin; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = newgrp; + PROJECTTYPE = Tool; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/newgrp.tproj/newgrp.1 b/newgrp.tproj/newgrp.1 new file mode 100644 index 0000000..2051365 --- /dev/null +++ b/newgrp.tproj/newgrp.1 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2002 Tim J. Robbins. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/usr.bin/newgrp/newgrp.1,v 1.2 2002/05/30 13:57:35 ru Exp $ +.\" +.Dd May 23, 2002 +.Dt NEWGRP 1 +.Os +.Sh NAME +.Nm newgrp +.Nd change to a new group +.Sh SYNOPSIS +.Nm newgrp +.Op Fl l +.Op Ar group +.Sh DESCRIPTION +The +.Nm newgrp +utility creates a new shell execution environment +with modified real and effective group IDs. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl l +Simulate a full login. +The environment and umask are set to what would be expected +if the user actually logged in again. +.El +.Pp +If the +.Ar group +operand is present, a new shell is started +with the specified effective and real group IDs. +The user will be prompted for a password +if they are not a member of the specified group. +.Pp +Otherwise, the real, effective, and supplementary group IDs +are restored to those from the current user's password database entry. +.Sh DIAGNOSTICS +The +.Nm newgrp +utility attempts to start the shell regardless of whether group IDs +were successfully changed. +.Pp +If an error occurs and the shell cannot be started, +.Nm newgrp +exits >0. +Otherwise, the exit status of +.Nm newgrp +is the exit status of the shell. +.Sh SEE ALSO +.Xr csh 1 , +.Xr groups 1 , +.Xr login 1 , +.Xr sh 1 , +.Xr su 1 , +.Xr umask 1 , +.Xr group 5 , +.Xr passwd 5 , +.Xr environ 7 +.Sh STANDARDS +The +.Nm newgrp +utility conforms to +.St -p1003.1-2001 . +.Sh HISTORY +A +.Nm newgrp +utility appeared in +.At v6 . +.Sh BUGS +Group passwords are inherently insecure, +as there is no way to stop users obtaining the encrypted passwords +from the group database. +Their use is discouraged. diff --git a/newgrp.tproj/newgrp.c b/newgrp.tproj/newgrp.c new file mode 100644 index 0000000..2fc9db1 --- /dev/null +++ b/newgrp.tproj/newgrp.c @@ -0,0 +1,309 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * newgrp -- change to a new group + */ + +#include +__FBSDID("$FreeBSD: src/usr.bin/newgrp/newgrp.c,v 1.2 2003/10/30 15:14:34 harti Exp $"); + +#include + +#include +#include +#include +#include +#include +#ifndef __APPLE__ +#include +#endif /* !__APPLE__ */ +#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#endif /* __APPLE__ */ +static void addgroup(const char *grpname); +static void doshell(void); +static int inarray(gid_t, const gid_t[], int); +static void loginshell(void); +static void restoregrps(void); +static void usage(void); + +static struct passwd *pwd; +static uid_t euid; + +extern char **environ; + +/* Manipulate effective user ID. */ +#define PRIV_START do { \ + if (seteuid(euid) < 0) \ + err(1, "seteuid"); \ + } while (0) +#define PRIV_END do { \ + if (seteuid(getuid()) < 0) \ + err(1, "seteuid"); \ + } while (0) + +int +main(int argc, char *argv[]) +{ + int ch, login; + + euid = geteuid(); + if (seteuid(getuid()) < 0) + err(1, "seteuid"); + + if ((pwd = getpwuid(getuid())) == NULL) + errx(1, "unknown user"); + + login = 0; + while ((ch = getopt(argc, argv, "-l")) != -1) { + switch (ch) { + case '-': /* Obsolescent */ + case 'l': + login = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + switch (argc) { + case 0: + restoregrps(); + break; + case 1: + addgroup(*argv); + break; + default: + usage(); + } + + if (seteuid(euid) < 0) + err(1, "seteuid"); + if (setuid(getuid()) < 0) + err(1, "setuid"); + + if (login) + loginshell(); + else + doshell(); + + /*NOTREACHED*/ + exit(1); +} + +static void +usage(void) +{ + + fprintf(stderr, "usage: newgrp [-l] [group]\n"); + exit(1); +} + +static void +restoregrps(void) +{ + int initres, setres; + + PRIV_START; + initres = initgroups(pwd->pw_name, pwd->pw_gid); + setres = setgid(pwd->pw_gid); + PRIV_END; + + if (initres < 0) + warn("initgroups"); + if (setres < 0) + warn("setgroups"); +} + +static void +addgroup(const char *grpname) +{ + gid_t grps[NGROUPS_MAX]; + long lgid; + int dbmember, i, ngrps; + gid_t egid; + struct group *grp; + char *ep, *pass; + char **p; + + egid = getegid(); + + /* Try it as a group name, then a group id. */ + if ((grp = getgrnam(grpname)) == NULL) + if ((lgid = strtol(grpname, &ep, 10)) <= 0 || *ep != '\0' || + (grp = getgrgid((gid_t)lgid)) == NULL ) { + warnx("%s: bad group name", grpname); + return; + } + + /* + * If the user is not a member of the requested group and the group + * has a password, prompt and check it. + */ + dbmember = 0; + if (pwd->pw_gid == grp->gr_gid) + dbmember = 1; + for (p = grp->gr_mem; *p != NULL; p++) + if (strcmp(*p, pwd->pw_name) == 0) { + dbmember = 1; + break; + } + if (!dbmember && *grp->gr_passwd != '\0' && getuid() != 0) { + pass = getpass("Password:"); + if (pass == NULL || + strcmp(grp->gr_passwd, crypt(pass, grp->gr_passwd)) != 0) { + fprintf(stderr, "Sorry\n"); + return; + } + } + + if ((ngrps = getgroups(NGROUPS_MAX, (gid_t *)grps)) < 0) { + warn("getgroups"); + return; + } + + /* Remove requested gid from supp. list if it exists. */ + if (grp->gr_gid != egid && inarray(grp->gr_gid, grps, ngrps)) { + for (i = 0; i < ngrps; i++) + if (grps[i] == grp->gr_gid) + break; + ngrps--; + memmove(&grps[i], &grps[i + 1], (ngrps - i) * sizeof(gid_t)); + PRIV_START; + if (setgroups(ngrps, (const gid_t *)grps) < 0) { + PRIV_END; + warn("setgroups"); + return; + } + PRIV_END; + } + + PRIV_START; + if (setgid(grp->gr_gid)) { + PRIV_END; + warn("setgid"); + return; + } + PRIV_END; + grps[0] = grp->gr_gid; + + /* Add old effective gid to supp. list if it does not exist. */ + if (egid != grp->gr_gid && !inarray(egid, grps, ngrps)) { + if (ngrps == NGROUPS_MAX) + warnx("too many groups"); + else { + grps[ngrps++] = egid; + PRIV_START; + if (setgroups(ngrps, (const gid_t *)grps)) { + PRIV_END; + warn("setgroups"); + return; + } + PRIV_END; + } + } + +} + +static int +inarray(gid_t gid, const gid_t grps[], int ngrps) +{ + int i; + + for (i = 0; i < ngrps; i++) + if (grps[i] == gid) + return (1); + return (0); +} + +/* + * Set the environment to what would be expected if the user logged in + * again; this performs the same steps as su(1)'s -l option. + */ +static void +loginshell(void) +{ + char *args[2], **cleanenv, *term, *ticket; + const char *shell; +#ifndef __APPLE__ + login_cap_t *lc; +#endif /* !__APPLE__ */ + shell = pwd->pw_shell; + if (*shell == '\0') + shell = _PATH_BSHELL; + if (chdir(pwd->pw_dir) < 0) { + warn("%s", pwd->pw_dir); + chdir("/"); + } + + term = getenv("TERM"); + ticket = getenv("KRBTKFILE"); + + if ((cleanenv = calloc(20, sizeof(char *))) == NULL) + err(1, "calloc"); + *cleanenv = NULL; + environ = cleanenv; +#ifndef __APPLE__ + lc = login_getpwclass(pwd); + setusercontext(lc, pwd, pwd->pw_uid, + LOGIN_SETPATH|LOGIN_SETUMASK|LOGIN_SETENV); + login_close(lc); +#endif /* !__APPLE__ */ + setenv("USER", pwd->pw_name, 1); + setenv("SHELL", shell, 1); + setenv("HOME", pwd->pw_dir, 1); + if (term != NULL) + setenv("TERM", term, 1); + if (ticket != NULL) + setenv("KRBTKFILE", ticket, 1); + + if (asprintf(args, "-%s", basename(shell)) < 0) + err(1, "asprintf"); + args[1] = NULL; + + execv(shell, args); + err(1, "%s", shell); +} + +static void +doshell(void) +{ + const char *shell; + + shell = pwd->pw_shell; + if (*shell == '\0') + shell = _PATH_BSHELL; + execl(shell, basename(shell), (char *)NULL); + err(1, "%s", shell); +} diff --git a/nologin.tproj/nologin.8 b/nologin.tproj/nologin.8 index 07ddc98..e2052a2 100644 --- a/nologin.tproj/nologin.8 +++ b/nologin.tproj/nologin.8 @@ -53,7 +53,7 @@ If the file .Pa /etc/nologin.txt exists, .Nm nologin -displays its contents to the user instead of the default message. +displays its contents (instead of the default message) to the user. .Sh SEE ALSO .Xr login 1 .Sh HISTORY diff --git a/nvram.tproj/nvram.8 b/nvram.tproj/nvram.8 index 2454e06..b251c52 100644 --- a/nvram.tproj/nvram.8 +++ b/nvram.tproj/nvram.8 @@ -41,17 +41,29 @@ Binary data can be set using the %xx notation, where xx is the hex value of the byte. The type for new variables is always binary data. .SH OPTIONS +.\" ========== .TP -.B \-p -Print all of the firmware variables. +.BI \-d " name" +Deletes the named firmware variable. +.\" ========== .TP .BI \-f " filename" Set firmware variables from a text file. The file must be a -list name=value statements. If the last character of a line is -\\, the value will be continued to the next line. +list of "name value" statements. The first space on each line +is taken to be the separator between "name" and "value". If +the last character of a line is \\, the value extends to the next line. +.\" ========== .TP -.BI \-d " name" -Deletes the named firmware variable. +.B \-x +Use XML format for reading and writing variables. +This option must be used before the +.B \-p +or +.B \-f +options, since arguments are processed in order. +.TP +.B \-p +Print all of the firmware variables. .SH EXAMPLES .LP .RS diff --git a/nvram.tproj/nvram.c b/nvram.tproj/nvram.c index d97fb9d..fc9a242 100644 --- a/nvram.tproj/nvram.c +++ b/nvram.tproj/nvram.c @@ -33,6 +33,7 @@ static void Error(char *format, long item); static void FatalError(long exitValue, char *format, long item); static void UsageMessage(char *message); static void ParseFile(char *fileName); +static void ParseXMLFile(char *fileName); static void SetOrGetOFVariable(char *str); static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef, CFTypeRef *valueRef); @@ -40,11 +41,15 @@ static kern_return_t SetOFVariable(char *name, char *value); static void DeleteOFVariable(char *name); static void PrintOFVariables(void); static void PrintOFVariable(const void *key,const void *value,void *context); +static void SetOFVariableFromFile(const void *key, const void *value, void *context); +static void ClearOFVariables(void); +static void ClearOFVariable(const void *key,const void *value,void *context); static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value); // Global Variables static char *gToolName; static io_registry_entry_t gOptionsRef; +static bool gUseXML; int main(int argc, char **argv) @@ -80,7 +85,11 @@ int main(int argc, char **argv) case 'p' : PrintOFVariables(); break; - + + case 'x' : + gUseXML = true; + break; + case 'f': cnt++; if (cnt < argc && *argv[cnt] != '-') { @@ -99,6 +108,10 @@ int main(int argc, char **argv) } break; + case 'c': + ClearOFVariables(); + break; + default: strcpy(errorMessage, "no such option as --"); errorMessage[strlen(errorMessage)-1] = *str; @@ -151,10 +164,13 @@ static void UsageMessage(char *message) { Error("(usage: %s)", (long)message); - printf("%s [-p] [-f filename] [-d name] name[=value] ...\n", gToolName); + printf("%s [-x] [-p] [-f filename] [-d name] name[=value] ...\n", gToolName); + printf("\t-x use XML format for printing or reading variables\n"); + printf("\t (must appear before -p or -f)\n"); printf("\t-p print all firmware variables\n"); printf("\t-f set firmware variables from a text file\n"); printf("\t-d delete the named variable\n"); + printf("\t-c delete all variables\n"); printf("\tname=value set named variable\n"); printf("\tname print variable\n"); printf("Note that arguments and options are executed in order.\n"); @@ -189,6 +205,11 @@ static void ParseFile(char *fileName) char name[kMaxNameSize]; char value[kMaxStringSize]; FILE *patches; + + if (gUseXML) { + ParseXMLFile(fileName); + return; + } patches = fopen(fileName, "r"); if (patches == 0) { @@ -197,6 +218,10 @@ static void ParseFile(char *fileName) state = kFirstColumn; while ((tc = getc(patches)) != EOF) { + if(ni==(kMaxNameSize-1)) + FatalError(-1,"Name exceeded max length of %d",kMaxNameSize); + if(vi==(kMaxStringSize-1)) + FatalError(-1,"Value exceeded max length of %d",kMaxStringSize); switch (state) { case kFirstColumn : ni = 0; @@ -288,6 +313,69 @@ static void ParseFile(char *fileName) } +// ParseXMLFile(fileName) +// +// Open and parse the specified file in XML format, +// and set variables appropriately. +// +static void ParseXMLFile(char *fileName) +{ + CFPropertyListRef plist; + CFURLRef fileURL = NULL; + CFStringRef filePath = NULL; + CFStringRef errorString = NULL; + CFDataRef data = NULL; + SInt32 errorCode = 0; + + filePath = CFStringCreateWithCString(kCFAllocatorDefault, fileName, kCFStringEncodingUTF8); + if (filePath == NULL) { + FatalError(-1, "Could not create file path string", 0); + } + + // Create a URL that specifies the file we will create to + // hold the XML data. + fileURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, + filePath, + kCFURLPOSIXPathStyle, + false /* not a directory */ ); + if (fileURL == NULL) { + FatalError(-1, "Could not create file path URL", 0); + } + + CFRelease(filePath); + + if (! CFURLCreateDataAndPropertiesFromResource( + kCFAllocatorDefault, + fileURL, + &data, + NULL, + NULL, + &errorCode) || data == NULL ) { + FatalError(-1, "Error reading XML file (%d)", errorCode); + } + + CFRelease(fileURL); + + plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, + data, + kCFPropertyListImmutable, + &errorString); + + CFRelease(data); + + if (plist == NULL) { + FatalError(-1, "Error parsing XML file", 0); + } + + if (errorString != NULL) { + FatalError(-1, "Error parsing XML file: %s", (long)CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8)); + } + + CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0); + + CFRelease(plist); +} + // SetOrGetOFVariable(str) // // Parse the input string, then set or get the specified @@ -446,12 +534,28 @@ static void PrintOFVariables() if (result != KERN_SUCCESS) { FatalError(-1, "Error (%d) getting the firmware variables", result); } - CFDictionaryApplyFunction(dict, &PrintOFVariable, 0); + + if (gUseXML) { + CFDataRef data; + + data = CFPropertyListCreateXMLData( kCFAllocatorDefault, dict ); + if (data == NULL) { + FatalError(-1, "Error (%d) converting variables to xml", result); + } + + fwrite(CFDataGetBytePtr(data), sizeof(UInt8), CFDataGetLength(data), stdout); + + CFRelease(data); + + } else { + + CFDictionaryApplyFunction(dict, &PrintOFVariable, 0); + + } CFRelease(dict); } - // PrintOFVariable(key, value, context) // // Print the given firmware variable. @@ -534,6 +638,33 @@ static void PrintOFVariable(const void *key, const void *value, void *context) if (valueBuffer != 0) free(valueBuffer); } +// ClearOFVariables() +// +// Deletes all OF variables +// +static void ClearOFVariables(void) +{ + kern_return_t result; + CFMutableDictionaryRef dict; + + result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0); + if (result != KERN_SUCCESS) { + FatalError(-1, "Error (%d) getting the firmware variables", result); + } + CFDictionaryApplyFunction(dict, &ClearOFVariable, 0); + + CFRelease(dict); +} + +static void ClearOFVariable(const void *key, const void *value, void *context) +{ + kern_return_t result; + result = IORegistryEntrySetCFProperty(gOptionsRef, + CFSTR(kIONVRAMDeletePropertyKey), key); + if (result != KERN_SUCCESS) { + FatalError(-1, "Error (%d) clearing firmware variables", result); + } +} // ConvertValueToCFTypeRef(typeID, value) // @@ -569,10 +700,32 @@ static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value) value[cnt2] = number; } else value[cnt2] = value[cnt]; } - valueRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, value, + valueRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)value, cnt2, kCFAllocatorDefault); } else return 0; return valueRef; } +static void SetOFVariableFromFile(const void *key, const void *value, void *context) +{ + kern_return_t result; + + result = IORegistryEntrySetCFProperty(gOptionsRef, key, value); + if ( result != KERN_SUCCESS ) { + int nameLen; + char *nameBuffer; + char *nameString; + + // Get the variable's name. + nameLen = CFStringGetLength(key) + 1; + nameBuffer = malloc(nameLen); + if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) + nameString = nameBuffer; + else { + Error("Error (-1) Unable to convert property name to C string", 0); + nameString = ""; + } + FatalError(-1, "Error (-1) setting variable - '%s'", (long)nameString); + } +} diff --git a/passwd.tproj/Makefile b/passwd.tproj/Makefile index cfb6938..6cb47e2 100644 --- a/passwd.tproj/Makefile +++ b/passwd.tproj/Makefile @@ -14,7 +14,7 @@ PROJECT_TYPE = Tool HFILES = stringops.h -CFILES = nis_passwd.c file_passwd.c netinfo_passwd.c ds_passwd.c passwd.c\ +CFILES = nis_passwd.c file_passwd.c od_passwd.c passwd.c\ stringops.c OTHERSRCS = Makefile.preamble Makefile Makefile.postamble passwd.1 @@ -26,10 +26,12 @@ MAKEFILE = tool.make NEXTSTEP_INSTALLDIR = /usr/bin WINDOWS_INSTALLDIR = /usr/bin PDO_UNIX_INSTALLDIR = /usr/bin -LIBS = /System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService +LIBS = DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) +FRAMEWORK_PATHS = -F/System/Library/PrivateFrameworks +FRAMEWORKS = -framework OpenDirectory -framework CoreFoundation diff --git a/passwd.tproj/PB.project b/passwd.tproj/PB.project index 909cd74..649e9d8 100644 --- a/passwd.tproj/PB.project +++ b/passwd.tproj/PB.project @@ -5,7 +5,7 @@ C_FILES = (); H_FILES = (stringops.h); OTHER_LIBS = (); - OTHER_LINKED = (nis_passwd.c, file_passwd.c, netinfo_passwd.c, passwd.c, stringops.c); + OTHER_LINKED = (nis_passwd.c, file_passwd.c, passwd.c, stringops.c); OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, passwd.1); SUBPROJECTS = (); }; diff --git a/passwd.tproj/ds_passwd.c b/passwd.tproj/ds_passwd.c deleted file mode 100644 index 38f21c9..0000000 --- a/passwd.tproj/ds_passwd.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -// password server can store 511 characters + a terminator. -#define kMaxPassword 512 - -//------------------------------------------------------------------------------------- -// ds_getpasswd -//------------------------------------------------------------------------------------- - -void -ds_getpasswd(const char *loginUser, char *name, int isroot, int wasroot, int changePassOnSelf, char **old_clear, char **new_clear) -{ - int tries, len; - char *p; - static char obuf[kMaxPassword]; - static char nbuf[kMaxPassword]; - char prompt[MAXNAMLEN + 16]; - - printf("Changing password for %s.\n", name); - - p = ""; - - if (isroot == 0) - { - if ( changePassOnSelf ) - { - strcpy( prompt, "Old password:" ); - } - else - { - snprintf( prompt, sizeof(prompt), "password for %s:", loginUser ); - } - - p = getpass( prompt ); - snprintf( obuf, sizeof(obuf), "%s", p ); - } - - if ( wasroot == 0 ) - { - tries = 0; - nbuf[0] = '\0'; - for (;;) - { - p = getpass("New password:"); - if (!*p) - { - printf("Password unchanged.\n"); - exit(0); - } - - tries++; - len = strlen(p); - - snprintf( nbuf, sizeof(nbuf), "%s", p ); - if (!strcmp(nbuf, getpass("Retype new password:"))) break; - - printf("Mismatch; try again, EOF to quit.\n"); - } - } - - *old_clear = obuf; - *new_clear = nbuf; -} - - -//------------------------------------------------------------------------------------- -// ds_passwd -//------------------------------------------------------------------------------------- - -int -ds_passwd(char *uname, char *locn) -{ - tDirReference dsRef = 0; - tDataBuffer *tDataBuff = NULL; - tDirNodeReference nodeRef = 0; - long status = eDSNoErr; - tContextData context = NULL; - unsigned long nodeCount = 0; - unsigned long attrIndex = 0; - tDataList *nodeName = NULL; - tAttributeEntryPtr pAttrEntry = NULL; - tDataList *pRecName = NULL; - tDataList *pRecType = NULL; - tDataList *pAttrType = NULL; - unsigned long recCount = 0; - tRecordEntry *pRecEntry = NULL; - tAttributeListRef attrListRef = 0; - char *pUserLocation = NULL; - char *pUserName = NULL; - tAttributeValueListRef valueRef = 0; - tAttributeValueEntry *pValueEntry = NULL; - tDataList *pUserNode = NULL; - tDirNodeReference userNodeRef = 0; - tDataBuffer *pStepBuff = NULL; - tDataNode *pAuthType = NULL; - unsigned long uiCurr = 0; - unsigned long uiLen = 0; - char *old_clear = NULL; - char *new_clear = NULL; - int isroot = 0; - int wasroot = 0; - char *loginUser = NULL; - int changePassOnSelf = 1; - const char *errMsgStr = NULL; - struct passwd *userRec = NULL; - - if (uname == NULL) - return -1; - - /* getlogin() is the wrong thing to use here. Use getpwuid(getuid()); */ - /* sns 5 Jan 2005 */ - - userRec = getpwuid( getuid() ); - if ( userRec != NULL ) { - loginUser = userRec->pw_name; - if ( loginUser != NULL ) - changePassOnSelf = (strcmp(loginUser, uname) == 0); - } - - status = dsOpenDirService( &dsRef ); - if (status != eDSNoErr) - return status; - - do - { - if ( tDataBuff == NULL ) - tDataBuff = dsDataBufferAllocate( dsRef, 4096 ); - if (tDataBuff == NULL) break; - - if ( locn != NULL ) - { - nodeName = dsBuildFromPath( dsRef, locn, "/" ); - if ( nodeName == NULL ) break; - - // find - status = dsFindDirNodes( dsRef, tDataBuff, nodeName, eDSiExact, &nodeCount, &context ); - } - else - { - // find on search node - status = dsFindDirNodes( dsRef, tDataBuff, NULL, eDSSearchNodeName, &nodeCount, &context ); - } - - if (status != eDSNoErr) break; - if ( nodeCount < 1 ) { - status = eDSNodeNotFound; - break; - } - - if ( isroot == 1 ) - { - // we already tried SetPasswordAsRoot and it didn't work - // get the old (current) password and try again - - // getpass - isroot = 0; - wasroot = 1; - } - else - if ( getuid() == 0 ) - isroot = 1; - - ds_getpasswd( loginUser, uname, isroot, wasroot, changePassOnSelf, &old_clear, &new_clear ); - - status = dsGetDirNodeName( dsRef, tDataBuff, 1, &nodeName ); - if (status != eDSNoErr) continue; - - status = dsOpenDirNode( dsRef, nodeName, &nodeRef ); - dsDataListDeallocate( dsRef, nodeName ); - free( nodeName ); - nodeName = NULL; - if (status != eDSNoErr) continue; - - pRecName = dsBuildListFromStrings( dsRef, uname, NULL ); - pRecType = dsBuildListFromStrings( dsRef, kDSStdRecordTypeUsers, NULL ); - pAttrType = dsBuildListFromStrings( dsRef, kDSNAttrMetaNodeLocation, kDSNAttrRecordName, NULL ); - - recCount = 1; - status = dsGetRecordList( nodeRef, tDataBuff, pRecName, eDSExact, pRecType, - pAttrType, 0, &recCount, &context ); - if ( status != eDSNoErr ) break; - if ( recCount == 0 ) { - status = eDSAuthUnknownUser; - break; - } - - status = dsGetRecordEntry( nodeRef, tDataBuff, 1, &attrListRef, &pRecEntry ); - if ( status != eDSNoErr ) break; - - for ( attrIndex = 1; (attrIndex <= pRecEntry->fRecordAttributeCount) && (status == eDSNoErr); attrIndex++ ) - { - status = dsGetAttributeEntry( nodeRef, tDataBuff, attrListRef, attrIndex, &valueRef, &pAttrEntry ); - if ( status == eDSNoErr && pAttrEntry != NULL ) - { - if ( strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrMetaNodeLocation ) == 0 ) - { - status = dsGetAttributeValue( nodeRef, tDataBuff, 1, valueRef, &pValueEntry ); - if ( status == eDSNoErr && pValueEntry != NULL ) - { - pUserLocation = (char *) calloc( pValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char) ); - memcpy( pUserLocation, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength ); - } - } - else - if ( strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrRecordName ) == 0 ) - { - status = dsGetAttributeValue( nodeRef, tDataBuff, 1, valueRef, &pValueEntry ); - if ( status == eDSNoErr && pValueEntry != NULL ) - { - pUserName = (char *) calloc( pValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char) ); - memcpy( pUserName, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength ); - } - } - - if ( pValueEntry != NULL ) - dsDeallocAttributeValueEntry( dsRef, pValueEntry ); - pValueEntry = NULL; - - dsDeallocAttributeEntry( dsRef, pAttrEntry ); - pAttrEntry = NULL; - dsCloseAttributeValueList( valueRef ); - valueRef = 0; - } - } - - if ( pUserLocation == NULL || pUserName == NULL ) { - status = eDSAuthInvalidUserName; - break; - } - - pUserNode = dsBuildFromPath( dsRef, pUserLocation, "/" ); - status = dsOpenDirNode( dsRef, pUserNode, &userNodeRef ); - if ( status != eDSNoErr ) break; - - pStepBuff = dsDataBufferAllocate( dsRef, 128 ); - - if ( isroot ) - { - pAuthType = dsDataNodeAllocateString( dsRef, kDSStdAuthSetPasswdAsRoot ); - uiCurr = 0; - - // User name - uiLen = strlen( pUserName ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), pUserName, uiLen ); - uiCurr += uiLen; - - // new pw - uiLen = strlen( new_clear ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), new_clear, uiLen ); - uiCurr += uiLen; - - tDataBuff->fBufferLength = uiCurr; - - status = dsDoDirNodeAuth( userNodeRef, pAuthType, 1, tDataBuff, pStepBuff, NULL ); - } - else - if ( changePassOnSelf ) - { - pAuthType = dsDataNodeAllocateString( dsRef, kDSStdAuthChangePasswd ); - uiCurr = 0; - - // User name - uiLen = strlen( pUserName ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), pUserName, uiLen ); - uiCurr += uiLen; - - // old pw - uiLen = strlen( old_clear ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), old_clear, uiLen ); - uiCurr += uiLen; - - // new pw - uiLen = strlen( new_clear ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), new_clear, uiLen ); - uiCurr += uiLen; - - tDataBuff->fBufferLength = uiCurr; - - status = dsDoDirNodeAuth( userNodeRef, pAuthType, 1, tDataBuff, pStepBuff, NULL ); - } - else - if ( loginUser != NULL ) - { - pAuthType = dsDataNodeAllocateString( dsRef, kDSStdAuthSetPasswd ); - uiCurr = 0; - - // User name - uiLen = strlen( pUserName ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), pUserName, uiLen ); - uiCurr += uiLen; - - // new pw - uiLen = strlen( new_clear ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), new_clear, uiLen ); - uiCurr += uiLen; - - // Authenticator name - uiLen = strlen( loginUser ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), loginUser, uiLen ); - uiCurr += uiLen; - - // authenticator pw - uiLen = strlen( old_clear ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) ); - uiCurr += sizeof( unsigned long ); - memcpy( &(tDataBuff->fBufferData[ uiCurr ]), old_clear, uiLen ); - uiCurr += uiLen; - - tDataBuff->fBufferLength = uiCurr; - - status = dsDoDirNodeAuth( userNodeRef, pAuthType, 1, tDataBuff, pStepBuff, NULL ); - } - else - { - status = eDSAuthFailed; - } - } - while ( isroot == 1 && status != eDSNoErr ); - - /* old_clear and new_clear are statics (don't call free) */ - if (old_clear != NULL) { - memset(old_clear, 0, strlen(old_clear)); - } - if (new_clear != NULL) { - memset(new_clear, 0, strlen(new_clear)); - } - if (tDataBuff != NULL) { - memset(tDataBuff, 0, tDataBuff->fBufferSize); - dsDataBufferDeAllocate( dsRef, tDataBuff ); - tDataBuff = NULL; - } - - if (pStepBuff != NULL) { - dsDataBufferDeAllocate( dsRef, pStepBuff ); - pStepBuff = NULL; - } - if (pUserLocation != NULL ) { - free(pUserLocation); - pUserLocation = NULL; - } - if (pRecName != NULL) { - dsDataListDeallocate( dsRef, pRecName ); - free( pRecName ); - pRecName = NULL; - } - if (pRecType != NULL) { - dsDataListDeallocate( dsRef, pRecType ); - free( pRecType ); - pRecType = NULL; - } - if (pAttrType != NULL) { - dsDataListDeallocate( dsRef, pAttrType ); - free( pAttrType ); - pAttrType = NULL; - } - if (nodeRef != 0) { - dsCloseDirNode(nodeRef); - nodeRef = 0; - } - if (dsRef != 0) { - dsCloseDirService(dsRef); - dsRef = 0; - } - - if ( status != eDSNoErr ) { - errno = EACCES; - switch( status ) - { - case eDSAuthPasswordTooShort: - errMsgStr = "The new password is too short."; - break; - - case eDSAuthPasswordTooLong: - errMsgStr = "The new password is too long."; - break; - - case eDSAuthPasswordNeedsLetter: - errMsgStr = "The new password must contain a letter."; - break; - - case eDSAuthPasswordNeedsDigit: - errMsgStr = "The new password must contain a number."; - break; - - default: - errMsgStr = "Sorry"; - } - fprintf(stderr, "%s\n", errMsgStr); - exit(1); - } - - return status; -} - - - - - - - - - - - diff --git a/passwd.tproj/netinfo_passwd.c b/passwd.tproj/netinfo_passwd.c deleted file mode 100644 index 29f56d7..0000000 --- a/passwd.tproj/netinfo_passwd.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void getpasswd(char *, int, int, int, int, char *, char **, char**, char **); - -static int -sys_ismyaddress(unsigned long addr) -{ - struct ifconf ifc; - struct ifreq *ifr; - char buf[1024]; /* XXX */ - int offset; - int sock; - struct sockaddr_in *sin; - //int i, len; (unused) - - if (addr == htonl(INADDR_LOOPBACK)) return 1; - - sock = socket(AF_INET, SOCK_DGRAM, 0); - - if (sock < 0) return 0; - - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - - if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) - { - close(sock); - return 0; - } - - offset = 0; - - while (offset <= ifc.ifc_len) - { - ifr = (struct ifreq *)(ifc.ifc_buf + offset); - offset += IFNAMSIZ + ifr->ifr_addr.sa_len; - - if (ifr->ifr_addr.sa_family != AF_INET) continue; - if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue; - - sin = (struct sockaddr_in *)&ifr->ifr_addr; - if ((ifr->ifr_flags & IFF_UP) && - (!(ifr->ifr_flags & IFF_LOOPBACK)) && - (sin->sin_addr.s_addr == addr)) - { - close(sock); - return 1; - } - } - - close(sock); - return 0; -} - -static int -is_root_on_master(void *d) -{ - int uid; - char myhostname[MAXHOSTNAMELEN + 1]; - char *p; - ni_index where; - ni_proplist pl; - int status; - ni_id dir; - struct sockaddr_in addr; - char *tag; - - uid = getuid(); - if (uid != 0) return 0; - - gethostname(myhostname, MAXHOSTNAMELEN); - p = strchr(myhostname, '.'); - if (p != NULL) *p = '\0'; - - status = ni_root(d, &dir); - if (status != NI_OK) return 0; - - status = ni_read(d, &dir, &pl); - if (status != NI_OK) return 0; - - where = ni_proplist_match(pl, "master", NULL); - if (where == NI_INDEX_NULL) - { - ni_proplist_free(&pl); - return 0; - } - - if (pl.ni_proplist_val[where].nip_val.ni_namelist_len == 0) - { - ni_proplist_free(&pl); - fprintf(stderr, "No value for NetInfo master property\n"); - return 0; - } - - p = strchr(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], '/'); - if (p != NULL) *p = '\0'; - - p = strchr(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], '.'); - if (p != NULL) *p = '\0'; - - if (!strcmp(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], myhostname)) - { - ni_proplist_free(&pl); - return 1; - } - - if (!strcmp(pl.ni_proplist_val[where].nip_val.ni_namelist_val[0], "localhost")) - { - ni_proplist_free(&pl); - ni_addrtag(d, &addr, &tag); - if (sys_ismyaddress(addr.sin_addr.s_addr)) return 1; - } - - ni_proplist_free(&pl); - return 0; -} - -static int -secure_passwords() -{ - void *d, *d1; - int status; - ni_index where; - ni_id dir; - ni_namelist nl; - - status = ni_open(NULL, ".", &d); - while (status == NI_OK) - { - dir.nii_object = 0; - status = ni_lookupprop(d, &dir, "security_options", &nl); - if (status == NI_OK) - { - where = ni_namelist_match(nl, "secure_passwords"); - if (where != NI_INDEX_NULL) - { - ni_free(d); - return 1; - } - } - - d1 = d; - status = ni_open(d1, "..", &d); - ni_free(d1); - } - - return 0; -} - -static void -parse_server_tag(char *str, struct sockaddr_in *server, char **t) -{ - /* utility to parse a server/tag string */ - - int len, i; - char *host, *tag, *slash; - struct hostent *hent; - - len = strlen(str); - - /* find the "/" character */ - slash = index(str, '/'); - - /* check to see if the "/" is missing */ - if (slash == NULL) - { - fprintf(stderr, "incorrect format \"%s\" for domain name\n", str); - exit(1); - } - - /* find the location of the '/' */ - i = slash - str; - - /* check if host string is empty */ - if (i == 0) - { - fprintf(stderr, "incorrect format \"%s\" for domain name\n", str); - fprintf(stderr, "no server name specified\n"); - exit(1); - } - - /* check if tag string is empty */ - if (i == (len - 1)) - { - fprintf(stderr, "incorrect format \"%s\" for domain name\n", str); - fprintf(stderr, "no tag specified\n"); - exit(1); - } - - /* allocate some space for the host and tag */ - host = (char *)malloc(i + 1); - *t = (char *)malloc(len - i); - tag = *t; - - /* copy out the host */ - strncpy(host, str, i); - host[i] = '\0'; - - /* copy out the tag */ - strcpy(tag, slash + 1); - - /* try interpreting the host portion as an address */ - server->sin_addr.s_addr = inet_addr(host); - - if (server->sin_addr.s_addr == -1) - { - /* This isn't a valid address. Is it a known hostname? */ - hent = gethostbyname(host); - if (hent != NULL) - { - /* found a host with that name */ - bcopy(hent->h_addr, &server->sin_addr, hent->h_length); - } - else - { - fprintf(stderr, "Can't find address for %s\n", host); - free(host); - free(tag); - exit(1); - } - } - - free(host); -} - -static void * -domain_for_user(char *uname, char *locn, ni_id *dir) -{ - char *upath; - int status; - void *d, *d1; - struct sockaddr_in server; - char *tag; - int bytag; - - /* - * Find the user in NetInfo. - */ - upath = malloc(8 + strlen(uname)); - sprintf(upath, "/users/%s", uname); - - if (locn != NULL) - { - bytag = 1; - - if (locn[0] == '/') bytag = 0; - else if (!strncmp(locn, "./", 2)) bytag = 0; - else if (!strncmp(locn, "../", 3)) bytag = 0; - - if (bytag == 1) - { - parse_server_tag(locn, &server, &tag); - d = ni_connect(&server, tag); - if (d == (void *)NULL) return (void *)NULL; - } - else status = ni_open(NULL, locn, &d); - status = ni_pathsearch(d, dir, upath); - free(upath); - - if (status == NI_OK) return d; - - ni_free(d); - return (void *)NULL; - } - - status = ni_open(NULL, ".", &d); - while (status == NI_OK) - { - status = ni_pathsearch(d, dir, upath); - if (status == NI_OK) break; - d1 = d; - status = ni_open(d1, "..", &d); - ni_free(d1); - } - - free(upath); - - if (status == NI_OK) return d; - return (void *)NULL; -} - -int -netinfo_passwd(char *uname, char *locn) -{ - char *oldpw; - char *newpw; - char *oc, *nc; - void *d; - int status, isroot; - ni_id dir; - ni_proplist pl; - ni_property p; - ni_namelist nl; - int ni_uid, uid, secure, minlen; - ni_index where; - - d = domain_for_user(uname, locn, &dir); - if (d == (void *)NULL) - { - fprintf(stderr, "user %s not found in NetInfo\n", uname); - exit(1); - } - - /* - * Read the passwd and uid from NetInfo. - */ - status = ni_lookupprop(d, &dir, "passwd", &nl); - if (status == NI_NOPROP) nl.ni_namelist_len = 0; - else if (status != NI_OK) - { - ni_free(d); - fprintf(stderr, "NetInfo read failed: %s\n", ni_error(status)); - exit(1); - } - - oldpw = NULL; - if (nl.ni_namelist_len > 0) oldpw = nl.ni_namelist_val[0]; - - status = ni_lookupprop(d, &dir, "uid", &nl); - if (status != NI_OK) - { - ni_free(d); - fprintf(stderr, "NetInfo read failed: %s\n", ni_error(status)); - exit(1); - } - - ni_uid = -2; - if (nl.ni_namelist_len > 0) ni_uid = atoi(nl.ni_namelist_val[0]); - - /* - * See if I'm uid 0 on the master host for the user's NetInfo domain. - */ - isroot = is_root_on_master(d); - uid = getuid(); - if ((isroot == 0) && (uid != ni_uid)) - { - ni_free(d); - fprintf(stderr, "Permission denied\n"); - exit(1); - } - - /* - * Lock onto the master server. - */ - ni_needwrite(d, 1); - - /* - * Get the new password - */ - secure = secure_passwords(); - minlen = 5; - if (secure == 1) minlen = 8; - getpasswd(uname, isroot, minlen, 0, secure, oldpw, &newpw, &oc, &nc); - - /* - * Authenticate if necessary - */ - if (isroot == 0) - { - ni_setuser(d, uname); - ni_setpassword(d, oc); - } - - /* - * Change the password in NetInfo. - */ - status = ni_read(d, &dir, &pl); - if (status != NI_OK) - { - ni_free(d); - fprintf(stderr, "NetInfo read failed: %s\n", ni_error(status)); - exit(1); - } - - p.nip_name = "passwd"; - p.nip_val.ni_namelist_len = 1; - p.nip_val.ni_namelist_val = (ni_name *)malloc(sizeof(ni_name)); - p.nip_val.ni_namelist_val[0] = newpw; - - where = ni_proplist_match(pl, p.nip_name, NULL); - if (where == NI_INDEX_NULL) - status = ni_createprop(d, &dir, p, NI_INDEX_NULL); - else - status = ni_writeprop(d, &dir, where, p.nip_val); - - free(p.nip_val.ni_namelist_val); - - if (status != NI_OK) - { - ni_free(d); - fprintf(stderr, "NetInfo write failed: %s\n", ni_error(status)); - exit(1); - } - - ni_free(d); - return (0); -} diff --git a/passwd.tproj/nis_passwd.c b/passwd.tproj/nis_passwd.c index 9043e92..8870e6e 100644 --- a/passwd.tproj/nis_passwd.c +++ b/passwd.tproj/nis_passwd.c @@ -163,7 +163,7 @@ int nis_passwd(char *uname, char *domain) tv.tv_sec = 2; tv.tv_usec = 0; ans = clnt_call(cl, YPPASSWDPROC_UPDATE, - xdr_yppasswd, &yppasswd, xdr_int, &ok, tv); + (xdrproc_t)xdr_yppasswd, &yppasswd, (xdrproc_t)xdr_int, &ok, tv); if (ans != 0) { diff --git a/passwd.tproj/od_passwd.c b/passwd.tproj/od_passwd.c new file mode 100644 index 0000000..fb4494c --- /dev/null +++ b/passwd.tproj/od_passwd.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +extern char* progname; +int master_mode; + +static int +cfprintf(FILE* file, const char* format, ...) { + char* cstr; + int result = 0; + va_list args; + va_start(args, format); + CFStringRef formatStr = CFStringCreateWithCStringNoCopy(NULL, format, kCFStringEncodingUTF8, kCFAllocatorNull); + if (formatStr) { + CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, formatStr, args); + if (str) { + size_t size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1; + va_end(args); + cstr = malloc(size); + if (cstr && CFStringGetCString(str, cstr, size, kCFStringEncodingUTF8)) { + result = fprintf(file, "%s", cstr); + free(cstr); + } + CFRelease(str); + } + CFRelease(formatStr); + } + return result; +} + +static void +show_error(CFErrorRef error) { + if (error) { + CFStringRef desc = CFErrorCopyDescription(error); + if (desc) { + cfprintf(stderr, "%s: %@", progname, desc); + CFRelease(desc); + } + desc = CFErrorCopyFailureReason(error); + if (desc) cfprintf(stderr, " %@", desc); + + desc = CFErrorCopyRecoverySuggestion(error); + if (desc) cfprintf(stderr, " %@", desc); + + fprintf(stderr, "\n"); + } +} + +static int +is_singleuser(void) { + uint32_t su = 0; + size_t susz = sizeof(su); + if (sysctlbyname("kern.singleuser", &su, &susz, NULL, 0) != 0) { + return 0; + } else { + return (int)su; + } +} + +static int +load_DirectoryServicesLocal() { + const char* launchctl = "/bin/launchctl"; + const char* plist = "/System/Library/LaunchDaemons/com.apple.DirectoryServicesLocal.plist"; + + pid_t pid = fork(); + int status, res; + switch (pid) { + case -1: // ERROR + perror("launchctl"); + return 0; + case 0: // CHILD + execl(launchctl, launchctl, "load", plist, NULL); + /* NOT REACHED */ + perror("launchctl"); + exit(1); + break; + default: // PARENT + do { + res = waitpid(pid, &status, 0); + } while (res == -1 && errno == EINTR); + if (res == -1) { + perror("launchctl"); + return 0; + } + break; + } + return (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS)); +} + +int +od_passwd(char* uname, char* locn, char* aname) +{ + int change_pass_on_self; + CFErrorRef error = NULL; + CFStringRef username = NULL; + CFStringRef location = NULL; + CFStringRef authname = NULL; + ODSessionRef session = NULL; + ODNodeRef node = NULL; + ODRecordRef rec = NULL; + CFStringRef oldpass = NULL; + CFStringRef newpass = NULL; + + if (uname == NULL) + return -1; + + /* + * If no explicit authorization name was specified (via -u) + * then default to the target user. + */ + if (!aname) { + aname = strdup(uname); + } + + master_mode = (getuid() == 0); + change_pass_on_self = (strcmp(aname, uname) == 0); + + if (locn) { + location = CFStringCreateWithCString(NULL, locn, kCFStringEncodingUTF8); + } + + if (aname) { + authname = CFStringCreateWithCString(NULL, aname, kCFStringEncodingUTF8); + } + + if (uname) { + username = CFStringCreateWithCString(NULL, uname, kCFStringEncodingUTF8); + if (!username) return -1; + } + + /* + * Connect to DS server + */ + session = ODSessionCreate(NULL, NULL, &error); + if ( !session && error && CFErrorGetCode(error) == eServerNotRunning ) { + /* + * In single-user mode, attempt to load the local DS daemon. + */ + if (is_singleuser() && load_DirectoryServicesLocal()) { + CFTypeRef keys[] = { kODSessionLocalPath }; + CFTypeRef vals[] = { CFSTR("/var/db/dslocal") }; + CFDictionaryRef opts = CFDictionaryCreate(NULL, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (opts) { + session = ODSessionCreate(NULL, opts, &error); + CFRelease(opts); + } + + if (!location) { + location = CFRetain(CFSTR("/Local/Default")); + } + } else { + show_error(error); + return -1; + } + } + + + /* + * Copy the record from the specified node, or perform a search. + */ + if (location) { + node = ODNodeCreateWithName(NULL, session, location, &error); + } else { + node = ODNodeCreateWithNodeType(NULL, session, kODTypeAuthenticationSearchNode, &error); + } + + if (session) CFRelease(session); + + if (node) { + rec = ODNodeCopyRecord(node, CFSTR(kDSStdRecordTypeUsers), username, NULL, &error ); + CFRelease(node); + } + + if (!rec) { + if (error) { + show_error(error); + } else { + fprintf(stderr, "%s: Unknown user name '%s'.\n", progname, uname); + } + return -1; + } + + /* + * Get the actual location. + */ + CFArrayRef values = NULL; + values = ODRecordCopyValues(rec, CFSTR(kDSNAttrMetaNodeLocation), &error); + location = (values && CFArrayGetCount(values) > 0) ? CFArrayGetValueAtIndex(values, 0) : location; + + printf("Changing password for %s.\n", uname); + + /* + * Prompt for password if not super-user, or if changing a remote node. + */ + int needs_auth = (!master_mode || CFStringCompareWithOptions(location, CFSTR("/Local/"), CFRangeMake(0, 7), 0) != kCFCompareEqualTo); + + if (needs_auth) { + char prompt[BUFSIZ]; + if (change_pass_on_self) { + strlcpy(prompt, "Old password:", sizeof(prompt)); + } else { + snprintf(prompt, sizeof(prompt), "Password for %s:", aname); + } + char *p = getpass( prompt ); + if (p) { + oldpass = CFStringCreateWithCString(NULL, p, kCFStringEncodingUTF8); + memset(p, 0, strlen(p)); + } + } + + for (;;) { + char *p = getpass("New password:"); + if (p && strlen(p) > 0) { + newpass = CFStringCreateWithCString(NULL, p, kCFStringEncodingUTF8); + memset(p, 0, strlen(p)); + } else { + printf("Password unchanged.\n"); + exit(0); + } + + p = getpass("Retype new password:"); + if (p) { + CFStringRef verify = CFStringCreateWithCString(NULL, p, kCFStringEncodingUTF8); + if (!verify || !CFEqual(newpass, verify)) { + if (verify) CFRelease(verify); + printf("Mismatch; try again, EOF to quit.\n"); + } else { + CFRelease(verify); + break; + } + } + } + + if (needs_auth) { + CFTypeRef values[] = { username, newpass, authname, oldpass }; + CFArrayRef authItems = CFArrayCreate(NULL, values, 4, &kCFTypeArrayCallBacks); + + ODRecordSetNodeCredentialsExtended(rec, + CFSTR(kDSStdRecordTypeUsers), + CFSTR(kDSStdAuthSetPasswd), + authItems, + NULL, + NULL, + &error); + + CFRelease(authItems); + } else { + ODRecordChangePassword(rec, oldpass, newpass, &error); + } + + if (error) { + show_error(error); + exit(1); + } + + if (oldpass) CFRelease(oldpass); + if (newpass) CFRelease(newpass); + +#if 0 + if ( status != eDSNoErr ) { + switch( status ) + { + case eDSAuthPasswordTooShort: + errMsgStr = "The new password is too short."; + break; + + case eDSAuthPasswordTooLong: + errMsgStr = "The new password is too long."; + break; + + case eDSAuthPasswordNeedsLetter: + errMsgStr = "The new password must contain a letter."; + break; + + case eDSAuthPasswordNeedsDigit: + errMsgStr = "The new password must contain a number."; + break; + + default: + errMsgStr = "Sorry"; + } + fprintf(stderr, "%s\n", errMsgStr); + exit(1); +#endif + return 0; +} diff --git a/passwd.tproj/passwd.1 b/passwd.tproj/passwd.1 index 367dde6..90fa398 100644 --- a/passwd.tproj/passwd.1 +++ b/passwd.tproj/passwd.1 @@ -41,21 +41,24 @@ .Nm passwd .Op Fl i Ar infosystem .Op Fl l Ar location +.Op Fl u Ar authname .Op Ar name .Sh DESCRIPTION .Nm Passwd -changes the user's password. First, the user is prompted for their -current password. -If the current password is correctly typed, a new password is -requested. -The new password must be entered twice to avoid typing errors. +changes the user's password. +First, the user is prompted for their current password. +If the current password is correctly typed, +a new password is requested. +The new password must be entered twice, +to detect (and avoid accepting) typing errors. .Pp -The new password should be at least six characters long and not -purely alphabetic. +The new password should be at least six characters long +and not purely alphabetic. Its total length should be less than .Dv _PASSWORD_LEN -(currently 128 characters) although some infosystems allow longer passwords. -Numbers, upper case letters and meta characters +(currently 128 characters), +although some infosystems allow longer passwords. +Numbers, upper-case letters, and meta characters are encouraged. .Pp Once the password has been verified, @@ -65,28 +68,22 @@ the authenticating host. .Bl -tag -width flag .It Fl i Ar infosystem This option specifies where the password update should be applied. -Under Mac OS X 10.3, supported infosystems are: +Under Mac OS X 10.5, supported infosystems are: .Bl -tag -width flag .It Ar opendirectory (default) -A system conforming to opendirectory APIs and supporting updates (including LDAP, netinfo, etc). +A system conforming to opendirectory APIs and supporting updates +(including LDAP, etc). If no -l option is specified, the search node is used. -.It Ar netinfo -The netinfo database containing the user's password. -If no -l option is specified, the local netinfo database is assumed. .It Ar file The local flat-files (included for legacy configurations). .It Ar nis A remote NIS server containing the user's password. .El .It Fl l Ar location -This option causes the password to be updated in the given location of the choosen infosystem. -When changing only the local password, -.Xr pwd_mkdb 8 -is used to update the password databases. +This option causes the password to be updated in the given location +of the chosen infosystem. .Bl -tag -width flag -.It for netinfo, -location may be a domain name or server/tag .It for file, location may be a file name (/etc/master.passwd is the default) .It for nis, @@ -94,9 +91,13 @@ location may be a NIS domainname .It for opendirectory, location may be a directory node name .El +.It Fl u Ar authname +This option specifies the username to use when authenticating to +the directory node. .El .Pp -The super-user privilages are not required change a user's current password +The super-user privileges are not required +to change a user's current password, if only the local password is modified. .Sh FILES .Bl -tag -width /etc/master.passwd -compact @@ -110,10 +111,10 @@ Temporary copy of the password file .Sh SEE ALSO .Xr chpass 1 , .Xr login 1 , +.Xr dscl 1 , .Xr passwd 5 , .Xr pwd_mkdb 8 , -.Xr vipw 8 , -.Xr nicl 1 +.Xr vipw 8 .Rs .%A Robert Morris .%A Ken Thompson diff --git a/passwd.tproj/passwd.c b/passwd.tproj/passwd.c index c0c8c33..0eb30fa 100644 --- a/passwd.tproj/passwd.c +++ b/passwd.tproj/passwd.c @@ -1,30 +1,32 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ -#define INFO_NETINFO 0 +#include + #define INFO_FILE 1 #define INFO_NIS 2 -#define INFO_DIRECTORYSERVICES 3 +#if !TARGET_OS_EMBEDDED +#define INFO_OPEN_DIRECTORY 3 +#endif #ifndef __SLICK__ #define _PASSWD_FILE "/etc/master.passwd" @@ -38,19 +40,21 @@ #include #include #include -#include #include "stringops.h" #ifdef __SLICK__ #define _PASSWORD_LEN 8 #endif +char* progname = "passwd"; + static char *saltchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; extern int file_passwd(char *, char *); -extern int netinfo_passwd(char *, char *); extern int nis_passwd(char *, char *); -extern int ds_passwd(char *, char *); +#ifdef INFO_OPEN_DIRECTORY +extern int od_passwd(char *, char *, char*); +#endif void getpasswd(char *name, int isroot, int minlen, int mixcase, int nonalpha, @@ -159,70 +163,71 @@ getpasswd(char *name, int isroot, int minlen, int mixcase, int nonalpha, void usage() { - fprintf(stderr, "usage: passwd [-i infosystem] [-l location] [name]\n"); - fprintf(stderr, "supported infosystems are:\n"); - fprintf(stderr, " netinfo\n"); + fprintf(stderr, "usage: %s [-i infosystem] [-l location] [-u authname] [name]\n", progname); + fprintf(stderr, " infosystem:\n"); fprintf(stderr, " file\n"); - fprintf(stderr, " nis\n"); - fprintf(stderr, " opendirectory\n"); - fprintf(stderr, "for netinfo, location may be a domain name or server/tag\n"); - fprintf(stderr, "for file, location may be a file name (%s is the default)\n", - _PASSWD_FILE); - fprintf(stderr, "for nis, location may be a NIS domainname\n"); - fprintf(stderr, "for opendirectory, location may be a directory node name\n"); + fprintf(stderr, " NIS\n"); + fprintf(stderr, " OpenDirectory\n"); + fprintf(stderr, " location (for infosystem):\n"); + fprintf(stderr, " file location is path to file (default is %s)\n", _PASSWD_FILE); + fprintf(stderr, " NIS location is NIS domain name\n"); + fprintf(stderr, " OpenDirectory location is directory node name\n"); exit(1); } int main(int argc, char *argv[]) { - char *user, *locn; - int i, infosystem; + char* user = NULL; + char* locn = NULL; + char* auth = NULL; + int infosystem, ch; int free_user = 0; - /* since DS works for most infosystems, make it the default */ - //infosystem = INFO_NETINFO; - infosystem = INFO_DIRECTORYSERVICES; - user = NULL; - locn = NULL; +#ifdef INFO_OPEN_DIRECTORY + /* since OpenDirectory works for most infosystems, make it the default */ + infosystem = INFO_OPEN_DIRECTORY; +#else + infosystem = INFO_FILE; +#endif - for (i = 1; i < argc; i++) - { - if (!strcmp(argv[i], "-i")) - { - if (++i >= argc) - { - fprintf(stderr, "no argument for -i option\n"); - usage(); - } - - if (!strcmp(argv[i], "NetInfo")) infosystem = INFO_NETINFO; - else if (!strcmp(argv[i], "netinfo")) infosystem = INFO_NETINFO; - else if (!strcmp(argv[i], "File")) infosystem = INFO_FILE; - else if (!strcmp(argv[i], "file")) infosystem = INFO_FILE; - else if (!strcmp(argv[i], "NIS")) infosystem = INFO_NIS; - else if (!strcmp(argv[i], "nis")) infosystem = INFO_NIS; - else if (!strcmp(argv[i], "YP")) infosystem = INFO_NIS; - else if (!strcmp(argv[i], "yp")) infosystem = INFO_NIS; - else if (!strcasecmp(argv[i], "opendirectory")) infosystem = INFO_DIRECTORYSERVICES; - else - { - fprintf(stderr, "unknown info system \"%s\"\n", argv[i]); + while ((ch = getopt(argc, argv, "i:l:u:")) != -1) + switch(ch) { + case 'i': + if (!strcasecmp(optarg, "file")) { + infosystem = INFO_FILE; + } else if (!strcasecmp(optarg, "NIS")) { + infosystem = INFO_NIS; + } else if (!strcasecmp(optarg, "YP")) { + infosystem = INFO_NIS; +#ifdef INFO_OPEN_DIRECTORY + } else if (!strcasecmp(optarg, "opendirectory")) { + infosystem = INFO_OPEN_DIRECTORY; +#endif + } else { + fprintf(stderr, "%s: Unknown info system \'%s\'.\n", + progname, optarg); usage(); } - } + break; + case 'l': + locn = optarg; + break; + case 'u': + auth = optarg; + break; + case '?': + default: + usage(); + break; + } + argc -= optind; + argv += optind; - else if (!strcmp(argv[i], "-l")) - { - if (++i >= argc) - { - fprintf(stderr, "no argument for -l option\n"); - usage(); - } - locn = argv[i]; - } - else if (user == NULL) user = argv[i]; - else usage(); + if (argc > 1) { + usage(); + } else if (argc == 1) { + user = argv[0]; } if (user == NULL) @@ -251,18 +256,17 @@ main(int argc, char *argv[]) switch (infosystem) { - case INFO_NETINFO: - netinfo_passwd(user, locn); - break; case INFO_FILE: file_passwd(user, locn); break; case INFO_NIS: nis_passwd(user, locn); break; - case INFO_DIRECTORYSERVICES: - ds_passwd(user, locn); +#ifdef INFO_OPEN_DIRECTORY + case INFO_OPEN_DIRECTORY: + od_passwd(user, locn, auth); break; +#endif } if (free_user == 1) diff --git a/pt_chown.tproj/Makefile.postamble b/pt_chown.tproj/Makefile.postamble deleted file mode 100644 index 401ddbc..0000000 --- a/pt_chown.tproj/Makefile.postamble +++ /dev/null @@ -1,2 +0,0 @@ -after_install: - chmod 4511 $(DSTROOT)/usr/libexec/pt_chown diff --git a/pt_chown.tproj/Makefile.preamble b/pt_chown.tproj/Makefile.preamble deleted file mode 100644 index ecc3ec7..0000000 --- a/pt_chown.tproj/Makefile.preamble +++ /dev/null @@ -1 +0,0 @@ -OTHER_CFLAGS = -D__FBSDID=__RCSID diff --git a/pt_chown.tproj/PB.project b/pt_chown.tproj/PB.project deleted file mode 100644 index ec106d6..0000000 --- a/pt_chown.tproj/PB.project +++ /dev/null @@ -1,37 +0,0 @@ -{ - FILESTABLE = { - FRAMEWORKS = (); - OTHER_LINKED = (pt_chown.c); - OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.dist); - PRECOMPILED_HEADERS = (); - PROJECT_HEADERS = (); - PUBLIC_HEADERS = (); - SUBPROJECTS = (); - }; - LANGUAGE = English; - LOCALIZABLE_FILES = {}; - NEXTSTEP_BUILDDIR = ""; - NEXTSTEP_BUILDTOOL = /bin/make; - NEXTSTEP_COMPILEROPTIONS = ""; - NEXTSTEP_INSTALLDIR = /usr/libexec; - NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; - NEXTSTEP_LINKEROPTIONS = ""; - NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; - PDO_UNIX_BUILDDIR = ""; - PDO_UNIX_BUILDTOOL = /bin/make; - PDO_UNIX_COMPILEROPTIONS = ""; - PDO_UNIX_INSTALLDIR = /usr/libexec; - PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; - PDO_UNIX_LINKEROPTIONS = ""; - PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; - PROJECTNAME = pt_chown; - PROJECTTYPE = Tool; - PROJECTVERSION = 1.1; - WINDOWS_BUILDDIR = ""; - WINDOWS_BUILDTOOL = /bin/make; - WINDOWS_COMPILEROPTIONS = ""; - WINDOWS_INSTALLDIR = /usr/libexec; - WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; - WINDOWS_LINKEROPTIONS = ""; - WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; -} diff --git a/pt_chown.tproj/pt_chown.c b/pt_chown.tproj/pt_chown.c deleted file mode 100644 index 4ac16f3..0000000 --- a/pt_chown.tproj/pt_chown.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2002 The FreeBSD Project, Inc. - * All rights reserved. - * - * This software includes code contributed to the FreeBSD Project - * by Ryan Younce of North Carolina State University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the FreeBSD Project nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/libexec/pt_chown/pt_chown.c,v 1.1 2003/01/02 20:44:41 jmallett Exp $"); -#endif /* not lint */ - -#include - -#include -#include -#include -#include - -/* - * pt_chown - * Utility support routine for grantpt(3). - * - * According to IEEE Std 1003.1-2001, grantpt(3) changes ownership and - * permission bits of a slave pseudo-terminal device associated with a - * master. - * - * Since doing this if we are not the owner of the slave (which would - * rarely happen) cannot be done by conventional methods, grantpt(3) - * has to rely on this support program, which is setuid root, to change - * the slave's owner, group, and permission mode attributes. It's - * a rather undesirable approach, but Digital Unix and Solaris also seem - * to rely on this approach to pull this off. - * - * This program hangs around long enough to do just these things upon - * its standard input (which is set up by grantpt(3) to be the master's - * descriptor, the one passed to it). The rationale behind this - * approach not allowing somebody to modify ownership of another active - * pseudo terminal is: - * - * 1) This program only operates on its standard input. If STDIN_FILENO - * is not open or is not a pseudo-terminal master, no action is - * taken and the program exits (ptsname() is called for a non-NULL - * return). - * 2) Only one active file description for a pseudo-terminal master - * can exist at a time (attempting to open an active PTY returns with - * EIO - I/O Error). Thus, if the pseudo-terminal is already in - * use by somebody else, it could not have been opened to begin - * with, and thus this program would be useless in such situations. - */ -int -main(int argc, char *argv[]) -{ - int retcode; - char *slave; - gid_t gid; - struct group *grp; - - retcode = EX_OK; - - if ((slave = ptsname(STDIN_FILENO)) == NULL) - retcode = EX_USAGE; - else { - gid = (grp = getgrnam("tty")) ? grp->gr_gid : -1; - if (chown(slave, getuid(), gid) == 0 && - chmod(slave, S_IRUSR | S_IWUSR | S_IWGRP) == 0) - retcode = 0; - else - retcode = EX_NOPERM; - } - - /* - * grantpt(3) checks the retcode for being either zero or - * nonzero. Any nonzero return results in errno being set - * to EACCES. - */ - exit(retcode); -} diff --git a/pwd_mkdb.tproj/pwd_mkdb.8 b/pwd_mkdb.tproj/pwd_mkdb.8 index ec4bd88..1d26952 100644 --- a/pwd_mkdb.tproj/pwd_mkdb.8 +++ b/pwd_mkdb.tproj/pwd_mkdb.8 @@ -43,7 +43,7 @@ .Op Fl u Ar username .Ar file .Sh DESCRIPTION -.Nm +.Nm pwd_mkdb creates .Xr db 3 style secure and insecure databases for the specified file. @@ -61,22 +61,11 @@ different from the historic Version 7 style format. .Pp The options are as follows: .Bl -tag -width Ds +.\" ========== .It Fl c Check if the password file is in the correct format. Do not change, add, or remove any files. -.It Fl p -Create a Version 7 style password file and install it into -.Pa /etc/passwd . -.It Fl s -Only update the secure version of the database. -This is most commonly used in conjunction with the -.Fl u -flag during a password change. -Because the insecure database doesn't contain the password there -is no reason to update it if the only change is in the password field. -Cannot be used in conjunction with the -.Fl p -flag. +.\" ========== .It Fl d Ar directory Operate in a base directory other than the default of .Pa /etc . @@ -93,6 +82,22 @@ other than for instance in a .Xr chroot 8 jail. +.\" ========== +.It Fl p +Create a Version 7 style password file and install it into +.Pa /etc/passwd . +.\" ========== +.It Fl s +Only update the secure version of the database. +This is most commonly used in conjunction with the +.Fl u +flag during a password change. +Because the insecure database doesn't contain the password there +is no reason to update it if the only change is in the password field. +Cannot be used in conjunction with the +.Fl p +flag. +.\" ========== .It Fl u Ar username Only update the record for the specified user. Utilities that operate on a single user can use this option to avoid the @@ -100,6 +105,7 @@ overhead of rebuilding the entire database. This option must never be used if the line number of the user's record in .Pa /etc/master.passwd has changed. +.\" ========== .It Ar file The absolute path to a file in .Ar master.passwd @@ -114,7 +120,7 @@ encrypted password and the insecure version has an asterisk The databases are used by the C library password routines (see .Xr getpwent 3 ) . .Pp -.Nm +.Nm pwd_mkdb exits zero on success, non-zero on failure. .Sh FILES .Bl -tag -width /etc/master.passwd -compact @@ -150,7 +156,7 @@ The program was renamed in order that previous users of the program not be surprised by the changes in functionality. .Sh BUGS Because of the necessity for atomic update of the password files, -.Nm +.Nm pwd_mkdb uses .Xr rename 2 to install them. @@ -160,7 +166,7 @@ on the same file system as the directory. .Pp There are the obvious races with multiple people running -.Nm +.Nm pwd_mkdb on different password files at the same time. The front-ends to .Nm pwd_mkdb , diff --git a/pwd_mkdb.tproj/pwd_mkdb.c b/pwd_mkdb.tproj/pwd_mkdb.c index 6833e36..de64cd6 100644 --- a/pwd_mkdb.tproj/pwd_mkdb.c +++ b/pwd_mkdb.tproj/pwd_mkdb.c @@ -31,8 +31,9 @@ * SUCH DAMAGE. */ +#include #ifndef lint -static const char copyright[] = +__unused static const char copyright[] = "@(#) Copyright (c) 1991, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ @@ -41,7 +42,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "from: @(#)pwd_mkdb.c 8.5 (Berkeley) 4/20/94"; #else -static const char rcsid[] = "$OpenBSD: pwd_mkdb.c,v 1.36 2003/06/08 21:14:55 millert Exp $"; +__unused static const char rcsid[] = "$OpenBSD: pwd_mkdb.c,v 1.36 2003/06/08 21:14:55 millert Exp $"; #endif #endif /* not lint */ @@ -62,6 +63,7 @@ static const char rcsid[] = "$OpenBSD: pwd_mkdb.c,v 1.36 2003/06/08 21:14:55 mil #include #include #include +#include "pw_scan.h" #define INSECURE 1 #define SECURE 2 diff --git a/reboot.tproj/reboot.8 b/reboot.tproj/reboot.8 index 46796be..a18e7ae 100644 --- a/reboot.tproj/reboot.8 +++ b/reboot.tproj/reboot.8 @@ -36,21 +36,21 @@ .Dt REBOOT 8 .Os .Sh NAME -.Nm reboot , -.Nm halt +.Nm halt , +.Nm reboot .Nd stopping and restarting the system .Sh SYNOPSIS .Nm halt .Op Fl lnqu -.Nm +.Nm reboot .Op Fl lnq .Sh DESCRIPTION The .Nm halt and -.Nm -utilities flush the file system cache to disk, send all running processes -a +.Nm reboot +utilities flush the file system cache to disk, +send all running processes a .Dv SIGTERM (and subsequently a .Dv SIGKILL ) @@ -66,11 +66,11 @@ The options are as follows: .It Fl l The halt or reboot is .Em not -logged to the system log. +recorded in the system log. This option is intended for applications such as .Xr shutdown 8 , that call -.Nm +.Nm reboot or .Nm halt and log this themselves. @@ -96,12 +96,20 @@ Normally, the utility is used when the system needs to be halted or restarted, giving users advance warning of their impending doom and cleanly terminating specific programs. +.Sh SIGTERM TO SIGKILL INTERVAL +The +.Dv SIGKILL +will follow the +.Dv SIGTERM +by an intentionally indeterminate period of time. +Programs are expected to take only enough time to flush all dirty data and exit. +Developers are encouraged to file a bug with the OS vendor, should they encounter an issue with this functionality. .Sh SEE ALSO .Xr wtmp 5 , .Xr shutdown 8 , .Xr sync 8 .Sh HISTORY A -.Nm +.Nm reboot utility appeared in .At v6 . diff --git a/reboot.tproj/reboot.c b/reboot.tproj/reboot.c index f970ca5..4282a1e 100644 --- a/reboot.tproj/reboot.c +++ b/reboot.tproj/reboot.c @@ -1,6 +1,7 @@ /* * Copyright (c) 1980, 1986, 1993 * The Regents of the University of California. All rights reserved. + * Portions copyright (c) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,11 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -66,6 +63,7 @@ static const char rcsid[] = #include // allocate #include // task_self, etc #include // bootstrap +#include #endif void usage(void); @@ -80,10 +78,14 @@ int main(int argc, char *argv[]) { struct passwd *pw; - int ch, howto, i, fd, kflag, lflag, nflag, qflag, pflag, uflag, sverrno; - u_int pageins; - char *kernel, *p; + int ch, howto, kflag, lflag, nflag, qflag, uflag; + char *p; const char *user; +#ifndef __APPLE__ + int i, fd, pflag, sverrno; + u_int pageins; + char *kernel; +#endif if (strstr((p = rindex(*argv, '/')) ? p + 1 : *argv, "halt")) { dohalt = 1; @@ -192,9 +194,11 @@ main(int argc, char *argv[]) if (!nflag) sync(); +#ifndef __APPLE__ /* Just stop init -- if we fail, we'll restart it. */ if (kill(1, SIGTSTP) == -1) err(1, "SIGTSTP init"); +#endif /* Ignore the SIGHUP we get when our parent shell dies. */ (void)signal(SIGHUP, SIG_IGN); @@ -236,16 +240,19 @@ main(int argc, char *argv[]) } #endif +#ifdef __APPLE__ + // launchd(8) handles reboot. This call returns NULL on success. + exit(reboot2(howto) == NULL ? EXIT_SUCCESS : EXIT_FAILURE); +#else /* __APPLE__ */ reboot(howto); /* FALLTHROUGH */ -#ifndef __APPLE__ restart: -#endif sverrno = errno; errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "", strerror(sverrno)); /* NOTREACHED */ +#endif /* __APPLE__ */ } void @@ -276,64 +283,60 @@ get_pageins() } #ifdef __APPLE__ -// XX another copy of this routine is in shutdown.c; it would be nice to share +// XX this routine is also in shutdown.tproj; it would be nice to share -#define LCK_MAXTRIES 10 -#define LCK_DELAY 30 +#define WAITFORLOCK 1 /* * contact kextd to lock for reboot */ int reserve_reboot() { - int rval = ELAST+1; + int rval = ELAST + 1; kern_return_t macherr = KERN_FAILURE; - mach_port_t tport, bsport, kxport, myport = MACH_PORT_NULL; - int busyStatus, nretries = LCK_MAXTRIES; - dev_path_t busyDev = ""; + mach_port_t kxport, tport = MACH_PORT_NULL, myport = MACH_PORT_NULL; + int busyStatus = ELAST + 1; + mountpoint_t busyVol; - // find kextd - tport = mach_task_self(); - if (tport == MACH_PORT_NULL) goto finish; - macherr = task_get_bootstrap_port(tport, &bsport); - if (macherr) goto finish; - macherr = bootstrap_look_up(bsport, KEXTD_SERVER_NAME, &kxport); + macherr = bootstrap_look_up(bootstrap_port, KEXTD_SERVER_NAME, &kxport); if (macherr) goto finish; // allocate a port to pass to kextd (in case we die) + tport = mach_task_self(); + if (tport == MACH_PORT_NULL) goto finish; macherr = mach_port_allocate(tport, MACH_PORT_RIGHT_RECEIVE, &myport); if (macherr) goto finish; - // loop trying to lock for reboot (i.e. no volumes are busy) - do { - nretries--; - macherr = kextmanager_lock_reboot(kxport, myport, busyDev, &busyStatus); - if (macherr) goto finish; - - if (busyStatus == EBUSY) { - if (*busyDev) { - warnx("%s is busy updating; delaying reboot (%d retries left)", - busyDev, nretries); - } else - warnx("kextd still starting up"); - if (nretries) sleep(LCK_DELAY); // don't sleep the last time - } - } while (busyStatus == EBUSY && nretries > 0); + // try to lock for reboot + macherr = kextmanager_lock_reboot(kxport, myport, !WAITFORLOCK, busyVol, + &busyStatus); + if (macherr) goto finish; - rval = busyStatus; + if (busyStatus == EBUSY) { + warnx("%s is busy updating; waiting for lock", busyVol); + macherr = kextmanager_lock_reboot(kxport, myport, WAITFORLOCK, + busyVol, &busyStatus); + if (macherr) goto finish; + } -finish: - if (macherr == BOOTSTRAP_UNKNOWN_SERVICE) { - mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); + if (busyStatus == EALREADY) { + // reboot already in progress rval = 0; - } else if (macherr) { - warnx("couldn't lock kext manager for reboot: %s", - mach_error_string(macherr)); - rval = ELAST + 1; + } else { + rval = busyStatus; } - if (rval && myport != MACH_PORT_NULL) { + +finish: + // in general, we want to err on the side of allowing the reboot + if (macherr) { + if (macherr != BOOTSTRAP_UNKNOWN_SERVICE) + warnx("WARNING: couldn't lock kext manager for reboot: %s", + mach_error_string(macherr)); + rval = 0; + } + // unless we got the lock, clean up our port + if (busyStatus != 0 && myport != MACH_PORT_NULL) mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); - } return rval; } diff --git a/sa.tproj/sa.8 b/sa.tproj/sa.8 index 4ba9503..288df04 100644 --- a/sa.tproj/sa.8 +++ b/sa.tproj/sa.8 @@ -36,19 +36,19 @@ .Nm sa .Nd print system accounting statistics .Sh SYNOPSIS -.Nm +.Nm sa .Op Fl abcdDfijkKlmnqrstu .Op Fl v Ar cutoff .Op Ar .Sh DESCRIPTION The -.Nm +.Nm sa utility reports on, cleans up, and generally maintains system accounting files. .Pp The -.Nm +.Nm sa utility is able to condense the information in .Pa /var/account/acct into the summary files @@ -75,87 +75,115 @@ after the last file is processed. The labels used in the output indicate the following, except where otherwise specified by individual options: .Bl -tag -width k*sec +.\" ========== .It Dv avio Average number of I/O operations per execution +.\" ========== .It Dv cp Sum of user and system time, in minutes +.\" ========== .It Dv cpu Same as .Dv cp +.\" ========== .It Dv k CPU-time averaged core usage, in 1k units +.\" ========== .It Dv k*sec CPU storage integral, in 1k-core seconds +.\" ========== .It Dv re Real time, in minutes +.\" ========== .It Dv s System time, in minutes +.\" ========== .It Dv tio Total number of I/O operations +.\" ========== .It Dv u User time, in minutes .El .Pp The options to -.Nm +.Nm sa are: .Bl -tag -width Ds +.\" ========== .It Fl a List all command names, including those containing unprintable characters and those used only once. By default, -.Nm +.Nm sa places all names containing unprintable characters and those used only once under the name ``***other''. +.\" ========== .It Fl b If printing command statistics, sort output by the sum of user and system time divided by number of calls. +.\" ========== .It Fl c In addition to the number of calls and the user, system and real times for each command, print their percentage of the total over all commands. +.\" ========== +.It Fl D +If printing command statistics, sort and print by the total number +of disk I/O operations. +.\" ========== .It Fl d If printing command statistics, sort by the average number of disk I/O operations. If printing user statistics, print the average number of disk I/O operations per user. -.It Fl D -If printing command statistics, sort and print by the total number -of disk I/O operations. +.\" ========== .It Fl f Force no interactive threshold comparison with the .Fl v option. +.\" ========== .It Fl i Do not read in the summary files. +.\" ========== .It Fl j Instead of the total minutes per category, give seconds per call. +.\" ========== +.It Fl K +If printing command statistics, print and sort by the cpu-storage integral. +.\" ========== .It Fl k If printing command statistics, sort by the cpu-time average memory usage. If printing user statistics, print the cpu-time average memory usage. -.It Fl K -If printing command statistics, print and sort by the cpu-storage integral. +.\" ========== .It Fl l Separate system and user time; normally they are combined. +.\" ========== .It Fl m Print per-user statistics rather than per-command statistics. +.\" ========== .It Fl n Sort by number of calls. +.\" ========== .It Fl q Create no output other than error messages. +.\" ========== .It Fl r Reverse order of sort. +.\" ========== .It Fl s Truncate the accounting files when done and merge their data into the summary files. +.\" ========== .It Fl t For each command, report the ratio of real time to the sum of user and system cpu times. If the cpu time is too small to report, ``*ignore*'' appears in this field. +.\" ========== .It Fl u Superseding all other flags, for each entry in the accounting file, print the user ID, total seconds of cpu usage, total memory usage, number of I/O operations performed, and command name. +.\" ========== .It Fl v Ar cutoff For each command used .Ar cutoff @@ -219,7 +247,7 @@ The field labels should be more consistent. The VM system does not record the CPU storage integral. .Sh CAVEATS While the behavior of the options in this version of -.Nm +.Nm sa was modeled after the original version, there are some intentional differences and undoubtedly some unintentional ones as well. In particular, the @@ -229,7 +257,7 @@ option has been added, and the option now understands more options than it used to. .Pp The formats of the summary files created by this version of -.Nm +.Nm sa are very different from the those used by the original version. This is not considered a problem, however, because the accounting record format has changed as well (since user ids are now 32 bits). diff --git a/sadc.tproj/sa1.8 b/sadc.tproj/sa1.8 index d129987..9fe6d9c 100644 --- a/sadc.tproj/sa1.8 +++ b/sadc.tproj/sa1.8 @@ -28,7 +28,7 @@ .Op Ar t n \" [t n] .Sh DESCRIPTION \" Section Header - required - don't modify The -.Nm +.Nm sa1 command is a shell script used to invoke the system activity data collector, .Nm sadc . @@ -44,7 +44,7 @@ where the .Ar dd represents the current day of the month. .Pp \" Inserts a space -.Nm +.Nm sa1 is intended to be started by cron. .Sh EXAMPLE CRON ENTRY .Bd -literal @@ -72,14 +72,14 @@ are digits that represent the day of the month. .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. -.Xr sa2 8 , -.Xr sadc 8 , -.Xr sar 1 , -.Xr iostat 8 , -.Xr vm_stat 1 , +.Xr crontab 1 , +.Xr fs_usage 1 , .Xr netstat 1 , -.Xr top 1 , +.Xr sar 1 , .Xr sc_usage 1 , -.Xr fs_usage 1 , -.Xr crontab 1 , -.Xr crontab 5 +.Xr top 1 , +.Xr vm_stat 1 , +.Xr crontab 5 , +.Xr iostat 8 , +.Xr sa2 8 , +.Xr sadc 8 diff --git a/sadc.tproj/sa2.8 b/sadc.tproj/sa2.8 index 320b5f8..fd8d32e 100644 --- a/sadc.tproj/sa2.8 +++ b/sadc.tproj/sa2.8 @@ -33,7 +33,7 @@ .Op Fl s Ar time \" [-s time] .Sh DESCRIPTION \" Section Header - required - don't modify The -.Nm +.Nm sa2 command is a shell script used to invoke the system activity reporter .Nm sar @@ -45,17 +45,17 @@ where the .Ar dd represents the current day of the month. The -.Nm +.Nm sa2 options are the same as those documented in .Nm sar(1) . .Pp \" Inserts a space When -.Nm +.Nm sa2 runs, it will also remove data and report files, found in /var/log/sa, that are more than one week old. .Pp The -.Nm +.Nm sa2 command is intended to be started by cron. .Pp .Sh EXAMPLE CRON ENTRY @@ -87,14 +87,14 @@ are digits that represent the day of the month. .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. -.Xr sa1 8 , -.Xr sadc 8 , -.Xr sar 1 , -.Xr iostat 8 , -.Xr vm_stat 1 , +.Xr crontab 1 , +.Xr fs_usage 1 , .Xr netstat 1 , -.Xr top 1 , +.Xr sar 1 , .Xr sc_usage 1 , -.Xr fs_usage 1 , -.Xr crontab 1 , -.Xr crontab 5 +.Xr top 1 , +.Xr vm_stat 1 , +.Xr crontab 5 , +.Xr iostat 8 , +.Xr sa1 8 , +.Xr sadc 8 diff --git a/sadc.tproj/sadc.8 b/sadc.tproj/sadc.8 index 9c8161d..ca36ea7 100644 --- a/sadc.tproj/sadc.8 +++ b/sadc.tproj/sadc.8 @@ -30,7 +30,7 @@ .Op Ar ofile \" [ofile] .Sh DESCRIPTION \" Section Header - required - don't modify The -.Nm +.Nm sadc tool is used to collect cumulative system activity data. The sample system data is collected at intervals .Ar t @@ -45,14 +45,14 @@ If the .Ar ofile file does not exist, it is created, otherwise it is truncated. .Pp \" Inserts a space -.Nm +.Nm sadc is intended to be used as the engine behind the .Nm sar(1) command, and is not typically invoked on the command line. Two shell scripts, .Nm sa1 and -.Nm sa2 +.Nm sa2 , are provided to drive the typical sampling, saving, and reporting process. .Pp @@ -99,13 +99,12 @@ data reporting. .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. -.Xr sa1 8 , -.Xr sa2 8 , -.Xr sar 1 , -.Xr iostat 8 , -.Xr vm_stat 1 , +.Xr fs_usage 1 , .Xr netstat 1 , -.Xr top 1 , +.Xr sar 1 , .Xr sc_usage 1 , -.Xr fs_usage 1 -.\" .Sh BUGS \" Document known, unremedied bugs +.Xr top 1 , +.Xr vm_stat 1 , +.Xr iostat 8 , +.Xr sa1 8 , +.Xr sa2 8 diff --git a/sadc.tproj/sadc.c b/sadc.tproj/sadc.c index bbbe829..a88e3ff 100644 --- a/sadc.tproj/sadc.c +++ b/sadc.tproj/sadc.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/sar.tproj/sar.1 b/sar.tproj/sar.1 index b9d68ae..02e5f33 100644 --- a/sar.tproj/sar.1 +++ b/sar.tproj/sar.1 @@ -23,18 +23,15 @@ .Os "Mac OS X" .Sh NAME \" Section Header - required - don't modify .Nm sar -.\" The following lines are read in generating the apropos(man -k) database. Use only key -.\" words here as the database is built based on the words here and in the .ND line. -.\" Use .Nm macro to designate other names for the documented program. .Nd system activity reporter .Sh SYNOPSIS \" Section Header - required - don't modify -.Nm +.Nm sar .Op Fl dgpu \" [-dgpu] .Op Fl n Ar mode \" [-n mode] .Op Fl o Ar filename \" [-o filename] t \" t .Op Ar n \" [ n ] -.Nm +.Nm sar .Op Fl dgpu \" [-dgpu] .Op Fl n Ar mode \" [-n mode] .Op Fl e Ar time \" [-e time] @@ -43,9 +40,10 @@ t \" t .Op Fl s Ar time \" [-s time] .Sh DESCRIPTION \" Section Header - required - don't modify The -.Nm +.Nm sar command is used to sample and report various cumulative statistic counters -maintained by the operating system. It can be invoked in two different ways. +maintained by the operating system. +It can be invoked in two different ways. .Pp In the first usage instance, .Ar n @@ -56,41 +54,55 @@ If .Ar n is not specified, only one sample will be captured. When the -o option is specified, -.Nm +.Nm sar will write the binary sampling data to the output file specified by .Ar filename . .Pp -In the second usage instance, there is no on-going sample interval to specify. -This is because the sampling input comes from a previously recorded, binary activity file. -The binary activity file can be specified using the -f -.Ar filename +In the second usage instance, +there is no on-going sample interval to specify. +This is because the sampling input comes +from a previously recorded, binary activity file. +The binary activity file can be specified using the +.Fl f Ar filename option. -When the -f option isn't used, -.Nm +When the +.Fl f +option isn't used, +.Nm sar attempts to open a default binary activity file, /var/log/sa/sadd, where .Ar dd represents the current day of the month. -The starting and ending time of the report can be restricted using the -e -and -s options. Here, the +.Pp +The starting and ending time of the report can be restricted using the +.Fl e +and +.Fl s +options. Here, the .Ar time field is specified in the form hh[:mm[:ss]]. -Finally, the -i option can be used to select the sampling interval. +.Pp +Finally, the +.Fl i +option can be used to select the sampling interval. Only records at least .Ar seconds apart will be reported. -When the -i option is not used, all of the previously recorded -interval samples are reported. +When the +.Fl i +option is not used, +all of the previously recorded interval samples are reported. .Pp -Due to the nature of on-going sample collection, the data is reported in a -verbose mode when more than one sampling option is specified. -Column headers are printed at the beginning of the report and averages are -printed when the -.Nm +Due to the nature of on-going sample collection, +the data is reported in a verbose mode +when more than one sampling option is specified. +Column headers are printed at the beginning of the report; +averages are printed when the +.Nm sar command terminates. .Sh OPTIONS The following options restrict the sample set that -.Nm +.Nm sar reports. .Pp \" Inserts a space .Bl -tag -width -indent \" Differs from above in tag removed @@ -199,13 +211,13 @@ are digits that represent the day of the month. .El .Sh SEE ALSO .\" List links in ascending order by section, alphabetically within a section. -.Xr sa1 8 , -.Xr sa2 8 , -.Xr sadc 8 , -.Xr iostat 8 , -.Xr vm_stat 1 , +.Xr fs_usage 1 , .Xr netstat 1 , -.Xr top 1 , .Xr sc_usage 1 , -.Xr fs_usage 1 +.Xr top 1 , +.Xr vm_stat 1 , +.Xr iostat 8 , +.Xr sa1 8 , +.Xr sa2 8 , +.Xr sadc 8 .\" .Sh BUGS \" Document known, unremedied bugs diff --git a/sar.tproj/sar.c b/sar.tproj/sar.c index c959499..1f046c0 100644 --- a/sar.tproj/sar.c +++ b/sar.tproj/sar.c @@ -461,11 +461,12 @@ main(argc, argv) #if 0 int efd; #endif + int fdlimit = getdtablesize(); /* This is the child */ /* Close all file descriptors except the one we need */ - for (i=0; i <= KERN_MAXFILESPERPROC; i++) { + for (i=0; i < fdlimit; i++) { if ((i != fd[0]) && (i != fd[1])) (void)close(i); } @@ -1120,6 +1121,14 @@ print_cpu_sample(timebufptr) += cur_cpuload.cpu_ticks[CPU_STATE_USER]; time += cur_cpuload.cpu_ticks[CPU_STATE_USER]; + + cur_cpuload.cpu_ticks[CPU_STATE_NICE] + -= prev_cpuload.cpu_ticks[CPU_STATE_NICE]; + + prev_cpuload.cpu_ticks[CPU_STATE_NICE] + += cur_cpuload.cpu_ticks[CPU_STATE_NICE]; + + time += cur_cpuload.cpu_ticks[CPU_STATE_NICE]; cur_cpuload.cpu_ticks[CPU_STATE_SYSTEM] -= prev_cpuload.cpu_ticks[CPU_STATE_SYSTEM]; @@ -1140,6 +1149,9 @@ print_cpu_sample(timebufptr) avg_cpuload.cpu_ticks[CPU_STATE_USER] += rint(100. * cur_cpuload.cpu_ticks[CPU_STATE_USER] / (time ? time : 1)); + avg_cpuload.cpu_ticks[CPU_STATE_NICE] += rint(100. * cur_cpuload.cpu_ticks[CPU_STATE_NICE] + / (time ? time : 1)); + avg_cpuload.cpu_ticks[CPU_STATE_SYSTEM] += rint(100. * cur_cpuload.cpu_ticks[CPU_STATE_SYSTEM] / (time ? time : 1)); @@ -1153,6 +1165,10 @@ print_cpu_sample(timebufptr) rint(100. * cur_cpuload.cpu_ticks[CPU_STATE_USER] / (time ? time : 1))); + fprintf(stdout, "%4.0f ", + rint(100. * cur_cpuload.cpu_ticks[CPU_STATE_NICE] + / (time ? time : 1))); + fprintf(stdout, "%4.0f ", rint(100. * cur_cpuload.cpu_ticks[CPU_STATE_SYSTEM] / (time ? time : 1))); @@ -1566,6 +1582,10 @@ exit_average() (int)avg_cpuload.cpu_ticks[CPU_STATE_USER] / (avg_counter ? avg_counter : 1)); + fprintf(stdout, "%4d ", + (int)avg_cpuload.cpu_ticks[CPU_STATE_NICE] + / (avg_counter ? avg_counter : 1)); + fprintf(stdout, "%4d ", (int)avg_cpuload.cpu_ticks[CPU_STATE_SYSTEM] / (avg_counter ? avg_counter : 1)); @@ -2289,7 +2309,7 @@ print_column_heading(int type, char *timebufptr, int mode) switch (type) { case SAR_CPU: - fprintf (stdout, "\n%s %%usr %%sys %%idle\n", p); + fprintf (stdout, "\n%s %%usr %%nice %%sys %%idle\n", p); break; case SAR_VMSTAT: diff --git a/sc_usage.tproj/Makefile.postamble b/sc_usage.tproj/Makefile.postamble index 952893a..a9cbc8d 100644 --- a/sc_usage.tproj/Makefile.postamble +++ b/sc_usage.tproj/Makefile.postamble @@ -65,6 +65,9 @@ # DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags # passed to ld/libtool (defaults to nothing) +ifeq "$(shell tconf --test TARGET_OS_EMBEDDED)" "YES" +OPTIMIZE_BUILD_CFLAGS = -O +endif # Library and Framework projects only: # INSTALL_NAME_DIRECTIVE: This directive ensures that executables linked diff --git a/sc_usage.tproj/sc_usage.c b/sc_usage.tproj/sc_usage.c index 6345efc..9000d6c 100644 --- a/sc_usage.tproj/sc_usage.c +++ b/sc_usage.tproj/sc_usage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -171,6 +171,7 @@ double other_start; int max_sc = 0; int bsc_base = 0; int msc_base = 0; +int mach_idle = 0; int mach_sched = 0; int mach_stkhandoff = 0; int vfs_lookup = 0; @@ -994,7 +995,7 @@ sc_tab_init(char *codefile) { /* Count Mach message MSG_ codes */ for (msgcode_cnt=0;;) { - n = fscanf(fp, "%x%s\n", &code, &name[0]); + n = fscanf(fp, "%x%55s\n", &code, &name[0]); if (n != 2) break; if (strncmp ("MSG_", &name[0], 4) == 0) @@ -1032,7 +1033,7 @@ sc_tab_init(char *codefile) { return; for (;;) { - n = fscanf(fp, "%x%s\n", &code, &name[0]); + n = fscanf(fp, "%x%55s\n", &code, &name[0]); if (n != 2) break; @@ -1049,6 +1050,10 @@ sc_tab_init(char *codefile) { mach_stkhandoff = code; continue; } + if (strcmp("MACH_IDLE", &name[0]) == 0) { + mach_idle = code; + continue; + } if (strcmp("VFS_LOOKUP", &name[0]) == 0) { vfs_lookup = code; continue; @@ -1478,10 +1483,50 @@ sample_sc() } else if (baseid == bsc_base) code = (debugid >> 2) & 0x1ff; - else if (baseid == msc_base) + else if (baseid == msc_base) code = 512 + ((debugid >> 2) & 0x1ff); + else if (type == mach_idle) { + if (debugid & DBG_FUNC_START) { + switched_out = find_thread(kd[i].arg5); + switched_in = 0; + } + else + if (debugid & DBG_FUNC_END) { + switched_in = find_thread(kd[i].arg5); + switched_out = 0; + } + + if (in_idle) { + itime_usecs += ((double)now - idle_start) / divisor; + delta_itime_usecs += ((double)now - idle_start) / divisor; + in_idle = 0; + } else if (in_other) { + otime_usecs += ((double)now - other_start) / divisor; + delta_otime_usecs += ((double)now - other_start) / divisor; + in_other = 0; + } + if ( !switched_in) { + /* + * not one of the target proc's threads + */ + if (now_collect_cpu_time) { + in_idle = 1; + idle_start = (double)now; + } + } + else { + if (now_collect_cpu_time) { + in_idle = 0; + in_other = 1; + other_start = (double)now; + } + } + if ( !switched_in && !switched_out) + continue; + + } else if (type == mach_sched || type == mach_stkhandoff) { - switched_out = find_thread(kd[i].arg5); + switched_out = find_thread(kd[i].arg5); switched_in = find_thread(kd[i].arg2); if (in_idle) { @@ -1495,17 +1540,12 @@ sample_sc() } if ( !switched_in) { /* - * not one of the target proc's threads - */ + * not one of the target proc's threads + */ if (now_collect_cpu_time) { - if (kd[i].arg4 == 0) { - in_idle = 1; - idle_start = (double)now; - } else { in_other = 1; - other_start = (double)now; + other_start = (double)now; } - } } if ( !switched_in && !switched_out) continue; @@ -1611,7 +1651,7 @@ sample_sc() se = &sc_tab[code]; scalls++; } else { - se = &faults[kd[i].arg2]; + se = &faults[kd[i].arg4]; total_faults++; } if (se->total_count == 0) diff --git a/sc_usage.tproj/trace.codes b/sc_usage.tproj/trace.codes index 66898c3..45833f9 100644 --- a/sc_usage.tproj/trace.codes +++ b/sc_usage.tproj/trace.codes @@ -1,4 +1,4 @@ -991 +1271 0x1f000000 DYLD_initialize 0x1f010000 DYLD_CALL_image_init_routine 0x1f010004 DYLD_CALL_dependent_init_routine @@ -219,6 +219,15 @@ 0xff002cac MSG_io_service_add_notification_ool 0xff002cb0 MSG_io_object_get_superclass 0xff002cb4 MSG_io_object_get_bundle_identifier +0xff002cb8 MSG_io_service_open_extended +0xff002cbc MSG_io_connect_map_memory_into_task +0xff002cc0 MSG_io_connect_unmap_memory_from_task +0xff002cc4 MSG_io_connect_method +0xff002cc8 MSG_io_connect_async_method +0xff002ccc MSG_io_connect_set_notification_port_64 +0xff002cd0 MSG_io_service_add_notification_64 +0xff002cd4 MSG_io_service_add_interest_notification_64 +0xff002cd8 MSG_io_service_add_notification_ool_64 0xff002ee0 MSG_processor_start 0xff002ee4 MSG_processor_exit 0xff002ee8 MSG_processor_info @@ -393,8 +402,49 @@ 0xff25abd4 MSG_semaphore_wait_signal 0xff25abd8 MSG_semaphore_timedwait_signal 0xffbebdcc MSG_clock_alarm_reply -0x1300000 MACH_vmfault +0x1020000 KTrap_DivideError +0x1020004 KTrap_Debug +0x1020008 KTrap_NMI +0x102000c KTrap_Int3 +0x1020010 KTrap_Overflow +0x1020014 KTrap_BoundRange +0x1020018 KTrap_InvalidOpcode +0x102001c KTrap_DeviceNotAvail +0x1020020 KTrap_DoubleFault +0x1020024 KTrap_Coprocessor +0x1020028 KTrap_InvalidTSS +0x102002c KTrap_SegmentNotPresent +0x1020030 KTrap_StackFault +0x1020034 KTrap_GeneralProtection +0x1020038 KTrap_PageFault +0x102003c KTrap_unknown +0x1020040 KTrap_FloatPointError +0x1020044 KTrap_AlignmentCheck +0x1020048 KTrap_MachineCheck +0x102004c KTrap_SIMD_FP +0x10203fc KTrap_Preempt +0x1070000 UTrap_DivideError +0x1070004 UTrap_Debug +0x1070008 UTrap_NMI +0x107000c UTrap_Int3 +0x1070010 UTrap_Overflow +0x1070014 UTrap_BoundRange +0x1070018 UTrap_InvalidOpcode +0x107001c UTrap_DeviceNotAvail +0x1070020 UTrap_DoubleFault +0x1070024 UTrap_Coprocessor +0x1070028 UTrap_InvalidTSS +0x107002c UTrap_SegmentNotPresent +0x1070030 UTrap_StackFault +0x1070034 UTrap_GeneralProtection +0x1070038 UTrap_PageFault +0x107003c UTrap_unknown +0x1070040 UTrap_FloatPointError +0x1070044 UTrap_AlignmentCheck +0x1070048 UTrap_MachineCheck +0x107004c UTrap_SIMD_FP 0x1300004 MACH_Pageout +0x1300008 MACH_vmfault 0x1400000 MACH_SCHED 0x1400004 MACH_STKATTACH 0x1400008 MACH_STKHANDOFF @@ -404,9 +454,13 @@ 0x1400018 MACH_MKRUNNABLE 0x140001c MACH_PROMOTE 0x1400020 MACH_DEMOTE +0x1400024 MACH_IDLE 0x1500000 MACH_MSGID_INVALID 0x1090000 DecrTrap 0x1090004 DecrSet +0x1090008 TimerCallIntr +0x109000c pmsStep +0x1090010 clock_deadline 0x10c0000 MACH_SysCall 0x10c0004 MSC_kern_invalid_#1 0x10c0008 MSC_kern_invalid_#2 @@ -627,6 +681,7 @@ 0x40c00fc BSC_#63 0x40c0100 BSC_obs_getpagesize 0x40c0104 BSC_msync +0x40e0104 BSC_msync_extended_info 0x40c0108 BSC_vfork 0x40c010c BSC_obs_vread 0x40c0110 BSC_obs_vwrite @@ -715,9 +770,9 @@ 0x40c025c BSC_getpgid 0x40c0260 BSC_setprivexec 0x40c0264 BSC_pread -0x40e0264 BSC_pread_extended +0x40e0264 BSC_pread_extended_info 0x40c0268 BSC_pwrite -0x40e0268 BSC_pwrite_extended +0x40e0268 BSC_pwrite_extended_info 0x40c026c BSC_nfssvc 0x40c0270 BSC_getdirentries 0x40c0274 BSC_statfs @@ -761,6 +816,8 @@ 0x40c030c BSC_setrlimit 0x40c0310 BSC_getdirentries 0x40c0314 BSC_mmap +0x40e0314 BSC_mmap_extended_info +0x40f0314 BSC_mmap_extended_info2 0x40c0318 BSC__syscall 0x40c031c BSC_lseek 0x40c0320 BSC_truncate @@ -874,7 +931,7 @@ 0x40c04d0 BSC_#308 0x40c04d4 BSC_#309 0x40c04d8 BSC_getsid -0x40c04dc BSC_#311 +0x40c04dc BSC_settid_with_pid 0x40c04e0 BSC_#312 0x40c04e4 BSC_aio_fsync 0x40c04e8 BSC_aio_return @@ -884,8 +941,8 @@ 0x40c04f8 BSC_aio_read 0x40c04fc BSC_aio_write 0x40c0500 BSC_lio_listio -0x40c0504 BSC_#321 -0x40c0508 BSC_#322 +0x40c0504 BSC__pthread_cond_wait +0x40c0508 BSC_iopolicysys 0x40c050c BSC_#323 0x40c0510 BSC_mlockall 0x40c0514 BSC_munlockall @@ -899,14 +956,14 @@ 0x40c0534 BSC_pthread_canceled 0x40c0538 BSC_semwait_signal 0x40c053c BSC_utrace -0x40c0540 BSC_#336 -0x40c0544 BSC_#337 -0x40c0548 BSC_#338 -0x40c054c BSC_#339 -0x40c0550 BSC_#340 -0x40c0554 BSC_#341 -0x40c0558 BSC_#342 -0x40c055c BSC_#343 +0x40c0540 BSC_proc_info +0x40c0544 BSC_sendfile +0x40c0548 BSC_stat64 +0x40c054c BSC_fstat64 +0x40c0550 BSC_lstat64 +0x40c0554 BSC_stat64_extended +0x40c0558 BSC_lstat64_extended +0x40c055c BSC_fstat64_extended 0x40c0560 BSC_#344 0x40c0564 BSC_#345 0x40c0568 BSC_#346 @@ -933,6 +990,60 @@ 0x40c05bc BSC_#367 0x40c05c0 BSC_#368 0x40c05c4 BSC_#369 +0x40c05c8 BSC_#370 +0x40c05cc BSC_#371 +0x40c05d0 BSC_#372 +0x40c05d4 BSC_#373 +0x40c05d8 BSC_#374 +0x40c05dc BSC_#375 +0x40c05e0 BSC_#376 +0x40c05e4 BSC_#377 +0x40c05e8 BSC_#378 +0x40c05ec BSC_#379 +0x40c05f0 BSC_mac_execve +0x40c05f4 BSC_mac_syscall +0x40c05f8 BSC_mac_get_file +0x40c06fc BSC_mac_set_file +0x40c0600 BSC_mac_get_link +0x40c0604 BSC_mac_set_link +0x40c0608 BSC_mac_get_proc +0x40c060c BSC_mac_set_proc +0x40c0610 BSC_mac_get_fd +0x40c0614 BSC_mac_set_fd +0x40c0618 BSC_mac_get_pid +0x40c061c BSC_mac_get_lcid +0x40c0620 BSC_mac_get_lctx +0x40c0624 BSC_mac_set_lctx +0x40c0628 BSC_setlcid +0x40c062c BSC_getlcid +0x40c0630 BSC_read_nocancel +0x40c0634 BSC_write_nocancel +0x40c0638 BSC_open_nocancel +0x40c063c BSC_close_nocancel +0x40c0640 BSC_wait4_nocancel +0x40c0644 BSC_recvmsg_nocancel +0x40c0648 BSC_sendmsg_nocancel +0x40c064c BSC_recvfrom_nocancel +0x40c0650 BSC_accept_nocancel +0x40c0654 BSC_msync_nocancel +0x40c0658 BSC_fcntl_nocancel +0x40c065c BSC_select_nocancel +0x40c0660 BSC_fsync_nocancel +0x40c0664 BSC_connect_nocancel +0x40c0668 BSC_sigsuspend_nocancel +0x40c066c BSC_readv_nocancel +0x40c0670 BSC_writev_nocancel +0x40c0674 BSC_sendto_nocancel +0x40c0678 BSC_pread_nocancel +0x40c067c BSC_pwrite_nocancel +0x40c0680 BSC_waitid_nocancel +0x40c0684 BSC_poll_nocancel +0x40c0688 BSC_msgsnd_nocancel +0x40c068c BSC_msgrcv_nocancel +0x40c0690 BSC_sem_wait_nocancel +0x40c0694 BSC_aio_suspend_nocancel +0x40c0698 BSC_sigwait_nocancel +0x40c069c BSC_semwait_signal_nocancel 0x5020018 IES_action 0x502001c IES_filter 0x5030010 TES_action @@ -986,7 +1097,179 @@ 0x51000bc PM_ClientCancl 0x51000c0 PM_ClientNotfy 0x51000c4 PM_AppNotify +0x5310004 CPUPM_PState +0x5310008 CPUPM_Idle_CState +0x531000c CPUPM_Idle_Halt +0x5310010 CPUPM_Idle_Loop +0x5310014 CPUPM_HPET_Start +0x5310018 CPUPM_HPET_End 0x7000004 TRACE_DATA_NEWTHREAD 0x7010004 TRACE_STRING_NEWTHREAD 0x7010008 TRACE_STRING_EXEC 0x8000000 USER_TEST +0x21800000 SMB_smbd_idle +0x21800004 SMB_syscall_opendir +0x21800008 SMB_syscall_readdir +0x2180000c SMB_syscall_seekdir +0x21800010 SMB_syscall_telldir +0x21800014 SMB_syscall_rewinddir +0x21800018 SMB_syscall_mkdir +0x2180001c SMB_syscall_rmdir +0x21800020 SMB_syscall_closedir +0x21800024 SMB_syscall_open +0x21800028 SMB_syscall_close +0x2180002c SMB_syscall_read +0x21800030 SMB_syscall_pread +0x21800034 SMB_syscall_write +0x21800038 SMB_syscall_pwrite +0x2180003c SMB_syscall_lseek +0x21800040 SMB_syscall_sendfile +0x21800044 SMB_syscall_rename +0x21800048 SMB_syscall_fsync +0x2180004c SMB_syscall_stat +0x21800050 SMB_syscall_fstat +0x21800054 SMB_syscall_lstat +0x21800058 SMB_syscall_unlink +0x2180005c SMB_syscall_chmod +0x21800060 SMB_syscall_fchmod +0x21800064 SMB_syscall_chown +0x21800068 SMB_syscall_fchown +0x2180006c SMB_syscall_chdir +0x21800070 SMB_syscall_getwd +0x21800074 SMB_syscall_utime +0x21800078 SMB_syscall_ftruncate +0x2180007c SMB_syscall_fcntl_lock +0x21800080 SMB_syscall_kernel_flock +0x21800084 SMB_syscall_fcntl_getlock +0x21800088 SMB_syscall_readlink +0x2180008c SMB_syscall_symlink +0x21800090 SMB_syscall_link +0x21800094 SMB_syscall_mknod +0x21800098 SMB_syscall_realpath +0x2180009c SMB_syscall_get_quota +0x218000a0 SMB_syscall_set_quota +0x218000a4 SMB_smbmkdir +0x218000a8 SMB_smbrmdir +0x218000ac SMB_smbopen +0x218000b0 SMB_smbcreate +0x218000b4 SMB_smbclose +0x218000b8 SMB_smbflush +0x218000bc SMB_smbunlink +0x218000c0 SMB_smbmv +0x218000c4 SMB_smbgetatr +0x218000c8 SMB_smbsetatr +0x218000cc SMB_smbread +0x218000d0 SMB_smbwrite +0x218000d4 SMB_smblock +0x218000d8 SMB_smbunlock +0x218000dc SMB_smbctemp +0x218000e0 SMB_smbmknew +0x218000e4 SMB_smbcheckpath +0x218000e8 SMB_smbexit +0x218000ec SMB_smblseek +0x218000f0 SMB_smblockread +0x218000f4 SMB_smbwriteunlock +0x218000f8 SMB_smbreadbraw +0x218000fc SMB_smbreadbmpx +0x21800100 SMB_smbreadbs +0x21800104 SMB_smbwritebraw +0x21800108 SMB_smbwritebmpx +0x2180010c SMB_smbwritebs +0x21800110 SMB_smbwritec +0x21800114 SMB_smbsetattre +0x21800118 SMB_smbgetattre +0x2180011c SMB_smblockingx +0x21800120 SMB_smbtrans +0x21800124 SMB_smbtranss +0x21800128 SMB_smbioctl +0x2180012c SMB_smbioctls +0x21800130 SMB_smbcopy +0x21800134 SMB_smbmove +0x21800138 SMB_smbecho +0x2180013c SMB_smbwriteclose +0x21800140 SMB_smbopenx +0x21800144 SMB_smbreadx +0x21800148 SMB_smbwritex +0x2180014c SMB_smbtrans2 +0x21800150 SMB_smbtranss2 +0x21800154 SMB_smbfindclose +0x21800158 SMB_smbfindnclose +0x2180015c SMB_smbtcon +0x21800160 SMB_smbtdis +0x21800164 SMB_smbnegprot +0x21800168 SMB_smbsesssetupx +0x2180016c SMB_smbulogoffx +0x21800170 SMB_smbtconx +0x21800174 SMB_smbdskattr +0x21800178 SMB_smbsearch +0x2180017c SMB_smbffirst +0x21800180 SMB_smbfunique +0x21800184 SMB_smbfclose +0x21800188 SMB_smbnttrans +0x2180018c SMB_smbnttranss +0x21800190 SMB_smbntcreatex +0x21800194 SMB_smbntcancel +0x21800198 SMB_smbntrename +0x2180019c SMB_smbsplopen +0x218001a0 SMB_smbsplwr +0x218001a4 SMB_smbsplclose +0x218001a8 SMB_smbsplretq +0x218001ac SMB_smbsends +0x218001b0 SMB_smbsendb +0x218001b4 SMB_smbfwdname +0x218001b8 SMB_smbcancelf +0x218001bc SMB_smbgetmac +0x218001c0 SMB_smbsendstrt +0x218001c4 SMB_smbsendend +0x218001c8 SMB_smbsendtxt +0x218001cc SMB_smbinvalid +0x218001d0 SMB_pathworks_setdir +0x218001d4 SMB_trans2_open +0x218001d8 SMB_trans2_findfirst +0x218001dc SMB_trans2_findnext +0x218001e0 SMB_trans2_qfsinfo +0x218001e4 SMB_trans2_setfsinfo +0x218001e8 SMB_trans2_qpathinfo +0x218001ec SMB_trans2_setpathinfo +0x218001f0 SMB_trans2_qfileinfo +0x218001f4 SMB_trans2_setfileinfo +0x218001f8 SMB_trans2_fsctl +0x218001fc SMB_trans2_ioctl +0x21800200 SMB_trans2_findnotifyfirst +0x21800204 SMB_trans2_findnotifynext +0x21800208 SMB_trans2_mkdir +0x2180020c SMB_trans2_session_setup +0x21800210 SMB_trans2_get_dfs_referral +0x21800214 SMB_trans2_report_dfs_inconsistancy +0x21800218 SMB_nt_transact_create +0x2180021c SMB_nt_transact_ioctl +0x21800220 SMB_nt_transact_set_security_desc +0x21800224 SMB_nt_transact_notify_change +0x21800228 SMB_nt_transact_rename +0x2180022c SMB_nt_transact_query_security_desc +0x21800230 SMB_nt_transact_get_user_quota +0x21800234 SMB_nt_transact_set_user_quota +0x21800238 SMB_get_nt_acl +0x2180023c SMB_fget_nt_acl +0x21800240 SMB_set_nt_acl +0x21800244 SMB_fset_nt_acl +0x21800248 SMB_chmod_acl +0x2180024c SMB_fchmod_acl +0x21800250 SMB_name_release +0x21800254 SMB_name_refresh +0x21800258 SMB_name_registration +0x2180025c SMB_node_status +0x21800260 SMB_name_query +0x21800264 SMB_host_announce +0x21800268 SMB_workgroup_announce +0x2180026c SMB_local_master_announce +0x21800270 SMB_master_browser_announce +0x21800274 SMB_lm_host_announce +0x21800278 SMB_get_backup_list +0x2180027c SMB_reset_browser +0x21800280 SMB_announce_request +0x21800284 SMB_lm_announce_request +0x21800288 SMB_domain_logon +0x2180028c SMB_sync_browse_lists +0x21800290 SMB_run_elections +0x21800294 SMB_election diff --git a/shutdown.tproj/Makefile b/shutdown.tproj/Makefile index e0df19d..2226b3d 100644 --- a/shutdown.tproj/Makefile +++ b/shutdown.tproj/Makefile @@ -31,6 +31,7 @@ LIBS = -lbsm DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) +FRAMEWORKS = -framework IOKit diff --git a/shutdown.tproj/PB.project b/shutdown.tproj/PB.project index a6190ce..cde35ad 100644 --- a/shutdown.tproj/PB.project +++ b/shutdown.tproj/PB.project @@ -1,7 +1,7 @@ { APPCLASS = NSApplication; FILESTABLE = { - FRAMEWORKS = (); + FRAMEWORKS = (IOKit.framework); H_FILES = (pathnames.h); M_FILES = (); OTHER_LIBS = (bsm); diff --git a/shutdown.tproj/shutdown.8 b/shutdown.tproj/shutdown.8 index 12bd570..7ca6c49 100644 --- a/shutdown.tproj/shutdown.8 +++ b/shutdown.tproj/shutdown.8 @@ -39,13 +39,13 @@ .Nm shutdown .Nd "close down the system at a given time" .Sh SYNOPSIS -.Nm +.Nm shutdown .Op Fl .Oo .Fl h .Op Fl u | -.Fl r | Fl k +.Fl r | Fl s | Fl k .Oc .Oo .Fl o @@ -55,7 +55,7 @@ .Op Ar warning-message ... .Sh DESCRIPTION The -.Nm +.Nm shutdown utility provides an automated shutdown procedure for super-users to nicely notify users when the system is shutting down, saving them from system administrators, hackers, and gurus, who @@ -66,9 +66,6 @@ The following options are available: .It Fl h The system is halted at the specified .Ar time . -.It Fl r -The system is rebooted at the specified -.Ar time . .It Fl k Kick everybody off. The @@ -76,19 +73,6 @@ The option does not actually halt the system, but leaves the system multi-user with logins disabled (for all but super-user). -.It Fl o -If -.Fl h -or -.Fl r -is specified, -.Nm -will execute -.Xr halt 8 -or -.Xr reboot 8 -instead of sending signal to -.Xr init 8 . .It Fl n If the .Fl o @@ -99,6 +83,25 @@ option to or .Xr reboot 8 . This option should probably not be used. +.It Fl o +If +.Fl h +or +.Fl r +is specified, +.Nm shutdown +will execute +.Xr halt 8 +or +.Xr reboot 8 +instead of sending a signal to +.Xr launchd 8 . +.It Fl r +The system is rebooted at the specified +.Ar time . +.It Fl s +The system is put to sleep at the specified +.Ar time . .It Fl u The system is halted up until the point of removing system power, but waits before removing power for 5 minutes so that an external UPS @@ -108,7 +111,7 @@ this mode automatically with supported UPSs in emergency shutdowns. .It Ar time .Ar Time is the time at which -.Nm +.Nm shutdown will bring the system down and may be the word .Ar now @@ -133,60 +136,41 @@ input. .Pp At intervals, becoming more frequent as apocalypse approaches and starting at ten hours before shutdown, warning messages are displayed -on the terminals of all users logged in. Five minutes before -shutdown, or immediately if shutdown is in less than 5 minutes, -logins are disabled by creating -.Pa /var/run/nologin -and copying the -warning message there. If this file exists when a user attempts to -log in, -.Xr login 1 -prints its contents and exits. The file is -removed just before -.Nm -exits. +on the terminals of all users logged in. .Pp At shutdown time a message is written to the system log, containing the time of shutdown, the person who initiated the shutdown and the reason. Corresponding signal is then sent to -.Xr init 8 +.Xr launchd 8 to respectively halt, reboot or bring the system down to single-user state (depending on the above options). -The time of the shutdown and the warning message -are placed in -.Pa /var/run/nologin -and should be used to -inform the users about when the system will be back up -and why it is going down (or anything else). .Pp A scheduled shutdown can be canceled by killing the -.Nm +.Nm shutdown process (a .Dv SIGTERM should suffice). +.Sh SIGTERM TO SIGKILL INTERVAL +Upon shutdown, all running processes are sent a SIGTERM followed by a SIGKILL. The -.Pa /var/run/nologin -file that -.Nm -created will be removed automatically. -.Sh FILES -.Bl -tag -width /var/run/nologin -compact -.It Pa /var/run/nologin -tells login not to let anyone log in -.El +.Dv SIGKILL +will follow the +.Dv SIGTERM +by an intentionally indeterminate period of time. +Programs are expected to take only enough time to flush all dirty data and exit. +Developers are encouraged to file a bug with the OS vendor, should they encounter an issue with this functionality. .Sh SEE ALSO .Xr kill 1 , .Xr login 1 , .Xr wall 1 , -.Xr nologin 5 , .Xr halt 8 , -.Xr init 8 , +.Xr launchd 8 , .Xr reboot 8 .Sh BACKWARD COMPATIBILITY The hours and minutes in the second time format may be separated by a colon (``:'') for backward compatibility. .Sh HISTORY The -.Nm +.Nm shutdown utility appeared in .Bx 4.0 . diff --git a/shutdown.tproj/shutdown.c b/shutdown.tproj/shutdown.c index 91ea293..e7a7928 100644 --- a/shutdown.tproj/shutdown.c +++ b/shutdown.tproj/shutdown.c @@ -1,6 +1,7 @@ /* * Copyright (c) 1988, 1990, 1993 * The Regents of the University of California. All rights reserved. + * Portions copyright (c) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,11 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,6 +28,7 @@ * SUCH DAMAGE. */ +#if 0 #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1988, 1990, 1993\n\ @@ -38,12 +36,13 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -#if 0 static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95"; -#endif -static const char rcsid[] = - "$FreeBSD: src/sbin/shutdown/shutdown.c,v 1.23 2002/03/21 13:20:48 imp Exp $"; #endif /* not lint */ +#endif +#include +#ifndef __APPLE__ +__FBSDID("$FreeBSD: src/sbin/shutdown/shutdown.c,v 1.28 2005/01/25 08:40:51 delphij Exp $"); +#endif #include #include @@ -53,6 +52,7 @@ static const char rcsid[] = #include #include #include +#include #include #include #include @@ -61,23 +61,22 @@ static const char rcsid[] = #include #include +#ifdef __APPLE__ #include +#include #include #include -#ifdef __APPLE__ #include "kextmanager.h" #include +#include #include // allocate #include // task_self, etc #include // bootstrap -#endif +#include #include "pathnames.h" - -#ifdef __APPLE__ -#define __unused -#endif +#endif /* __APPLE__ */ #ifdef DEBUG #undef _PATH_NOLOGIN @@ -109,9 +108,16 @@ struct interval { #undef S static time_t offset, shuttime; -static int dohalt, dopower, doreboot, doups, killflg, mbuflen, oflag = 1; +#ifdef __APPLE__ +static int dohalt, doreboot, doups, killflg, mbuflen, oflag; +#else +static int dohalt, dopower, doreboot, killflg, mbuflen, oflag; +#endif static char mbuf[BUFSIZ]; static const char *nosync, *whom; +#ifdef __APPLE__ +static int dosleep; +#endif void badtime(void); #ifdef __APPLE__ @@ -126,15 +132,15 @@ void nolog(void); void timeout(int); void timewarn(int); void usage(const char *); -int audit_shutdown(int); #ifdef __APPLE__ +int audit_shutdown(int); int reserve_reboot(void); #endif +extern const char **environ; + int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { char *p, *endp; struct passwd *pw; @@ -149,7 +155,7 @@ main(argc, argv) #ifndef __APPLE__ while ((ch = getopt(argc, argv, "-hknopr")) != -1) #else - while ((ch = getopt(argc, argv, "-hknoru")) != -1) + while ((ch = getopt(argc, argv, "-hknorsu")) != -1) #endif switch (ch) { case '-': @@ -160,7 +166,6 @@ main(argc, argv) break; case 'k': killflg = 1; - oflag = 0; break; case 'n': nosync = "-n"; @@ -179,6 +184,11 @@ main(argc, argv) case 'r': doreboot = 1; break; +#ifdef __APPLE__ + case 's': + dosleep = 1; + break; +#endif case '?': default: usage((char *)NULL); @@ -195,19 +205,19 @@ main(argc, argv) if (oflag && !(dohalt || dopower || doreboot)) usage("-o requires -h, -p or -r"); -#else - if (killflg + doreboot + dohalt > 1) - usage("incompatible switches -h, -k, and -r"); - if (oflag && !(dohalt || doreboot)) - usage("-o requires -h or -r"); + if (nosync != NULL && !oflag) + usage("-n requires -o"); +#else /* !__APPLE__ */ + if (killflg + doreboot + dohalt + dosleep > 1) + usage("incompatible switches -h, -k, -r, and -s"); + + if (!(dohalt || doreboot || dosleep || killflg)) + usage("-h, -r, -s, or -k is required"); if (doups && !dohalt) usage("-u requires -h"); -#endif - - if (nosync != NULL && !oflag) - usage("-n requires -o"); +#endif /* !__APPLE__ */ getoffset(*argv++); @@ -254,7 +264,11 @@ main(argc, argv) (void)putc('\n', stdout); #else (void)setpriority(PRIO_PROCESS, 0, PRIO_MIN); +#ifdef __APPLE__ + if (offset) { +#else { +#endif int forkpid; forkpid = fork(); @@ -262,9 +276,8 @@ main(argc, argv) audit_shutdown(1); err(1, "fork"); } - if (forkpid) { + if (forkpid) errx(0, "[pid %d]", forkpid); - } } audit_shutdown(0); setsid(); @@ -328,14 +341,15 @@ static const char *restricted_environ[] = { }; void -timewarn(timeleft) - int timeleft; +timewarn(int timeleft) { static int first; static char hostname[MAXHOSTNAMELEN + 1]; FILE *pf; char wcmd[MAXPATHLEN + 4]; - extern const char **environ; + + /* wall is sometimes missing, e.g. on install media */ + if (access(_PATH_WALL, X_OK) == -1) return; if (!first++) (void)gethostname(hostname, sizeof(hostname)); @@ -380,8 +394,7 @@ timewarn(timeleft) } void -timeout(signo) - int signo __unused; +timeout(int signo __unused) { longjmp(alarmbuf, 1); } @@ -393,9 +406,9 @@ log_and_exec_reboot_or_halt() die_you_gravy_sucking_pig_dog() #endif { +#ifndef __APPLE__ char *empty_environ[] = { NULL }; - -#ifdef __APPLE__ +#else if ((errno = reserve_reboot())) err(1, "couldn't lock for reboot"); #endif @@ -404,9 +417,9 @@ die_you_gravy_sucking_pig_dog() #ifndef __APPLE__ doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" : #else - doreboot ? "reboot" : dohalt ? "halt" : + doreboot ? "reboot" : dohalt ? "halt" : dosleep ? "sleep" : #endif - "shutdown", doups?"with UPS delay":"", whom, mbuf); + "shutdown", doups?" with UPS delay":"", whom, mbuf); #ifndef __APPLE__ (void)sleep(2); #endif @@ -424,27 +437,49 @@ die_you_gravy_sucking_pig_dog() #ifndef __APPLE__ else if (dopower) (void)printf("power-down"); -#endif if (nosync != NULL) (void)printf(" no sync"); +#else + else if (dosleep) + (void)printf("sleep"); +#endif (void)printf("\nkill -HUP 1\n"); #else #ifdef __APPLE__ - { - int ws = 0; - int fp = fork(); - if (fp == 0) - execl(_PATH_BSHELL, _PATH_BSHELL, "/etc/rc.shutdown", NULL); - else if (fp > 0) - waitpid(fp, &ws, 0); + if (dosleep) { + mach_port_t mp; + io_connect_t fb; + kern_return_t kr = IOMasterPort(bootstrap_port, &mp); + if (kr == kIOReturnSuccess) { + fb = IOPMFindPowerManagement(mp); + if (fb != IO_OBJECT_NULL) { + IOReturn err = IOPMSleepSystem(fb); + if (err != kIOReturnSuccess) { + fprintf(stderr, "shutdown: sleep failed (0x%08x)\n", err); + kr = -1; + } + } + } + exit((kr == kIOReturnSuccess) ? 0 : 1); + } else { + int howto = 0; + + logwtmp("~", "shutdown", ""); + + if (dohalt) howto |= RB_HALT; + if (doups) howto |= RB_UPSDELAY; + if (nosync) howto |= RB_NOSYNC; + + // launchd(8) handles reboot. This call returns NULL on success. + exit(reboot2(howto) == NULL ? EXIT_SUCCESS : EXIT_FAILURE); } -#endif + /* NOT-REACHED */ + +#else /* __APPLE__ */ if (!oflag) { (void)kill(1, doreboot ? SIGINT : /* reboot */ dohalt ? SIGUSR1 : /* halt */ -#ifndef __APPLE__ dopower ? SIGUSR2 : /* power-down */ -#endif SIGTERM); /* single-user */ } else { if (doreboot) { @@ -455,19 +490,12 @@ die_you_gravy_sucking_pig_dog() warn(_PATH_REBOOT); } else if (dohalt) { - char *halt_args; - if(doups) { - halt_args = "-lu"; - } else { - halt_args = "-l"; - } - execle(_PATH_HALT, "halt", halt_args, nosync, + execle(_PATH_HALT, "halt", "-l", nosync, (char *)NULL, empty_environ); syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT); warn(_PATH_HALT); } -#ifndef __APPLE__ else if (dopower) { execle(_PATH_HALT, "halt", "-l", "-p", nosync, (char *)NULL, empty_environ); @@ -475,9 +503,9 @@ die_you_gravy_sucking_pig_dog() _PATH_HALT); warn(_PATH_HALT); } -#endif (void)kill(1, SIGTERM); /* to single-user */ } +#endif /* __APPLE__ */ #endif finish(0); } @@ -485,8 +513,7 @@ die_you_gravy_sucking_pig_dog() #define ATOI2(p) (p[0] - '0') * 10 + (p[1] - '0'); p += 2; void -getoffset(timearg) - char *timearg; +getoffset(char *timearg) { struct tm *lt; char *p; @@ -589,12 +616,11 @@ nolog() (void)write(logfd, mbuf, strlen(mbuf)); (void)close(logfd); } -#endif +#endif /* !__APPLE__ */ } void -finish(signo) - int signo __unused; +finish(int signo __unused) { #ifndef __APPLE__ if (!killflg) @@ -610,17 +636,21 @@ badtime() } void -usage(cp) - const char *cp; +usage(const char *cp) { if (cp != NULL) warnx("%s", cp); (void)fprintf(stderr, - "usage: shutdown [-] [-h [-u] | -r | -k] [-o [-n]]" +#ifdef __APPLE__ + "usage: shutdown [-] [-h [-u] [-n] | -r [-n] | -s | -k]" +#else + "usage: shutdown [-] [-h | -p | -r | -k] [-o [-n]]" +#endif " time [warning-message ...]\n"); exit(1); } +#ifdef __APPLE__ /* * The following tokens are included in the audit record for shutdown * header @@ -668,67 +698,62 @@ int audit_shutdown(int exitstatus) } -#ifdef __APPLE__ -// XX copied from reboot.c; would be nice to share the code +// XX copied from reboot.tproj/reboot.c; it would be nice to share the code -#define LCK_MAXTRIES 10 -#define LCK_DELAY 30 +#define WAITFORLOCK 1 /* * contact kextd to lock for reboot */ int reserve_reboot() { - int rval = ELAST+1; - kern_return_t macherr = KERN_FAILURE; - mach_port_t tport, bsport, kxport, myport = MACH_PORT_NULL; - int busyStatus, nretries = LCK_MAXTRIES; - dev_path_t busyDev = ""; - - // find kextd - tport = mach_task_self(); - if (tport == MACH_PORT_NULL) goto finish; - macherr = task_get_bootstrap_port(tport, &bsport); - if (macherr) goto finish; - macherr = bootstrap_look_up(bsport, KEXTD_SERVER_NAME, &kxport); - if (macherr) goto finish; - - // allocate a port to pass to kextd (in case we die) - macherr = mach_port_allocate(tport, MACH_PORT_RIGHT_RECEIVE, &myport); - if (macherr) goto finish; - - // loop trying to lock for reboot (i.e. no volumes are busy) - do { - nretries--; - macherr = kextmanager_lock_reboot(kxport, myport, busyDev, &busyStatus); - if (macherr) goto finish; - - if (busyStatus == EBUSY) { - if (*busyDev) { - warnx("%s is busy updating; delaying reboot (%d retries left)", - busyDev, nretries); - } else - warnx("kextd still starting up"); - if (nretries) sleep(LCK_DELAY); // don't sleep the last time - } - } while (busyStatus == EBUSY && nretries > 0); - - rval = busyStatus; + int rval = ELAST + 1; + kern_return_t macherr = KERN_FAILURE; + mach_port_t kxport, tport = MACH_PORT_NULL, myport = MACH_PORT_NULL; + int busyStatus = ELAST + 1; + mountpoint_t busyVol; + + macherr = bootstrap_look_up(bootstrap_port, KEXTD_SERVER_NAME, &kxport); + if (macherr) goto finish; + + // allocate a port to pass to kextd (in case we die) + tport = mach_task_self(); + if (tport == MACH_PORT_NULL) goto finish; + macherr = mach_port_allocate(tport, MACH_PORT_RIGHT_RECEIVE, &myport); + if (macherr) goto finish; + + // try to lock for reboot + macherr = kextmanager_lock_reboot(kxport, myport, !WAITFORLOCK, busyVol, + &busyStatus); + if (macherr) goto finish; + + if (busyStatus == EBUSY) { + warnx("%s is busy updating; waiting for lock", busyVol); + macherr = kextmanager_lock_reboot(kxport, myport, WAITFORLOCK, + busyVol, &busyStatus); + if (macherr) goto finish; + } + + if (busyStatus == EALREADY) { + // reboot already in progress + rval = 0; + } else { + rval = busyStatus; + } finish: - if (macherr == BOOTSTRAP_UNKNOWN_SERVICE) { - mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); - rval = 0; - } else if (macherr) { - warnx("couldn't lock kext manager for reboot: %s", - mach_error_string(macherr)); - rval = ELAST + 1; - } - if (rval && myport != MACH_PORT_NULL) { - mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); - } - - return rval; + // in general, we want to err on the side of allowing the reboot + if (macherr) { + if (macherr != BOOTSTRAP_UNKNOWN_SERVICE) + warnx("WARNING: couldn't lock kext manager for reboot: %s", + mach_error_string(macherr)); + rval = 0; + } + // unless we got the lock, clean up our port + if (busyStatus != 0 && myport != MACH_PORT_NULL) + mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); + + return rval; } -#endif +#endif /* __APPLE__ */ diff --git a/sync.tproj/sync.8 b/sync.tproj/sync.8 index 049007e..6d39ad0 100644 --- a/sync.tproj/sync.8 +++ b/sync.tproj/sync.8 @@ -61,8 +61,8 @@ utilizes the .Xr sync 2 function call. .Sh SEE ALSO -.Xr sync 2 , .Xr fsync 2 , +.Xr sync 2 , .Xr halt 8 , .Xr reboot 8 , .Xr update 8 diff --git a/sync.tproj/sync.c b/sync.tproj/sync.c index 9a242f3..10a4856 100644 --- a/sync.tproj/sync.c +++ b/sync.tproj/sync.c @@ -54,6 +54,10 @@ * SUCH DAMAGE. */ +#include +#include + +int main() { sync(); diff --git a/sysctl.tproj/Makefile b/sysctl.tproj/Makefile index fc19331..cd1ef2d 100644 --- a/sysctl.tproj/Makefile +++ b/sysctl.tproj/Makefile @@ -14,7 +14,7 @@ PROJECT_TYPE = Tool CFILES = sysctl.c -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble sysctl.8 +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble sysctl.8 sysctl.conf.5 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/sysctl.tproj/Makefile.postamble b/sysctl.tproj/Makefile.postamble index f5f7c67..72a3197 100644 --- a/sysctl.tproj/Makefile.postamble +++ b/sysctl.tproj/Makefile.postamble @@ -111,3 +111,5 @@ after_install: mkdir -p "$(DSTROOT)/usr/share/man/man8" install -c -m 644 sysctl.8 "$(DSTROOT)/usr/share/man/man8/sysctl.8" + mkdir -p "$(DSTROOT)/usr/share/man/man5" + install -c -m 644 sysctl.conf.5 "$(DSTROOT)/usr/share/man/man5/sysctl.conf.5" diff --git a/sysctl.tproj/sysctl.8 b/sysctl.tproj/sysctl.8 index 5261f6b..cf7fa58 100644 --- a/sysctl.tproj/sysctl.8 +++ b/sysctl.tproj/sysctl.8 @@ -65,17 +65,21 @@ described as a dotted set of components. .Pp The following options are available: .Bl -tag -width indent +.\" ========== .It Fl A List all MIB variables including opaque variables (which are normally suppressed). The format and length are printed, as well as a hex dump of the first sixteen bytes of the value. +.\" ========== .It Fl a List all the currently available non-opaque values. This option is ignored if one or more variable names are specified on the command line. +.\" ========== .It Fl b Force the value of the variable(s) to be output in raw, binary format. No names are printed and no terminating newlines are output. This is mostly useful with a single variable. +.\" ========== .It Fl n Show only variable values, not their names. This option is useful for setting shell variables. @@ -84,16 +88,19 @@ For instance, to save the pagesize in variable use: .Pp .Dl "set psize=`sysctl -n hw.pagesize`" -.It Fl X -Same as -.Fl A -but prints a hex dump of the entire value instead of just the first few bytes. +.\" ========== .It Fl w Ar name=value Used to set values. The MIB name ( .Ar name ) followed by an equal sign and the new value ( .Ar value ) to be used. +.\" ========== +.It Fl X +Same as +.Fl A , +but prints a hex dump of the entire value +instead of just the first few bytes. .El .Pp If just a MIB style name is given, @@ -155,6 +162,7 @@ privilege can change the value. .It hw.byteorder integer no .It hw.physmem integer no .It hw.usermem integer no +.It hw.memsize integer no .It hw.pagesize integer no .It user.cs_path string no .It user.bc_base_max integer no @@ -184,6 +192,7 @@ This information can be obtained by using the command: .Bd -literal -offset indent sysctl debug .Ed +.Pp In addition, .Nm sysctl can extract information about the filesystems that have been compiled @@ -192,6 +201,7 @@ This information can be obtained by using the command: .Bd -literal -offset indent sysctl vfs .Ed +.Pp By default, only filesystems that are actively being used are listed. Use of the .Fl A @@ -199,29 +209,29 @@ flag lists all the filesystems compiled into the running kernel. .Sh EXAMPLES .Pp For example, to retrieve the maximum number of processes allowed -in the system, one would use the follow request: -.Bd -literal -offset indent -compact +in the system, one would use the request: +.Bd -literal -offset indent sysctl kern.maxproc .Ed .Pp To set the maximum number of processes allowed -in the system to 1000, one would use the follow request: -.Bd -literal -offset indent -compact +in the system to 1000, one would use the request: +.Bd -literal -offset inden sysctl -w kern.maxproc=1000 .Ed .Pp Information about the system clock rate may be obtained with: -.Bd -literal -offset indent -compact +.Bd -literal -offset indent sysctl kern.clockrate .Ed .Pp Information about the load average history may be obtained with: -.Bd -literal -offset indent -compact +.Bd -literal -offset indent sysctl vm.loadavg .Ed .Pp Information about the system's swap space usage may be obtained with: -.Bd -literal -offset indent -compact +.Bd -literal -offset indent sysctl vm.swapusage .Ed .Sh FILES diff --git a/sysctl.tproj/sysctl.c b/sysctl.tproj/sysctl.c index 631ad40..b861263 100644 --- a/sysctl.tproj/sysctl.c +++ b/sysctl.tproj/sysctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -87,14 +87,15 @@ setting values where the format is specified as unsigned integer. */ +#include #ifndef lint -static char copyright[] = +__unused static char copyright[] = "@(#) Copyright (c) 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95"; +__unused static char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95"; #endif /* not lint */ #include @@ -158,6 +159,7 @@ struct list secondlevel[] = { static int Aflag, aflag, bflag, nflag, wflag, Xflag; static int foundSome = 0; +static int invalid_name_used = 0; void listall(char *prefix, struct list *lp); void old_parse(char *string, int flags); @@ -213,7 +215,7 @@ main(argc, argv) usage(); for (; *argv != NULL; ++argv) parse(*argv, 1); - exit(0); + exit(invalid_name_used ? 1 : 0); } /* @@ -348,7 +350,8 @@ old_parse(string, flags) useUnsignedInt = 1; break; - case CTL_VM: + case CTL_VM: break; +#if 0 /* XXX Handled by the new sysctl mechanism */ switch (mib[1]) { case VM_LOADAVG: { /* XXX this is bogus */ double loads[3]; @@ -392,6 +395,7 @@ old_parse(string, flags) fprintf(stderr, "Use vmstat or systat to view %s information\n", string); return; +#endif case CTL_DEBUG: mib[2] = CTL_DEBUG_VALUE; @@ -441,18 +445,33 @@ old_parse(string, flags) switch (type) { case CTLTYPE_INT: if (useUnsignedInt) { - uintval = strtoul(newval, 0, 0); + uintval = strtoul(newval, NULL, 0); + if ((uintval == 0) && (errno == EINVAL)) { + fprintf(stderr, "invalid argument: %s\n", + (char *)newval); + return; + } newval = &uintval; newsize = sizeof uintval; } else { - intval = atoi(newval); - newval = &intval; - newsize = sizeof intval; + intval = strtol(newval, NULL, 0); + if ((intval == 0) && (errno == EINVAL)) { + fprintf(stderr, "invalid argument: %s\n", + (char *)newval); + return; + } + newval = &intval; + newsize = sizeof intval; } break; case CTLTYPE_QUAD: - sscanf(newval, "%qd", &quadval); + quadval = strtoq(newval, NULL, 0); + if ((quadval == 0) && (errno == EINVAL)) { + fprintf(stderr, "invalid argument: %s\n", + (char *)newval); + return; + } newval = &quadval; newsize = sizeof quadval; break; @@ -463,7 +482,7 @@ old_parse(string, flags) if (flags == 0) return; switch (errno) { - case EOPNOTSUPP: + case ENOTSUP: fprintf(stderr, "%s: value is not available\n", string); return; case ENOTDIR: @@ -496,7 +515,7 @@ old_parse(string, flags) fprintf(stdout, "%s = %s\n", string, ctime((time_t *) &btp->tv_sec)); else - fprintf(stdout, "%d\n", btp->tv_sec); + fprintf(stdout, "%ld\n", btp->tv_sec); return; } if (special & CONSDEV) { @@ -609,7 +628,7 @@ void vfsinit() for (loc = lastused, cnt = 0; cnt < maxtypenum; cnt++) { mib[3] = cnt; if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) { - if (errno == EOPNOTSUPP) + if (errno == ENOTSUP) continue; perror("vfsinit"); free(vfsname); @@ -645,6 +664,7 @@ findname(string, level, bufp, namelist) bufp[0][strlen(*bufp)-1]='\0'; if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { fprintf(stderr, "%s: incomplete specification\n", string); + invalid_name_used = 1; return (-1); } for (i = 0; i < namelist->size; i++) @@ -654,6 +674,7 @@ findname(string, level, bufp, namelist) if (i == namelist->size) { fprintf(stderr, "%s level name %s in %s is invalid\n", level, name, string); + invalid_name_used = 1; return (-1); } return (i); @@ -738,10 +759,22 @@ parse(char *string, int flags) case CTLTYPE_INT: if ((*fmt == 'I') && (*(fmt + 1) == 'U')) { uintval = (unsigned int) strtoul (newval, NULL, 0); + if ((uintval == 0) && + (errno == EINVAL)) { + errx(1, "invalid argument: %s", + newval); + return; + } newval = &uintval; newsize = sizeof uintval; } else { intval = (int) strtol(newval, NULL, 0); + if ((intval == 0) && + (errno == EINVAL)) { + errx(1, "invalid argument: %s", + newval); + return; + } newval = &intval; newsize = sizeof intval; } @@ -750,6 +783,10 @@ parse(char *string, int flags) break; case CTLTYPE_QUAD: quadval = strtoq(newval, NULL, 0); + if ((quadval == 0) && (errno == EINVAL)) { + errx(1, "invalid argument %s", newval); + return; + } newval = &quadval; newsize = sizeof quadval; break; @@ -764,7 +801,7 @@ parse(char *string, int flags) if (!i && !bflag) putchar('\n'); switch (errno) { - case EOPNOTSUPP: + case ENOTSUP: errx(1, "%s: value is not available", string); case ENOTDIR: @@ -837,6 +874,23 @@ S_timeval(int l2, void *p) return (0); } +static int +S_xswusage(int l2, void *p) +{ + struct xsw_usage *xsu = (struct xsw_usage *)p; + + if(l2 != sizeof (*xsu)) + err(1, "S_xswusage %d != %d", l2, sizeof *xsu); + + fprintf(stdout, + "total = %.2fM used = %.2fM free = %.2fM %s", + ((double) xsu->xsu_total) / (1024.0 * 1024.0), + ((double) xsu->xsu_used) / (1024.0 * 1024.0), + ((double) xsu->xsu_avail) / (1024.0 * 1024.0), + xsu->xsu_encrypted ? "(encrypted)" : ""); + return 0; +} + static int T_dev_t(int l2, void *p) { @@ -987,13 +1041,13 @@ show_var(int *oid, int nlen, int show_masked) if (!nflag) printf("%s: ", name); fmt++; - val = ""; + val = (unsigned char *)""; while (len >= sizeof(int)) { if(*fmt == 'U') printf("%s%u", val, *(unsigned int *)p); else printf("%s%d", val, *(int *)p); - val = " "; + val = (unsigned char *)" "; len -= sizeof (int); p += sizeof (int); } @@ -1004,13 +1058,13 @@ show_var(int *oid, int nlen, int show_masked) if (!nflag) printf("%s: ", name); fmt++; - val = ""; + val = (unsigned char *)""; while (len >= sizeof(long)) { if(*fmt == 'U') printf("%s%lu", val, *(unsigned long *)p); else printf("%s%ld", val, *(long *)p); - val = " "; + val = (unsigned char *)" "; len -= sizeof (long); p += sizeof (long); } @@ -1028,13 +1082,13 @@ show_var(int *oid, int nlen, int show_masked) if (!nflag) printf("%s: ", name); fmt++; - val = ""; + val = (unsigned char *)""; while (len >= sizeof(long long)) { if(*fmt == 'U') printf("%s%llu", val, *(unsigned long long *)p); else printf("%s%lld", val, *(long long *)p); - val = " "; + val = (unsigned char *)" "; len -= sizeof (long long); p += sizeof (long long); } @@ -1048,6 +1102,7 @@ show_var(int *oid, int nlen, int show_masked) if (!strcmp(fmt, "S,clockinfo")) func = S_clockinfo; else if (!strcmp(fmt, "S,timeval")) func = S_timeval; else if (!strcmp(fmt, "S,loadavg")) func = S_loadavg; + else if (!strcmp(fmt, "S,xsw_usage")) func = S_xswusage; else if (!strcmp(fmt, "T,dev_t")) func = T_dev_t; if (func) { if (!nflag) diff --git a/sysctl.tproj/sysctl.conf.5 b/sysctl.tproj/sysctl.conf.5 new file mode 100644 index 0000000..709c601 --- /dev/null +++ b/sysctl.tproj/sysctl.conf.5 @@ -0,0 +1,75 @@ +.\" Modified August 3, 2007 +.\" Portions Copyright (c) 2007 Apple Inc. +.\" Copyright (c) 1999 Chris Costello +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: src/share/man/man5/sysctl.conf.5,v 1.16 2004/07/03 18:29:23 ru Exp $ +.\" +.Dd August 3, 2007 +.Dt SYSCTL.CONF 5 +.Os +.Sh NAME +.Nm sysctl.conf +.Nd kernel state defaults +.Sh DESCRIPTION +The +.Pa /etc/sysctl.conf +file is read in when the system goes into multi-user mode to set default +settings for the kernel. +The +.Pa /etc/sysctl.conf +is in the format of the +.Xr sysctl 8 +command, i.e.\& +.Bd -literal -offset indent +sysctl_mib=value +.Ed +.Pp +Comments are denoted by a +.Dq # +at the beginning of a line. +.Sh FILES +.Bl -tag -width /etc/sysctl.conf -compact +.It Pa /etc/sysctl.conf +Initial settings for +.Xr sysctl 8 . +.El +.Sh EXAMPLES +To disable coredumps, you may use a configuration like: +.Bd -literal -offset indent +# Disable coredumps. +kern.coredump=0 +.Ed +.Sh SEE ALSO +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +file appeared in +.Fx 4.0 . +.Sh BUGS +If loadable kernel modules are used to introduce additional kernel +functionality and sysctls to manage that functionality, +.Nm +may be processed too early in the boot process to set those sysctls. diff --git a/update.tproj/Makefile b/update.tproj/Makefile index a851a51..e69df73 100644 --- a/update.tproj/Makefile +++ b/update.tproj/Makefile @@ -12,12 +12,13 @@ NAME = update PROJECTVERSION = 2.8 PROJECT_TYPE = Tool -CFILES = update.c disk_power.c power_mgmt.c -HFILES = disk_power.h power_mgmt.h +CFILES = update.c +HFILES = -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble update.8 +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble update.8 \ + com.apple.update.plist update.sb -FRAMEWORKS = -framework CoreFoundation -framework IOKit +FRAMEWORKS = MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles CODE_GEN_STYLE = DYNAMIC diff --git a/update.tproj/Makefile.postamble b/update.tproj/Makefile.postamble index 0e58184..df90f1e 100644 --- a/update.tproj/Makefile.postamble +++ b/update.tproj/Makefile.postamble @@ -108,6 +108,18 @@ # target runs. Such rules should be specified with the '::' syntax rather than # a single colon. -after_install: +install-man-page: mkdir -p "$(DSTROOT)/usr/share/man/man8" install -c -m 644 update.8 "$(DSTROOT)/usr/share/man/man8/update.8" + +LAUNCHD_PLIST_DIR = $(DSTROOT)/System/Library/LaunchDaemons +LAUNCHD_PLIST = com.apple.update.plist +SANDBOX = "$(DSTROOT)/usr/share/sandbox" + +install-launchd-plist: + install -d $(LAUNCHD_PLIST_DIR) + install -c -m 644 $(LAUNCHD_PLIST) $(LAUNCHD_PLIST_DIR)/$(LAUNCHD_PLIST) + +install-sb: + install -d $(SANDBOX) + install -c -m 644 update.sb $(SANDBOX) diff --git a/update.tproj/Makefile.preamble b/update.tproj/Makefile.preamble index 3a44cfd..94cd779 100644 --- a/update.tproj/Makefile.preamble +++ b/update.tproj/Makefile.preamble @@ -111,4 +111,4 @@ OTHER_HELP_DIRS = # $(NAME).%d[.%d][.%d] and the following line must be uncommented. OTHER_GENERATED_OFILES = $(VERS_OFILE) -AFTER_INSTALL = after_install +AFTER_INSTALL = install-man-page install-launchd-plist install-sb diff --git a/update.tproj/PB.project b/update.tproj/PB.project index b0255a9..f62d0fc 100644 --- a/update.tproj/PB.project +++ b/update.tproj/PB.project @@ -1,16 +1,16 @@ { DOCICONFILES = (); FILESTABLE = { - C_FILES = (update.c disk_power.c power_mgmt.c); - H_FILES = (disk_power.h power_mgmt.h); + C_FILES = (update.c); + H_FILES = (); OTHER_LIBS = (); OTHER_LINKED = (); - OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, update.8); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, update.8, com.apple.update.plist); PRECOMPILED_HEADERS = (); PROJECT_HEADERS = (); PUBLIC_HEADERS = (); SUBPROJECTS = (); - FRAMEWORKS = (CoreFoundation.framework, IOKit.framework); + FRAMEWORKS = (); }; GENERATEMAIN = YES; LANGUAGE = English; diff --git a/update.tproj/com.apple.update.plist b/update.tproj/com.apple.update.plist new file mode 100644 index 0000000..238f9fc --- /dev/null +++ b/update.tproj/com.apple.update.plist @@ -0,0 +1,14 @@ + + + + + Label + com.apple.update + OnDemand + + ProgramArguments + + /usr/sbin/update + + + diff --git a/update.tproj/disk_power.c b/update.tproj/disk_power.c deleted file mode 100644 index e0d76fe..0000000 --- a/update.tproj/disk_power.c +++ /dev/null @@ -1,350 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "disk_power.h" - -int PowerStateSummary( IOATAPowerState powerState ); - -/* --- PowerStateString() -*/ - -char * PowerStateString( IOATAPowerState x, int opt_summary ) -{ - char * result; - - if ( opt_summary ) - { - switch ( PowerStateSummary( x ) ) - { - case -1: - result = "ON"; - break; - case 0: // This is the only value where the two scales collide. - result = "OFF"; - break; - default: - fprintf(stderr, "ERROR: %s: unknown IOATAPowerState %d\n", __FUNCTION__, (int)x); - result = "UNKNOWN"; - break; - } - } - else - { - switch ( x ) - { - case kIOATAPowerStateSystemSleep: // This is the only value where the two scales collide. - result = "SystemSleep"; - break; - case kIOATAPowerStateSleep: - result = "Sleep"; - break; - case kIOATAPowerStateStandby: - result = "Standby"; - break; - case kIOATAPowerStateIdle: - result = "Idle"; - break; - case kIOATAPowerStateActive: - result = "Active"; - break; - default: - fprintf(stderr, "ERROR: %s: unknown IOATAPowerState %d\n", __FUNCTION__, (int)x); - result = "UNKNOWN"; - break; - } - } - - return result; - -} // PowerStateString() - -/* --- PowerStatesMax() -*/ - -IOATAPowerState PowerStatesMax( IOATAPowerStates * powerStates ) -{ - IOATAPowerState driverDesire = powerStates->driverDesire; - IOATAPowerState deviceDesire = powerStates->deviceDesire; - IOATAPowerState userDesire = powerStates->userDesire; - - IOATAPowerState maxState = 0; - - if ( driverDesire > maxState ) maxState = driverDesire; - - if ( deviceDesire > maxState ) maxState = deviceDesire; - - if ( userDesire > maxState ) maxState = userDesire; - - return maxState; - -} // PowerStatesMax() - -/* --- PowerStateSummary() -*/ - -/* Returns --- -1 == ON --- 0 == OFF --- Can be used together with the positive values denoting IOATAPowerState's. --- But you have to be careful not to confuse with OFF == 0 == kIOATAPowerStateSystemSleep. -*/ - -int PowerStateSummary( IOATAPowerState powerState ) -{ - int result; - - // Summarizing twice does nothing. Idempotent. - if ( powerState <= 0 ) - result = powerState; - else -#if 1 - if ( 0 <= powerState && powerState <= kIOATAPowerStateSleep ) - result = 0; - else - result = -1; -#else - if ( 0 <= powerState && powerState <= kIOATAPowerStateStandby ) // Spun down. - result = 0; // OFF - else - if ( kIOATAPowerStateIdle <= powerState && powerState <= kIOATAPowerStateActive ) // Spun up. - result = -1; // ON - else - { - fprintf(stderr, "ERROR: %s(%d): unexpected value.\n", __FUNCTION__, powerState); - exit(-1); - } -#endif - - return result; - -} // PowerStateSummary() - -/* --- GetATADeviceInfo() -*/ - -// Fairly often this returns -11, meaning that it was unable to locate a matching device. -// If this happens, just wait awhile and try again. -// -// See GetATADeviceInfoWithRetry() -// - -int GetATADeviceInfo( DiskDevice * device ) -{ - int result; - - IOATAPowerStates * powerStates = & device->powerStates; - - kern_return_t kr; - mach_port_t masterPort; - io_registry_entry_t service; - io_iterator_t iterator; - - kr = IOMasterPort(MACH_PORT_NULL, &masterPort); - assert(KERN_SUCCESS==kr); - - /* look for drives */ - IOServiceGetMatchingServices(masterPort, IOServiceMatching ( "ATADeviceNub" ), & iterator ); - if ( ! iterator ) - { - result = -10; - goto Return; - } - - while (( service = IOIteratorNext( iterator ) )) - { - CFStringRef str = nil; - CFMutableDictionaryRef properties = nil; - CFDictionaryRef physCharacteristics = nil; - io_iterator_t child_iterator; - io_registry_entry_t child; - - // Device Model - - char deviceModel[ 256 ]; - bzero( deviceModel, sizeof deviceModel ); - - str = IORegistryEntryCreateCFProperty( service, CFSTR("device model"), kCFAllocatorDefault, kNilOptions ); - if ( str ) - { - CFStringGetCString( str, deviceModel, sizeof deviceModel, kCFStringEncodingMacRoman ); - CFRelease( str ); - } - - // Device Interconnect & Device Location - - char deviceInterconnect[ 256 ]; - bzero(deviceInterconnect, sizeof deviceInterconnect ); - char deviceLocation[ 256 ]; - bzero(deviceLocation, sizeof deviceLocation ); - - IORegistryEntryCreateCFProperties( service, & properties, kCFAllocatorDefault, kNilOptions ); - if ( properties ) - { - physCharacteristics = CFDictionaryGetValue( properties, CFSTR("Protocol Characteristics") ); - if ( physCharacteristics ) - { - // device interconnect - str = CFDictionaryGetValue( physCharacteristics, CFSTR("Physical Interconnect") ); - if ( str ) - { - CFStringGetCString( str, deviceInterconnect, sizeof deviceInterconnect, kCFStringEncodingMacRoman ); - } - - // device location - str = CFDictionaryGetValue( physCharacteristics, CFSTR("Physical Interconnect Location") ); - if ( str ) - { - CFStringGetCString( str, deviceLocation, sizeof deviceLocation, kCFStringEncodingMacRoman ); - } - } - - CFRelease( properties ); - } - - IORegistryEntryGetChildIterator( service, kIOServicePlane, & child_iterator ); - while (( child = IOIteratorNext( child_iterator ) )) - { - int driverDesire, deviceDesire, userDesire; - - // fill in interconnect info if we don't already have it - if ( 0 == strlen(deviceInterconnect) ) - { - str = IORegistryEntryCreateCFProperty( child, CFSTR("Physical Interconnect"), kCFAllocatorDefault, kNilOptions ); - if ( str ) - { - CFStringGetCString( str, deviceInterconnect, sizeof deviceInterconnect, kCFStringEncodingMacRoman ); - CFRelease( str ); - } - } - - if ( 0 == strlen( deviceLocation ) ) - { - str = IORegistryEntryCreateCFProperty( child, CFSTR("Physical Interconnect Location"), kCFAllocatorDefault, kNilOptions ); - if ( str ) - { - CFStringGetCString( str, deviceLocation, sizeof deviceLocation , kCFStringEncodingMacRoman ); - CFRelease( str ); - } - } - - // Device Type - - char deviceType[ 256 ]; - bzero( deviceType, sizeof deviceType ); - - // Power State - - char powerState[ 256 ]; - bzero( powerState, sizeof powerState ); - - // find out what type of device this is - ATAPI will be added as SCSI devices - str = IORegistryEntryCreateCFProperty( service, CFSTR("ata device type"), kCFAllocatorDefault, kNilOptions ); - if ( str ) - { - CFStringGetCString( str, deviceType, sizeof deviceType, kCFStringEncodingMacRoman ); - CFRelease( str ); - - if ( 0 == strcmp( deviceType, "ata" ) ) // regular ATA disks (not ATAPI) - { - IORegistryEntryCreateCFProperties( child, & properties, kCFAllocatorDefault, kNilOptions ); - if ( properties ) - { - str = CFDictionaryGetValue( properties, CFSTR("Power Management private data") ); - if ( str ) - { - CFStringGetCString( str, powerState, sizeof powerState, kCFStringEncodingMacRoman ); - } - CFRelease( properties ); - } - } - } - - if ( 3 == sscanf ( powerState, - "{ this object = %*x, interested driver = %*x, driverDesire = %d, deviceDesire = %d, ourDesiredPowerState = %d, previousRequest = %*d }", - & driverDesire, & deviceDesire, & userDesire - ) - ) - { - device->timestamp = time( NULL ); - - device->name = strdup( deviceModel ); // copy of the original - device->location = strdup( deviceLocation ); // copy of the original - device->interconnect = strdup( deviceInterconnect ); // copy of the original - - powerStates->driverDesire = driverDesire; - powerStates->deviceDesire = deviceDesire; - powerStates->userDesire = userDesire; - - IOObjectRelease( child_iterator ); - IOObjectRelease( iterator ); - - result = 0; - goto Return; - } - - } // while (child...) - - IOObjectRelease( child_iterator ); - - } // while (service...) - - IOObjectRelease( iterator ); - - result = -11; - goto Return; - -Return: - return result; - -} // GetATADeviceInfo() - - -/* --- GetATADeviceInfoWithRetry() -*/ - -// Devices are often momentarily busy, e.g., when spinning up. Retry up to 10 times, 1 second apart. - -int GetATADeviceInfoWithRetry( DiskDevice * diskDevice ) -{ - int err; - - int retryNumber; - - for ( retryNumber = 0; retryNumber < 10; retryNumber++ ) - { - err = GetATADeviceInfo( diskDevice ); - if ( noErr == err ) - { - goto Return; - } -#if 0 - char errorStringBuffer[ 256 ]; - char * errorString = errorStringBuffer; - errorString += sprintf_timestamp_now( errorString ); - errorString += sprintf(errorString, ": WARNING: %s: sleeping and retrying...\n", __FUNCTION__); - fputs( errorStringBuffer, stderr ); - fflush(stdout); -#endif - sleep(1); - } - - // Failure. - goto Return; - -Return: - return err; - -} // GetATADeviceInfoWithRetry() - diff --git a/update.tproj/disk_power.h b/update.tproj/disk_power.h deleted file mode 100644 index 141cb94..0000000 --- a/update.tproj/disk_power.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __SPINDOWN_H__ - -#define __SPINDOWN_H__ - -#include -#include -#include -#include - -/* IOATAPowerStates */ - -struct IOATAPowerStates -{ - IOATAPowerState driverDesire; - IOATAPowerState deviceDesire; - IOATAPowerState userDesire; -}; - -typedef struct IOATAPowerStates IOATAPowerStates; - -/* DiskDevice: see GetATADeviceInfo(), GetATADeviceInfoWithRetry() */ - -struct DiskDevice -{ - time_t timestamp; - char * name; - char * location; - char * interconnect; - IOATAPowerStates powerStates; -}; - -typedef struct DiskDevice DiskDevice; - -/* Devices */ - - -/* PowerStatesMax() --- Returns the max-of-three power state "desires" from the given IOATAPowerStates. -*/ -IOATAPowerState PowerStatesMax( IOATAPowerStates * powerStates ); - -/* PowerStateString() --- Returns human-readable string name for the given IOATAPowerState. --- Returns pointer to a static, const string. -*/ -char * PowerStateString( IOATAPowerState x, int opt_summary ); - -/* Routines for printing fs_usage-compatible timestamps: HH:MM:SS.000 -*/ -int sprintf_timestamp( char * str, time_t t ); -int sprintf_timestamp_now( char * str ); -char * timestampStr_static( time_t t ); /* Returns pointer to a static, const string. */ - -#if 0 -/* Routines for printing time intervals: HH:MM:SS -*/ -int sprintf_interval( char * str, time_t interval ); -char * intervalStr_static( time_t interval ); /* Returns pointer to a static, const string. */ -#endif - -/* GetATADeviceInfoWithRetry() --- This invokes GetATADeviceInfo() repeatedly at one second intervals until it returns without error. --- Gives up after 10 tries, so it is possible that this could return an error. -*/ -int GetATADeviceInfoWithRetry( DiskDevice * diskDevice ); - -/* --- -*/ - -#endif /* __SPINDOWN_H__ */ diff --git a/update.tproj/power_mgmt.c b/update.tproj/power_mgmt.c deleted file mode 100644 index a1a1245..0000000 --- a/update.tproj/power_mgmt.c +++ /dev/null @@ -1,114 +0,0 @@ - -#include "disk_power.h" - -#include -#include -#include - -#include - -/* --- -*/ - -int on_battery_power( void ) -{ - int result = 0; // Assume we're not running on battery power. - kern_return_t kr; - mach_port_t master_device_port; - - CFArrayRef cfarray = NULL; - - kr = IOMasterPort( bootstrap_port, & master_device_port); - if ( KERN_SUCCESS != kr) - { - fprintf(stderr,"ERROR: IOMasterPort() failed\n"); - goto Return; - } - - kr = IOPMCopyBatteryInfo( master_device_port, & cfarray ); - if ( kIOReturnSuccess != kr ) - { - // This case handles desktop machines in addition to error cases. - result = 0; - goto Return; - } - - { - CFDictionaryRef dict; - CFNumberRef cfnum; - int flags; - - dict = CFArrayGetValueAtIndex( cfarray, 0 ); - cfnum = CFDictionaryGetValue( dict, CFSTR(kIOBatteryFlagsKey) ); - - if ( CFNumberGetTypeID() != CFGetTypeID( cfnum ) ) - { - fprintf(stderr, "ERROR: on_battery_power(): battery flags not a CFNumber!!!\n"); - result = 0; - goto Return; - } - - CFNumberGetValue( cfnum, kCFNumberLongType, & flags ); - -#if 0 - printf( "BatteryFlags = %#08x\n", flags ); - - printf( "BatteryChargerConnect : %s\n", ( 0 != ( flags & kIOBatteryChargerConnect ) ) ? "TRUE" : "FALSE" ); - printf( "BatteryCharge : %s\n", ( 0 != ( flags & kIOBatteryCharge ) ) ? "TRUE" : "FALSE" ); - printf( "BatteryInstalled : %s\n", ( 0 != ( flags & kIOBatteryInstalled ) ) ? "TRUE" : "FALSE" ); -#endif - - result = ( 0 == ( flags & kIOPMACInstalled ) ); - } - -Return: - if (cfarray) - CFRelease(cfarray); - return result; - -} // on_battery_power() - -/* --- -*/ - -int is_disk_awake( void ) -{ - int result = 1; // Go ahead and sync by default. - int err; - DiskDevice diskDevice; - IOATAPowerState powerState; - - bzero(&diskDevice, sizeof(diskDevice)); - - err = GetATADeviceInfoWithRetry( & diskDevice ); - if ( err ) - { - result = 1; // Go ahead and sync. - goto Return; - } - - powerState = PowerStatesMax( & diskDevice.powerStates ); - -// printf( "%s: power state = %s\n", __FUNCTION__, PowerStateString( powerState, /* opt_summary = */ 0 ) ); - - result = ( powerState >= kIOATAPowerStateStandby ); - -Return: - if (diskDevice.name) - free(diskDevice.name); - if (diskDevice.location) - free(diskDevice.location); - if (diskDevice.interconnect) - free(diskDevice.interconnect); - -// printf( "%s => %s\n", __FUNCTION__, result ? "TRUE" : "FALSE" ); - return result; - -} // is_disk_awake() - -/* --- -*/ - diff --git a/update.tproj/power_mgmt.h b/update.tproj/power_mgmt.h deleted file mode 100644 index 9d4cb4a..0000000 --- a/update.tproj/power_mgmt.h +++ /dev/null @@ -1,2 +0,0 @@ -int on_battery_power( void ); -int is_disk_awake( void ); \ No newline at end of file diff --git a/update.tproj/update.8 b/update.tproj/update.8 index 7a2105f..72f099e 100644 --- a/update.tproj/update.8 +++ b/update.tproj/update.8 @@ -55,14 +55,13 @@ The normal_interval and save_energy_interval can be used to set the .Xr sync 2 interval in seconds of the normal case and the case where the computer is trying to save energy. .Pp .Nm Update -is commonly invoked at startup time by -.Xr rc 8 +is invoked at startup time by +.Xr launchd 8 when the system goes multi-user. .Sh SEE ALSO .Xr sync 2 , .Xr fsck 8 , -.Xr init 8 , -.Xr rc 8 , +.Xr launchd 8 , .Xr sync 8 .Sh BUGS It is possible on some systems that a diff --git a/update.tproj/update.c b/update.tproj/update.c index 8e2638d..17c33ee 100644 --- a/update.tproj/update.c +++ b/update.tproj/update.c @@ -1,151 +1,44 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ -/*- - * Copyright (c) 1987, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1987, 1990, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#include +#include #include #include -#include - -#include "power_mgmt.h" -#include "disk_power.h" -extern char *optarg; - -static void usage(const char *argv0) __attribute__((noreturn)); -static int parsetime(const char *arg); - -int main(int argc, char *const argv[]) +int +main(void) { - int normal_intr = 30; - int save_pwr_intr = 30; - int on_bat, disk_up, last_sync = 0, current_sync_interval = 0; - - if (argc > 3) - usage(argv[0]); - if (argc > 2) - save_pwr_intr = parsetime(argv[2]); - if (argc > 1) - normal_intr = parsetime(argv[1]); - - if (normal_intr == -1 || save_pwr_intr == -1) - usage(argv[0]); - - if (normal_intr > save_pwr_intr) - normal_intr = save_pwr_intr; - - daemon(0, 0); + const char* progname = "update"; + char* errmsg; + int res = sandbox_init(progname, SANDBOX_NAMED, &errmsg); + if (res) { + fprintf(stderr, "%s: sandbox_init: %s\n", progname, errmsg); + sandbox_free_error(errmsg); + } for (;;) { - if (last_sync >= current_sync_interval) { - sync(); - last_sync = 0; - } sleep(30); - last_sync += 30; - - on_bat = on_battery_power(); - disk_up = is_disk_awake(); - - current_sync_interval = normal_intr; - if (on_bat && !disk_up) - current_sync_interval = save_pwr_intr; - + sync(); } -} - -static int parsetime(const char *arg) -{ - char *q = NULL; - int r; - - r = strtol(arg, &q, 10); - - if (r < 1) - return -1; - if (arg == q) - return -1; - - switch (*q) { - case 'h': - r *= 60; - case 'm': - r *= 60; - case 's': - case '\0': - break; - default: - return -1; - } - - return r; -} - -static void usage(const char *argv0) -{ - fprintf(stderr, "usage: %s [normal_interval [power_saving_interval]]\n", argv0); - exit(EXIT_FAILURE); + return 0; } diff --git a/update.tproj/update.sb b/update.tproj/update.sb new file mode 100644 index 0000000..d8cb413 --- /dev/null +++ b/update.tproj/update.sb @@ -0,0 +1,18 @@ +;; Copyright (c) 2007 Apple Inc. All Rights reserved. +;; +;; WARNING: The sandbox rules in this file currently constitute +;; Apple System Private Interface and are subject to change at any time and +;; without notice. The contents of this file are also auto-generated and not +;; user editable; it may be overwritten at any time. +;; +(version 1) +(debug deny) +(allow process-exec (regex #"^/usr/sbin/update$")) +(allow sysctl-read) +(allow file-read-data file-read-metadata + (regex #"^/usr/lib/.*\.dylib$" + #"^/var" + #"^/private/var/db/dyld/" + #"^/dev/urandom$" + #"^/dev/dtracehelper$")) +(deny default) diff --git a/utmp_update.tproj/Makefile.postamble b/utmp_update.tproj/Makefile.postamble deleted file mode 100644 index f11cc67..0000000 --- a/utmp_update.tproj/Makefile.postamble +++ /dev/null @@ -1,2 +0,0 @@ -after_install: - chmod 4511 $(DSTROOT)/usr/libexec/utmp_update diff --git a/utmp_update.tproj/PB.project b/utmp_update.tproj/PB.project deleted file mode 100644 index 068e4df..0000000 --- a/utmp_update.tproj/PB.project +++ /dev/null @@ -1,37 +0,0 @@ -{ - FILESTABLE = { - FRAMEWORKS = (); - OTHER_LINKED = (utmp_update.c); - OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); - PRECOMPILED_HEADERS = (); - PROJECT_HEADERS = (); - PUBLIC_HEADERS = (); - SUBPROJECTS = (); - }; - LANGUAGE = English; - LOCALIZABLE_FILES = {}; - NEXTSTEP_BUILDDIR = ""; - NEXTSTEP_BUILDTOOL = /bin/make; - NEXTSTEP_COMPILEROPTIONS = ""; - NEXTSTEP_INSTALLDIR = /usr/libexec; - NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; - NEXTSTEP_LINKEROPTIONS = ""; - NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; - PDO_UNIX_BUILDDIR = ""; - PDO_UNIX_BUILDTOOL = /bin/make; - PDO_UNIX_COMPILEROPTIONS = ""; - PDO_UNIX_INSTALLDIR = /usr/libexec; - PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; - PDO_UNIX_LINKEROPTIONS = ""; - PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; - PROJECTNAME = utmp_update; - PROJECTTYPE = Tool; - PROJECTVERSION = 1.1; - WINDOWS_BUILDDIR = ""; - WINDOWS_BUILDTOOL = /bin/make; - WINDOWS_COMPILEROPTIONS = ""; - WINDOWS_INSTALLDIR = /usr/libexec; - WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; - WINDOWS_LINKEROPTIONS = ""; - WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; -} diff --git a/utmp_update.tproj/utmp_update.c b/utmp_update.tproj/utmp_update.c deleted file mode 100644 index 733c649..0000000 --- a/utmp_update.tproj/utmp_update.c +++ /dev/null @@ -1,147 +0,0 @@ -/* $NetBSD: utmp_update.c,v 1.6 2003/02/26 18:16:50 christos Exp $ */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include - -__RCSID("$NetBSD: utmp_update.c,v 1.6 2003/02/26 18:16:50 christos Exp $"); - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int, char *[]); - -int -main(int argc, char *argv[]) -{ - struct utmpx *utx; - size_t len; - struct passwd *pwd; - struct stat st; - int fd; - uid_t euid, ruid; - char tty[MAXPATHLEN]; - - euid = geteuid(); - ruid = getuid(); - if (seteuid(ruid) == -1) - err(1, "seteuid"); - - if (argc != 2) { - (void)fprintf(stderr, "Usage: %s \n", - getprogname()); - exit(1); - } - - len = strlen(argv[1]); - - // arg string can't be greater the 4x the size of struct utmpx - // nor less that the size of struct utmpx - if (len > sizeof(*utx) * 4 || len < sizeof(*utx)) - errx(1, "Bad argument"); - - // need an extra byte because strunvis will null terminate - if ((utx = malloc(len + 1)) == NULL) - err(1, NULL); - - if (strunvis((char *)utx, argv[1]) != sizeof(*utx)) - errx(1, "Decoding error"); - - switch (utx->ut_type) { - case USER_PROCESS: - case DEAD_PROCESS: - break; - default: - errx(1, "Invalid utmpx type %d", (int)utx->ut_type); - } - - if (ruid != 0) { - if ((pwd = getpwuid(ruid)) == NULL) - errx(1, "User %lu does not exist in password database", - (long)ruid); - - if (strcmp(pwd->pw_name, utx->ut_user) != 0) - errx(1, "Current user `%s' does not match " - "`%s' in utmpx entry", pwd->pw_name, utx->ut_user); - } - - (void)snprintf(tty, sizeof(tty), "%s%s", _PATH_DEV, utx->ut_line); - fd = open(tty, O_RDONLY, 0); - if (fd != -1) { - if (fstat(fd, &st) == -1) - err(1, "Cannot stat `%s'", tty); - if (ruid != 0 && st.st_uid != ruid) - errx(1, "%s: Is not owned by you", tty); - if (!isatty(fd)) - errx(1, "%s: Not a tty device", tty); - (void)close(fd); - if (access(tty, W_OK|R_OK) == -1) - err(1, "%s", tty); - } else { - struct utmpx utold, *utoldp; - /* - * A daemon like ftpd that does not use a tty line? - * We only allow it to kill its own existing entries - */ - if (utx->ut_type != DEAD_PROCESS) - err(1, "Cannot open `%s'", tty); - - (void)memcpy(utold.ut_line, utx->ut_line, sizeof(utx->ut_line)); - if ((utoldp = getutxline(&utold)) == NULL) - err(1, "Cannot find existing entry for `%s'", - utx->ut_line); - if (utoldp->ut_pid != getppid()) - err(1, "Cannot modify entry for `%s'", tty); - } - - (void)seteuid(euid); - if (pututxline(utx) == NULL) - err(1, "Cannot update utmp entry"); - - return 0; -} diff --git a/kgmon.tproj/Makefile b/vifs.tproj/Makefile similarity index 85% rename from kgmon.tproj/Makefile rename to vifs.tproj/Makefile index 9436b34..4b15f5f 100644 --- a/kgmon.tproj/Makefile +++ b/vifs.tproj/Makefile @@ -7,14 +7,14 @@ # and Makefile.postamble (both optional), and Makefile will include them. # -NAME = kgmon +NAME = vifs PROJECTVERSION = 2.8 PROJECT_TYPE = Tool -CFILES = kgmon.c +CFILES = vifs.c -OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kgmon.8 +OTHERSRCS = Makefile Makefile.postamble vifs.8 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles @@ -28,8 +28,6 @@ DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) - - NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc @@ -39,10 +37,6 @@ PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac include $(MAKEFILEDIR)/platform.make --include Makefile.preamble - include $(MAKEFILEDIR)/$(MAKEFILE) -include Makefile.postamble - --include Makefile.dependencies diff --git a/vifs.tproj/Makefile.postamble b/vifs.tproj/Makefile.postamble new file mode 100644 index 0000000..da87139 --- /dev/null +++ b/vifs.tproj/Makefile.postamble @@ -0,0 +1,3 @@ +after_install:: + mkdir -p $(DSTROOT)/usr/share/man/man8 + cp vifs.8 $(DSTROOT)/usr/share/man/man8/ diff --git a/kgmon.tproj/PB.project b/vifs.tproj/PB.project similarity index 87% rename from kgmon.tproj/PB.project rename to vifs.tproj/PB.project index 71ca9e4..5f5712f 100644 --- a/kgmon.tproj/PB.project +++ b/vifs.tproj/PB.project @@ -1,11 +1,11 @@ { DOCICONFILES = (); FILESTABLE = { - C_FILES = (); + C_FILES = (vifs.c); H_FILES = (); OTHER_LIBS = (); - OTHER_LINKED = (kgmon.c); - OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, kgmon.8); + OTHER_LINKED = (); + OTHER_SOURCES = (Makefile, vifs.8); PRECOMPILED_HEADERS = (); PROJECT_HEADERS = (); PUBLIC_HEADERS = (); @@ -28,7 +28,7 @@ PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; PDO_UNIX_LINKEROPTIONS = ""; PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; - PROJECTNAME = kgmon; + PROJECTNAME = vifs; PROJECTTYPE = Tool; PROJECTVERSION = 2.8; WINDOWS_BUILDDIR = ""; diff --git a/vifs.tproj/vifs.8 b/vifs.tproj/vifs.8 new file mode 100644 index 0000000..a5d2e1a --- /dev/null +++ b/vifs.tproj/vifs.8 @@ -0,0 +1,46 @@ +.\" +.\" (c) 2005 Apple Computer, Inc. All rights reserved. +.\" +.\" @APPLE_LICENSE_HEADER_START@ +.\" +.\" The contents of this file constitute Original Code as defined in and +.\" are subject to the Apple Public Source License Version 1.1 (the +.\" "License"). You may not use this file except in compliance with the +.\" License. Please obtain a copy of the License at +.\" http://www.apple.com/publicsource and read it before using this file. +.\" +.\" This Original Code and all software distributed under the License are +.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the +.\" License for the specific language governing rights and limitations +.\" under the License. +.\" +.\" @APPLE_LICENSE_HEADER_END@ +.\" +.Dd November 18, 2005 +.Dt VIFS 8 +.Os +.Sh NAME +.Nm vifs +.Nd safely edit fstab +.Sh SYNOPSIS +.Nm vifs +.Sh DESCRIPTION +The +.Nm vifs +utility simply locks the fstab file before invoking an editor on it. +This is important to facilitate the modification of fstab by automated tools +and system management software. +.Pp +Always use +.Nm vifs +to edit fstab, instead of invoking an editor directly. +.Sh SEE ALSO +.Xr vi 1 , +.Xr fstab 5 +.Sh HISTORY +The +.Nm vifs +utility originates from Mac OSX 10.5. diff --git a/vifs.tproj/vifs.c b/vifs.tproj/vifs.c new file mode 100644 index 0000000..59c37ae --- /dev/null +++ b/vifs.tproj/vifs.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *warning = "\ +#\n\ +# Warning - this file should only be modified with vifs(8)\n\ +#\n\ +# Failure to do so is unsupported and may be destructive.\n\ +#\n"; + +int +main(int argc, char *argv[]) +{ + struct stat sb; + int fd, x; + uid_t euid; + pid_t editpid; + char *p, *editor; + + if (argc != 1) { + printf("usage: vifs\n"); + exit(1); + } + + euid = geteuid(); + if (euid != 0) + errx(1, "need to run as root"); + + /* examine the existing fstab, try to create it if needed */ + if (stat(_PATH_FSTAB, &sb) < 0) { + if (errno == ENOENT) { + fd = open(_PATH_FSTAB, O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + errx(1, "error creating %s", _PATH_FSTAB); + write(fd, warning, strlen(warning)); + close(fd); + } else { + errx(1, "could not stat %s", _PATH_FSTAB); + } + } + + /* prepare the file for the editor */ + fd = open(_PATH_FSTAB, O_RDONLY, 0); + if (fd < 0) + errx(1, "error opening %s", _PATH_FSTAB); + + x = fcntl(fd, F_SETFD, 1); + if (x < 0) + errx(1, "error setting close on exit"); + + x = flock(fd, LOCK_EX | LOCK_NB); + if (x != 0) + errx(1, "file is busy"); + + /* obtain and invoke the editor */ + editor = getenv("EDITOR"); + if (editor == NULL) + editor = _PATH_VI; + p = strrchr(editor, '/'); + if (p != NULL) + ++p; + else + p = editor; + + editpid = vfork(); + if (editpid == 0) { + execlp(editor, p, _PATH_FSTAB, NULL); + _exit(1); + } + + for ( ; ; ) { + editpid = waitpid(editpid, (int *)&x, WUNTRACED); + if (editpid == -1) + errx(1, "editing error"); + else if (WIFSTOPPED(x)) + raise(WSTOPSIG(x)); + else if (WIFEXITED(x) && WEXITSTATUS(x) == 0) + break; + else + errx(1, "editing error"); + } + + /* let process death clean up locks and file descriptors */ + return 0; +} diff --git a/vipw.tproj/Makefile.postamble b/vipw.tproj/Makefile.postamble index de7e523..d290d54 100644 --- a/vipw.tproj/Makefile.postamble +++ b/vipw.tproj/Makefile.postamble @@ -109,5 +109,5 @@ # a single colon. after_install:: - $(MKDIR) -p $(DSTROOT)/usr/share/man/man8 + $(MKDIRS) $(DSTROOT)/usr/share/man/man8 $(CP) vipw.8 $(DSTROOT)/usr/share/man/man8/ diff --git a/vipw.tproj/pw_util.c b/vipw.tproj/pw_util.c index d22d94c..3af548f 100644 --- a/vipw.tproj/pw_util.c +++ b/vipw.tproj/pw_util.c @@ -55,7 +55,8 @@ */ #ifndef lint -static char sccsid[] = "@(#)pw_util.c 8.4 (Berkeley) 4/28/95"; +#include +__unused static char sccsid[] = "@(#)pw_util.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ /* diff --git a/vipw.tproj/vipw.c b/vipw.tproj/vipw.c index d15932b..a258899 100644 --- a/vipw.tproj/vipw.c +++ b/vipw.tproj/vipw.c @@ -54,14 +54,15 @@ * SUCH DAMAGE. */ +#include #ifndef lint -static char copyright[] = +__unused static char copyright[] = "@(#) Copyright (c) 1987, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)vipw.c 8.3 (Berkeley) 4/2/94"; +__unused static char sccsid[] = "@(#)vipw.c 8.3 (Berkeley) 4/2/94"; #endif /* not lint */ #include diff --git a/vm_stat.tproj/vm_stat.1 b/vm_stat.tproj/vm_stat.1 index 0a8ebeb..d68387d 100644 --- a/vm_stat.tproj/vm_stat.1 +++ b/vm_stat.tproj/vm_stat.1 @@ -2,7 +2,7 @@ .\" .Dd August 13, 1997 .Dt VM_STAT 1 -.Os Mac OS X +.Os "Mac OS X" .Sh NAME .Nm vm_stat .Nd show Mach virtual memory statistics @@ -23,7 +23,7 @@ each statistic (an count of 1 displays the values per second). However, the first line of output following each banner displays the system-wide totals for each statistic. The following values are displayed: -.Bl -tag -width indent -compact +.Bl -tag -width indent .It Pages free the total number of free pages in the system. .It Pages active diff --git a/vm_stat.tproj/vm_stat.c b/vm_stat.tproj/vm_stat.c index 01d9a62..ec9680f 100644 --- a/vm_stat.tproj/vm_stat.c +++ b/vm_stat.tproj/vm_stat.c @@ -52,7 +52,7 @@ natural_t percent; int delay; char *pgmname; mach_port_t myHost; -int pageSize = 4096; /* set to 4k default */ +vm_size_t pageSize = 4096; /* set to 4k default */ void usage(void); void banner(void); @@ -182,7 +182,7 @@ print_stats(void) void get_stats(struct vm_statistics *stat) { - int count = HOST_VM_INFO_COUNT; + unsigned int count = HOST_VM_INFO_COUNT; if (host_statistics(myHost, HOST_VM_INFO, (host_info_t)stat, &count) != KERN_SUCCESS) { fprintf(stderr, "%s: failed to get statistics.\n", pgmname); exit(EXIT_FAILURE); diff --git a/zdump.tproj/zdump.8 b/zdump.tproj/zdump.8 index 065a1d6..43344f2 100644 --- a/zdump.tproj/zdump.8 +++ b/zdump.tproj/zdump.8 @@ -9,25 +9,27 @@ .Nm zdump .Nd timezone dumper .Sh SYNOPSIS -.Nm +.Nm zdump .Op Fl -version .Op Fl v -.Op Fl c Ar cutoffyear -.Op Ar zonename ... +.Op Fl c Ar cutoff_year +.Op Ar zone_name ... .Sh DESCRIPTION The -.Nm +.Nm zdump utility prints the current time in each -.Ar zonename +.Ar zone_name named on the command line. .Pp The following options are available: .Bl -tag -width indent -.It Fl -version -Output version information and exit. +.\" =========== +.It Fl c Ar cutoff_year +Cut off the verbose output near the start of the given year. +.\" =========== .It Fl v For each -.Ar zonename +.Ar zone_name on the command line, print the time at the lowest possible time value, the time one day after the lowest possible time value, @@ -40,8 +42,9 @@ Each line ends with if the given time is Daylight Saving Time or .Em isdst=0 otherwise. -.It Fl c Ar cutoffyear -Cut off the verbose output near the start of the given year. +.\" =========== +.It Fl -version +Output version information and exit. .El .Sh "SEE ALSO" .Xr ctime 3 , diff --git a/zic.tproj/HACK/Africa/Abidjan b/zic.tproj/HACK/Africa/Abidjan deleted file mode 100644 index d4a349c1fe9c4862deb709aaca07bf4dddf2de41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 scmZQzzzUdvq96< ze1gb@6PG0!P8Q9)aB7QB!|C9&0cWN*Fq}1IxWL4S0{{R2e+FbW%LYak5Y52l;~T;d N?idmbCc#1s3;>dZD6;?n diff --git a/zic.tproj/HACK/Africa/Addis_Ababa b/zic.tproj/HACK/Africa/Addis_Ababa deleted file mode 100644 index d2a92208ef5cf51e85b3d4a83a0424f310a10704..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74 ucmZQzzzUdvq96Ntd~01k@K;1J2xLSG2$eY(2&XwUh{V?ji2BDf zFf%eCL1tDKAY^6*in4(iY|N|-3`~X~SMv!lvVdp?P8cbpz{m>{XApwO2Ka_Bgu4cV Th!6&65W^YBU|?hfYk&{{LM%mX diff --git a/zic.tproj/HACK/Africa/Asmera b/zic.tproj/HACK/Africa/Asmera deleted file mode 100644 index d2a92208ef5cf51e85b3d4a83a0424f310a10704..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74 ucmZQzzzUdvq96oc3ru=8PiCK%`kXJ@%mf&jnE(I(kix(KCRzUf|M-D{1EiXP T$HzB>!3l^R9YYwxffxn=LpBs3 diff --git a/zic.tproj/HACK/Africa/Bissau b/zic.tproj/HACK/Africa/Bissau deleted file mode 100644 index dd3c9dcb2a325ccc55367f10b2510dcd18269dc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmZQzzzUdwq96q%TmXs6C@`@2_=Ye9JBEO`3;<_w1yKM1 diff --git a/zic.tproj/HACK/Africa/Brazzaville b/zic.tproj/HACK/Africa/Brazzaville deleted file mode 100644 index 9cd21e9068e634b30e2f1bac5a59ecd385f17aab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 scmZQzzzUdvq96PcL?Nla#RO>mvkYBICV3C}t`1axmj@Yx6Kh+g)2JSQLs=*OC4 z1J_PqxEb=f#s?uxg3gX z)6hzJBJ{Wsj64$p;i^+9Y_(Jb*Te@gFL40%_VZv8GgrFSNx;^Q8&e-WRp!$^M%VGL z%=ghpy8gWi+K~T*Zmj%*HXZ!{H(z*$U_=%4OTLb_co#yc>=^R5IsyYk(P*n$1Prvy zVu8Jc%2cD6tTBvk|Gb{o#d92`gE6SlGa z9)2`I>c$ROIMYONAWHmgNDrBb(4nqnFlpQrCBHC$DeV&|_1Z8@d(?prXTF2!`PC>R e@*xB&|CNByQDyROW&)rtkx2c4MB+bL0r(4B&RUKD diff --git a/zic.tproj/HACK/Africa/Casablanca b/zic.tproj/HACK/Africa/Casablanca deleted file mode 100644 index 75cae561a23131c9a9829af98a33f4e96132ccdd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmZQzzzSG^q96=~WxhWAY6gu*=oa^htDBQJ-YG&^?t65Ww zoo2aY${%ViD`T0pH8nMB)rwl^>r-p}59@A>2T<6-QdvN5+7TU2MZ zB|Be#QNiEn(B|}r=J}o(wa`1(EttB+!tM4XzOPXv+__jH^z%M^|J%!kC5bL(X?UKu zEvYxyj+6>(XYHANu2OIqi#9kmf92ObPd1RWlixUKWS&hRubOk@tYrf{auNM|R8P}4e$T2mY9s=J_X)`MfKtp32bzgUY_{~s(bXptjv)+=+RVRnqU gdvgw!p4p`4R{r~^~ diff --git a/zic.tproj/HACK/Africa/Conakry b/zic.tproj/HACK/Africa/Conakry deleted file mode 100644 index eb111e38700eb7733cee4d9133f64b7bc4e876e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95 zcmZQzzzUdwq96feDOE|Np;V!NBnU|HlsuEFdKe96r7w433T= J4Bhvi3iBhC;^FT88EQ;_=YgJI);F_3;<_=1vCHv diff --git a/zic.tproj/HACK/Africa/Douala b/zic.tproj/HACK/Africa/Douala deleted file mode 100644 index 026ade8c3121fddc921d5d3bb2cb59dae556e809..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96CP0|4cq4>|w< diff --git a/zic.tproj/HACK/Africa/Freetown b/zic.tproj/HACK/Africa/Freetown deleted file mode 100644 index edf47b068a6844c78f8bc779da03ac46ab6ba727..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmZQzzzSG_q96Fb2Mc~X{UWVsAH3Bb!8ya4m*;DY! zWDCQqweLT?5q;k9reC?>?T?&>cZDko-rron@FD2-hmX51H+(YTFJNLsgDlKQ@c;kM tQ$WsSU|?kV|Nr9$22KVBJ^@Bvu#k|OZwP~ diff --git a/zic.tproj/HACK/Africa/Gaborone b/zic.tproj/HACK/Africa/Gaborone deleted file mode 100644 index 33adc15d137c5fe53f83cbd374bb95e68fbeb041..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79 xcmZQzzzUdvq96b%6zpKtUM=kd&4IBTKMj2t%-Aa0rOc006BB2Ppsm diff --git a/zic.tproj/HACK/Africa/Harare b/zic.tproj/HACK/Africa/Harare deleted file mode 100644 index 149b559d14040658872e2c406426f2acf59fd8af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96jeL zyg~qng3|*|hTsca3@Q(}9<~Q?KVW;nbA%^=cmInAd`s;w@ULV|5NIn75bSuKAe6rB zf^f#k1Q9Ro3!)yY6U4OR1H?6Y6C`*hU6AC+Pmp|jEI{gG_XFt*-T^Wfb05fVth>O( lNB}Z0$Ta{R%b;bz$il!NqrkxF;~T=@>KY6pLO?P=003adIeP#A diff --git a/zic.tproj/HACK/Africa/Kigali b/zic.tproj/HACK/Africa/Kigali deleted file mode 100644 index ec75652ab4bdfb8896068643320001e967a11784..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96pKS^)F_ diff --git a/zic.tproj/HACK/Africa/Luanda b/zic.tproj/HACK/Africa/Luanda deleted file mode 100644 index e831304798eefe388a8129e63f0f02a68caf1cb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96Jr`tlmi*98_ZGBGkRNS*-6%P26gFfeEtFmm|#hA;#> Lf^cvMNCpT1lU)l` diff --git a/zic.tproj/HACK/Africa/Mbabane b/zic.tproj/HACK/Africa/Mbabane deleted file mode 100644 index 18f011aaed80eeadef2601e1a7b378a56ddb750b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96=3Jfehz99_3jv*i}0{~Ft1X2J1 diff --git a/zic.tproj/HACK/Africa/Mogadishu b/zic.tproj/HACK/Africa/Mogadishu deleted file mode 100644 index bac76c97a4fb5471a0be80c1f47027ea663dc891..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92 zcmZQzzzUdwq96_)?i>^U{G7bz~br{!r%lV GAOHY(5eno0 diff --git a/zic.tproj/HACK/Africa/Monrovia b/zic.tproj/HACK/Africa/Monrovia deleted file mode 100644 index d912dcde1f1f82469ee6656f8fb868993c72496d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmZQzzzUdwq96~j2u3`Aq>ur LARHV5k^uq$FrWy_ diff --git a/zic.tproj/HACK/Africa/Niamey b/zic.tproj/HACK/Africa/Niamey deleted file mode 100644 index 2d0febbc3da48b3f989645682b99b7746ada78d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95 zcmZQzzzUdwq96e0)O~oE<|L I!hsk90DhVZiU0rr diff --git a/zic.tproj/HACK/Africa/Nouakchott b/zic.tproj/HACK/Africa/Nouakchott deleted file mode 100644 index 002c7e52fc51cbe5701535f4cfff0a44003e9074..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95 zcmZQzzzUdwq96mDctoi9*!VSb=u!t_B^)jUDXVfzPlwyX#0^@lzf#4CfF?H6R@4WNWiYmae{rt)d>z6$0j&N zM@?|@{3YOQ(Ca66EbdVPsluZS|Dpryg>G>)9Rvu8F4oLgkdaDI}Bz=h7o4=xso30(3MOW-|z{{vs=ngae+DIWw%qzaT4TYXTr z(fFXEBl$s9hU22L0W5()4P TVQ_X01`#0)42+B*l|TRhf~zzx diff --git a/zic.tproj/HACK/Africa/Windhoek b/zic.tproj/HACK/Africa/Windhoek deleted file mode 100644 index 8897d0508aa82fb01ab5a3957aba83c1972879a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 532 zcmZQzzzUdwq96gZ+$TE_`qP8_PxMJ;}V0h z+sy(K!FLU&YP$!LC34 zgMCyfgG0XK2S=-L1}A^z56)7S3@-YtA6$M(Gq~|R|KN7>FN6CJmI9B%k`12MpA~p5 z`rY8Y{X~IJ)7=K&>8lF-lJ+E?oSJ@y+=z}6kFL8l&}UiluF4Jls+|XDEq}wP<~Xjq2lJFg32Y| z8>)65DX4C_*-*3S!H3%1Zwz%!hd$K%-e6#4q7`Id5S0K$sf+>xD+7a;0V8K{xMK)I MFc=4ifTVx`0CoSXdH?_b diff --git a/zic.tproj/HACK/America/Adak b/zic.tproj/HACK/America/Adak deleted file mode 100644 index 8ecd096236c59ae8f8c7e4dc315cf8a3f430a00b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmchLYfQ~?7{~voPNfT7bdpqbp`E0D-HtBgIhAhe^si2LszVpuJ4H^a)0&uLnlKdA zMjNuF-*QXG>|rBj&Do)?lOcwN8Ox>Cn zrhV^OvoGUlKB3cC=%!&Ysx?b)>cFyhjJ4`egSBdiwW;fZrNy1BZDtb)VwJ32und+7 z^H_V=MqF+h&N>+6qQex6D_;9kN39<^-4#&h0b5*ocABoLjRu!y9d%6;f?LTC;x00W z)p28Fjo=e_cn%Q{&J=}aokaNJBYJ*NlC`%-(Cf)*x~{t)y{|M-ALUUb$8)G}(Pi+f z0qP&!1_3FqG|;0OME-ob-b4yPjxHoDJzNu|xlElS%T06;KcsN(yZbVUe>FDVi$7opT&1 z)=IGC`72U7K(Oro94$X)gB9mr(n|R^tU7Rq%CoJZy0C}VgnWfvQTyp`hf%2YIY(+| zZ-BzGg(${5pzd=a**jDZ^^apnL(eH}?Dr(feRbG$#Dee`1H*sCi2onMaRn^Ha9m9u okH6rH7Tkj4nyYwLdS?WZ6e%M~monk=J3La##E2Kh{Picl0rdb8Qvd(} diff --git a/zic.tproj/HACK/America/Anchorage b/zic.tproj/HACK/America/Anchorage deleted file mode 100644 index f3ffb589e67e6ed1a2cfb4e77dc836c42162f953..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 826 zcmchLeJs>*9LImoaj2X;lsxq%oD=zY3>ClQoDRh~c}Sij^6XL~QqmeL536iUYhP+)}OuKd%yPjd>H1hG1Pu_)1^r}o!hG$ z15}e)VX!tCNjC?xSxt`wnDz)(ufYvCl>$~@Ax3UixXM80iiRQ=70=rUc}*EAW3weR zR?e~}-zIR|yjrz=W)XI%lq%C9HSl}KS+fo$>}>2~&8u3#BEOlnOi_T9w2a*qB!}I? zc-Gpf6!#eWu{InT+N^}3?MD}CH|dP_&w13L-w^k9EmBeu1derT>Xc{;`wG4iXa5aw zi5e%aRv$p%-bVzR>nJp7Cc^h~=)P1&_CI}w9#gld=lw1`Fi=9hYU>g1#8K}&3O?mN z)Hm`P_{lA)zaR$!e16b_JP8EaS&+alZVBuAJDXF@zlu6YgSIq*r|N;;n1_)hXC zSuB{FB8B}8v|64st@OK+h}?4Cpa&;NH5roL50^{QnA(x zmHY})`R*oEEhm#p!^KejDwxzfXvE8p>_}~WAzo?TBzg=-|6euW{>N%G<(Ukl(bSdc oakt!f%S|j*|NqAX7#RNl-?@Q-<^TWV2N*bfd_x#q LgF_e`ffxb+@c|Iu diff --git a/zic.tproj/HACK/America/Aruba b/zic.tproj/HACK/America/Aruba deleted file mode 100644 index e2ecedc8af841322fc9e7608086ac96777496261..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmZQzzzUdwq96WjRzys|Nr|u7#RNlKd^&=<^TWV2N*bfd_x!< M{eU<)1f&ND0Oz3)xBvhE diff --git a/zic.tproj/HACK/America/Asuncion b/zic.tproj/HACK/America/Asuncion deleted file mode 100644 index 5ec5c8b9e6950bffdf35d41d51b850f26c47c586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 719 zcmc(dZ%oVq7{`C5lTsmaom7-0IX%a%KlgePoDNGxg=*7*N zWtug+O;2palAf6*G1pkVIL3Id-;MypHYp zKs?hb3b&x^+%&nH^}N_PLLNOo+0$SHuQn+z$(PYmeGxC;F-$9>CFm162P-A%EOv_^ z@oXddPL+b>?R{SLauWO=NAv2te&pYw#egfB5ZKtkYjkI6ZSfln%5kOOWDTy9$3loA z7T5b!QRu=!4E=r!HdrrW7%6F^d4R(oy1^!s38gv@+T8M21SEi!()ilX3K;W{Mf_rwr+k#aq{Id@D%d%nn7(;EYMqZOEM)KWoDI~N*m!rp6U z+*c3+`;V)!C{9Dgxy@YS-vXsk{a9)nq%vPCmwim8gTHFH{D}c7-gRMRr-=>?SorYy z51{Sv!XxDepsJ}2tCdF5l??IGuorMFX%=hTZKMy8vi|cqs&&1`wXgc%#N-4Tx~J&m zh=l8|2EZwk3hQe+;q>L#*q|P#Gu0w?a&}tq|6;d4pB4nW{TT}`cKg`q-*#H0P^pEi MJcl`I$D97)H{c`iuK)l5 diff --git a/zic.tproj/HACK/America/Atka b/zic.tproj/HACK/America/Atka deleted file mode 100644 index 8ecd096236c59ae8f8c7e4dc315cf8a3f430a00b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmchLYfQ~?7{~voPNfT7bdpqbp`E0D-HtBgIhAhe^si2LszVpuJ4H^a)0&uLnlKdA zMjNuF-*QXG>|rBj&Do)?lOcwN8Ox>Cn zrhV^OvoGUlKB3cC=%!&Ysx?b)>cFyhjJ4`egSBdiwW;fZrNy1BZDtb)VwJ32und+7 z^H_V=MqF+h&N>+6qQex6D_;9kN39<^-4#&h0b5*ocABoLjRu!y9d%6;f?LTC;x00W z)p28Fjo=e_cn%Q{&J=}aokaNJBYJ*NlC`%-(Cf)*x~{t)y{|M-ALUUb$8)G}(Pi+f z0qP&!1_3FqG|;0OME-ob-b4yPjxHoDJzNu|xlElS%T06;KcsN(yZbVUe>FDVi$7opT&1 z)=IGC`72U7K(Oro94$X)gB9mr(n|R^tU7Rq%CoJZy0C}VgnWfvQTyp`hf%2YIY(+| zZ-BzGg(${5pzd=a**jDZ^^apnL(eH}?Dr(feRbG$#Dee`1H*sCi2onMaRn^Ha9m9u okH6rH7Tkj4nyYwLdS?WZ6e%M~monk=J3La##E2Kh{Picl0rdb8Qvd(} diff --git a/zic.tproj/HACK/America/Barbados b/zic.tproj/HACK/America/Barbados deleted file mode 100644 index 287748edc12057019339b533665775fc892b6dae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmZQzzzSG^q96!^xncf%>jw*518*#>mwm8EFE3(o-2Vql_yQu9+C6-* z^qo<}a`k@+%g>2KtYm+XuyXCUh*i%IC9IwWG~mcpmJU9~-gzre?yP zdi#jIJGm3~#VbbapYb-~fIV}>!HV+L#!-vO2}hqlzHwY}{e$Dj zkKQ=RIPt;B<;!oJdRYA6^n@c3XAXuwI9sqRf<5VW0{hMj0TPLY2@sDG^ct diff --git a/zic.tproj/HACK/America/Boise b/zic.tproj/HACK/America/Boise deleted file mode 100644 index 19ec977fceb44ba93c01e94b5ca77e047a553fe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 849 zcmd6m`!5v$9L2wv>zVQ;lxIS8rAXwF9^{?3D^husM?~JD!na7%l&_kl4EJU;YUR;d z4?VQDria=z8(LCpF|}%1Bd?p=`msNt&)L~IJHH=*f1r13xgJ-TzwLsu79)UKLlm5v2Zh6PsF-Cy z!gzgF3YjJ4Z8NN5H%uy>D_9M?N$pw(s(-&si$#J5tbWl^|X$1+9t` zs9l%{OH&e1XO|D?`gx?J!9IbqDqx}#$saT`4;UqYZYM{%^Ah&r~(~ z3C+oGAP4G27$Fs7<5et!3FvlQuzr&;~hCHtp~#0m$5kD3PhOx;+-~? z5D9NMO1FigM(*>jpQkChyODSIr_r9)d${*z5XDq9U~G*Y#ibC&7YD*VzkRqr#ugGp zo|w2r3zD?sINA6IBu{wofw_K2>9gR}x3}P6r!uEKc}?lnV|=LjCS_zjz>% diff --git a/zic.tproj/HACK/America/Buenos_Aires b/zic.tproj/HACK/America/Buenos_Aires deleted file mode 100644 index 5d4eefd5866bfce3e62934687436181f7b4f5dc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 427 zcmZQzzzSG_q96$YHzG$qhT?`W<#$DKOY2UVC8I*2Nok|JdlT zXWDgxy*Hm6*jK@|VgGIkhXYal8xGE$>u|{Wu)*QF3kQzKeA{p|fyLqIKP`jfj^+oB zKUi;YqH&7DDc^+~PQ7b8aL)I?!MP1@4_wwX-EhS@<-iwP4udcAza99>nq%Yf#C^lvqC~==ypgd*k z1{HxR3slWNZBYGCwm@Bx-$4CB!~#u*j|Q3>tQKfJxNM+3GhBg@iAc!8j067vfA|Um q!~g%s4=}L&|9|xYBgg;$j~{@@s}~qpoP9$W9D_hOI0O^{PyhfnUY=Y4 diff --git a/zic.tproj/HACK/America/Caracas b/zic.tproj/HACK/America/Caracas deleted file mode 100644 index eeba277f55218816549d3b2e6929093e2e6e2796..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86 zcmZQzzzUdwq96$YHzG$qhT?`W<#$DKOY2UVC8I*2Nok|JdlT zXWDgxy*Hm6*jK@|VgGIkhXYal8xGE$>u|{Wu)*QF3kQzKeA{p|fyLqIKP`jfj^+oB zKUi;YqH&7DDc^+~PQ7b8aL)I?!MP1@4_wwX-EhS@<-iwP4udcAza99>nq%Yf#C^lvqC~==ypgd*k z1{HxR3slWNZBYGCwm_5Nqk-lIs|AcqL_!v3Eb#yT!&ev>{{KIIfPv-z|Em`mIsX5D Z`~XB=y}-cY>>I-17zDz>A)vs90stS)n2Z1b diff --git a/zic.tproj/HACK/America/Cayenne b/zic.tproj/HACK/America/Cayenne deleted file mode 100644 index b979bd15d85e8fa63e08a97e7e6f34dd0a4b4bb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86 zcmZQzzzUdwq96iAJ>mCZ(*ul5|No!+z`*eT|M3G1EdT#sy}-cY;~T=@ K?iK=44+H?@2NA>o diff --git a/zic.tproj/HACK/America/Cayman b/zic.tproj/HACK/America/Cayman deleted file mode 100644 index 2db156478f6d33bdc8977cf5a18fd9d56f69c873..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq969=0v`NY|jai$F~JP3!(_+h?iS5KFGTR6+P1ukox#B8Hd$d(rJ74>s)r6ZNE z4#q)lStMU;@PWKE56&;Nfr8kzeEmCbx)JD(g)!Fjy~rGkb}XSEgbVSeg*+9{lwyh2 zGb-tpV5z(ulvY>b?Wf&vC%=Qss%oG-xq>S^o8WGN1y&{;hI@_)T;;bH?i&VhwZk{` zqu>*+F$kub5r3>z-AuL3B7E?*lSx)=ewY!e zf^t5}B){ba&a`??3M+p>g(E^zQoDgl*D_%ie~ZeJ6Qt5oz^WDdX?DqR7UUcUwbSAJ zPEt6`iQdNQLEGS64>Q&fo59>QnmkWW6Xxrh;sV8S(3D+(ngjDmt8)w&J{+Y*ciU0> z`eRz0QI0wh0(kFW2I{)LgeAN0@KWOjc;7yqmuVD%aQQ(NN*|KmEML~^D5T}RcC25P zN-G+6qCr|DeOPFVhOr*B^29RyC@=z6?NdY}kvpt*>P2IrIhd^a2~8Cif|*tin{`WJ z%~&m)S4&`RTP|DVkJGx+qimVnLF>;VTZL4Rb;1$+*zp3{_=TXYVFKCNZp96P01_=V zLeWS(h~+d;-0TnbPlj=0u?RNRsk6f=J=mN(#EwzQu;uV0-s&SHr{EHHwpJpSO=sCv zr;oO+IKXaDNA4PD&|Q*G9z!wcS&>598@+HxP9A((WQATy$G|&P7e5OM1D{w+-YIqg zUoRc@(=!2oOIZ$><3xdro^s&8YTEUtnuF@+((d+b-gA9~f~)W2=P9kUH|sKngx)4h zOu|sl76=R2gZs=&A$)@a?$I2dJ2K>b>8~E~P0mo!|(}BE~ z92;*wp)&=Y) H=fC(HgUa5f diff --git a/zic.tproj/HACK/America/Cordoba b/zic.tproj/HACK/America/Cordoba deleted file mode 100644 index fd2d7687fb9fa4726497bb91eb741ac2543892d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 397 zcmZQzzzSG_q96$YHzG$qhT?`W<#$DKOY2UVC8I*2Nok|JdlT zXWDgxy*Hm6*jK@|VgGIkhXYal8xGE$>u|{Wu)*QF3kQzKeA{p|fyLqIKP`jfj^+oB zKUi;YqH&7DDc^+~PQ7b8aL)I?!MP1@4_wwX-EhS@<-iwP4udcAza99>nq%Yf#C^lvqC~==ypgd*k z1{HxR3slWNZBYGCwt$g|NXWvB0ssF$e1(DG|Nr9$7+C)Qzj}d@^DcfN<{)V1nIO15FF;sKJ3)AQK!E!62MHQ^+b(F9A41%DbmYA&97Ox5B!~m8`TPt>?!WbMPg^c3j5| zJG%fHPhp&_fHoGEp(>~v;xQfLKjuS1L<}Z8Nd|SWj@389A@Q@4lbQwC+#kZp6=AgH z=6Bwj^@p~d9%hW4pzXFPOj+DZ8vPJzrmm4T?jC9fn<;gv8&mIJg|ulW>MopwUBf0! zud+bKLkDN(=^*Qpk#}!WLUyg1^%1F*lfQy<1qB%ry=<6}k}>oh8+*QyDR2%=?JsE0 z`*F;7by7iZ5AH1;gnd^o)1IJHb;o5UhWNqhSi37~(O>F*Tgc7BhOP;F1BGs~` z(?F$Pv(>ho%DdL!;cO2baZ9iQ#;Ee>B-%n}!JhjZ?Xz#ep}LEX(Qa^t zJ!9vCcBt~+;p)~Vs2MxMwKZm_dsNBw#V$J5mctDxMdYfF=YYWfA5k1A7X(r4V`081 Vjtm7zGBOQ9Uarp_2LIc9`~@u-;UWM4 diff --git a/zic.tproj/HACK/America/Curacao b/zic.tproj/HACK/America/Curacao deleted file mode 100644 index 0ea02cd0037762a1e0da50fad701243ac98be508..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmZQzzzUdwq96_;+QL}YMDjRy{_&6heZKqr_WgYYf`6i~U3Kbc(5maAuE9}N_mCa) z{bj12UUlPWi=#@N<%wTi6*TAA3kGf<$fU3mP2~w7lEtH$pAVQzz0txpj#e(QK=A@E z63=+@s#oS@sW#))H@}h9z#LomOcE-b(WdD-*(MsIUC{*CdrhN5VS39q}m`Se68g^?BCinbf=uu@)>m#bsGj0)iNfOc9 z<1P6Z_@b|+KKM?F(eL{d_>cU+4U>0ZqsoE2U*PO|YPjC^B4TLyD5>Yf{H?Fhqd{l*YoE5Vqura-o=9COkGAXgfTI|HpD&$yKHt%Q(26T<~RUqhkVgNvTshFup-xp?Fy zl^p%TrDtwYS;aV)H=m}8R%6>UO~j Td1$;q9;Y=_TVix-pTGPDs3PRh diff --git a/zic.tproj/HACK/America/Dawson_Creek b/zic.tproj/HACK/America/Dawson_Creek deleted file mode 100644 index d9648458b3ffce21a946192e96b99f6e0fe52350..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360 zcmZQzzzUdwq96;EkHP`F#*WBbx0s|vi ikm>*bxf2)}{{Qc9U|<2U88`x5LKp&qLl}I47y diff --git a/zic.tproj/HACK/America/Denver b/zic.tproj/HACK/America/Denver deleted file mode 100644 index fc45907a08f34a2225e5557f3083d2dad235602d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 860 zcmd6m`7ag#7{?z+u9Qbb?u774y%IT6AxGqnT;<9Ukz8+d@Dynpd2}o#a?QxP*HSuI zo9R%SW)n-Y7O7RMwcKy-Tfg=P^!e`l-Dl7555PZ>lU${ha#2#LtJX9*@}+h~sx8*z zx(gqvK4Fd>%YUH&EqUJU_nPAFT7g^YAv;h=LWpzDdDALE}N3M}kh!~Aio`Z?)J6z#?6-+fAqnQPR z+1y(esAPg*sFN+mgJI>v2DW^)k5<(jV3(pQa`nH? zo8u3YoA4C7yG4_SS~h!{xRB>W1$xOFlUIKhdcU7XTiZg=r^g6z@!@L#`Gx*maB>7d24rL<`MXm4e{OKQsfbSHq;xx_i}H3oPEv10N|aVES!E5I*pS

6E)=3S1 zdxiTu8GAuV&pl3YpU_B3ws9a) z8L+oyKY70&VISpXTG-XYzAq1vU&|NtzqFMW?S71l52jH-UK=i{Du<;JdoeI06(r6@ z7$gaVV8eI}v9X1a@9SBrB?4(*9ET2mg5~Yr9QII~!uMP7ilz?~vGE5-*4(A2RCA2Z zIYTi4N|c4wQta#jjC0DPmBKZQH?4tqYQ%(ZxscddiAhf*Vb$rwoP6FDQmQL>^*$2- zMLMUJxlo!kh|^PyDMM_}nf_lX%UFVPt7jx1wZk<(+ey)@gV_TIXl?5d=5$?vb@dN0 z_hbX)e`v{b5&vx1IFb*EE9|4$o*h0BD% R7?}{HcICJdnfl-V@*4^9BA5UG diff --git a/zic.tproj/HACK/America/Dominica b/zic.tproj/HACK/America/Dominica deleted file mode 100644 index 3cfb60adeca6c7b3a9fb481f33eedc60ea285170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq96hV;=}m=|FHrFhX4PMA7Ehd@eN^c3=RP)VgLZn{|cx8 diff --git a/zic.tproj/HACK/America/Edmonton b/zic.tproj/HACK/America/Edmonton deleted file mode 100644 index 308bcaebae9fac91b5628be0fe6a5246478586ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 845 zcmd6m|4$467{=e|>p6OhqEu4pT;d`pB^2pgx=P(qA&%;lQba3MFO|uBd1DQ0)m2I{ z3Tq-1wx)dBvJ8>L)M8j>B0AUa{s5n6pY7T6`vdS##_HEmM>(T+vE~X={>5B=)-eXRaE2IhBYI1;X#3rJJeI4Q}qs?Ilh8l zL%VUfKN3b7y-`*Zixt3^DM3l;?j&@wX)CMLwo8^eJ0Hp6@&HdOe?*Sy_Befi9XY9V=$!ZvT%>PtM$jd2wYrBQHwMwj8x{+8g1Gw* zyA3E|*6m7mf0|0OOY?co)o_wzYuMxDe44At!+B}emx(^Zl zlUW&j9#oD$d5!xKSPNYoX;nj!J-0aO`(cW1DdTmWNwmK9CT?g5p_qbF+*ss6n-U1s z*$UV!-;7&gBoHeOz_=wA5O2AOHTK^?Gq{Ym{^^8-4i`>*eGRr_B~LxsSRLa1j7IS*Ca47{Qtjm b10&1-|Em`;aQOI!FgUvaac~GwCkOxlGny72 diff --git a/zic.tproj/HACK/America/Ensenada b/zic.tproj/HACK/America/Ensenada deleted file mode 100644 index f9da0ee658c261d64c7f8759f0dc80e01f619b28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 537 zcmZQzzzSG^q96A#4R5T(8NEwG>6 zE8viSXMtnO$_Y;X`xZE-bWd>6U$DT{C3k`wf71eY75@qDKjtfVvKUVAywRxO^+b4r z_l{%*pR)!6zB61E{MHHy_*bYa1oV6n2uyTd5R`LGAlOlLL5R-|flx*E1z|d~1i~3! zE{G7_HX-7{=>?HrXH1AXuy#T8)v5_GD^DrJZjG4`*SSU^eyZJsgv>sL#JXsKB+mkc z2iz$>7N1?Wc+#jRR}%J*IZ zRlDL9s?X~P)GV%EP`jQ_psqP~L4Dr`0Y)YuWTpZ9|9{dN28RFt`x_Wo{{Nplfq?@= YGV=KNhA;#KhcNg8aezw*FrFa*0L~Dr7XSbN diff --git a/zic.tproj/HACK/America/Fort_Wayne b/zic.tproj/HACK/America/Fort_Wayne deleted file mode 100644 index 3961e6565c64ad60c80755558524f8e3d97afdf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 269 zcmZQzzzSG_q96SQd<_d{-7Yv4uGDbqhI_&3j(-i85;;Fy zF8$1K#o_gbtD#pJt|^@TaNTq}!wrV@A8v}yWVrcY;)h%Rwl>^8Q2gP}z3B~iS57Fn zx399{erHj^gL%;n4>Lmw9@W`4JoYpzcoHYy@Zyu$hga+j4F7h>eE7fo{{x2U|2{Cb zKYYNz$iT=1#!NsO88S06vjE}$|2sD@GW`F)dI19qn9Ttq8F>ExKYoBwz&SjG!8sU+ OT|yXKfwU`-MgRa~zhqwk diff --git a/zic.tproj/HACK/America/Fortaleza b/zic.tproj/HACK/America/Fortaleza deleted file mode 100644 index ed1327b39c2b5971ea14eb68ef551d8e315d7cee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmZQzzzUdwq96&LpEjso rIj+FSga!WpfBOXk!~g$RFEFtD|Nr;_BZrS~2!m@d5W9qcoCE{_M_V{g diff --git a/zic.tproj/HACK/America/Glace_Bay b/zic.tproj/HACK/America/Glace_Bay deleted file mode 100644 index eec6e75ae693ce49b9aef77d1dbe34da8bf9f35f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 775 zcmd6l>n{}m7{-rCLb;UOOYWo&aydwDCpsc;E^#Qmy&9NttpdI znjN*NEz?WclHygH4=oj~Rf^L&-}?jlJ^O9Xp3jd!@K4m0t4bC1N>yFAYW9YQtfvOA z$Zg>HsrNX7GsLn0oXQq~27bY%Fanx^!??`#E@)YG;d1@+pe<-d?XP8^!=f;r50o)G3Pa+MKX3=U=wR|Fx8r5GqnXUoBf04 zQ$q2JlhaDJp7+=;yqfHdTG+ukog5as(Mdau zoF*=y^G7Gz&{vKwFGFFYED1MtIfAglA6=WY!7WqD?uDOVbC@4{L=Sp-vMt; z1&hoFNi;phKEFH2ci;*8ji040w;BC=3u)__#~5%amICvyVbI9}2#%`7khB;O3$t*W z*b_qa!ZFO&7{Y#LutfbANM3K}@DJm#qsN&e27gdwi!SfHHAYdTpBWl@X;+F4M(19p zn7|o~ji{tJs~5Q2C57SzotR)$0SVlM((ed~@?uOH4Te4Kjl8$p7Lx0Vcwe(7V0Ij* zR9I80#GCggYfze#DX05SQ-+}zW?DX@%sCUxTDVEs!}FN)u7M78zQx>ucF1e&!-LoB zA-~`%9;(fQg2YE$m=Og>ITJTRa_#Bq>}kmF4GfI*&8vJe=(pV5AFHr&^J2P x7J|n+MyaCO4l7UJrzL9tO%#f!g93pI9a2Qt14Mdn&#jvS(hQF0F!WqDo_h)le?{`Laf8^@6=UmhD zh*35Dj4r#(nBq~yntKta>_dF+X(WVnLJ@0)!ev8ZP#Y7+N|5x+!sG!J*1ga(#crUo zFPZC`)0o;3%ncPXrZpvDV}_WjvLI}dzh}D2g$(gSs%5XBo_L2$uiMBR9>nJH3)teg z1kKPbYFk^7)pMR(O(tZw9A{3!N#+{MnYY$Rokq=Vk}T#&MlgRmntJ~X=$|d%_Nj2} zxc-fW&N(RR@J5|@53x+zj&h}g6+YKk8A4WmIKwKJ znR^E7xOYs)eHRO9d{B-3CzLeV^KhU_%7e`bsLn}&xk7?NF`=kQ|AAUx0hTC#TE4!4 zb^bK1Bll1@G0MYN?Km>r$NKg=Y;bh)Xk9mLtu~6hXL W$L;o5qtyuoY7cq3nc0a%fAkx+x7IrV diff --git a/zic.tproj/HACK/America/Goose_Bay b/zic.tproj/HACK/America/Goose_Bay deleted file mode 100644 index 56102d88a46d60c6d070bf0e71b061ace0a8ce86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1171 zcmbu1dr*{R7{$L8ToBRa5{XHM$ z;H@ba3Z|ebjWKo0+7?aNOz{DvJ_O+*awAf?N#F{6vH#Uf|1kZ|oHJ*hIrA{ge_}Cn zHQ7Y#j7{C)!<)(0r)vz8YK^MAQs+{lRYzv&F7#*`iqz7}CmJ+Yxc$-}3aT|%70J@Z zM4h6^Q7P32eysRWL~E}tIi$GO8&dmIwX5QWpS1Rdaa_|};!+FtZz~|-3n>_bG_9FS z*|xWo{H+KxwmsdG|5s= zpcZPe@+)HLc8<=oIYF$LVwiWG){lPwC zEj|(N0uJHM_@rVQ7D=bj(cPIWw(LPC(G+nSo}|vbJ;bG@o4PhMkf-W(bje56#4UdW zmmYY7xX0bXr!y;b9)1^aS;Rr`bU1}x-n+nS`aG3cg@LU5B=sJU!86)o>eCiVmaDhX z73ZWxt_q+lE3AlbT0E}GyGNc4TZhkWZYF+SuDE*Dmt>7tK!x*lP#Ah~?c+1x-*^Sr zb-oABpG6vQDGy#aa+wBx5DP&$H8l88E(wV~OxLHx5T!hwZczG>P)P(0^H@Z}CQ>on z>=6m)S&ZoGBpWr}xas;hM4qz7sLwkfy6^##@=Ney(tNr(>omj!-KVjeN+HheCf(wb z1Y4PU$~mYAhZQt_jFJRhKHb(HLSCvnirde7kR4@vG4Z&V(2O`tQn^EN_!``~!yHm% zi*Z+g0aEQ&(==B-q>VVz^r_Dvqs2%w@07#t`YxK)SVyvtYU#_LyhCzwtLUD?*(5jN zTg*$1CVTzWxG&U~~}eeFy;s17cp zrSDz@M#PBbnEemUHJ^pVv)In&??1PK&{ZR11flsDV@ka#yLgegAhd(XQV^PSjI|*2 Yp~xmGCYFg(#xlVs&-7sBO!+r|1J(V@yZ`_I diff --git a/zic.tproj/HACK/America/Grand_Turk b/zic.tproj/HACK/America/Grand_Turk deleted file mode 100644 index 4cd05a2d8233f1a31e5ae67b2fb3351432b37c8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 675 zcmc(dYfQ}n7{>p}EGcKw&8g_d>2z^O<&@GJ=d#m9uR7^MiY`YN>KwYEV-#CvqFg>? zhBma3Qf^CJlV#L>3ewNq!)-d)-y z{oj|h=-90xoR*h`v3u@P^3b`mr}8U#g-o+|pew9!va-}+8l*E{(C4)ke65UrBYm*4 z_dc$=ei8g@-g3b4Ita|Na8P+W1xMfJ)yXxq#^W^0LbFLWe+%W#u_T{t!O)LB6gFIe z;p0k(xSED*`=p>SD{x)gA6Rcl;YiaYY|ut2o9FJX7y9=O>ERmL`~K2-q5ylys? zCc(kDb9_h>1T|6<*D4aJ_LrXPB>`0bJcb*l9qI6pHy;^$M@KuOv9WuU%uQZ+>}(e; jaQH6~#X%QA5XDh)SSX4QdIYDGG`*l!+04}2&u8N=)h_0_ diff --git a/zic.tproj/HACK/America/Grenada b/zic.tproj/HACK/America/Grenada deleted file mode 100644 index 5eb4e1956fd879ffb49adbb9321148185064e070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq96hVlEV1^|1lW`hX4PMA7Ehd@eN^c3=RP)VgLZjiwbN2 diff --git a/zic.tproj/HACK/America/Guadeloupe b/zic.tproj/HACK/America/Guadeloupe deleted file mode 100644 index 8bb10fdf5af35bdf6d74ed886077a03f5d4cecd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq96_7}+^UR<7>JEG8ngsT<(=JHrR3u2Ae-fbn>fHm46EPQ<7{T!W i|J5oC4FCV{+`z~JWG`Ug@bL{{aCQOW;1G~uKmY)ZJR3X! diff --git a/zic.tproj/HACK/America/Guayaquil b/zic.tproj/HACK/America/Guayaquil deleted file mode 100644 index ad7bb791607262c8477833868fde66e9cf275cac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq96f1 fBsu^8zj^^g9zVdq>Ej#1;O^uOBqBpVMnM4p*%BMJ diff --git a/zic.tproj/HACK/America/Halifax b/zic.tproj/HACK/America/Halifax deleted file mode 100644 index 92d441b68ef9bcda040b6dd271994a16c61f1f56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1225 zcmd^<`#0Bj9LK+6X0k|g$z>$vGUcO167xy&om<{>SECmzqFn3iQteBp)pBOavDR&* zX%;nozeCwXA6?{Bs~2K!@sg5bUC>$x-|_qYgFT+-anAER|A41R^q(ltth3JYWX9R9 zku`F@=;Y%b;Z)lKuCV$5oE8?d9}D#OVouJT-5t#TWN5;b1QZD+lm4=E&b9ox?v=7K zqtkrZA5Pr)$$k8Vt9jfnFWUL?oN4ajmG!(VGl-Ly|G@w1og}NsmGYJ5HC$B!@RxK1 z+2svxe6^aMtVZRIP}8K#)r!LT+5$US-Do9$^++ctv^*8+BgEXbZ*%$UtdP4ApTytf zvbcs6Xa1H}6xZmGAT*9kWw&*iaJvI!cMd&*W_XS*k~Vt4-^bRVYHBl;8nDL^%J9T;k`0JW z=&80o4q7PD;K&3HsrJ)QQ#bxKaFd?N>u}_735;fDvsa0S;P1`b*=xTz_{Y_ky|MLy zG0RvS*IW)0YTh_8=0$G@m*Hf)4NWy_;&k;qQv5uEqGQ9P^mPl)NoywMq+zB4FX0{5 z%vAX%c$ceWYNi$Np4RtFU33)Ghtt_yN&}6K@9=#g4CeioikhVo(mD}}^Rq)pJHrVV z#IB|f!i-SI(~xu>r%}&xiuBD4*+R8mGEkag1|yST*w@R9ntH&vzMg$37r^99F*B8n z(xQC_m|4&RS{!!<&FwGI60iNZROdKZSZ_s(=_;^N7o%0rF|Z!8!jI}Qz^286Ei2pv z%PTCIt<(j$e063Q6Gkgip0SU`YiOnaJ!WrVOb#n#Y?Z2l91ZWH<3Jy+ep`-C4cBQ+ z*AaBSNZ?YFf}b3|2Ck<9kxx7eYrjfnZhi-0-If66Zo3WEyW2AlO)n6e>oM_IGzxM3GW6jPhJXUqq1jA?0B zZ6?B!x%?t&t?^VQG<30M<`Nqrb#&&fcjkHadG_pi{|Lfgr9HE1(5Q9>P1nDeeDBni z{wiuINMK!Y>FDZ@V%^dZbl=*^dzPnB&)G=c+o4B&(yzR~{sTQRAK(*7I+#$GvL8MH z_%SNyKL@3lY&gPxJ!ry|DuYem5TI@tJ$HiJ&6Mcox$e$|U{gNBA5rqq%Jv+@R$=%_}{_=10B5g7j9t(6tAKL8tkm zxPvgVDdEP_RG8={a8vUjn2z~zvq?LcKaOXM2PIh2?8_|n$;q<9idiY#XlafXTjn1H z>xegOx%C>XaOz|>i;lt8c!b+dH;~;#AM9TprIiEM;BY6KR<%~c@mx4L)fB_I%$Zz@ z6mV6_usX&YYl0oI*4+Ybwgy;dEWlm&Gu*$8z+J?$lFkaKJ!9Ymjh%s7Gq=M z9E8_QBSQ5FkwrtGJbj8vnxakgk>u<(MZ17DTeZ`cc`Xzp)KkoO6>S|lOtB~=1y@pB zTP5O~4k6)m0k$1YL*m{oNXiVx_E--jhuR~>(+sKhdPp<*h4ck>q|`Dce@WR_9?_1vyR`GfW!hC%SQd<_d{-7Yv4uGDbqhI_&3j(-i85;;Fy zF8$1K#o_gbtD#pJt|^@TaNTq}!wrV@A8v}yWVrcY;)h%Rwl>^8Q2gP}z3B~iS57Fn zx399{erHj^gL%;n4>Lmw9@W`4JoYpzcoHYy@Zyu$hga+j4F7h>eE7fo{{x2U|2{Cb zKYYNz$iT=1#!NsO88S06vjE}$|2sD@GW`F)dI19qn9Ttq8F>ExKYoBwz&SjG!8sU+ OT|yXKfwU`-MgRa~zhqwk diff --git a/zic.tproj/HACK/America/Indiana/Knox b/zic.tproj/HACK/America/Indiana/Knox deleted file mode 100644 index 5c1ec1600ad10cec410e2ef14ea1d8976b0ec31f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 532 zcmZQzzzSG^q96SQd<_d{-7YxY@vq@hBIk#zp;sBMDV+Uq z-E=#{4Tkj}Zi>!ixcOk>hg<))Hrzf?{Nc{M=?!;RPAIsyud?BOXHmg}dC?6IGeZg< z)!8;Y_B1Pa5+~pAG~DLHGj|(?=jL)BUZ~44y!a&c;T1ar!>fxwKD>VRh~dq(BOl%# zJHqg8|HFd!>mM|Hn18t7WB;LsFY)aKzkZ}M{C?s2;m-|EhQBAYKm6OF&G3H(?+1n% zybO%(?>{h=zh_`BNWp^n&?&rb*;t^>i;e_XmTZgU|V!I+`!22|NrU*3@l(a X2Z&_gaSjh*a1I7ymk; diff --git a/zic.tproj/HACK/America/Indiana/Marengo b/zic.tproj/HACK/America/Indiana/Marengo deleted file mode 100644 index 6bc8d13e5be6efac8461c66e6d664f086135d96d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289 zcmZQzzzSG_q96SQd<_d{-7YxY@vq@hBIk!Y_og@8T{)rP zQJrnWV^6b!Cvox(Pc(A25|a_`qE7FM%cDZvkt-g9J8*`vvR< zhZ5L(B?~wOHWhHLo$`U}Lt6p^BM35~L1q>>WCF7O|KGWRk>UUU)e9I{z-$f>$-wjf b|M3Hi0?y$f49>wo>=MG@3Zz|uGy(tsMgeEM diff --git a/zic.tproj/HACK/America/Indiana/Vevay b/zic.tproj/HACK/America/Indiana/Vevay deleted file mode 100644 index fcd224f8be67cf59d6c1beb70233485e74aae538..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmZQzzzSG^q96SQd<_d{-7YxY@vq@hBIk!kb+!%vcF27A zzx@9LhUx!4Ft$H@z*PR=19QQ@1eS!q1*`!N5*Qdkkck-z|Nq~)fsx_=|J4f^SU_wB cj{pCUA7JEh4i8~)4h~^(1!0#Eko8~y02{kBHvj+t diff --git a/zic.tproj/HACK/America/Indianapolis b/zic.tproj/HACK/America/Indianapolis deleted file mode 100644 index 3961e6565c64ad60c80755558524f8e3d97afdf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 269 zcmZQzzzSG_q96SQd<_d{-7Yv4uGDbqhI_&3j(-i85;;Fy zF8$1K#o_gbtD#pJt|^@TaNTq}!wrV@A8v}yWVrcY;)h%Rwl>^8Q2gP}z3B~iS57Fn zx399{erHj^gL%;n4>Lmw9@W`4JoYpzcoHYy@Zyu$hga+j4F7h>eE7fo{{x2U|2{Cb zKYYNz$iT=1#!NsO88S06vjE}$|2sD@GW`F)dI19qn9Ttq8F>ExKYoBwz&SjG!8sU+ OT|yXKfwU`-MgRa~zhqwk diff --git a/zic.tproj/HACK/America/Inuvik b/zic.tproj/HACK/America/Inuvik deleted file mode 100644 index 7ce69b63c6e0d65ec7a00229792503c123c851ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 730 zcmc(TeN4;&7{{N>MK#uQxYDJh(shYTN-q-S>Rft%p%;3Su2Oo{E>w>dTNXWe8C$C^ zZH7i+O_NMx&0E@PZPdIqlf~FFD@;Fk{_&6heZKoV`#xWQe`0D_jT)&mXzbFKo<4nR zuaxyebNaRm4~m}D$@Ie+E;ysip;^~6AgN=ACAnF+G)WCoO(>9X8@1xv} zK|c4I6&59+c-7BtQ}M9+Zace=6w#WNqrCQJEGetB>~Y$Q)@f_ev($>#tFzH7c9y*5 z+i-*D82K!4Lton&@SR+Uem`G;|G;P5INl2ZT^78lw;2K(KJn(JYS>cvjDu>MC^)K% zw`Nt6N_mPyRB04yS;lJTAX3jZqDJgQn&+h$_Rf^H_atEWpd&<__rb`kVu;e&V08U^ zh{^Eg*!+hO7i7)x;a4ER;XCheuZNv5&WX}Xl=!BPlfE6N_<{Fd?54uv$6R#m92F-|Vo7!dmHI!zvd|PdAnU+#r4Gt}oIssrGU&z%vEoYr z9K0QahlcFoaC-q)b^=t@L~-@W2>_8XCL-~?{}4fFW)TQN1A$l&I`ks5KX;LF2T8Ol Q9-`w6sthHZ(Yd6aUL;CsnU^hDi;Zk0 zrp>exGl?Zb=Cv0xi|nC|iS(>7t#I!2ufKhseZKqb5rluTK=;+Fr&6cB&6>L#v8CrT zoE><9t>>CTA0J^HhB^8n3yzstr5RkTQL<%KG+DjA4>{A#D+EW3p8pBvUJ-`lDg|d}SWu2s!rOzsQLcp?)pjpQJ?(-!esz;(*ckK1nrLU&1m^c&hg}U% zu%PWU6c%+L9;$$%)JI&Ln+_#`?OYlj0=vcaTqaASvRUME^B^i8jpMyj_O!3Zn=1xH zRCzuY_jim_Rjn6R*WV{Wq(6hdJKz6rwb}=LB0;OYaal0bYDWe|#tM0YporHg*Tp=4 E07b0<*8l(j diff --git a/zic.tproj/HACK/America/Jamaica b/zic.tproj/HACK/America/Jamaica deleted file mode 100644 index a77982e0a8c1993d144c1d8b1bdd8ea0fa8f094d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmZQzzzUdwq96h*|PH5ZC1XAfcq0Aj$FegA@~Y p0wWU^`2YV79tMX0|95U+VEO<5_yI-^Z{H9G*I*!a2?03?2mnGWFNpvE diff --git a/zic.tproj/HACK/America/Jujuy b/zic.tproj/HACK/America/Jujuy deleted file mode 100644 index d101bd1aab5426b98c1bd49f05ff794b1dc5322c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449 zcmZQzzzW!bq96$YHzG$qhT?`W<#$DKOY2UVC8I*2Nok|JdlT zXWDgxy*Hm6*jK@|VgGIkhXYal8xGE$>u|{Wu)*QF3kQzKeA{p|fyLqIKP`jfj^+oB zKUi;YqH&7DDc^+~PQ7b8aL)I?!MP1@4_wwX-EhS@<-iwP4udcAza99>nq%Yf#C^lvqC~==ypgd*k z1{HxR3slWNZBYGCwm@Bx-$4CB!~%_XT@IRu_HNL6@X&#giAc!8j0suUSXuu6KYWFO z;s5{R2N;0ts}~qK{{Mgc07PEB01^R;^Mb{NoP9$W9D_hOID{b_!~zmPCMo~`*V?F~ diff --git a/zic.tproj/HACK/America/Juneau b/zic.tproj/HACK/America/Juneau deleted file mode 100644 index a9d678418ddc3e9060bceee19a6542513522a7f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 806 zcmchLYb@1q7{~wTI4hAm}-x; z8C&>`wOqDXYivm^)}p4Y>1J)prdr17oZj@N^|H@*pJ(6a%P@aMSF>u>Qm0YdEhbb} zIHho8*9XEt-RaCSEmGjs8nOH`L(ow=aRP+|bz?=Go=k}PpAMYSOh!nk5HHCI&{6&PIvYfpj%Z9CD&qbR~8cY5_j|nyGVA+ z&CpYlLA>0*p|^f0@v$)lpASyNcXb8)#zkb$s~51BI?{c^gW%5@(15l!2rOKrvP<_c zDEcuC&S=FDw;sAbqyj_591XKi#jqdUBwP@H;WLdSV!;+82b3gg(jN}A$jQNOfao$$ z5>wBISVb&7l(ztKnFo!F8iROSbDH4N35m>inq>YEljdh>@=6CD9v!AB&uj5W*9=L$ zn}cbpA#$`i3e&T15Jgos91E`^$I~JqLz+%b_`5=;NhQtNDu%4(Ggo>9a5axj3s{W$f?jXc-m^5l)7Dq(w|+VOk4_O zFRzgDr6f2zlus(2`a$Jw6+PE$164J-^nAlQ@EHETq9gc^QL7s-FpOG#lj8|~Ujwze dx`;8-?mXidc^ngys4*mtkwt1AS)``@;TNQ>`jY?v diff --git a/zic.tproj/HACK/America/Knox_IN b/zic.tproj/HACK/America/Knox_IN deleted file mode 100644 index 5c1ec1600ad10cec410e2ef14ea1d8976b0ec31f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 532 zcmZQzzzSG^q96SQd<_d{-7YxY@vq@hBIk#zp;sBMDV+Uq z-E=#{4Tkj}Zi>!ixcOk>hg<))Hrzf?{Nc{M=?!;RPAIsyud?BOXHmg}dC?6IGeZg< z)!8;Y_B1Pa5+~pAG~DLHGj|(?=jL)BUZ~44y!a&c;T1ar!>fxwKD>VRh~dq(BOl%# zJHqg8|HFd!>mM|Hn18t7WB;LsFY)aKzkZ}M{C?s2;m-|EhQBAYKm6OF&G3H(?+1n% zybO%(?>{h=zh_`BNWp^n&?&rb*;t^>i;e_XmTZgU|V!I+`!22|NrU*3@l(a X2Z&_gaSjh*a1I7ymk; diff --git a/zic.tproj/HACK/America/La_Paz b/zic.tproj/HACK/America/La_Paz deleted file mode 100644 index 12a7f6f4e0ce16e5ced2c344500facc2ba9a47b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92 zcmZQzzzUdwq96mE4HuXEw}fBpmVKfhm4 zD41|Sb>8C(YN9mY!I_vcij4nsK9YA6{{(+zSjEauatBH}c2 zK69d*s?x<=6E+o|tKzXXIiKoO)m&dr@T#GhU*}z>hO%S)COwlHbGP$bMGQ451G!o5 zL+^s;@_VT*eUJrUi;*|9N*uAZ(+1jvrr1^^f=?e*__?SXzEn2i*X)b6Yfo@r;H*D##>hNePa&p!Os8V>!n8}Rr2#h@yY zq57gZ2y&#Tb@?B|lki|~JsRSo%R;NqB+PJSU3g5o`FBvSqmc9)3)tZ0 zBN$em&BJdLfMMPhgyY#TBAw7^M;we)Y{gN5D?lXoL*qHKVYJj9O(yx$7+n(-Yuk~y z)0W3JjV99?V;)!0OXG`rc*2=_!i4EKG37Q*@*jqiH`alfT{}+kxCK*1)hIE~1&Qhl zOZAdL+VF(U+t$MLvLd#4s-zjYM|oy(C|N4EvDMLqG%Ml=TF04@jVvB*eTR^p#2@Xg zTWPk?0Ub;SgF}lL=lp5`$I5=3TmJy&6`Jt;(o5i!)yK{!GhjjVD|SiEqlKPj?7IFC zxmhy1yKSLGhI?6N=1H=i(6#%x-X(6%d=RwffEZ$(xsy<>LWJ7>>Xe`v=3z0Whx^L*wJ;y-0!d`&T_ z$`}(n6_@%+N9tbU(fm9z>p7~sya2buwb_=BDb`@UPt(RI;t+=(L2yPy?!nXJ} z(b15}ce{$D&a(a3Ri7>0E66}9PL{fL8tlmllX}%bct6EUdZ2X0KGjU|FxZp-PxNbiHE8wYLAK_6u%WNf_Vy2C*Pz8wXLpi)Sspta zN~6&QtJpF7Gx|WMVyDHva1Abpn0+gK2X8 zF7&&pfscxH`0?o=@Xwi#0S8>+6Rnm5GhV?Im71r<-i2w3$s80|55aOf4jFrgLiz@I z`s;HP+H`|wbQIIf$|o51vqZDL`5k9}znsF;YjDoa9q{SGgBYW@zl?q-J_7|l&Mxxf^7HOYO!qr2yq-(XrHJyj)%j$ky+w>EBRd^NGl^%lh z^`{W?x5D}*&76_86f#3Ac*ES;u+e=VXZa^n)+^-A_F=U7PAq2+deN4;sl2sCM%#`p z!tJMeDJO3V?%4MW37L?Y8U40R^qxnU53|`Y9{&GdY%rXyk_m&M{HQShmn}^#Yz>BA X8)OaV{AxbO52iz9l* diff --git a/zic.tproj/HACK/America/Maceio b/zic.tproj/HACK/America/Maceio deleted file mode 100644 index 27af65e7e8a8f6449ab250951be1b7259733c6f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 610 zcmZQzzzUdwq96&LpEjso zIj&&PP-$Q&>$|`xA=<#0Ela_~!Pda!nU8{*g1mv*F+BwfPU{U8%LEiGU&?NPOa$iVsCv<0q)OAK7kRV;89 zY%_4*K2^cvV}^m}^l}BSi(Ura<&g?LyV5rJhFdH6&GOjbZ!W74P^GmYP{DFRP!!LG zU*^?=vX+c~+ssc!5F5&Giap zGJ7_Z?VPAk{%78XikZa^;2I3XE+L?_0|Wrs+03p0 diff --git a/zic.tproj/HACK/America/Managua b/zic.tproj/HACK/America/Managua deleted file mode 100644 index f2cb9cbdb5e43ab3f6f876b359d0144028e15b2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmZQzzzSG^q96Ajj^#UV@k8cP=crXyVgn*m`1ON})HOV diff --git a/zic.tproj/HACK/America/Mazatlan b/zic.tproj/HACK/America/Mazatlan deleted file mode 100644 index affdb692fc47b0c4260fc441a646ab8258e0ed21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 569 zcmZQzzzSG_q96}Q7bPfimu{$6FsyreQA>+W`j z>`iPFa*kbY$es9NLf*2i4f%zqCKR+yZzzmM(K*-&hCQlP{wx}j8RwLqDE1w+}d zUV#e!D29q#`2v;iZ5XO{1qxK3mt&||oI9a*Jp)5sv;TzpzDEp$YHzG$qhT?`W<#$DKOY2UVC8I*2Nok|JdlT zXWDgxy*Hm6*jK@|VgGIkhXYal8xGE$>u|{Wu)*QF3kQzKeA{p|fyLqIKP`jfj^+oB zKUi;YqH&7DDc^+~PQ7b8aL)I?!MP1@4_wwX-EhS@<-iwP4udcAza99>nq%Yf#C^lvqC~==ypgd*k z1{HxR3slWNZBYGCwm@Bx-$4CB!~%_9=?647cx=#m@X&#giAc!8j0suUSXuu6KYWFO z;s5{R2N;0ts}~qK{{Mgc07PEB01^R;^Mb{NoP9$W9D_hOID{b_!~zmPCMo~`$401y diff --git a/zic.tproj/HACK/America/Menominee b/zic.tproj/HACK/America/Menominee deleted file mode 100644 index aad6bb0e32c860565bbfd5dd5a5abfdd476068bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 797 zcmc(TZA=UR7{{N|bXReai_Tk;Zl_Z8c0w+9)k>kdUQtfzT%kwm%~hx=mQ#c%u6C;X7#~S)>OE2XYzyE&!=f4NwpV*kc7A=&UwQR@Q%U)F1 zF@g1^)2X4RA0Hn#QlCc1hJtVKTrtcOq9~daXxZ522~!pC(bo4F+LlX6=y(f-H!gu4 zpF#V3C5*u0?7Qq9V1Ol2b?hN- z1?kcfmKu9WW|zUTceiQjP#AmOt0phQcJ!{@Ps?tr(5EPce5*WgxmFJ=_6g80A{qSS zhA==H41p`2V36%Rkk9?X^3O(C`Qs4>cMrm<{_DKD=_jq}Jjo%a-qG6g$co%93O!bi z>o#5_Wo9m_e2!6=Di*^ALEUM z_OR*1OODk@DQ;Ig$A=0@9eth?T!$&q>j)=74<(ChFnO?vQpOHrYF7nqevyV-8gIhZ zRt2V&ord&kH{7Pn15Hr~Z;w<%Mw%;U$^v0Wh&5-;j3e#*PplpFr=7pLS=Z-G*#lQO zr)8XWbw9-26>n(Ij)qe4NdtqGCD!IlvDE*K$<*F#1t!zAda(Jk1(pT} RWs(|{@n%(O2s7Wm{05hq4+#JO diff --git a/zic.tproj/HACK/America/Mexico_City b/zic.tproj/HACK/America/Mexico_City deleted file mode 100644 index 3e953e270f6a50454098fce45dcb8856305256f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 582 zcmZQzzzSG^q96;Z%I?KK~4*8gd+-QD-WuK!+x{p^Ad4*3Tf99wz|octFx zIH%+nxahYuxVi)uxbdeoxT_c!xc_Ko@MIA!@Vt@A;Pv=>f%gt~2A{LSAADzMGWf0e z`oX_~n<1d*`iHM=&XW>2kRRmzt$8) z9hle5|KGWRk;lh3guypBguxkv KT|z*q0}KF`-^?Ze diff --git a/zic.tproj/HACK/America/Miquelon b/zic.tproj/HACK/America/Miquelon deleted file mode 100644 index 5911e99774089cecc1565ea38119cbb06c0d0eab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 679 zcmchVTS(IZ7{&jlgc(aPZ*5xMYRFL|q}U0jqE7?EkW z2O}z>6v{F)!azP>^udyEi6BL0SV0#ugF-6(=X~zD-{Bk%=lKZ2KXI8~9d=-yx1)PB zKUTFbFE1d^>}BMom9V$!8~KDzv2TzBR=C<(>NEw?>8~hzYX?6&qkn%ltn7M-t8QL~ z0P8yrJW&flnFAbLa*;x!+j(`WmDYHjWqDW@$>;8%!Y!5*pVihDe2LY9DL#>86Z&!8QP z1(v#2j?A_KfZV|o>32K3|3a06utZD{hU z1k=Q6%>JQ=9J1i9(J0v6(ZIPq-ms^!kn=9hKz^}?_u4#ZpH{&Ixj)IQSjvS7V^ri3 ziWdJ~vV3>L{j=Ao*!~4eUfZa&YZ%K0TH!$R11!H?4;57{Sa~K7s&YEHx+n<_#$Dh; zDZyZsR&$Lqk!pS!xz0V1>R!h1;VEZ2((B7dhu_n&wrH&H93)$V4<0|?K~Bz#{=YW-Bk`8TY36lt;glC!~@!#z9JZZ6xf`^(lH zd-iYLu=mRJ9sA}_->`p6<&FdOl^YJuon~<;K6=C9+6s#!_O=_2#zt8jlb7Fc+}6h8 z1c!~mNm)6IlP}~9PKSo!~Yx8G#CynHDKI%as^Ao9RrrP#}}~Q zf4_k<%3XtJ(&+85No0$}ZLfZ_4^V}CG9u6^3vbI~Gyzt2e70L4os$S_ER6mq0 zP*>zPP`?ndK$A;*gXRXS1zHa-8)#3ES)g-Zs{s=u1Tr&%AdJVv$jX9%Y%Czi%EE>a zg0uerKOMrr@c;kS3yduP|DQX-zy%|(UI4KlKVanh|NqVnMiyV+5Qfl5k6;i9!axQP JFoFmO008yWpXmSq diff --git a/zic.tproj/HACK/America/Montreal b/zic.tproj/HACK/America/Montreal deleted file mode 100644 index 0bbe44a97bd3ccafd108f5402fe793a435a168fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1218 zcmd^<`#aSK9LJ9)jOt+NqMJ3*sYFT%ue1MiJGfc%7)~Zxlo;933w?=izqK7ZF zC8}~qaxt$QRll^H#QZc5RY94j{BpE`P?%~XzoJ+wy?S`M{Ferjk&DswSE zn>Ik*TF<%rRRjIgRnI*SuTyVz5%*QpLw`XXa(WRwPr8N!F=yf5&@=cVAPQc(N8&3- zKX`5Fi-QXz=#AI`hjg~m(4Y?wtL$myksXiTn?qy8vss<3Cehh3)`)MX2@%Ba;TUMb zC{C0UXh|QVw$&}rF{#A&^)o?NbRKp280gWrIH~a*O%@b5r6i8TIkBvt5=;gOJJ~Sm z6Z#;;ji+v1L`E_RPg^~Src3mA#(W9P)ahm833^~Wpo_EGdtvtd9-LEI3v&zq#CaKo zU=l9k5050neD5dx(XIkAwW;C->rauHQ5Kso3M2Ee+bGfXCP~``T-3da7MI84l6o(& zNDINGS66~%^aiv_o&n1g3bx)q1k2rIyuzaeY|Iz)O6zi1r9GK#XEl*+S3j>FE+f0@ z`)uEwMh*pixTf?QTAQRq#~-(oH1rC792W!Y+)txZP#`#4hNFwK6S#_f(9LuKxD6g) znWi?#9&O?E9nWAxu`O@>V7h8*L7pi5`1$$x}LvUK>x6w@E8* zSrSU0i7L>?=mhvs25x=17kq_S^m`zO&vVjwTah*RCmi8`@1_ET?BKv?E7~q|;T`^l z6eKa{ooilDu%R<5<~$_DfEj)WKJ+2p}d{qyLnUsv#Ei4qa`E&Ue<#s@hVD!};v|IsxJ4FCThKfu7^;~T=@7#spp!~g)z*b1ls diff --git a/zic.tproj/HACK/America/Nassau b/zic.tproj/HACK/America/Nassau deleted file mode 100644 index 540765312a6d131b2919ccc7291ddad35826795b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 825 zcmd6m`%ldQ7{H%maN5yEz2b{ zhM1MhQZBg+iLpeyX>*(O&Ro*%tMj`*z~|X#d-nYP2*N+n9b2_(IXI@a8&|vemi!Da zz+c`8@LLg&1M~CgkI6C|l*ZBEKr9b^T1vy6o;-5jnns(Zvv^u0;m{~c%6dpApI8@1 zK@UbyKZ0PK&pR}5x&>03Rvd475)6eCXvn2tM0?Tr)p458qQ;3=OUUF*F`L$8(4_Ko zHruw6CT9lmlsJ1bSIT*+hcQi)8?nV~Iao^jSf*nHvhRjy)zb&lJHDcIYdg$nc!D$Q z8o)*)@T@)6FgyA^&)IN+Y?s{OxxrO5&%B=P>^GC$=xvl6Mw9&QDYXCMMh?wo==fX( z3u-fQ;bm7)6o#NvwFN9vtJyhk5L|+kyg2d=EU|N7SLbGMGnl~cR$b)&p`Sg5ZjfhN z2QPhHOUo{NL$B+*Y5D%A=zTPWd~z<~ijpGm4L^W>Y02QP&|rYS9|W4jVvy}z2pZVJ zN<9NmcE)gU?`H^Ua_7*;`V@9p#;eYKr11PqnX>^O+PkbRVIO4PP*;tr0d=J;Lnz8pz2#k65|`a^oLz zUPdBp_B_X10=;3Ytdcc~1kwy57npcaL02Si>z_&6uPx>s?GoB~Vm0nM-%EwXE?87~ mmvkimVMMWUryz*py%vd{C|$ diff --git a/zic.tproj/HACK/America/New_York b/zic.tproj/HACK/America/New_York deleted file mode 100644 index 2ddcd429597596a11eec0ed36090b472b3171347..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1250 zcmcJPdo&jY6vuxg11ow4pW{b z@+#6$>6h7BMF~aMV~UcSQbrj2yMO$#&pn@WzUQ9rxqn`P;JwV5-p)9~z_c@2E+cmt zW?p^*Oss9o&s)68b4Sya;oQ^B~u~k@J*OAm6Z%^CxrY?7~z&+nG$~ULhCO zgwgqCH!jL>q~bCoz7VHNCBL|0X{ZB~#TsI{y$)1tQO1j!^Wl=kTdb61s8Vags=g+u zmKfn`Q8`@ceZapJ-=UiNDy~f{rMm1>d^IASt|cDi>&}r>9~8hh^t?&r6pJ?%%&9@w z9~(x!pi$l$8(YobkM9|qV4Rxw_wqgK4!Z9t;ueisdSIN-t%59SQ~rV5D1q81^YCF^ zFg@x_!H$A&p|fTOK28Y&%5cK2Fgxgu)59L&8tC<3fPZ_fqdt3Geqy3XPc;>|fAKI4 zNWSEOH}~jSUo$^%xk!Ve3Vu=B3`50D$e9)JGOZkk zi=%6z=pTg*I412wW24?Y{?vlrwVLxpgE~!CF6F7bDH0r?WU=Hf5|1LDgOeZu6FAp} zK+^g#O6gw%sUs>lPca+jolj>OP6Ao_4&~ZTlYCt$&aX-&g@OcDJP|?*Qi542=5tyY zX3vX!v`Ja0#f#14=mRZTUa~?9RHO%4Ra_QShh*+eU9o^Z^N>Zzi@e031~zL z_`^fTV1;Kle-vI!D~;=UmBUe5t(?o6+IvZJ@;YkCc#>9U4r&jW(At`0)M@qr-Hb3? zSGFGX;v7-`*b?|SG?WeYjDexOkd53PfwAUVUT;tXCQ|Zjs@6`XeM4+Eeud0MciG}$ z25l&QftJN7!(LLdXZ>rvk~kRywQH;DzG2j$3h7y z5Vme+hn{|LtTg3Kx8{=5&#L@I;S+L>ddDt@e<#;K6?EHqj@+%s(PPsQ^3>?S%{md} zC8$Mj<-_1jS?Dve3w-Mm(C@wrY$?d(trZ5~pK^!;eq00)ww(jx^l6*Wmbd#WQIM7< z2V1_T5G5N7Rd1ot;nn!%L?wkaNn?1&N!n2|fICH(;H#s5;;!5i5V5-mG3fy8_HE=n zAzNXuc_Ht!vx5DqsT`^2N0DR5(F&Fn-R{OQL(A#w%SL?Qwiv~pam9m0JrtKSmpoU}~!Bfp#tfPyPqE1rMWv8P14JkTxoQiIzbWz@}$4Tn#;wVvCiMC`dHnG(b zZA~jNQ&?)qTvNt~?4^xq(!0iHg`@M`cfV)9?b-AB5rluDySQrAQoE?Oi(31ev2Dl` z9-m+whXoSZ4dYVNi(nvhpaIu`Ass`bHy6lwNQuh^YRROlhD}>?X?cAPo0V^;6)G8< zC%ce^T*4~@jcAp`kS*;cU?rMiv92MA=M2#L!wjq*`-(Qhqp+s$8QQk@ft_05wbjjF zpYV~_<@J(-?>%;mXd)+zPIh)FA?H7LQDTrllJ}R;W!j%y2aluM3k9riRpEwfe&Aji zi5|_C;HgxySMfY}%jE16_YQoWUD?lT5d8IxIly{?0zS=h;KFU%I5NhY-nP=_-ftLm z>nLqG^&ErGXHrPvRoq%z1>2%eV`z2;NZr*KCJlvflO&WmID+hFDa-ZrLH;_CBc{GU zWPbohJzYXO&Wd?w_h*Ve_={s29#U+E6~^UXrudKrR79Pm1iML0bStD?!W~SqXn-VY z$K)RckTO(*sV`$-cUK#yUH5|Y`fA>D#vDME#Tk_zlqnD6taLNVmN;`x(09r;lcLh* z6)ESOaPRMaQjLo+Z}J@N>zl^>ksGkT=?NBewm@M~4`N*f6s0`k;@mVS+1Smc;lXe~ z+{kM8R8r3)mze}n*+d+d&)U+Vn?77IszZl6V)01N6jj!EV^!mQ5_JB5G@1uPI)X+s Ra7EAylPZL;c!l<}!e8SL2*3aU diff --git a/zic.tproj/HACK/America/Nome b/zic.tproj/HACK/America/Nome deleted file mode 100644 index 1764415cb826136c04b23cb0df4c8fabc0e81ef3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmZQzzzW!aq96Z?*4aE+y_vT*U6!>v~bM4Cjt`D~ka6hFT2i^m_FYxWW z>A=78Mu5P~-424Cy8?tN=Q;>y&Iu5StalLgtP2pcOmq;}ObC!rsy!gd=@cNv6n{YK zlhX$2N2&{CE~#vgJ;c61ZWG%E`GqeRD3njUcFnxi6 zQL)hiWA`QllVFhrrs^pMW=7u@n6tYXSjY$~SUlG-u>Ad1!Rk1df%Wa{3N{PT4T_tvb`;WB-o-FnY zJa6#_w=2X=3WzS^-MX5|fo*sWO$;yQO3#835EkdQgY zAh9k}A<47OAUV!kAw@I6Ak|J+Ax)@eL%JNlLi(q;4H|V#Ihl8*~JCJ(1P{CiO zP;slzkyNU|Nq7U22sD@5C*^S5C$h8?c@@|;OGq|fIMUX0LA|b=Kufz diff --git a/zic.tproj/HACK/America/Noronha b/zic.tproj/HACK/America/Noronha deleted file mode 100644 index 0a9ae0d5ebe8ccd4fd7abfd46a271b57a1893e6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmZQzzzUdwq96-it{OQi0AbYYwL9XKD1o;K(3lxkGPEc&%T%g3gYl3nF(*ot2>JwDWpDa+l rvQvPO2@CxH|KS`4hX4N`KVV?_|Nr9$Mh+j}5C*qkAa)4>ISB{=?p8N6 diff --git a/zic.tproj/HACK/America/Panama b/zic.tproj/HACK/America/Panama deleted file mode 100644 index 898e9c84671ae64623cc4ce30d34fe2274757062..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 xcmZQzzzUdvq96>HelIpHVdb`9`^e%ciolEJ_3%!u1^sb~*id-x;rlB>{W=_d$ znMJc`W$j{%O{*u|hEz}5`oqLzR-%6H^sm2to_)Ui>=A^2Vq*9jHBxEN*vqw@HF&dY z1eyl>u=!S<=gadS@fA+djKVWy)-6T1DmQ>vC)tseTE=Vq7s%Reo^2duU~4|cQpr3> zzx_tp_!!s?jiP;TFRX3X;kxD)a44PT^=E6qG2snw$ZIAipGWK*SxqihjqK{4Nv;bW zD7R3NeDoT+f0EP2o(lAM9RZuPDY*He8z?lv=-FTaUfD_PUHlogsDgNF>;U+<+Ox0s z1Mo8w*p`gA8 zkKVZmg+)zxthNA(lAmyKRt%H`YWaAC7nDlRaG4^S%I4C!+)_d1@0DEfbp@U5a^X`0 z->I@C98b6DNmK2NRhJ%jYC#oM4H0s4`v%jWeh;#3FwH DHuU|3 diff --git a/zic.tproj/HACK/America/Paramaribo b/zic.tproj/HACK/America/Paramaribo deleted file mode 100644 index 0147927412a9410f86acf3dec6538f106fcecf64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmZQzzzW!aq96 qVPFB0J|Obk2?h=@$@~BR)e8)~KE5Fg0YL2M>K?)n925dF84dvVx*;_H diff --git a/zic.tproj/HACK/America/Phoenix b/zic.tproj/HACK/America/Phoenix deleted file mode 100644 index d684fb39956e69e6b7c1d5eb98391c0d965328e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmZQzzzUdwq96=FVp8wdb|n;^&l diff --git a/zic.tproj/HACK/America/Port-au-Prince b/zic.tproj/HACK/America/Port-au-Prince deleted file mode 100644 index 4401144dee3f29bf6236140ec5c4662c5e67de37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 652 zcmZQzzzSG_q96#+*jVnM6nf=>a@P6>DyG{WsCrF&pe8!wfx1@l1NDDf6EwL(A86j2o}l&0 z{DJnq$^@OuAql$kq7(EsnJyy& z+Y+2p5))kXGZI`~oD&I)evEp5_md)GT&R zs9pE?L0z+ILVe%S2TY7`$jm}}`2YVN7Y2s^|BoMFWc~kt=LQB&WOhJ+ZwP~{3lIl~ MfKnJEBZy=G0J^2@2LJ#7 diff --git a/zic.tproj/HACK/America/Port_of_Spain b/zic.tproj/HACK/America/Port_of_Spain deleted file mode 100644 index f75940e3dfe86a06fc9aaae2e85c96964d907831..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 xcmZQzzzUdvq96nR|FIAThX4PMA7Ehd@eN^c39;Tf4XNLkUhC7K(6BR0r>@i7Zi+NA5d&CzM#bYrkEO#Gxd)ok)47^3ol*^OA6ciq30?@_4%_FORX7trW6V7OAbW z%u8k?y<8vip_dufieg%=HGSw|vkbZ1_rCZ0@3;N;|NIB|C&ufmK?8N`8oHouu!Gul z!T9FV8jY(>S>QNIrWTLU4Eo57ucP^FGi{vgPx_~Jdv$5 ziLf=#h0hnLg1z3(&a=y-vSS|RML z=|HE1dDxZvjGcWZV0T12yNCur;#$L!wK0;KWw3OnpIqm{c+c||a+^p;_qKDiw_lDP zRmrrk*#-CKXu-2sfL@9u@Q#~9A4wqidcH-!4ffz~_k;bvuR*}dYYrTlg#(|u_+ZZ} z9U5-npsObD|k5OF3Bf*$Wj*wV*T+q4HxEM11{? zk%J0|dS}JaH>7Z+YmsBh%;D(e4;-tOP+a~H$A_AdDyo$e9Dh=xTO}WZca$W$g-NqL zl)PAhDY`~F{yr5?baunZfe=iszXoY7PIyXF1nR0FPFJcRBh`^JrM{3AWX#!?ag^im zjdK>f>GYow){I+I?({>>>szAykym)8af;5~e}DyrPYEy9V`0i96lLdOao{kNghykk z_%>)gG^|~&hB9F!mrbdm{FghQe>->qJ*xk4kjM?KpWCDxB92KW#P1y zmXVpwOE3D6w#p1^m125XYx>Z`W`taK`P%1x&wl^?_5l2ob;hqr6Jk>08^PUR_?LF^v^3NY!bJyGy36wF$5#Nyb8z3~c;Gyj3CsTW3GCvs?j@xgCn; zY{~x9GCGVdk>j&T+}8Dxw(FmwlTH9Ts`Tg_KMOl^AG3?kIP3~*W>;Ykh~27KygEvf z4H+z%>L$0D5Z?2of!xQ_(W9w^_I4{!T9HKiZn)z9936NTTcVdT5xiq&&_^5qzMikq zZ@mM^?7y?@+bZ}kzvO_SX*lqqoey@d(4m1k4!kx+hZ~WD3I-{-<|-bEY$bVS0VIOG0PRz!Bkl{&R}Lb^S`^+|8EV3zK3RDFg$1h3xnaspqZsy5eM>EqY7iJ@dq8B B?Gpe1 diff --git a/zic.tproj/HACK/America/Regina b/zic.tproj/HACK/America/Regina deleted file mode 100644 index a62958a0a5ffd9ce72734c8270b9107ca398a423..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 362 zcmZQzzzSG^q966EHiJ%`U&$7_%>`!_5ZNVz~jMoSHllG1hgLPR2BZP z^8?R=-FyZGyU)LSu;-mn!QP$R35SX}J{(Sb{oqL8s}DylCMO&-JoDkW;`#?Cq+S-B zU2{xwmw}-Ieni?(J)zaKE#m;laGj2@f-q8XnboPk8L<((oiscfwOm zwT5TzUINdBoEcuI>j=E~q{{G$oloG^C3c3_&prsexptZ1?XgP&OpIhe=KufaK4D<^ h|9|xYMiwA@0s{w#&A{X18^Yl00>r@~49-9d0{}VchOPhr diff --git a/zic.tproj/HACK/America/Rosario b/zic.tproj/HACK/America/Rosario deleted file mode 100644 index 0a58464cfea916307b6df27186a422cf7a7511fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 407 zcmZQzzzSG_q96$YHzG$qhT?`W<#$DKOY2UVC8I*2Nok|JdlT zXWDgxy*Hm6*jK@|VgGIkhXYal8xGE$>u|{Wu)*QF3kQzKeA{p|fyLqIKP`jfj^+oB zKUi;YqH&7DDc^+~PQ7b8aL)I?!MP1@4_wwX-EhS@<-iwP4udcAza99>nq%Yf#C^lvqC~==ypgd*k z1{HxR3slWNZBYGCwm@Bx-$4CB!~#YpA|VSi7Wn`F;VTRb|NkF9z`*kV|J4hO9RL46 ZegGn`USMEx_6=ch3xce;K4<6b?EHQN;hz{Tt~%?eU9_&tsvNTU zUZGUkp!WhPwM^Sqx((a63);tt8h&E$t$ga&gdGNIZKw4xcTUtPpZ!Yau70^vtjT8~ zO-*{ol&p^tWDxJk61giG2FBnLK}JjMJaFl!?_{)KhSJ_aS~fb1#?9YgdCxG)DzvcT zP8XVFwZqCwLu?ve4XX}!vYAT>tloKx%}sBRg;N<@Oc#^ok`%TaOdzYzL2TWoAe;Be zXnWn7);XD_2ia431EWuuq9GkIeq`WWv3U%4ClPC0=> zFhRvzBk=p;%Kj~r5b#>YTdxklw&w2~n9~YD6@!ebH?%$LF$a4+q>%6$-eFcrp&soR zI-{X5(`pR+5KH0HB^c3N0J{bgF|vLS>~8bNsB$lezHW;#$>yLuso*^UKOi>AnpHL< z5a&0~@se3euo~lpiDBA1$DH`Gi}sC=Vp3Bb?eFWwopCgk#=)mfdqGP$PLouuS?aEQ(!my*aODh_gsoV99gwzf0HQmc1r zW__sFriH1b3$=wzYwY02)+(}C7rE@;Ip6!<@7ZsA_I!Q>;h(J0uLcdM^%}ZG!@c76 z4y!0#$7(Qj&U<6mL@A8<-^a0;SH9_jyIvM#)f`0iu`k3I{fN6 zj=!ynU@^fB7yDkqlG!jXwJy@~tO>5v)sXb{72H|ZPu)|0nINDjEPqyG#*$}7 z8hV-JgLiNcdVi9GFW92*D|hf;AISbK))4ST%DXQvKw!VfdkQTnsCA0>#(k%Km!EU6 z`!MZS=`h5yokA0OF?6nh!aeR{_&^0k+FZiON7q0$pNCP6$wCn?$Z8z$d=MkyZ$F}3y%rS-Pq z;k+I=(p-<}vSv7X{tRX~U4UZ+8qPG$fvlJk&iX8aY}Z82?stJ)b3e{)i=ez237^n7 zQU04{E>M}#$@a~7Dt?wu*Dqlq4p32v7FCiNC{{ed;y-Vp)Qhlm^Z}G@?dGyh4V16k z;)?4fP^ndORb?Wa?at)tOcmAK4C8Yl3aYK%!Nx}aH=;Nq7X(q9))}o8#rH#ksXSIG Ngoo)>DD?+5@D~Bq_YwdA diff --git a/zic.tproj/HACK/America/Scoresbysund b/zic.tproj/HACK/America/Scoresbysund deleted file mode 100644 index 57a53cea8777ede72ce18c6d088c760f0f4a5349..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 707 zcmchVTS(IZ6vqFiONollOlQqYHJ4f|FR7`y)YdkvX{pOBH8Zc(TDeqaX)6+u81e;D zh)G5w5w?1;dQiI;MkYawu#zI_9%7i7gslDPp_iWf4!^^XbI#)tgn!1x<93K;uif!uX54z4lcfbnzFur1a#XGciIv@;A_peL$M~U8D^SVAJSD zY_?y9e(*Nan{CMGzQ8Re6Smq;GIRSWW*JMFz1B#BUdL_H4CW}qnKKp1Twg76Uo7B` z$uR7^@q>AeImqwuMnTUv?6OXvuw@9l3mqt`|H3`VH&I+L$dcezl&b73^SaLRK(hSP zSys%Lxp$zJ`$i1he<_c~N0m6xq@t-S8wV?bd8jcKm6=H}mq~FrDhO4YX;ga)sEP1p z&G;Y=WhI!;#7mg0~vaa+S74R@+Hyvz2bM+-G}8{&P8lU${ha#2#LtJX9*@}+h~sx8*z zx(gqvK4Fd>%YUH&EqUJU_nPAFT7g^YAv;h=LWpzDdDALE}N3M}kh!~Aio`Z?)J6z#?6-+fAqnQPR z+1y(esAPg*sFN+mgJI>v2DW^)k5<(jV3(pQa`nH? zo8u3YoA4C7yG4_SS~h!{xRB>W1$xOFlUIKhdcU7XTiZg=r^g6z@!@L#`Gx*maB>7d24rL<`MXm4e=Y7uWy#M)}^WpLSleshNY-bsn z>8vj}cPDWE`JA4qba7&8MwMPd=FOwh3j!IJ_3dI&cJdUL6Z1;+Lr@2IapxlGC1Dkp zYx`1~XOhKT)^C?yQAp;lOjk(rp9FISk20iJ8xKngD-KDo6$D9&E~blqJnkg9e&nF& zMg(6{92_XR>82tnaT1Ee7K4&fQ&Uly_B^g!)j?W5I>6l;GLcraHgc8eZsC=86mxGE z7wS~q>=akWrSpF}T`m3@5AuIGkS(qe1oCVBsswd9LO!$068tLXpIdK`EU52x$Zg2h z7c|=Na~mhe#Z3u%xy_o#1kJt${N_n}@!c>ZxOY@Y_g&?ob+;+~X8sf&fHKj%I%qTN zr?$R4XjfOl_PaGq+7W|~@*<$4avOH0ctBUW0J}q1!S9K>_}E1gp6r;yr~Faqan_+{ z8tSaqbdq{sjIe%1DfPFsvVopT8Z0Vdf7E8upSLSvsIUT`XJo>QvPFNDQ2Z_$+-1Kk&+xTKpvujK*i zSC_%kqEa-ta1IRj50KHJL@?gkNXx=f#U?g|wA?j;nQEORvlTm;+3Txlu42#3JHEyh z{l@H_%4oE>X9w@5d*jOMMqrt^7OlRKhgBh7WF7q!Ry(huHC}aKW2Q}Ot@GeL#R(ED zsbPYihxGodOKe^3En456!ZsAPp>6pd_CZ=X+I{cF?4!=(#^f+?@JK?(AP$6<0k}!H z5}Z^W(b+@|oG1LqMSd7uXd}5kz7HRYmk}p<&fLD6OYZr1nMdq1@=U$KHU}u6SNLhR z#l8o=wd~?c1*J%a}D~~wvz>GSYn8NH47P5$KBJ}EVN|=!ybLf_7t^Zcx@I$oGih} zi^&kR?=0>;5)Au%izzx7;FEP{D8^|8?AMK_1C~zgz~pv{Q{}U`hqe?yq{2QeGoa6! z23bP(2K@YL6HEMJDJGq`#&~l7ANe_NEDCSnl1wJek>kl^O{aJYGfw|FoAv%)Ic0aD OH_v^`OocP@FMk8yMg?2| diff --git a/zic.tproj/HACK/America/St_Kitts b/zic.tproj/HACK/America/St_Kitts deleted file mode 100644 index aed21c4cd9102dbf104fbe220d4b8a932b7383b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq96|4|bLhX4PMA7Ehd@eN^c3=RP)VgLZbiwZCR diff --git a/zic.tproj/HACK/America/St_Lucia b/zic.tproj/HACK/America/St_Lucia deleted file mode 100644 index ff851956f7acc463028dfcce728ba2140e2023a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq96hVp1}D3|6v6NhX4PMA7Ehd@eN^c3=RRxF)#oC%7zMT diff --git a/zic.tproj/HACK/America/St_Vincent b/zic.tproj/HACK/America/St_Vincent deleted file mode 100644 index a8ea0299ede12f47232584e14e4d3f6be7fe4a90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ycmZQzzzUdvq966CNXcv`U&$7_%@vG;R>zeGimvY6F-Uf$;zTbv6tP|NrmY az{v9d|LO${96r7w49+e<92^2N0tf&CiWNNo diff --git a/zic.tproj/HACK/America/Thule b/zic.tproj/HACK/America/Thule deleted file mode 100644 index a82ecf7accfb977b032e9e244ca71240b4c5147c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 535 zcmZQzzzUdwq96j09H~(*QSquLO4$@c{Q9X%9S^e+GEo z@Oa?$_;!Hz4y^}1XTD$Xox$_KZ_UjM{^jo;1oZ5_5SYlF5R^0bLa@Wzgb<(l3!w_< z6T);7FN8B}Oo$Mz3y63yIU(|ELO|4k(uC-%P6071Cq9VXsuB>_S^OY=DqBE8X6S>& zI;9Iqp5_md<5(`FXi7dvwS9IWO~@=EUG~I<^iL8A8Glz@$h`O~A?t3>h3t)Y5^|2M z49K0hFClMPcR+sOf`o#$+u)ULaFp{`jqp}ueX1tvzC!TEfdBv`YQ3ZY diff --git a/zic.tproj/HACK/America/Thunder_Bay b/zic.tproj/HACK/America/Thunder_Bay deleted file mode 100644 index 1bef65ac489c047b2fea463c7d09035080d919ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 758 zcmd6l`!Cf27{>fxyvPbT~8!lmt0b0M4B{HE448xn`NZd zqMBHxbrr2vN_%CiWyw3Mtr6n){(wHuKHIbB=SL9!iPF-#>@ug8T<+qgo(630w})pZ z8Ao7_g!2n5svak$LgE#;0Ln0rDj@`7lL1_*eFfBnR#f9EP^S~9@%}Pt_A78zZzXB9 zSFm5{-C$B6@W%26Fpd1on=-n{%=sak2h@{=UK?9l<&ovW1C**olJwJ6w3>7! z>%MBVc^v_po6>R1O&72&4Me*JeXv(3*dcco9R20&6!sCEEv?zbp$}YDHQCK@l-#~d zv-{jV@)#WEtsk0bTh|ZtynCFspLvB|my*ak`v&f)EQ6iFXVE7m5qxb6Q0D6cep=D! zZ)Ohuzw=qHtP1jXQ5-Pw4FY@IIOv56?YuxbP2$)IOomL<0=Vyhh>Pa~KhH znj%fcFv=#I_6qkgTCWzOsRd(xWkGCz1;)Jzfqm`G9DmCJ5^BnM|2bWN^khyfwWB1t zjFS^|C`D??sh&S6O~)4%MsG0tLHW)9wlL-o%wtE~~Tb2<^L zN+2ipDd(oeL!L(m=lglVVM!eq*v3)8EOL>SCl!r`aq+Y<9l7JgB|{=Q+8T<-Iwz>K j!V$~r9+4pWU$VIPxL+hJF7{p*lx4mVf-F2@`O(5(`WqD& diff --git a/zic.tproj/HACK/America/Tijuana b/zic.tproj/HACK/America/Tijuana deleted file mode 100644 index e23f80bdb1cb4bd167657ad95e89be0d4a0fdcbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 997 zcmdUu`BTgR7{74h^&8NqL5!SpWDgWpS> z>4P*J>&=6pLF|qV+6mAovcbkmOZfDm6F(RJgfA6!_*L~Bn$#VvNw^H(vTIqJcAdV* zmGh6N6Vx1VoLi=Dr=JcP+&cO={4$H-ww@W#*18Sb8)BfNY8n2%H48dRrKme?2SSbn z4R)D=VQMezmN1%(qQ%@j$b@=$8MDaoGl}+kvoSm%l2}$Vl7%kgo33^j{V&x!2robv>F~l1C6cF+R%lpwaz@~%>c5g z?9YR*|DqvJd05WJZX_4 z3!|0uVX-V8mqbp1rIKJ=<~bB%%-3-25Ce$S2J-UXZ$VM%#4BFjgq7zlcvZz~TCHl~ zHK%S+TtXGc?>I>b^O|vO%uY&le}+jj6_jj!5mOv?KuX(TOf_2$snwfteUmS2xDOwu4`cG=PwrmL*#hVF2eZ#|KS`4hX4PMA7Ehd@eN^c3=RP)VgLZi3JPoh diff --git a/zic.tproj/HACK/America/Vancouver b/zic.tproj/HACK/America/Vancouver deleted file mode 100644 index 6d6ce9589fd72a1a3610e976698865b95e5f5a6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1008 zcmdUu`BTgR7{w8)GJnylNN? zN(_^$Sz|P=80F|7>ntfHB1x-$_Ye3y^O!n5G7_#7MIg;OO~2@j!Kd>N~?g;3M|gljbfFY7MxtAcY>S9+LV zXJnE#cO$=1#nW4L7{5~l());M{6XeOALXG~ZyEp%Qa5a9n*xo77T8!JhR+|nv8nhc zG?!`dOLjH16m@ZH!gctXRmW}HZqc_m4S$c!r*^+Q{^7BUe%hsT$M`(>C5q-wqjc!( z*onUzqM@s5CH}cP7rIO2s5@f=LXHge_6`93l>XQ!VLTZ`Nx5%;3H9?dW<&cXGQ!Vn z43Ee}C})$_3)Ej*!~?3!VW1|P2VE@!Q9&WXk!%>8L1?-u5zJKUaY$G&h!sIN)O9Kh zlR2aL7$priHb;rR6G_?}dBodcWKl7cN8b8Hql!Ct^vPPn z1;_c^0Bi9Rl-lHiw7Z#QCfh+)_n2)Om%)V6Vz#YR)5P3EJn7O>vQuwh`$My6a?C+= zNVK9U@+5Rr_9G{02s%47&{RVgbg}3QF7*<0{ap`kWnDO}_8v^XV9qnHp9S}hn&nr@UMu#Iw;l6r?{zdsw1eeVekAWWfeM4kq^L?mpZ8`ouVgv;mfOSp zoY}bGyeaslNYQ`)cL<2`;=r}fLFqY;gM3RM*wT&c1;S-07uTZG=0f)8c&?3!w z4u7_p78l&dC6^adM8-LcJnT+ORhby24u@rmcw8Pa16Ifaai#lch&GMom{EEV)8@~s z{=5TKg#)jCbqCg59KvhM-q5=29~^u7HpL}Was2L6l(48B*GKQ6M7I~1G)F}nBv&!n zZZ{-%9>WyTDoCkG#Z4_fu=!dfZh34ATl2SYYSAE2?_9#$GFw5=`+uX;9Vb0Or_0(d Q82Eb!3I58Uo(l`YU%*FH4*&oF diff --git a/zic.tproj/HACK/America/Virgin b/zic.tproj/HACK/America/Virgin deleted file mode 100644 index cdd324dda6060522e31c76491d1be2e06e633ba3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 zcmZQzzzUdvq96hVp1}D3|6v6NhX4PMA7Ehd@eN^c3=RRxF)#oC%7zMT diff --git a/zic.tproj/HACK/America/Whitehorse b/zic.tproj/HACK/America/Whitehorse deleted file mode 100644 index 5d86e0fe0d4e013b4a25aa5f32b0da5f23bcb1c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 730 zcmZQzzzSG_q96<5f`3x+S1u`d&fRYmb1M=tTu}t$70K|K2Xp-%6ZGp!7Z^--nqZhdNx`UCWrDGLiGoQm+XPef zFa|8Fc{VEO-l?gT~-Fv$xN XXAq2Z31Nr~24WW=BLIYf90ULW-dg2J diff --git a/zic.tproj/HACK/America/Winnipeg b/zic.tproj/HACK/America/Winnipeg deleted file mode 100644 index 0676968396dbb4132ccb6af9f7d9d3c6b48b33fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 988 zcmdUu=~D~<7{=ccZ6!-=vaXe5XC*l*2_1@^%~5JgIbw^}x_UdLP`!-?JL3wCXhaw^ zjHGFlk|<4shDwx_Mbeb?3L}-4zWWFKp83r@^L&2*{)yq=b-)4g|2ohG=?1;J^wPUN z8TpxXzQh$DURXe--pTyrP(M|xOt|LI7I@*ek!$^H;iaUKUpd@?I>_dF(HW@MrEmin zLqo+ne$#ZC8ncdLQ*j)<)kdN&V=cYYDDi#5BKn|k#OC0M^igJoE%Jr%$-4C8dbJgGUL) z_E(Y2G?Zmcxir0P3ELE>(u|rAw9VK}Gjl!BE+L3!ot%cV)iE$9N`Q0afne|3h7M9^ zaGdiL=NXR!r?IW<)Y1?0dmpoNxegXI+~9@TeYB|XD7zeMBG+_ex9}2jPdjO0`1qP%-QD2zm?sM`!)AAaJpd^s$y9LX!vWU%ta5B82V1E0gM zc$G>@zS|4f&)tNS%hTCk(oO+0;(0YxQlRK82I{gY=*K=>Q<6e!YlCrJ)=gNS=Z3-B z%b7;>0}FR8~jv%1Tkw)`$O$ZM??Ya=K}I z`6Jws@|t#Dxr*TtMT7^m7_p`vBEz;}lyf0OFI|DV#OEN!PQx)hi4ZGX#<8ze5Z7tT yd+vI`-e*GIcWDE~-~7r6``sz=XbpqG{~5i$;FbaC_17Q%^sLJ09WY#um`3Y)0+EGT4$@iaIfgpzEK2TitwMo0T`}nMi57x;g4AdXfHu zCmVb)Bf~LM-tk10jJi~KXX{sjd^a>M8zGZO1KgGN1x%e*&@A8?nCrer3+p>zvAWDw z8Z}_`Zkny`KZRZ-mg^6hiwvdvfr*jE-SCnXG?TjUIh1H4cs^N8uqg}AL#1=k2*Cz*wh4vvgcTG OT#y9HA4#CR{oyyv>;4n~ diff --git a/zic.tproj/HACK/America/Yellowknife b/zic.tproj/HACK/America/Yellowknife deleted file mode 100644 index 44f1e5b63695974613878144d0abc8850ed14448..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 701 zcmchLeN4;&7{{Lyy)5hT(z}vM*Cj3~y-1Yn&ZX;g6?M^@+$p73?V^{*lr0NS%-C9Q z+6;}tBEmFV^Om++8#QmuWHDN1h4FKzfBo(A?DO4c55PZ}WB3|1Qf|=L^P9RmxVgui zS_US$_1um0C$-i*nBf4^5>3I3cg^IY>?~ZIEC*YK4DCY1U@!JY2lps)w6sDeQxQ2$ zd9m}DB`q1WV3*#HoF==WhcPfBZ>#EVe*pAl7wHTnDp+M1QT^u#@7D^ETf)*bbwdWP5><-rVKnZ%0XUznN2pb7{xLJGiqemQrh*FzvJ- zrDqdnR4O4;k%_xfC6FbS;_mPTpk0{GI+w4Yn~LN;zlI@u(35js-h{o^=5cP{5arc> z;C<)2D8KMA7aTc5g_?0J(w0$i=p!tVrOo+!J83`P35T|ybbL8XC-ZAc20G}h9pcK?b6lmoN*9xXt7Y|c)g;sPS0UXZ z1L$U{gVZ|-(h)t}1qIx@RPdN`glD51Ylr3_GdRGjeFEzeXW?DjhxMUi`WVOQ>->Qm zf(2}}iKCy>H2mKB(tq|Lp7&GbN)Z$8x_3&^%rGROH1a%S_eZ+;k>u~_VX(t+GwFXRmjGQU~Cfz~V3 zmQF)wsw1+0^Poo0L*Y|A9I0Z#ng`TN<*9LIljagwz%ai}hlO7hWRhvMVmMxM&uk>n{dPsw?R5-Qq~HL~epWqHWT z41H9qwO#p6mW7s^%xtly%NA>`k%!3Tr2gvf-tWC%`|SPM=f4lf{Zsl&tu|VfEJZtS zoW9w@O^?;ktg#Q9?dpfQsXY9l`ULYYo!Np?20xpnxLEBBnk!DIe>Z^m))}?@scte* zx74nA*Gz_;6}4+0my=OLX00hG$xJVrnW@4_Fy_h3+r(t?HVQ2(&1usE58SL+pe+?b z6h;bQYlbdbxz5A35H(s0hQUV6F`Kz|ur(cJwnKHWW2Tes?08PQ2JbPu`Wo8(w3OKw zU!XlVQkg@10>Sx9=;$q>y>Tfhva%&73`A!`UvLrHqszp05OeEL+`|Xg&vwkMX&l^N z8?k+5y|BOWEAvQg1U@B|l=`qGs~(zs7ux%Sqz+5G9ie@>^epe*IGN|CWmf zlo=49ion3?PzY*s!{7oDgj8DM!6*|rlrLtX?lT~bG-oo4A&|Q+urS_t3Kxv9aP=S^ zo?|Sc^BEl(9mdFp+jO*}9iuK5QgnSC#-!hZ*y0k53od|T@rf939|H;Aet6snA<-^@ zC4RAjBtr>Hdc%X{30s!(L`bPU1}yEmE}dwaVCkpSbh3(%8DXzTkv)!?&W)5M>&0x7 zGRhIPV$R}y$Thx-xg(b$Z!!x{zes~K@5@>KonSbtRIq{~2PmwTvZACwI#=Mtbanoi zw`#?DtN*XHzsYeLO&8;M8qGkT4qv1B_(98ozLmykdAlJtHkR{}%9kROb3Q@KkpDja F%U^%93_bt= diff --git a/zic.tproj/HACK/Antarctica/South_Pole b/zic.tproj/HACK/Antarctica/South_Pole deleted file mode 100644 index 8a2d81e8cb0013ec736eb07b23fcc0d2c694a362..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 730 zcmc(dZA{Do9LMjUXxGC<(r%SYin{9=rBa7f*MlDD%BkFa(RE!9^gvEHZKYo+!J83`P35T|ybbL8XC-ZAc20G}h9pcK?b6lmoN*9xXt7Y|c)g;sPS0UXZ z1L$U{gVZ|-(h)t}1qIx@RPdN`glD51Ylr3_GdRGjeFEzeXW?DjhxMUi`WVOQ>->Qm zf(2}}iKCy>H2mKB(tq|Lp7&GbN)Z$8x_3&^%rGROH1a%S_eZ+;k>u~_VX(t+GwFXRmjGQU~Cfz~V3 zmQF)wsw1+0^Poo0L*Y|A9I0Z#ng`TN<ocPGQ!bN}cFRa*A}n>qt(gmM)|tQR$)^j_9D3N<(YS(jL~NrO9P2 zmiUl-2+eg&9ZAhXvpFM_99`tHHm8~S(r3@J=Y8J&_I`W?VMZD1>2#)bT%YNEZk<#s z)b$pncEq&lItL@sbxA_ac{!e*^hWm)M?6zopeNl3Ls#uN+!Te+r)3zaaK)DbJLqzN zuL&ZIhL2**Pm6JBFD4`p@C`anx*1|p*F#fHjm|7O6brn5(%fN)7G|$0G3cUX>^3d6 zSGn+c0~g&pL93g$VBOpTn=@x&TS?dzABMe3jm1gZu_Q_fhad%(y7q5x_gQfH10$|z{Z5yQAGxynC0)y&&~5)sx@TOWM{++r)vfT7wZnVkDfrmb z!`HI_zEh>}x2mT9KpFym9IIX>FsLzwvi3l(E)QXFoi*2FIWVLw0BggI>r@es4mdl9h>|k_NC1RS-aeZzsHdG#E?B-+K zsLEuVpNh(;aBh;sFy6(P@ssXMFb_k*3sY{HaKhHMaVGZ7LsEkYl3Rzdt#k}2)f%Lx z^dYU}6VrolV0&^WGwf=SDQjWYoa@ZCA+tZ!FlS259ghmRb3n;mO^H-J%){;q8FL%s zuqVfkd&_;07aIh1mIV7eY_VVQ0|!h5s+59Am}M}7MYF~K--2LmFVcUqF$D47`G@@Daz&g{kSmn>Gm&2U()Vv8 CcJq$_ diff --git a/zic.tproj/HACK/Asia/Aden b/zic.tproj/HACK/Asia/Aden deleted file mode 100644 index 0a3c20f3a8f90ff73d110655e7978e95ba3b4002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ucmZQzzzUdvq96QsYWs8E=k?8{3Tc#=KEU6UGol>Eo*AgwDUlOHYkYX!f z7+bc$sK|MOv2DZxlOWXzrm|KG%#7G4nEjPmU?Hs{U~%W)0?XfQ0#=yLcnI} zUj^G;rv&U;?R)V@+3ZSI(Q@{;qj} zCv(6A&vU5@ydE1(@LuP>z~_v=fN!7X0>3qe0{(g23j%tC1p>o06oRt93Iv;TDTH`m z7YG%5qY$ROQy}cyIfV$3s}mxwZBU5(vVB6-wn+-nS7uI#nZIs9?3U^YarF}x#7~Kx zkPu(AAhEVeAjv*tL2_)2K#IKCf>c{Ofi#X_g>+d3f%F%q3K@Ty1Ts&ED`eeyB9OiO zr$Wv#h6%atw-xf1KAMo9zE`23^~i+6fSU`7QkP9AHrTzO#I<8WsleO?WqL~m%0ARD zsNicCsJM{0pz>X&K-C841=Z)g1!`s{DAcag6{xFpQmF6a7hq&&f diff --git a/zic.tproj/HACK/Asia/Amman b/zic.tproj/HACK/Asia/Amman deleted file mode 100644 index 6e447126126c0d751e9b2fa432c32041183af2a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 684 zcmcJNeN4=89LMiedKR`8Q*?Eu2b70%Nc4E+DxI!VB;Ky;qzCD8Ds);}e~=+Ie-Mq> z(!((MqpVebAT@nwvUynEjEt2wV~y6P-~4Oym-l<`*WUYl{(Z}2f0g~rRf?ptnMmFJ z{`D7PwxxoOZY??|r5aA-Bf`ZYpDsi5b*`T#==RDg-2448r~ZlXXm-F{ORMm18-~wS zXR)|`8cV9F^R>K%!q}(tOY4Py(uh!+9v~pJM+B;ivDEdN2y!iD(0i>e_(L~B2FxO~ zE0@b!62w*mcu}>=VDRyB64!^9C@-U~g={3z6pEg4OVgg(^2NP8d=c(n1yw5EV}p+2MPmOT=obD4Y4T6Xof`>R$skHh!9eS+{$IoeurMAg|w z z8sEdeYy#V}hY_F~KwwM{c7&M_ByUErQx!s_-3+mIaOan6^P$Gb`Os-?@2;`n&ak00 zhChhs?k*)Gt_E;V?N%xZrBvoB5LxYny=oWiOaG4j-d3oT@1R>v;JnW-MW!PvH2jO(spd{F~6t(`cOkV9=jH4X>GGC^y=5t%;|164>|P$S9S z14&bUNdB}8-7^VNCf%57`V9TR52jU&10AzW&-}=vWh2Z`y`n*PkH_5lm>G7NnM>`= za=nYJnNpsxw&0{$$L#5R^Bhq`FVlF%TF65Z>uXv zohjcSy{F}Z%$m{*vUAcd$n}I@kgxH$ppavEK`}<_f|8H)1!Wta3o6=wFQ`htyP(E> z|AIOzcYykrKLHv~ekW*FEKbn8a>zjI$WjIEElUh^mb5GAPH8jHYspm5FUc@4Nby!M zjGc7As3?Aev2Do#lOV?prm|rN%#4&bnEkalU?J^bU~yOKfaPx`1FJoM4p`r2F|b)C z>0rC-nSovFZwLEXCkz}??>aa(KiS~qy5GS$`Pc>*)rAhO&MP*!u{JxnD|c;he>eYt zCv(mQ&vT6jydL{)@LrdEz~@Z1fp4Gd0lziA2L5^K2LgKZ4Fbbm9D;HL4T8X36xWZRAA?UGQEQaWgliA zsNh>{P;sI5K;^qugQ^Yj2ddAd8`R9Kaj0GAX;4=g=TP6LZNSLP1c5B9NRW-4i-Qvk zxp`;+85r~xfC-Ah!hwN>fgvP;k&}VJEda!ZkT4NOey|!*uo@s6C<|mmNT6OYn~~qg fH-sVB!xc;fhcGw>hCs*=kQEG!Kma7cYy<%Sf(GSU diff --git a/zic.tproj/HACK/Asia/Aqtobe b/zic.tproj/HACK/Asia/Aqtobe deleted file mode 100644 index 6ff44005bec793a871d067e4f94df7a92961ca82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 747 zcmZQzzzVp5q96j*KpyVTcLD`1qf{OOv3#!uZE~s(e zzo5>_9iaZ@Pk_dg-wB!(ixV`j95T>4vQ$BP%Mt^fCG85jQ`!vlS~3;%OEL@$QoI!m zV_P;D6$LIZwoTh$5@fu38eV72Gn2J2hj6l|7p z8`$o;p7 z65<;+B-VB)B-tlzNRG`?NRfBhkZS9rkj9Z{kS?pIkp9BiAmguqLgooogRDEB6tY*a z8{{10TaerS(jaf?hXwiRrws~PFD)nxc)p=1b<2WcgOeLdT&FE4639_+sad6TO zGBB9V0HrJo2L=`fhL8kC4h9Cd01z8O!bBK(!D@uTY9zq2KsHc~u#ayDgQGVH2ZI?P TGB5;80GS}b2n0Y9%!UvEmq6Vr diff --git a/zic.tproj/HACK/Asia/Ashkhabad b/zic.tproj/HACK/Asia/Ashkhabad deleted file mode 100644 index 2859f3cc7a4e2ed361371514128869caf6a2c345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 273 zcmZQzzzVp4q96j*KpyVTcLD`1qf{OOv3#!uZE~s(e zzo5>_9iaZ@Pk_dg-wB$WCml2^7AG(=GeIB=D-vX5=ip>uFxvxil7#~U3j;$)0wYkw sEda!ZkT4ODI7AJQ7=eI+5zGV=0QUtsEF2g)FxVVUz99^b R!9eU10#eGz$Oxhs7y$1}zbya& diff --git a/zic.tproj/HACK/Asia/Bahrain b/zic.tproj/HACK/Asia/Bahrain deleted file mode 100644 index dbd08f864981c5d188ba189a2864205e53f188ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmZQzzzUdwq96#~1I-A0 diff --git a/zic.tproj/HACK/Asia/Baku b/zic.tproj/HACK/Asia/Baku deleted file mode 100644 index 8efd48ad950ab5b36aced8e25441057ac5489f1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 745 zcmZQzzzX<)q96hk;+Pk^ZU%mZQ)=M2O-&N_(yV%#9{is69dZBqlO zGpz@t_e^>qv!?lh?3|JZay_XJiv7pyZ?ZK-os>fr<|I16Aoi57fBd zK2T?sOi=&Im7uXV$U);NXMyIG3l3UGHXCRid0k-e?DYY|*qZ`IMOy@nZFdWp1Wgk# zm7ObKW>g_y_P1WZLVC&si@S*emcPp;SnYKdu)ZBJ!Ddw1A81^9iobe+ArFPfl=GzAxbZ?wNom^Faa6b0-A69xoQ~UbjlX z=gj^IzI{Ccerpy^@XyN=27A%mT zAwQv@%~YT;&_w;OoDk(0w@FkI4sf5 diff --git a/zic.tproj/HACK/Asia/Bangkok b/zic.tproj/HACK/Asia/Bangkok deleted file mode 100644 index 1206ce546c6c2372d175a9fa5fff605255b1b859..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96fo3K&?Nd_x#KokKue1^{T=1$zJh diff --git a/zic.tproj/HACK/Asia/Beirut b/zic.tproj/HACK/Asia/Beirut deleted file mode 100644 index 40a523b5911c1eb9b6924abe2b14e80278ec46f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 769 zcmd6l*)!Dv9L0aqwTo0^i70esr`)R|!llLXm8}h5>y1K|OO`NAH8p9I;xpown}Of!}FK5?_p&^|Ts-XGBC%$YgoJRd>$C##m%6|YdS?3JwjFeQoWi_bwr zXgN0ebWxM7m>-GDsCnBWH&1th%KieYmYiTp_XSRkB2CZC@Jx3V%#LL9oYEBL+Z%DA zD413^#i7WdfHeHoSyQhSv}~lPH9Jl^qIA|7F#_GmdDiQw2K_;6TvItj1}!2q%y~j) zOU}IU-90iNO+<@Mf=%7G*|JKVtf~ibvqB16>K)lSrWb7F@o4KgPg}j7q1enC>?~Al z_bZz0g$%YI)+UFpVRUTh0H>;UbUuFzT=FW>HCX{}v2E-ga+9`u-{2iix#VGy!xH@{ zlKhTj>8zAIKS_A!TT|NAXTrO?CE(TMf!=paV9!Nk^ili--;^J?H|it!$v&XJM?VDE z_MvRU0|*q=Vc?%$3YvS#`^IZ&|L}c2&|gjm+sZh&HjzTEC2(kI0EK1xGsqJlJO=Sl zkUvC7{V-B&3sJ^47_F%Z(cd&MX5up(9#i3w*Kgox_YfX?I!VXtCOG!`AjOppaC}xP zVfmuh_jgi7|l=Foi%3pZS1$>vzkdg~ul~7T8F&DQe rp+s4OXD=5+X<-qTrNx4v_8&>GcU41(_^zxeCHxk^~aV diff --git a/zic.tproj/HACK/Asia/Bishkek b/zic.tproj/HACK/Asia/Bishkek deleted file mode 100644 index c5fe2fee3b570ccae2b9d8051a4511b2d8e2b6d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 720 zcmZQzzzR5lq96fORSQt6L@~}gMp}e?E*20O#hi|pyb1QK-v1=0Tu1{2UMjW98lxF zctD-yuY>xRcMcl++81a(H#g8avQ$C)xTJy3l6D2%WxoydS~3;%+wK||qCY=QAq!_!yw~^nnLESSq51vDA69lrbB0)BG4jMuR2G G5CQ;e7}#_G diff --git a/zic.tproj/HACK/Asia/Brunei b/zic.tproj/HACK/Asia/Brunei deleted file mode 100644 index 7a43240899b53ccefe1c4707dc91b94112572031..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86 zcmZQzzzUdwq96mZ4*&oF diff --git a/zic.tproj/HACK/Asia/Chungking b/zic.tproj/HACK/Asia/Chungking deleted file mode 100644 index c9e99cd561a29801b2017e7fe161163a73788ca9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmZQzzzSG^q962USfy_SNO4F4 jBPRnxbOs}k9i73z=j<98!r&PU#2!Gx$2$b97D503WEl`U diff --git a/zic.tproj/HACK/Asia/Dacca b/zic.tproj/HACK/Asia/Dacca deleted file mode 100644 index 63b355f8fa60826b351b2a0fdc3aaa239f89e4cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmZQzzzSG_q96z?kcV#wgHvcw2!m&E2!o5GGmz&J0#XhI0DF!T%>V!Z diff --git a/zic.tproj/HACK/Asia/Damascus b/zic.tproj/HACK/Asia/Damascus deleted file mode 100644 index 2087aebb3c38457f2c6259a1fe243ae30dbbdcb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 836 zcmZQzzzUdwq96CG5mbE`@^rF9t^(^ zy)XE4`z*uXr6mRb_A)g5Z(II>VV(&CWBTm^ruy^-W>3BkEQxO#ShXjAU~^VrVCOkr zz@ZY{!14Ci2QJoj2CnmZ1>7%q7~qY^|V02y^2AxQ}Tn7O$mc?_Ph@&M*AC7Rb30zL|q!xS=9^FzePXL zcs?OO^O1Cd)+x~d?M>PVI*a2k=+1V3px09qpkGs+V3521f?+&Ef>D6U1!D)}2PTFY z0j7%S31&jGFPJmUdSL$fe1OGM`3IKQLISLg1t(Z#j48h0-t=i|(=nSGijk-1u%jaA)8PaQ_(hz~j;60MAR461)x{yWqX~ z=mVc6zXE)x{7mp`)4kwdUY8J%vFSo!#Ks3fp3ee;EuSWYXiHuQm6muA#^W0h_IK`s z@OPI2BJN#Gh`hjhA?g6jgXoQx0Wk|L5@ILiT!?Gln-E{}@j^n%hX;vassTxEDhbKv z5f@U_!ylwd^aP}F-g%JrTQDH~wLn6~9hVE4XPh5o?X3vNUR$1!GjH{U-2Oiad5s1a z@(cAJ6eOht6b2hi|pyb1QK-v1=0Tu1{2UMjW98lxF zctD-yuY>xRcMck-QWZ3wybaJy*k{1V%mjfftVocJgPoIs!Jz@@5(c*b1{MZ}qyk2u uNJs*R4IyD7AaS4?evmk$Fof;n8^Yic8Vn|YWQZ3C0~sK|2n1jTlmGzsiaW#r diff --git a/zic.tproj/HACK/Asia/Gaza b/zic.tproj/HACK/Asia/Gaza deleted file mode 100644 index 010c8b9da10673e0fd657f057b5370616bdb4f59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 363 zcmZQzzzSG^q966c7hR?-P1z)Ut8oq|kFZd=W*zn!#(ueQ=T^W8#uoe7#c#7fI zPs08_!K31*tC0gMb-ATtvI$iN_@01Ood fEdxei=m1Ghun4cKYY2m@Yj6mIrwb4RX&3+iQ*m=- diff --git a/zic.tproj/HACK/Asia/Harbin b/zic.tproj/HACK/Asia/Harbin deleted file mode 100644 index 9f591265e7710d49a9c4ba6a3e2fed8e2305f3d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 186 zcmZQzzzSG_q96fz)*GsWJ`Gm o0}BH~K?4IP14G>e5W8*yBd?Ed2!n@XPzZx_Fc7d_-VQ0 z79ZP+TQ{Y5+x?uyqtcz3+H@4w>h^!Gd7oygI6Uw(1N zhZTMrAHz5A_|##b@!8>m#g_~rjjsxuEWWva(fF=fXYoTcQR63Tg2m6T&Kkd-I$8X_ z7r)}qxwsvF_c^Zkx6Wb5|9Q$Q82XfUFxIiIV9I0J!5sU11&i;q9jxvw8f@mw7VK)z zG&sbbT5z(R(BS-b+=A=bDh=*yD=m1A^=R;J>$c!qmZu>&+tNZPKWBw-wX}tZzuyYu s?Kc>h7^wi685pv`Azn9u5l9y_FmQrNULW5O1`qFG5D~)Q45VQI09qHA$^ZZW diff --git a/zic.tproj/HACK/Asia/Irkutsk b/zic.tproj/HACK/Asia/Irkutsk deleted file mode 100644 index 944623f2edd9aa7aba07cac2ff210b9f9ff19094..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmb`FZ!FXS9L9g#DP_Y8f8%&0A<;!7eR) zvo$kYYE634rqX66nMJmgTD3L1n%S(h?#J4^=w;8d@3YUIeZTL%g78n-T3T^LRar)4 zhkNct^3O9PjRSmnh8mFkXZbPhy9w6l-SK9HaaBx)-rjqkqSvZ z72{eSU5KZ$Kba|GYNWOW@>pLSj-Rt*TB{GzPX-`EFG1%1txzdH;e^XKWCguI*77*A zofeoqJ%F60XUu(g9jB&xnRmON>cJM~H?*^$qnw2W71Y#SLs6WH#p*JYct=nhn}XA} znb65Xp!*VzGpmj$9d$+7+z*uZu0a3Xo@bli;#`lJ=XFnDXqx1Ov>8@t2YFHcn3YLg zta7}?>X7@WHaE~{-wES{hBb?qaCsn+SH^Qtd!rC_{n4neNkBuJ3|12BbxUnFc++O7 zwPa)Qe_0ST6XItT83d^y)VEu05d?!tDmd%Az%}#2;Bk B)QRoWFd2fw_E3GkJW`{DD@rNrmaCJ#)dL&ZEv_4Y)s8q!oWHQ?DsGlACx|u(IEr4rL z_0pE_&Ft1pGret4bFHn7wC!m#cc@6lYhkvrsIrSBt-`CK5Mot)wfAw|^&Q4q%`TrqP^ZotzHT?%)Phx>Kks;heJf z>W3tTkfCvF^v>QrY8Ppm-qq%cdYE{s-fgpnbL-aVJ#OA*o;A+g@ahf3Yi$V`k*_2p z)8>*<39-aGd@>pBCnG){Ze)yuJ&}rn)l!v?mzsl6_S6S`jV?I$h8V}`zMx;-OB}E1 z#0izHIC0fQ^jDt1fOHcC7VBVAL=yxh?}lK{0}v8e1|j__2zA$BXwMRme=EhXOVKc; zD;2}F85q$NhEuDeFtWx2r)7C#RHYoI$BHmo=?*h|o?}dOKg5b|VVw6vi0gd@@ixs6 zZ)ky;PY%PZ#s)}eyMl?^sv+t4L7ZJs09^G(oHKt5Cg*2j%H(`hB*fud*Cd?h=Zo_` z`(vteETncg;R3S^7M|_HMMir_s~rsKx;L;`^${{O2A~;6ShDUFE{!|~%hKCW>9r3s zBN{Plz!}W;M9hA%2Xp$1F}I~0m-i?zuYM8c-zeeELvfZX zlmrZiRWV;-^a2-D4;l_!-OCbtvyO;hK|Ls4z6)+I?4XUE={_7}+^RBGuezQyLUc%}9%^jBn`955?ImU78zZ%1rt@}C{nV6Ya zm{=JYQWStn8PXLPSQr>GD?nu31O`q9hJpqVJE?$y#mhH@!OJlWNCby~)WQJ(J%1Pr diff --git a/zic.tproj/HACK/Asia/Jayapura b/zic.tproj/HACK/Asia/Jayapura deleted file mode 100644 index 697c6fad44cba559a0e5feb57a4c21afca39a52b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmZQzzzUdwq96A{(&2LsNo`NweX*q00E`_mp=SXp`DVoSn< zOI;@mE~jp2xRU+g!u2STgzNX^58Tk-T5wa&?ZGX97awlD-u&S9788a$I~5+>ebCEr zZ_Bxc`%CsWJm@ZCcoYs<{Prq=Ynkx{nSDPV$aa3bAa~|}f_%cv0EMQF35uRuFDS+OCMe5uUr>oM zNKj?44^ZQN`#|m5vkU64&p*&Oz#O1?^&G59Nj`dOa=g2Zv@8x diff --git a/zic.tproj/HACK/Asia/Kamchatka b/zic.tproj/HACK/Asia/Kamchatka deleted file mode 100644 index e33ab594a4035c19a5b3f378d2c4a61a3ccf9764..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmb`FTS(IZ7{&k2X%itM^M1+uTBgo4F-=|R5}UW>5>2Nkby=EOrsg#Zl>##g3{oR2 zvcyCNiDVe~U>8EfNR-UtK$7)h1{zor?XLtq^w>FkhaZRUd;0|8pOTqcaYR*^Mr4~_ zr=Ym`x1AGqa)rv?QEzmRWsf+lTvIxJxvFxS88teO*{NKHz2Mqs3%8q6xVJ20Ywag^ z6i>r5>m|H2L-3C5g^zzHd|fWX&$=FRX%FQ~?c6qZV^LA1T2xGGjoU{+Ch~XYY z&OGIw?omcP>0)&Aea3WLpvrKGdmC?IpSp;#`R5Vmn@DwR9`;)VGTu85@e3LxnEN4N zJOBqi%Ao1DLE@MXlUlzaxzCa*C2x@0@|oK7uRK`%ifLi5snhiFko_a3`(I)D_v_5q z@(>wQXPLRwio=7M%$h7kc2_0z16t%XWFWUK1jvoRk@^(o#keA0AIt*xUob@3@~F(2 zg|5pioL}X!)oC7o@qtCNLo9wU!V}M?P;&7uPj){>X<-vjHFw~2>K&9B>TpKch;nrf zDmEEV8Cb*0#duV0%x2Yu0@VxAtT9@ncHDz??Q+)lOL(r@iVdxEG&7g1TWax_EjLId z=6@Iemj$71Sp2LGqaYQ8!3i@fLFgF~c|HF$VlVC_Ch3G!wQeoabmFC8X3`p%;x}5N B?lS-Y diff --git a/zic.tproj/HACK/Asia/Karachi b/zic.tproj/HACK/Asia/Karachi deleted file mode 100644 index 1571d2b7a950296a2c22de763d4a270f928d7902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126 zcmZQzzzSG_q96 jqca$Rq+0+32bkpb@eN_{3=U!Nb_@z(2=ER8se}RmEyNQB diff --git a/zic.tproj/HACK/Asia/Kashgar b/zic.tproj/HACK/Asia/Kashgar deleted file mode 100644 index 424ffbcff6bc47080d24fd4e304f303b4593fcdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmZQzzzSG_q963HjHicLR_*B;?*mV;A;(~;tLWje;`Tr97$haA!X%f zri|P{>g+S7-MWnQ;hW63)W^);Gu+c~ky#xz%+6|LPW@@*2IVp@Q-gemP!zA3{(xXOF!DF4#9FP~2q#b-x|=w@jhr$}g6x9-*vxoCjhjSzd6D6?n+XFfFSr zuCv4+GH>=GF-64c#)TwNDPe@ y7yp-qNS+^;GFwQ5C~GuWDnxFXo)_|Oqwn=UQPE1Fh!38R1f_nH!a%2a(8V7!4A@Zs diff --git a/zic.tproj/HACK/Asia/Kuala_Lumpur b/zic.tproj/HACK/Asia/Kuala_Lumpur deleted file mode 100644 index f503dd8b83c1bd69dd9b14bd1bd6c5ba10ec5c6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmZQzzzW!aq963$PVPvC!W$=dG2t%TnR;s%-=j7-c-EUXL+i7_DM uNd*in3=HWCAhK=(11AGRW(9~{(7?bO>>I-1>*y20;1vvHM23LW!vO$1y%iz= diff --git a/zic.tproj/HACK/Asia/Kuching b/zic.tproj/HACK/Asia/Kuching deleted file mode 100644 index 8f9575c6d040622ae689c7829bcaa27977921814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 211 zcmZQzzzW!aq96m1dc*$D(g6o!*EAfwx**`N-2;Zh+b&-? zsvz8ObOw9CaYlEB>C*Z(gp_r D&a8^d_x!2b!t%cS;*Jk1{4_p>Z{G2#!$9M+c}l~V3?YrL3Y#px zxqs34&XCOTLw(7IpR5TMKfgL_{CetS@%vuYBhaLatDX(DYQ`*5; z$GUb7YN5&HHi4j7FfhGGB7a`37HufvT8tHtee0H b^kG2*11Ff|_3;g1@bwP{5g`oDKpF-BvKUdY diff --git a/zic.tproj/HACK/Asia/Magadan b/zic.tproj/HACK/Asia/Magadan deleted file mode 100644 index fe9851e165bd2ba6021b9ceee49a7e4bf89ba412..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmb`FTS(IZ7{&j(nOad2<|SKdX7f_>l1|IJW@c`=yy0!l^0IPTCvVKmd`Kx$i$a1- zQYcZwY!4zOJ}jtwNJK=WM5st9DdZp`6h`f@1U~fGIedp7hwpp)1mT~uv$W!fsC z+n=~9yS}{d`?ymcrg3sHn4RrPC!BwD#=0y#)VR(}ns<$PY1~EvvAf?BvW^|t(;|U; z-7-83^YF}@#@>`sctt$NKL0*=yR~EgmS)JMLzFM~&}Xhk@HM6izEe80->Z0&|Db^f z9_RC5o0^KoXa-aTFtEsjL0T1pE95v7r9eoUJwjy;PzHU2a&-yeZng}coxr=Bqu*INJ4!>(ILltoq5Qgu7rNizqW&(?)Qd}+XQ(K?iORq`s7fqD zwL>Lp6gODIOc=M7(l`-@+C>#Fn_N*huHcpXp{yTp;MH1ZHnc9$N@Bfksm%s&vXxp( zHWvSv1);UT@=!ucmmn2{UbB_GAherAUeCXc*o!+Vb%vmhOInNc4DnL1vSY@+)rEU!ZX;mK> l7?~IuK#-ws0+3)RXkcIku^Bi6Jc2_Q0z5((ynr+W006H37f}EJ diff --git a/zic.tproj/HACK/Asia/Muscat b/zic.tproj/HACK/Asia/Muscat deleted file mode 100644 index b46c0c07ac9ff10a9e07e9f86b6f017cf3739672..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ucmZQzzzUdvq96WM_68(s;lRM+;~T=@9vlMVG5`R68wN)J diff --git a/zic.tproj/HACK/Asia/Nicosia b/zic.tproj/HACK/Asia/Nicosia deleted file mode 100644 index 6d5dd048af94ddbb499315fe933dcdc536c32965..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 716 zcmc(ddo0xf6vuy(#3k=8c@`3pSFRKhE-JTsT*W+G_t8mF9*Osh@UTV#4MO$jU zhPEbKSg)CC>1>s?m3CT9+Pc;zJ#1R;|NY(1KBjWqODd=cKNetpU&VQb79Buhv4M>02e!Sg4pyj zil>^v`QssUd07NY9;wl_zlq##9c1?lD)MM4WY78(@+wK@rP%?rEY+XAqpip%P{h8j zleAo9U_Ubv_)S~licbdcfAtju9>0KbFJK)UgdL)Fw@)|GJh_>tnn|fZFB;+4?Tk&y-#sx_h-uP z80VamPiU8Jm~+c+66W4urTjSM#kO#Ma2XYNYPirQjZ_Pdq3V|g)Dxvx^ah}KSdP2< z!eGy}P%LS4gwn$fsHy$|W$J0%tF)(mX?9#5_nj(2rnu5;l(e?5xk~7xs&99>n$OdI z(sRxIdaCWI~JX4In7!YDIUl8291dCLeLXb++ KjiE4J=J*R&6Y|Rd diff --git a/zic.tproj/HACK/Asia/Novosibirsk b/zic.tproj/HACK/Asia/Novosibirsk deleted file mode 100644 index f92077237c8ad1a0a809b2134ccb6b896f2ce4d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmZQzzzR5kq96I_hf94SrfTIc8=EuxgP5c@-;de6mn!YD8}$@Q1br2LD~Al1{Ljx8&st)ZBXMr zyg{Aiy@C3d2L>8X?mK8!v^!{CnZclSr0RqAmL&!{OQss=PH8jHYiV`RFDY{{NJ)1v zjGc7As3`YCrm|rN%!~{VnEkalU?J`2U~yOKfaPxk2dh1Q4p`q7a0rC-i-TS3ZwLEX*Bl&D?>aa(e>&jgy5GS$`N{zo)rAhO&f5;Su{JxnE6+IK{%-yO zPv)uvp6415cs-6e;Jq&SfX|sq2j4!|1Ac3w9sKju4+QksIs}HhI0WU$I|Q4nIfVEy zI)sXIID~0Gb_o0S${|AJ|AB~WXB;BGJUkG!ZJk5(mBR;O=ASwcyJhKtxcW5*;-|D9 zNQmz{kXXCKA<4erKyqxGLyCORfmGWJhcu3Shjdvlhx8YL4jF%S95PQBJ7nGEbI4vH z>X36x>p*V%cZa-XJO}dAZ#opTzB^DD@by4Z>V*Tv2GA=X$1c5B9NRW-4g^8J! zg^isykb%K>4=81YBrvcrFcdT}axyR^6@b_f5+(u?2dVM#4Po%}4+9gyAt0R$j6eWp G00{uRY2aW0 diff --git a/zic.tproj/HACK/Asia/Omsk b/zic.tproj/HACK/Asia/Omsk deleted file mode 100644 index 1c09845a8006aaba7d581b4591f3809cb521ce7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmb`FYeb#_u*Ss_>ZA`}{3pe12NnAJWd@JBy8hx2eaygy$-_@`vHRg9<_Tg1NM zo}y9nZgNiJq_T8vb{UX6%lbW?f4sfu@?o}1F{O~Zj+At{4V&rSYohXI2Dh~7>Cq5Q z&r&tFX1Q~lVLiPfesR0{Griqj(`W5Vs-%lh&0Dc!_LI@K_KMMWyhrZ$i8xr)X%Et1lskzDG5l)XMkHArySS%x(A4AQ=RM8>Ay z%$OL#k@+_~I@E{E@yE>Se9r8_JIrb9Wo}0+^K#pH%+ihg$VwJux1i7?nMK-S9G6wV zq>O{G3aq_McN}u|%to1v}d)BeSG>OV)D^D4}vZ`o|r!}uwts7vC z`~l4YFJPX#!CJ?D)Q(wLXT6O2`?)+bT7!mb4Y2g3<7{0H8r#DlvA0{c)M15Jt(Mx^ yuN?kw7li0B@v~x#f>aRlD Vf(8Z-AKws$U?BE%4gpDn0RVZa4&wj- diff --git a/zic.tproj/HACK/Asia/Pyongyang b/zic.tproj/HACK/Asia/Pyongyang deleted file mode 100644 index c96feaf7ba6deb5d74696826d17a4e6636b9508b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97 zcmZQzzzUdwq96#~1ltIF diff --git a/zic.tproj/HACK/Asia/Rangoon b/zic.tproj/HACK/Asia/Rangoon deleted file mode 100644 index e2ca4b8602f76d8e1d28ee2da03259863093edb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmZQzzzSG^q96oc3oiUr9CP~9ABl^z(myaV0fnPfK=RQUAnCdZ44hy#Z;)>Y SgHvcw2!mH}2!k(>0|Nk-CJ$Et diff --git a/zic.tproj/HACK/Asia/Riyadh b/zic.tproj/HACK/Asia/Riyadh deleted file mode 100644 index 1efd826ae1a67d87a377ffcab2740d41d8bf7050..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96RD_T;(10Q*LkAU=kRg$1(m+B* zD$3NMj^;EEnqTSk@_Me%?|*RiTK8}5b$z?{UVGi^78Cow^?4u_Jp(n!X#i0#q5e}i zS^b~rCiP!!e(HS_rPTX3WRuu+GZG)uP7(pZBzZ}i2FvD?PSAEgETCNpcyEB>%39Mw@RUh2+7c_#}gr4RvTtOgX8v&m~pO4pIyErg1kvlDcXH zQIG_2^=_IVr%V%GqnCAk&hj?lhqp+Ed9m;uM)Q>XDh+ zQ8Eu^vZ&clGv!CoET3IuRn|w=QtQdaElXXWjAQK)D-e@ zDWDZa^0cyd2l?7}lV9dCTK%Ds0xYLfU`jr%d8ReHmRV7xWEn-ds8e)d3T^KlL^1a3DE3en?fkHm{;+7E zT`8s%|MWB^8fj2c>;c-{F@%z}q9`T&JEb-R(q7f4v@gh&(yDLMe!1CnV0kqiESo}y zBu`SNi!Nmq7EpFCQI7o~%FR@wybq~Vkdj2F)Kck8O*);GSEX}4IduN)Br2CGrV3Xf zT`W3Fl|L=0%AuC3v*uGxcN<-q=}uQuUs7$?TDmsnC)LNr()D{I=%&sAYS^MdjkiwI z?eV766w*M=R~A$2s7KVcGKlV+>!Eh(IOXtsnEBQeEQy}O+Aih=tr&@^?tcR|5(qVUuiA$-&aehe?}*ZC3vxfU?odNzG0cL zV3w`$XZh0SJgVP|6`VR*F>eVgeQn_}HV&+kUe9A+o3Wbl1s<0u;PDUgnG95zqmo&p zRf;ESY~e{^pIP&o4{IykW1ZD@tXpxB^@r)Pz&(=3$HY-}9ICJA5I^noXv3!2#?%9Jfz3VD{sXtoNA;@NfY*hXm)&+)6~xfQx> zH#D8?-No6V)Su_|wetd}S?riw%1&Puc#(B9JEy(p#jl*%WkwCVCg}0+_xJNMfdson zhOm2c2Ya#=d#yXc-gRTyM=_39`1bJ1@)hhmq?!HPOnG%l3H$er;XucDUX$~kgTDB3 z$n3kkHqDkpUsiC~3|(Fye~35Sm*-9TJ2-sX4~}T|=PmS@x2{{l+iDv*N^urP`(EPh z<%S$Hq?BXbCh*RZY>w+w;rLtyPO=`!sR;_aPoTnSk=dNyGJy|p5g!Z_a7Nt)&Qvnv zEWdiru5jXj2Nx`q=c9Q!T=-4M$84&(c>f|k{`w`Cnrz?`NkjPL z!z?~6oW^IO8@Q~^lg~});qx0(_`-D^t{8KbF9x`AW#u=nlHJYKUYcBUs*bOSd+=4~ zf4H{bAlLO6a=mQ}U(X2U8}Em6gLyGGCfo9@Coj3lFqWHRHMphyGPh}Y@}2Ns{8vL7 zcc>Zh-Jn*!R};dW^0M4naeI)sgrwA9X_+BIhYgn;tU!XeHKsfm~L!&8Er;U=IKEv3=)Xdz%a^@@|>o;uNOT@LZ$b`rJ;l8H$+yZ;=VoRTVS zwP)`>nSFcrSV^bOP8n>SW|NdCnP8i~-`-)@frA+_I}T-LWp8zjIP8{_>+KWj7Z9A6 zf281OVbQVT<0YjhPM$h_rtIvw^B2l1E>>Qus;;?w=(%RPA z(%f|C_Fs+d9e3;R)z$vpdH+GxrOJno9zQwv^x5gI=PzEqdj00@yZ0Z~26TsQ^!OO@ zX`A!Hn1chKB)xkBi0R1<8c_EO{2NxnJQxcD;UZ`Z2}+C9>4u%~3M_>O;Z7I|J)j*l zftpYm%81nNg>T^#*b1-1Dp&@O!6PsOroj}L2;<;(co?35!F+fI*28xA2L2GKI~=M)A+&(La085oS+E3NhRv`G_K4IQ497wpXb$H= zHy8pV;cl1Ka12?fdW_!@4|PmU!-6( z)Q2=SNG`xe*a_c2+=5VA z)C-m1Bq)Ry&=z7=LQGE>hy*tx#Ds;hNHB9D<|)iVk_WLDVF`L{N{Af^jnD^9hRPxZFW@a$1~cGRxB}WhEjU7?{wLT5!=ac+y}ChS RmX-tm5dX3oc=dl*{SVm^RiXd@ diff --git a/zic.tproj/HACK/Asia/Riyadh88 b/zic.tproj/HACK/Asia/Riyadh88 deleted file mode 100644 index ee7474e57a5403b14bd1ec9afe89dad37e553a08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3580 zcmd_t`BzT+7YFbLsYIEIggSd`&{I7sL#8Jwb5v+hp(sP9iZn>1NTG<*K#3G3C7~!K zl)1PE@Po-C9$vSi*&GJIS zqFmugk&W<7;knT0yjf^Et|>JCC=_1U+6yfQ-v}>1Y!O}i*-CHBn+gkuQEur9$xQ9{-+hGf%_NRy4_XiC^xnp)FH(*=8);a^I&R}5&DdNSE9RUrFfKbo!loaVUA zqPZu^$+1I3&UOdLB}0kkwFi@%^-FS3aH9FIs%fExIeA29l4pZDEjHRlUK_uXcg-?d zs#8zP{HN3M%N4Xj-IP`?$);7s{b`MIEcv?rCchH_Q>_p|A#B+H7=)!o##^OHCq03cYCCmF~31z8CHNq(KQbsg#(gL;G8g zQu1g+N{Pv*)F;E~pm7PMZL+5H+G~_Sv+3~KCv@cM5<05UMp?@OD7)l09ao8^ocaAJ z_vB&9lQE)`4i_l@$RsNGTtkJE7trbbuc_!wAe|j6OXqg(rs8MXbY6U%E`(c9>Agz2 zIK+X<1DdF!+J`Fpf2Yen5p<=rH&yjGK-CLHbgkeF-H@}Pn{)2at)nh<`^$5xnd(Qi z$v^3C+gAExyc*q)O{Ti0!SvAd7(I$Gqx$>js6o$)o&;9W)9W*+aX>9Kt#qX3vd8p7 zZ6URIw9w1K<@6@&J$;lcr}kzq`fS!nU+NyyH+@I?9(0p_+?Y)NXkDUTt42}B#XOej zX~43cX)JfTFL&t@!wQZ+xofr`D}HNb<>@ZmE%gqoytCvUk^)xUEwEa1Johq}=iZU) zxKCXZtLru+YVb$uWsJy9*Eb=F581 z9#?23o%+lYc{jG4Tg?-)%-QN|I$KXuVVjgdp49f5r;MM=Q)4T5T9YZyFg?h& z5vn}%ehAy?wy}MnJ3Cyv&2t7wc+&5er*71U` z_UtjWiak@t@uIdu_8M=@-m%AcNfYxj(==Wlp~*h?_wlO0IQB2w#{nM693-E{!HxzT zl9k6BzM1jHX{8*NI+-`Ut>tiuD{qNw;fUt7yw&U%Z;RZ?Q4h2@T0e(lf+f7;#%9Xf-L-G0M4+EJYAr^6>IFY?L0?ws%agA2|jaiQ`^ zKJ9v+i%$6SnU0=(&h8`^XV`K{`=5NlCW1>71ul~`%gV`jQRu3uq})xVdk8q~MufOI1t$~9EYwHNaLv;1@^>l}@0SP+VLk&en#wMEm#luX^%=-)mKABfB2|A^KrwI zr_UOjnv=X1u6XYBqUGhf_*WZ3cXxi5M2|X=5vj{|YWNR)1}k7TjD^0?8A_lo>@Ica zC)fz9U?EI{F>pOx1ZP1@D1rlF52*$n@B?gu58y3W35(%LmybIG|I9vv&LsQsCs?p!@A)E}mNfo_?ci=i% S8B5E~pMn2Gbw2!mq5cJ#I8Gn{ diff --git a/zic.tproj/HACK/Asia/Riyadh89 b/zic.tproj/HACK/Asia/Riyadh89 deleted file mode 100644 index 6f12699d139b010ce6cddac921c4336e5e90ac75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3580 zcmd_t`&&)v8wT*UjpR@$qM~@8C!KeqlBr1%g^t1qsT5L@L=i%%Lh3jcRK?bwxH9ZTZgfjmn^ z+0$}SZZ%s}B({rlP3fY_#8{kS9hXO@e9Y)*?W z4^D`0W~SnM%n|XUPM0LQyQov7I!P}jQ5Q`qbq!uYie;}zNhN@~``o1-$K9!yw33vk zjv|%3L)80|HuZH%CDkkmsl5!N{x*+EJ;jp-Jh(s_W)`FwvzN5$RB5noENMr)CY?*Z zG*sg%iQu1!$_|sRiY5*7i6_0ncVr;-CqvI0WRz!3#vcnv<}{E@GZSg}i*_1e<3}Tt zZC;%{Od99YgB%K1(S%NI zb@|X6fd3k*((5WYd#cZKvx*4=QQj=C_>d?yI z0~B>uMypkdX^pQHMIW!Cb)6k){nT3&b8tGvetJl86N4x|>jNdUMN^`!5^YLNqs@;7 zQSyjya;9IQ z+(R>I&*$f~Z*n;8&z91GS4nixPK$osnn#CP%;|`EIpxPYQNf)%bkx9)jzzts!mG=v zNLzu5Llfylr5cs0X4A<4JvvoVK)-jhq%$+lP}!03boT3Is&H|mb2)WX`NoUR+c(pN zbbqR`45U9AL+Iv`XH=`!LiMH1bVtdH8ocVLG2e~ueygT?u6A@kx0IUSn$g3tztW>^ zgX!^;bZQ;dot|u5OHUiy>6y`ddcOJ|y}0f|Z93)jcbGZ7s>-7`{nY90yaakz`kp>0 z1yH+JJ$=l#r%&IC=(DRfeaTIwuW!E6_puA;M|uM*JaOPomW3?cIEXtpZse|pA6Rj< zFL%3E!`*d8a*rjs+_S1DE2~AaNKPuVZN?6v1w6h|j~!LB*(qQkPb^7i=NT#N?$Vt-a#DC&x*AV!-N`d72eVhg zKAzdA$FmI!*n71l&$)JveRU?W-;z3>TQ!FR)c)pq^CEfvNktA+%HV}FnS=6AaqxFX z4smVb#d|_I^z9E08<)mQGmJR=X$3F0^5lrbHjZqHZds-a0?BFEi6Y_ zjsD5n=4ab6cJ^btjB}8VpCEB`nmB2)vx}>nyT=sIsne$aGQ(@;tl8dke0=@p`UlLL zzaVg7P;k(~zyEF+koh`38S6OxbLiNR(OEnj(FZ^-7>hhJV*RG%W{q(6DH*Xae9lu>$SD*jqorcD{ zP516MKgfRg=y6M+f5?*X9n(BL++13pICXrN4DWQHU?`DvXz&>R0rO!RTnT;QSZDzI z$kqP_Ti|6_3irVj7zO9UDbN<0!XdDiT)pq`J#2;b@CvMiC*f~!Kg@yKU@F`MT8o6vo1X zums+RZE_8JLxLmV1UL;YgezbI+z#{L33wjfhL7MIxkd`GI~)iFG=tV~JamIz&>x1t zNVpot!_6=QX2D!|03L=%VKLkS1K}Jv6;6V7&=ML$HMxdQ;s2U^4Y?d9!8I@(2EfVC z25P__at%JhzhEt_fP3K%xDhUcL2w?N4n1HrOok2ctz1KWI10{$d*CtnMXr$wtbq^V z2f4;da1gYB6QMT@gXp|*4l=rJd=VLaHb$RK&}S1Z`M!xMw1rdPd>922A-ZjH9Qho) z0bAfZxiWNHhPQ!C2RjB34VO70V=^-IT!x9sLa~o`i!2ry6O*MOW7;xIUUm>W`LGb; zxsdHf#)-%hI5hm;;trClxy+{7Ql447UEep8I3#y_L6J-9@fJ$xF5#BMbH%v fkZbfAHo+>nhCa|?fbV$iT?V#LU3R0)z|<Lx%)MivH!f(8(~X8|LNcW?-U Kw@V0!3k3jUIv^1M diff --git a/zic.tproj/HACK/Asia/Shanghai b/zic.tproj/HACK/Asia/Shanghai deleted file mode 100644 index 2f0c5ec3e0248cdb933e2f94d26528b049b766b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmZQzzzUdwq96Yfa0pBz7Euxm4DTvGnP#E1qN7z!T%4QHsEz{tYD WP|(1@;o}>^;Oqj#!66_CAOHYh`5}D( diff --git a/zic.tproj/HACK/Asia/Singapore b/zic.tproj/HACK/Asia/Singapore deleted file mode 100644 index 41cfd6251f5460d4d2ae16f8fc7d2336ff866187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmZQzzzW!bq963$PVPvC!W$=dG2t%TnR-*@?Th#P2fFfuVSv9Pi+ zFeJu+^duE9urM&BD}czl2@ISJ44D-mHjw0HU?^x{;0^W-VeobI31RRG4q*s(4*}^y F0ssX57?c12 diff --git a/zic.tproj/HACK/Asia/Taipei b/zic.tproj/HACK/Asia/Taipei deleted file mode 100644 index aa2b3f056c83b53ec02720a2fedfdfbe4ed42037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268 zcmZQzzzUdvq966#vSPTV{IKA<&3=X(Y-t5I zWj{6Cd_METt^aBaw@;icxbq;g;qEGi5BG|S8SZaQDR@xR%J6X7^be0>cQiaMKV9&| z?hV6J1BHTTiiHf%g_ah)U|Q1f;`5CUFCX7vcy*Ph;Pp}NhBw>nKfL|^hvD6fBOl)1 z)NlAu`J;gSPZ$Ho+pYr6yPXYO=k|UO-gA{f#7y7=10#`;p>6^r&_e|c3@pwrAq>vJ JAwV7j0|2e=Uc3MR diff --git a/zic.tproj/HACK/Asia/Tashkent b/zic.tproj/HACK/Asia/Tashkent deleted file mode 100644 index d89d8329b69112cf61b105d8eaa1f3ca1db204ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmZQzzzR5kq96hi|pyb1QK-v1=0Tu1{2UMjW98lxF zctD-yuY>xRcMcj)-Ucu-GeIB=D-vX5XJByn0dk0200RpHLs9`FCj&!B0*DPEVIm-L dpc;N3-w=in$6zo4BtxS@K)M+ifdI?^5&+paHV*&* diff --git a/zic.tproj/HACK/Asia/Tbilisi b/zic.tproj/HACK/Asia/Tbilisi deleted file mode 100644 index eb308e2de6403cf89c4cb620b42676fa2953fd23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 353 zcmZQzzzTSQq96k*fwGO%0~HY$^zLyl|XT~00w~&C*Kf;5GPMC5gfwc?h3*{1_&?$0hob8 F0015NO5Fee diff --git a/zic.tproj/HACK/Asia/Tehran b/zic.tproj/HACK/Asia/Tehran deleted file mode 100644 index 0b3a6aee1397be304cb71395ae2d1f2046a8d72f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 645 zcmZQzzzR5kq96;uILU8g|ZVGH#tsdp7Qq4+FxR!y}Is%&VuDTbbB^==r!K9(9eB(!XTM%hoQfu zhmnhug|Xp04->WH7N$ZMPnfa)+F|yE)x-Ryo`uC#ixZZo5_ec_-+RJ(&9fagGd_CQ z_DNaTRjHh?&-dNo5FO#+7|>|pWP8`c*_h43MPA^9tBBxs1Yay!y*YkFi{2(rlByUrtP({+pNc@IzI zOySy*+aT(ZS88XGpXhO-Agpjlq4U`jMHb(76st0Nlt^h=l(LzeDE%F~qwINxNBNzJ z78NJodQ|Qgv#46FaH4vF=Z>155Rcl%T8p~e_7n9<8+I@v6*JBXweWMD9` z03{3{$-=;3XaPzcZUKxu3=9?yAhx{+hz%h@vOc~c3?V@583e+?At1d#z{m)p85jU} CZNjSn diff --git a/zic.tproj/HACK/Asia/Tel_Aviv b/zic.tproj/HACK/Asia/Tel_Aviv deleted file mode 100644 index b604803358821b60e26c76234abb3cc1e8c786e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 413 zcmZQzzzSG^q96A{(&2LsNo`NweX*q00E`_mp=SXp`DVoSn< zOI;@mE~jp2xRU+g!u2STgzNX^58Tk-T5wa&?ZGX97awlD-u&S9788a$I~5+>ebCEr zZ_Bxc`%CsWJm@ZCcoYs<{Prq=Ynkx{nSDPV$aa3bAa~|}f_%cv0EMQF35uRuFDS+OCMe5uUr>oM zNKj?44^ZQN`#|m5vkU64&p*&Oz#O1?sVgd&M diff --git a/zic.tproj/HACK/Asia/Ujung_Pandang b/zic.tproj/HACK/Asia/Ujung_Pandang deleted file mode 100644 index cfb66cc0f7b4d277376643c2d551ec6d00e5ceb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmZQzzzSG^q96f^S51o=flr^XM(7DVuP5()DPkuQyIj6o-B}fd7?q`)}Iej zXM7u^_cnfzS>wGxc8<*gxgOmG@-=b`6ms|%D8?`>Q1bq`K-v1y0u}Ac3sj|#EKuX# zx@P!u1;18-#hphDmOtD+SnWB|V0}a5gU!;147NMC zKG?M$X0V_B=7U4(QU=HJb03^s+Zmh_UKhBiW-_=soGox;^=5EaSYP1&F1^8%VPb*j zInM^K2gL>6>$Dqu4ulr?_VG6Ott|ZDpZmTcpfmVGU^ov$P^RgJV6%4&A)ewNLd7mH zglYWz5cX{oLxhl6LBzEw43Qsy6hv(+V~DLs8Q6f?|XD4JA$|3rYnV8_JYc7nFTSZm8fs{-NT6 zYeVJhl^?1$s5exf?*33S(}kgSb?%3{N;QW1ZvPLA%uIBL3=AnIphT5a07_GJ6Bs!e Y7z!E~SbTg#7(#sx`Ny;GY0w0`T~Wzj0Q!|!~&%_uLfmJ=K>Y? zbOu$S_z!C8o(yWA96xBVYcptEQvSfm%!C9P7=mO##)c$-Os$*1$jQJ^(7?d!;~T;d S8WbAB;Oqj#!66_uU;qH>L>l`5 diff --git a/zic.tproj/HACK/Asia/Vientiane b/zic.tproj/HACK/Asia/Vientiane deleted file mode 100644 index 963a7c962943f8e878b58f6829a5a2197fa0f662..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmZQzzzSG^q96 Vf(8Z-AKws$U?BE%4gpDn0RVkL4&wj- diff --git a/zic.tproj/HACK/Asia/Vladivostok b/zic.tproj/HACK/Asia/Vladivostok deleted file mode 100644 index 98c916374305d57e5853905bc8df9b5cbb494029..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmb`FTS(IZ7{$+YmeFlRIWKuBFUwY5D$UYqUY6OsEVX6oa;3Ixu8XN`^LE0-hlWH5 zrAQVe-Ap7*L5zYl2}Jf_Lc_pHuwG0`BD+BQD}fI^b`Ia+$Km_lKH#5nb+p0=s&I_J zYae(VR8PO@o82f=>fGGTHmR#=Qab-g?f$7#=V70;d5(nZyar;qsWX(`ZGQBzuA^_Y z6a5TdxjAo&TU4*(moTut_Tk9y8ju4XU5Zdo0*~ z$ABHp`3Sk3hS2g@gcXG%T${_CWf9z^h~e%`DI>gn7#Tj#$lqX;mm8uc-gEDd@7Omm z$Y{GAF&*!q=pR6A!wbZ<-o*am4#d~@GeOyi#KJZv1(raWSjz)0DkS^sm^`CrigN-} zMpJm`LjYA>a;A>NBduvQ(>wi!ztH2 z(0i|k{-Xy@|C&R|@K2nX7>D8RTa*rcp|SB9&UTFPoc=b>H}vv?`YFqbZ}4JRJIj?8 zR!A{nkwXjMh(GgQ#{K{R diff --git a/zic.tproj/HACK/Asia/Yakutsk b/zic.tproj/HACK/Asia/Yakutsk deleted file mode 100644 index 6cc45a6e643c09f533287f6f81e9f0f1ad22107b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmb`FZ7kFQ9LN91d0HFat@3oq6*}?|!bnHbG44c89^z2QvyPDS*ot^@%f8?JzWeOE-|yW|5dJA^Q!9?B8q-c$8?=-iv;5-$nmyKz-Yfwp->wesAbfs$} zC@+(6Pv$r7RWH&le3tIsPw62W;l6GCR7hV#u{I9Rr6+Q)x>C8Oob4Td>D#LzR;?USD zhR-eIaNk!bN1q|0?Ij|w4dO__eMDWJV_Mb-ExUJ-8$yxJ|e0?XT9prY?1&lTQtCg&?ZAaaVmWGvL)ZYtc!?YTWJ;`Vq@

D2rZpK diff --git a/zic.tproj/HACK/Asia/Yekaterinburg b/zic.tproj/HACK/Asia/Yekaterinburg deleted file mode 100644 index 52a071ed8e92292ffa40c130e4536e1dd2d2a682..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 751 zcmZQzzzTSPq96j*KpyVTcLD`1qf{OOv3#!uZE~s(e zzo5>_9iaZ@Pk_dg-wB!(ixV`jY*ElUGF?D>%Ygu$B^v{Drz{H4YndFNU(ym_kWw08 z7`xztQBm~;W80<+CPA?mOl4Cpm>Jn$F#GFv!9qGFz~ZjP1qhDZs9cGr)eTbS&jvUrKf2(ex<0_w`N#z~)`g5R3V0RKGG3jsae0fFH`0YN#s0m0@b0U?8C|n z6@2>xDlT+isC>6DplUqv!?lh?3|JZay_XJiv7pyZ?ZK-os>fr<|I16Aoi57fBd zK2T?sOi=&Im7sCwn}fzv&H~MfjRl%l-Xv%pxtpN9T#bpCREYy_h9oF>%8|wd<6%l%r1_ZENEG zNZK)^($bKxyhPVqWM$}ul()n%%u@~nV7 zIVH@S_z?=~tD*2R16SBEEc#jxt|p&=YmuArIzI=Cx6*jiBos@OpJR!*9dEs^#j?5w zP+n34w}pqW;=9X0(w9PITr%7VO@J!DFsQa&jWre?P-}G^?)uf?-HutT=eS}0m^I$( z5rF8%0T2xnsv$9yYUrwf#&cfKSQV1k#IK;5YC5qw#uS?Klc*N&EUM*FIo|hGgZnAL zRIAA`s`V=&w(WQZ4_sTJ-SQRli_v4|p++{MWe?)||G z|2)LJ%IjiAzHek+pS;bCCR}00_Or}ydqrg2r;JQE6p%^NO!7PTG?`LOB-1icWO_W1 zEKN6pWv4VjImrnj+8kAa3~)J5pH+2Kz;`#wvufNKc7^I7t1i>Ys*g9YD|Xq$-!Gm<fn>!i{Mt62ks3O=#iQNTk^BeGa>@E zrW`}B?I+PYd>{I33P+y13;L>W!EMGyxNT}Z`l&gC-^1m&W6}_I{xpHR+7)3ps{;PT z!|Hnfw z+$Z@dV)580XR%n^`;<~#n5A!rqdf1D>DcH$Q%X_VP%9SpAA9g9yPcjs^FD8mlDyrC PH^0P@fRgGBIGn!$zu3s+ diff --git a/zic.tproj/HACK/Atlantic/Bermuda b/zic.tproj/HACK/Atlantic/Bermuda deleted file mode 100644 index bb0bb775aa0d79d0fd14f60f56b2864fd5b85f12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 725 zcmc(dYb@0P7{>o%rbD@uT#i$c+mSj^?x}Ec9FaGUIFw#;kA#j(mm^a)%PN!7T9#>T zT2m(7G&{1X52n}3MvB+kd}v*@Rw+*BeD8a|XTR;)^Z5~ke`0D_jT)&nXzW(^1|{Pb zu06Qa<`Rg678HG{0!yw$tBH%WOsB@>k1EKzQ^Ph_QpvUM#oN?7K>6cod(m# zB4J-=6YuYJhm3}DKG0$gSdh$_S~tp42JyiRGs>1aaZdOw<=O>ep5!^@%{gNJ!YwKo zoyWqrjdZB{4HgY`LUB_+9=>@NN=mQek@{jNO?$#+xd~7n+Qvtt{XpY!?qVQzb7-{P~u;$zYGFkGUqt_3{2!dY!OedJ>^`-aZ6%IT3vJ97382 zdEGIDTC7-HP>dx86BH>rELExy78H(U^8yeq)iQiCo)K@u7&+w6<@aZCMfZ0qJ3n$| z>kF=Gc*LmcUPhN(W=!EQVy)eXQ}-Y~>l6}#+o6iBfy!-1Vqhy1M~aa2%f{qBE!Mou zV~WE}bx$(aHfor9CW!0G6x1{%VZB~TZAlxN$XkZFq7NE>^Hbn$JZ5B6i@ z=ml(YUV>rZ7BgC!VeC53&6Snd(tMnmxhI%qDP{I*3r&VJZj~9Cql{#ZE1G$JdgML# z;kL;LY`^}E`9pJ2(BX~3?l0J3pMbe_5IfC7D60R&U8y%vTsXiIc^gXAPL|ES#`0jY z{KIKhxUJmXU&}osChonMPs@WU>}yi9(vgk*6>=VEOh8p;3an)^9E=G;weANFc?+;b z`O!B11~pzT);zg~+Oc6CzUsh{!5-GN-C@16okwdsX>YMpG(#+r{&!DJeWf5w&v8NG ic{5>-Ab3GE|L<(bFbP_X(In*RJY<_ZrAQ?Dvwj0L)z9<* diff --git a/zic.tproj/HACK/Atlantic/Cape_Verde b/zic.tproj/HACK/Atlantic/Cape_Verde deleted file mode 100644 index 363cef50a18ed64c7cd76867768b9fcd096afa7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmZQzzzSG^q96LW$$|TPzo4m{L@f%$7vWrU}o}+wV5Q<(el$S0e!bLYyGQ-+u)#``F^juoxh#x{X5n-k&C*PmUoGP9sVMBZ{gcJM`6%fM zMQPu6>~&6}%sqmAWj>U*eC7W1JE$lfW@Tgts&rmjf^V@}NmhTpz#6}u2ZkIxIA-FZ zo?=>`)S>pYjy6vL4%bBTNLv!>^3q_p$WR|2fd<12j)scR7%OGtkN0Q_nP$_AM{rDx z^4Luej*s-Sx#Iy_yq!GZ=%%yXN%0)X|IX~}OpoxV0D(J&KpgzH8*@yeB7QHv)?E@1op-2v=Z8@B%9rm54hT5^TV5kvJw3C$W^~36e(HJ7^P6YhdC&QH2zjnF z6jNoC8dOBtO|zP3V)J&T(!78AF+YEa7D%$_cj=TCRT)uTn^LEJJ@3ouM^*b!aXB0Ik!yP3zDyfL(^)xbPD&-$qM}KQe;{df)}?KB&ZOO;jCA;4p&bK{ zsD$H0B{Q4p^^rKzbupN9O;yRdX@IPIu!{72Eg(HD0kKjME0ebM&>IP6$~w?5CJeF1&sXOC9WZ$Hf3w(Mo@7&S9@*H$xkpOi2I6FJP_ zmz381cmIpHL`#4 zj!#QC|^mXvsouLn9bhioqnm5H@Bam>xX_uSARB)kC4M$x{eCM^|{w$_C7g z&EfTRhG4ELK=b)+XmQ^RE&KKHjW#uWvt|*kN+~2D@)0wcl zvKaTo#K7Ln8I0i6=#*o>KC-CV(;m^(7iP;sXgVj z>i?tVav3N;7eY9zbwFPEJ@D_nuH`?;<_xbhlD LA)+|{iNpC9QrNZ% diff --git a/zic.tproj/HACK/Atlantic/Reykjavik b/zic.tproj/HACK/Atlantic/Reykjavik deleted file mode 100644 index d810ba49b63f612f0d7bbf8a38453f7bb416739c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429 zcmZQzzzW!aq96d00*1G@I&z(`%d-oVjyW;cSn}f^&P;E1b_^TX12{M1_mqFBV*CUAy42_NfI| zQu`NNwY;cs&9!jBb;->NH&lZc-1s?F;TB(k!mXR-3b&t%FSxTaQsM476NP(=N*CN; zC#LYADSW}h-X98&k}MZI&b_7Z#7TO=Q{O!b&lLYIcy4xM!3%CFg_mNx7QB4*N8#1C zISXE&x~K5wTHS)Ts}3l<+m^84eb*v|57V3$e9UT5_*5US@Hu$Ff-muo3SW(z7JRc; zR`@QQvfzh2tHO`ZZVP_?d#>>7vc`hnFPInn+2g9f#0Z7VEaX7e|Nmd-0K*Xo7+L=R i|M-D{6P?Y#8{`|p;29hYB0?D4fgF%(Mn(|DzyJUfDx75i diff --git a/zic.tproj/HACK/Atlantic/South_Georgia b/zic.tproj/HACK/Atlantic/South_Georgia deleted file mode 100644 index 529be328f281265719bf3f34cb66414e9c2c67a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq961YHsP|HFeN&OmnnJ&1`g%$=q_mbZoH)kx+}Q zhYTV@rZ9`!Mu8%i8a0FF)r5X z_8o}@vG>w**&Ja51HrL8==27LoO5tUl+gWeF*rP9p^@h@9PJ;VvD+d(h-d;Ahu`S( zq>o%bn?2pS^{{5b}BhN>eRe4+&)vyemTyC^g?k;8JDX``DC!=nup z{v!b+T~rh~CC8}mK@{CpQKN~1EGI|K4s(U<`FYkl{sisQXT0Of4CLIr!?{xnly|C=clJ(GeoZ6qI@?bL z`Dbvq@jU4iMl8%bN=34K)W_&a|0@oQeVU;7r574(i@-3b;JvStpv2_C`^@X0v{}Ms zT~a9DW8sQ6IaMYN@cuG8s*+#iYV{n|tTJP5&?wb@Fk#)wD^&Ne1rNMGPW4wyuwk+X zjO}V{ywwf|>kNG8bR`_ts(6`XNo;Kvvvl~cE{eluK@i2safz)c4zVB=MawIzPmT*x ROn{}m0L9OZJCRp1uj~CtQXUmu<&noFDTKJlqpn9nU61TiI3}}}w9H1j3vIHN zVJbD#WYw%Z*UXwxQy+S5STn28a@*=te?aH#obCKRAK;%-U#F_5bY(riw=(>;QrU04 zI2>~i!$WcMk%zGyZTFIowG?2yS|nGKdr@7-9KuKuh09`UxUNxS%8Z(NZ>jlUm0Amf z+|+Ce?bmOhQ?>%#M^B)aJPZBCTiEP700YHEY_V*Gp)>=AKPzD*J_uv&OEj@bqsdSO z%>=7JCpUHKl|?c>coQO5MJu%xH^ zcY3aYVv!NVGwM*>+4iUKvjI0sjXq+~pvOgf& za~?5aFL2Cg0LZw%63Y{% zIXLMjrYtEOX;x-T_i;nU#=Xe2FhJ%g>Eqv6A~8BC!(a=k>|&JaN&9oN;|Dk jR=gGEwF3O{2DSgdKuwG4(M{cgzpWyY=$Q2_P(l0xRcqm4 diff --git a/zic.tproj/HACK/Australia/Adelaide b/zic.tproj/HACK/Australia/Adelaide deleted file mode 100644 index 3a4d27e8ae05e8c93e7bcd23a4e95e0caf13667a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L8D1ISP?G6M5V#ggjD7<(2CudELB1UGff*kX&3O?Vu}{P=5!ZO-+;HbF&k)niHmFT*bTJyuDM!#-pJ4#G@0I(5Tw z>=B&w)o>b4r}JDHT+|P^=HXeo)~u#mmy+(qGI-P_a;+kTo`pVK=PTv8-A*L@IT*-fQ)u*J=V`aSuLb#O$@Rx zfK005Hr*%$+hs9$KA$1lAq*LnbH_^;hIV)|Y-BsaYekG`cSdC10_7(SuydCwqH^aE z?e!5cq2q`(dxAKZF2pVLAYL@e_{j@M_|VD3?h5RlsNH*|8Kj(q0 zHWa9C@u2(;3o{y7yJ{4u1ZY&=S!r}T*RCGAt mNU19-YXL369}Bhr0}BKywdT>M+qC|+hDf7h7PpoL3Vs2L;Nt@T diff --git a/zic.tproj/HACK/Australia/Brisbane b/zic.tproj/HACK/Australia/Brisbane deleted file mode 100644 index 6798e973476788aa9d7ece984cef1bce62f99696..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmZQzzzSG^q96M}mo8u~ zuxw!Am0?izJj`=(?B4o diff --git a/zic.tproj/HACK/Australia/Broken_Hill b/zic.tproj/HACK/Australia/Broken_Hill deleted file mode 100644 index 46aff75df20c539a041f5d0ddfc473478acd6e57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L3qtIm$C8k#{#k9;u|ll}D1-&8tgYLb@RmvWrBkJ7+zt=|x#u5^a*H z6w?Q*u;@}rt@OcC;|tZwdY4;UpZWtjXXk9^_xT6}|CH7&RY$F(v-!PiBd=Vn?Q;Co zAKQuk-Xz7qO&K3F`YTlDi!oSXuMpDg7bEf+^ zx6T%N&t5~nOcMsTdSRF}4x{SJF!t-gJjG#{SU15`nhnz*hhXL%h535NXl|E9^Ip-6WRw{fJ4T6EV4fcQRpy4)9>Ku)DFkN z$8gfEhSSv>aGorNOZ7u8d31`difeRhQ_x*{k{(rwTq;YUXPyt2`37=%v^7^)iRk4i zpx1XDdRtn-dvubkzWl`Mu70k0J_etL3HWy2fuHg|#Ah1dpWckM2f7&$T#3N6dIpJd z5ge%GI_+qLILH|?mBUbBC__~eZg}Owuoh2-53EN-r70tuoe`BiL&*_6Y}{mm=&UKk zczr}{*bw5(o+93*4e>J_keaF}9XX4H53NjWFU98JDsHK(q3n7Algdh%d?KD(lVwaP z%}1(O%rsdXw%OP*-FGFn!w+(+1&~kJV#l|y$mr8V=IBdgHI8HFz0b_9=s`}y3+|FP zAy;{uyCrv-mtMzwk4r2F-p@ToWTD$R6u!-*!k`?Ap>P&WrJ}gijU}oe?5znyY0F~l mD{@6yC7>brV@=_IV1Ynct$y_JCXK(XCV?@rvs*(A1-}40eB^5Y diff --git a/zic.tproj/HACK/Australia/Canberra b/zic.tproj/HACK/Australia/Canberra deleted file mode 100644 index f9dca840549911095fd7e66c3a4c7f688db5bf54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L9OZJCRp1uj~CtQXUmu<&noFDTKJlqpn9nU61TiI3}}}w9H1j3vIHN zVJbD#WYw%Z*UXwxQy+S5STn28a@*=te?aH#obCKRAK;%-U#F_5bY(riw=(>;QrU04 zI2>~i!$WcMk%zGyZTFIowG?2yS|nGKdr@7-9KuKuh09`UxUNxS%8Z(NZ>jlUm0Amf z+|+Ce?bmOhQ?>%#M^B)aJPZBCTiEP700YHEY_V*Gp)>=AKPzD*J_uv&OEj@bqsdSO z%>=7JCpUHKl|?c>coQO5MJu%xH^ zcY3aYVv!NVGwM*>+4iUKvjI0sjXq+~pvOgf& za~?5aFL2Cg0LZw%63Y{% zIXLMjrYtEOX;x-T_i;nU#=Xe2FhJ%g>Eqv6A~8BC!(a=k>|&JaN&9oN;|Dk jR=gGEwF3O{2DSgdKuwG4(M{cgzpWyY=$Q2_P(l0xRcqm4 diff --git a/zic.tproj/HACK/Australia/Darwin b/zic.tproj/HACK/Australia/Darwin deleted file mode 100644 index ba8b16a4d254fa9c58da82864705c548aad55391..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmZQzzzUdvq96n_Niik;LkZ~}?18C5Lq7gV4E)1obc=8AMUfxUIcYeS>Ww1eY(dp(!e(#RN`yCxa zu1jNSk1(dqkiU5<<+wUTKG9W!NtJ_qPuw-o1ypas?KHFJPHB3#;~f*c>s8 zE%leM)wvtinI*7ZzX%&q9Jc8v!Pc#awx0rFFNmSNx{wZYUUXE6=`>(jE~ayaU=YCd$_YL2fJES z^skLTKt&k?bF;ZydIfvJ!?-u76#JZ<8DtZWpfxaf*$<+bj|`c%!2Y3E3?24iSkD~7 zJIxqzc@&Y#1s*8w!NI&KMu}B86ro|XM;XMyYrk zmxt9EIC9OLiK-AJRV*@Dp3amEGaOA0W@^v^(gN(5ZZid`QV>NaMDY8a>am6ft?$jgmTmHdp=l6lkwbh6fa40TrLsW9n;BV`QI5ll! I3v>{_06ER;00000 diff --git a/zic.tproj/HACK/Australia/LHI b/zic.tproj/HACK/Australia/LHI deleted file mode 100644 index 843ef4c45c2a9e282b337679de11118d2f5a3652..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 663 zcmcgqYedRLV@9=9-UOY0hlcmYR>HHcL&tS!PgTp%rD; z6rvYqNT`%p^nj$qe$)!7pb~lrWfUeAafU@3(Z7Co#~sIUKTi<;2{%XUloQnsIkUUh zuhQ32RT8D|ZSYZ;;4|6)UojEBJx0jhD6p_a4f(Ju{Hz`DKh?{Cym~11jUq6)ok3+2 z3=XViNcspvKEGwCvWKCM?osJ}h|2zpT>PPeVYa(iGIkJ4(T(sc<%lq}Ao92lQ6@c> zRfl7FLNr!ndm>uyjhLt}h?$*%O6Eb;_)En8nC8k`w-NVZjPc#inQ&u}>gJnF>^jM$ zlG9wZ|01V0B0#wVHaQxM`Rgl!w%*0;IdfA>E#gH4}1V^aVrrAeL*7%)z?L zGG>o-c6UGa+gn0L&{80H4)eddN;VD9%`8ochn@T`q_-_B#xP$f4%IRN9C zR+t7$v8Bm^{1a&?$j?M!V==cTMxn@*!eajgC`nkv(zy{d%jeNNIiK5RKe24|E6d02 ztmt{l?IRyyX}QMA?uXc6?&QwqepF=*p}OQ4Y9ejerL94&X9McOkFsvs2zXQxkJYeF z>De$4fZg_J?&*wYW1lzoTK(8`c!mM}mo8u~ zuxw!Am0?izJjdRLV@9=9-UOY0hlcmYR>HHcL&tS!PgTp%rD; z6rvYqNT`%p^nj$qe$)!7pb~lrWfUeAafU@3(Z7Co#~sIUKTi<;2{%XUloQnsIkUUh zuhQ32RT8D|ZSYZ;;4|6)UojEBJx0jhD6p_a4f(Ju{Hz`DKh?{Cym~11jUq6)ok3+2 z3=XViNcspvKEGwCvWKCM?osJ}h|2zpT>PPeVYa(iGIkJ4(T(sc<%lq}Ao92lQ6@c> zRfl7FLNr!ndm>uyjhLt}h?$*%O6Eb;_)En8nC8k`w-NVZjPc#inQ&u}>gJnF>^jM$ zlG9wZ|01V0B0#wVHaQxM`Rgl!w%*0;IdfA>E#gH4}1V^aVrrAeL*7%)z?L zGG>o-c6UGa+gn0L&{80H4)eddN;VD9%`8ochn@T`q_-_B#xP$f4%IRN9C zR+t7$v8Bm^{1a&?$j?M!V==cTMxn@*!eajgC`nkv(zy{d%jeNNIiK5RKe24|E6d02 ztmt{l?IRyyX}QMA?uXc6?&QwqepF=*p}OQ4Y9ejerL94&X9McOkFsvs2zXQxkJYeF z>De$4fZg_J?&*wYW1lzoTK(8`c!mn{}m0L72jL|)0{{eC3nQPEW{d0e_Fggo=8>yc2`BXgDOn9PTyWj4}XXp^-J zQ>mFIt7e7Enprby>VsMv*32rj+_w7EAJ92FXFI>o2l%HnH>oNrUE9p>t%$s5F zkH$T~=tzQe>~TEDJN=}}wqi`wT1qvfe$>>rf>yL8wN?ex_S~TMv;}nx-&5z&I(3(Z zxwX|CdT-xBU%m!|C(mG*HV32TJJ=R51mm(R*lyDflf-P8{H%tl;0R0?T4`pVNwbkE zTBwE5qEkZ4`JJ??714TFmo_p5ZJYXFmn5e>m2?Qc1;^YkaB`@Cvv?dX>gjNG>w)XU z7~FJjz^$hnyFM4gz4E2L*h0K6Jv>7AO)y+uCUC-mq3m>u-7wxO^0 zclvIC0!vc}WyuG1>tzTJ|nvv5mm6n=sGQ&NYFz}-U4EM z7ZDfn3MWk`5$}E<@vD7EG#O#ybR&{h?lHN)6e&|zd8)O6sSgX7R$0RI#wcc_$MbYW zKF$ORC`pY(rmY3DgkH$rasWBj#>n|(jS`6qNV6@{&@B%Qr(&(QOO4 i%mtP8YWQPyjsL(vU7PCBExl@gTSY{%ahqFB1@R016W}HQ diff --git a/zic.tproj/HACK/Australia/NSW b/zic.tproj/HACK/Australia/NSW deleted file mode 100644 index f9dca840549911095fd7e66c3a4c7f688db5bf54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L9OZJCRp1uj~CtQXUmu<&noFDTKJlqpn9nU61TiI3}}}w9H1j3vIHN zVJbD#WYw%Z*UXwxQy+S5STn28a@*=te?aH#obCKRAK;%-U#F_5bY(riw=(>;QrU04 zI2>~i!$WcMk%zGyZTFIowG?2yS|nGKdr@7-9KuKuh09`UxUNxS%8Z(NZ>jlUm0Amf z+|+Ce?bmOhQ?>%#M^B)aJPZBCTiEP700YHEY_V*Gp)>=AKPzD*J_uv&OEj@bqsdSO z%>=7JCpUHKl|?c>coQO5MJu%xH^ zcY3aYVv!NVGwM*>+4iUKvjI0sjXq+~pvOgf& za~?5aFL2Cg0LZw%63Y{% zIXLMjrYtEOX;x-T_i;nU#=Xe2FhJ%g>Eqv6A~8BC!(a=k>|&JaN&9oN;|Dk jR=gGEwF3O{2DSgdKuwG4(M{cgzpWyY=$Q2_P(l0xRcqm4 diff --git a/zic.tproj/HACK/Australia/North b/zic.tproj/HACK/Australia/North deleted file mode 100644 index ba8b16a4d254fa9c58da82864705c548aad55391..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmZQzzzUdvq96M}mo8u~ zuxw!Am0?izJj`=(?B4o diff --git a/zic.tproj/HACK/Australia/South b/zic.tproj/HACK/Australia/South deleted file mode 100644 index 3a4d27e8ae05e8c93e7bcd23a4e95e0caf13667a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L8D1ISP?G6M5V#ggjD7<(2CudELB1UGff*kX&3O?Vu}{P=5!ZO-+;HbF&k)niHmFT*bTJyuDM!#-pJ4#G@0I(5Tw z>=B&w)o>b4r}JDHT+|P^=HXeo)~u#mmy+(qGI-P_a;+kTo`pVK=PTv8-A*L@IT*-fQ)u*J=V`aSuLb#O$@Rx zfK005Hr*%$+hs9$KA$1lAq*LnbH_^;hIV)|Y-BsaYekG`cSdC10_7(SuydCwqH^aE z?e!5cq2q`(dxAKZF2pVLAYL@e_{j@M_|VD3?h5RlsNH*|8Kj(q0 zHWa9C@u2(;3o{y7yJ{4u1ZY&=S!r}T*RCGAt mNU19-YXL369}Bhr0}BKywdT>M+qC|+hDf7h7PpoL3Vs2L;Nt@T diff --git a/zic.tproj/HACK/Australia/Sydney b/zic.tproj/HACK/Australia/Sydney deleted file mode 100644 index f9dca840549911095fd7e66c3a4c7f688db5bf54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L9OZJCRp1uj~CtQXUmu<&noFDTKJlqpn9nU61TiI3}}}w9H1j3vIHN zVJbD#WYw%Z*UXwxQy+S5STn28a@*=te?aH#obCKRAK;%-U#F_5bY(riw=(>;QrU04 zI2>~i!$WcMk%zGyZTFIowG?2yS|nGKdr@7-9KuKuh09`UxUNxS%8Z(NZ>jlUm0Amf z+|+Ce?bmOhQ?>%#M^B)aJPZBCTiEP700YHEY_V*Gp)>=AKPzD*J_uv&OEj@bqsdSO z%>=7JCpUHKl|?c>coQO5MJu%xH^ zcY3aYVv!NVGwM*>+4iUKvjI0sjXq+~pvOgf& za~?5aFL2Cg0LZw%63Y{% zIXLMjrYtEOX;x-T_i;nU#=Xe2FhJ%g>Eqv6A~8BC!(a=k>|&JaN&9oN;|Dk jR=gGEwF3O{2DSgdKuwG4(M{cgzpWyY=$Q2_P(l0xRcqm4 diff --git a/zic.tproj/HACK/Australia/Tasmania b/zic.tproj/HACK/Australia/Tasmania deleted file mode 100644 index d6825f5aa00324adc3216d5e1f616a9a13a9e345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 825 zcmd6lM^6&~0EJ%}VaQSmvX??x3OJz1QlvmZ83JXn_Niik;LkZ~}?18C5Lq7gV4E)1obc=8AMUfxUIcYeS>Ww1eY(dp(!e(#RN`yCxa zu1jNSk1(dqkiU5<<+wUTKG9W!NtJ_qPuw-o1ypas?KHFJPHB3#;~f*c>s8 zE%leM)wvtinI*7ZzX%&q9Jc8v!Pc#awx0rFFNmSNx{wZYUUXE6=`>(jE~ayaU=YCd$_YL2fJES z^skLTKt&k?bF;ZydIfvJ!?-u76#JZ<8DtZWpfxaf*$<+bj|`c%!2Y3E3?24iSkD~7 zJIxqzc@&Y#1s*8w!NI&KMu}B86ro|XM;XMyYrk zmxt9EIC9OLiK-AJRV*@Dp3amEGaOA0W@^v^(gN(5ZZid`QV>NaMDY8a>am6ft?$jgmTmHdp=l6lkwbh6fa40TrLsW9n;BV`QI5ll! I3v>{_06ER;00000 diff --git a/zic.tproj/HACK/Australia/Victoria b/zic.tproj/HACK/Australia/Victoria deleted file mode 100644 index fa307b5a612ccac4630f9f108e3bfa6eb64eaa53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmd6l>n{}m0L72jL|)0{{eC3nQPEW{d0e_Fggo=8>yc2`BXgDOn9PTyWj4}XXp^-J zQ>mFIt7e7Enprby>VsMv*32rj+_w7EAJ92FXFI>o2l%HnH>oNrUE9p>t%$s5F zkH$T~=tzQe>~TEDJN=}}wqi`wT1qvfe$>>rf>yL8wN?ex_S~TMv;}nx-&5z&I(3(Z zxwX|CdT-xBU%m!|C(mG*HV32TJJ=R51mm(R*lyDflf-P8{H%tl;0R0?T4`pVNwbkE zTBwE5qEkZ4`JJ??714TFmo_p5ZJYXFmn5e>m2?Qc1;^YkaB`@Cvv?dX>gjNG>w)XU z7~FJjz^$hnyFM4gz4E2L*h0K6Jv>7AO)y+uCUC-mq3m>u-7wxO^0 zclvIC0!vc}WyuG1>tzTJ|nvv5mm6n=sGQ&NYFz}-U4EM z7ZDfn3MWk`5$}E<@vD7EG#O#ybR&{h?lHN)6e&|zd8)O6sSgX7R$0RI#wcc_$MbYW zKF$ORC`pY(rmY3DgkH$rasWBj#>n|(jS`6qNV6@{&@B%Qr(&(QOO4 i%mtP8YWQPyjsL(vU7PCBExl@gTSY{%ahqFB1@R016W}HQ diff --git a/zic.tproj/HACK/Australia/West b/zic.tproj/HACK/Australia/West deleted file mode 100644 index bf5a03e55901b38028c9dd75f166cc0175e2ff3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150 zcmZQzzzSG^q96n{}m0L3qtIm$C8k#{#k9;u|ll}D1-&8tgYLb@RmvWrBkJ7+zt=|x#u5^a*H z6w?Q*u;@}rt@OcC;|tZwdY4;UpZWtjXXk9^_xT6}|CH7&RY$F(v-!PiBd=Vn?Q;Co zAKQuk-Xz7qO&K3F`YTlDi!oSXuMpDg7bEf+^ zx6T%N&t5~nOcMsTdSRF}4x{SJF!t-gJjG#{SU15`nhnz*hhXL%h535NXl|E9^Ip-6WRw{fJ4T6EV4fcQRpy4)9>Ku)DFkN z$8gfEhSSv>aGorNOZ7u8d31`difeRhQ_x*{k{(rwTq;YUXPyt2`37=%v^7^)iRk4i zpx1XDdRtn-dvubkzWl`Mu70k0J_etL3HWy2fuHg|#Ah1dpWckM2f7&$T#3N6dIpJd z5ge%GI_+qLILH|?mBUbBC__~eZg}Owuoh2-53EN-r70tuoe`BiL&*_6Y}{mm=&UKk zczr}{*bw5(o+93*4e>J_keaF}9XX4H53NjWFU98JDsHK(q3n7Algdh%d?KD(lVwaP z%}1(O%rsdXw%OP*-FGFn!w+(+1&~kJV#l|y$mr8V=IBdgHI8HFz0b_9=s`}y3+|FP zAy;{uyCrv-mtMzwk4r2F-p@ToWTD$R6u!-*!k`?Ap>P&WrJ}gijU}oe?5znyY0F~l mD{@6yC7>brV@=_IV1Ynct$y_JCXK(XCV?@rvs*(A1-}40eB^5Y diff --git a/zic.tproj/HACK/Brazil/Acre b/zic.tproj/HACK/Brazil/Acre deleted file mode 100644 index 801849e4ca80ed5291f74348571ac6a9bf077c91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmZQzzzUdwq969;Tf4XNLkUhC7K(6BR0r>@i7Zi+NA5d&CzM#bY-it{OQi0AbYYwL9XKD1o;K(3lxkGPEc&%T%g3gYl3nF(*ot2>JwDWpDa+l rvQvPO2@CxH|KS`4hX4N`KVV?_|Nr9$Mh+j}5C*qkAa)4>ISB{=?p8N6 diff --git a/zic.tproj/HACK/Brazil/East b/zic.tproj/HACK/Brazil/East deleted file mode 100644 index e504ee823486a05aa28f35767a6f0ea58b73665f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 720 zcmc(dYb@0P7{>opCgk#=)mfdqGP$PLouuS?aEQ(!my*aODh_gsoV99gwzf0HQmc1r zW__sFriH1b3$=wzYwY02)+(}C7rE@;Ip6!<@7ZsA_I!Q>;h(J0uLcdM^%}ZG!@c76 z4y!0#$7(Qj&U<6mL@A8<-^a0;SH9_jyIvM#)f`0iu`k3I{fN6 zj=!ynU@^fB7yDkqlG!jXwJy@~tO>5v)sXb{72H|ZPu)|0nINDjEPqyG#*$}7 z8hV-JgLiNcdVi9GFW92*D|hf;AISbK))4ST%DXQvKw!VfdkQTnsCA0>#(k%Km!EU6 z`!MZS=`h5yokA0OF?6nh!aeR{_&^0k+FZiON7q0$pNCP6$wCn?$Z8z$d=MkyZ$F}3y%rS-Pq z;k+I=(p-<}vSv7X{tRX~U4UZ+8qPG$fvlJk&iX8aY}Z82?stJ)b3e{)i=ez237^n7 zQU04{E>M}#$@a~7Dt?wu*Dqlq4p32v7FCiNC{{ed;y-Vp)Qhlm^Z}G@?dGyh4V16k z;)?4fP^ndORb?Wa?at)tOcmAK4C8Yl3aYK%!Nx}aH=;Nq7X(q9))}o8#rH#ksXSIG Ngoo)>DD?+5@D~Bq_YwdA diff --git a/zic.tproj/HACK/Brazil/West b/zic.tproj/HACK/Brazil/West deleted file mode 100644 index 27325b7ded4a6a98591c96b98a01e81f987e6457..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 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 diff --git a/zic.tproj/HACK/Canada/Eastern b/zic.tproj/HACK/Canada/Eastern deleted file mode 100644 index 0bbe44a97bd3ccafd108f5402fe793a435a168fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1218 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 OH_v^`OocP@FMk8yMg?2| diff --git a/zic.tproj/HACK/Canada/Pacific b/zic.tproj/HACK/Canada/Pacific deleted file mode 100644 index 6d6ce9589fd72a1a3610e976698865b95e5f5a6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1008 zcmdUu`BTgR7{w8)GJnylNN? zN(_^$Sz|P=80F|7>ntfHB1x-$_Ye3y^O!n5G7_#7MIg;OO~2@j!Kd>N~?g;3M|gljbfFY7MxtAcY>S9+LV zXJnE#cO$=1#nW4L7{5~l());M{6XeOALXG~ZyEp%Qa5a9n*xo77T8!JhR+|nv8nhc zG?!`dOLjH16m@ZH!gctXRmW}HZqc_m4S$c!r*^+Q{^7BUe%hsT$M`(>C5q-wqjc!( z*onUzqM@s5CH}cP7rIO2s5@f=LXHge_6`93l>XQ!VLTZ`Nx5%;3H9?dW<&cXGQ!Vn z43Ee}C})$_3)Ej*!~?3!VW1|P2VE@!Q9&WXk!%>8L1?-u5zJKUaY$G&h!sIN)O9Kh zlR2aL7$priHb;rR6G_?}dBodcWKl7cN8b8Hql!Ct^vPPn z1;_c^0Bi9Rl-lHiw7Z#QCfh+)_n2)Om%)V6Vz#YR)5P3EJn7O>vQuwh`$My6a?C+= zNVK9U@+5Rr_9G{02s%47&{RVgbg}3QF7*<0{ap`kWnDO}_8v^XV9qnHp9S}hn&nr@UMu#Iw;l6r?{zdsw1eeVekAWWfeM4kq^L?mpZ8`ouVgv;mfOSp zoY}bGyeaslNYQ`)cL<2`;=r}fLFqY;gM3RM*wT&c1;S-07uTZG=0f)8c&?3!w z4u7_p78l&dC6^adM8-LcJnT+ORhby24u@rmcw8Pa16Ifaai#lch&GMom{EEV)8@~s z{=5TKg#)jCbqCg59KvhM-q5=29~^u7HpL}Was2L6l(48B*GKQ6M7I~1G)F}nBv&!n zZZ{-%9>WyTDoCkG#Z4_fu=!dfZh34ATl2SYYSAE2?_9#$GFw5=`+uX;9Vb0Or_0(d Q82Eb!3I58Uo(l`YU%*FH4*&oF diff --git a/zic.tproj/HACK/Canada/Saskatchewan b/zic.tproj/HACK/Canada/Saskatchewan deleted file mode 100644 index a62958a0a5ffd9ce72734c8270b9107ca398a423..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 362 zcmZQzzzSG^q966EHiJ%`U&$7_%>`!_5ZNVz~jMoSHllG1hgLPR2BZP z^8?R=-FyZGyU)LSu;-mn!QP$R35SX}J{(Sb{oqL8s}DylCMO&-JoDkW;`#?Cq+S-B zU2{xwmw}-Ieni?(J)zaKE#m;laGj2@f-q8XnboPk8L<((oiscfwOm zwT5TzUINdBoEcuI>j=E~q{{G$oloG^C3c3_&prsexptZ1?XgP&OpIhe=KufaK4D<^ h|9|xYMiwA@0s{w#&A{X18^Yl00>r@~49-9d0{}VchOPhr diff --git a/zic.tproj/HACK/Canada/Yukon b/zic.tproj/HACK/Canada/Yukon deleted file mode 100644 index 5d86e0fe0d4e013b4a25aa5f32b0da5f23bcb1c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 730 zcmZQzzzSG_q96<5f`3x+S1u`d&fRYmb1M=tTu}t$70K|K2Xp-%6ZGp!7Z^--nqZhdNx`UCWrDGLiGoQm+XPef zFa|8Fc{VEO-l?gT~-Fv$xN XXAq2Z31Nr~24WW=BLIYf90ULW-dg2J diff --git a/zic.tproj/HACK/Chile/Continental b/zic.tproj/HACK/Chile/Continental deleted file mode 100644 index cc1139fd77a9e2dd5b1460cc871181ea33c23f9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 852 zcmd6m{V&x47{$N1%1t*(xce;K4<6b?EHQN;hz{Tt~%?eU9_&tsvNTU zUZGUkp!WhPwM^Sqx((a63);tt8h&E$t$ga&gdGNIZKw4xcTUtPpZ!Yau70^vtjT8~ zO-*{ol&p^tWDxJk61giG2FBnLK}JjMJaFl!?_{)KhSJ_aS~fb1#?9YgdCxG)DzvcT zP8XVFwZqCwLu?ve4XX}!vYAT>tloKx%}sBRg;N<@Oc#^ok`%TaOdzYzL2TWoAe;Be zXnWn7);XD_2ia431EWuuq9GkIeq`WWv3U%4ClPC0=> zFhRvzBk=p;%Kj~r5b#>YTdxklw&w2~n9~YD6@!ebH?%$LF$a4+q>%6$-eFcrp&soR zI-{X5(`pR+5KH0HB^c3N0J{bgF|vLS>~8bNsB$lezHW;#$>yLuso*^UKOi>AnpHL< z5a&0~@se3euo~lpiDBA1$DH`Gi}sC=Vp3Bb?eFWw9Fbi$iDpo$$S~F(v)J!wmnYDJ>d~>Zo>)&3_o@dXVzaNJAEA}g^)mExjZ0*iH zuVt0&!&)-~HORSSG~37u&{nNA+lkd^A6cyDGJDa%Gg3MBJ zSkuqZJ5?^h+J-NB=Zr~MSHYV3as9CV{AaVkzX>)R8Z^7`d(m}ktJ!s-5ry1h6prOn z(M&RK>{LgP(#5El`)F)kT*0s zt`iRm+G$Midx%-Arm_4Ei2aa5;}-5ieD7^?c+3C^_1WY|XA&q%63NjT2_$NR2{Eeh zm{dTHYr;_J{++18g{ZdY(4={Fc_8xNul656i&60%ZqoQsQ(rzo@_^B zV=}Jktlu}I8qA7-ExojFO zYn4_Dnf*{{cE+Q$q#iHT2sU( zd;>8tD&s$fq?oKLWk0*>F;$k%rf&<-)QxhXdIX}fF0PZ;3EjOTOi%fa^d$?p0eeKV z7KSiG+v{YgF62f+85w=q#f*nD$YijT&*ot?=T15|ZMjBsi)z@s=npVUZRhjdRag*o zk(vJQgP*m}Nb(izsz;@RRMBiJb_dU%;v>5#&~#4{@=W zR_7_;o)!j=7$0~BufiI(jU+bx?(NV|`dR*$D6MHb{r6;M3Ggz8$&n zt8At9HFB`*3$)>Q4*5srQ$Vte0>uj27$~72Qy&U;u%O`Yu?W?jpwO4z*fcssVYe3} zT%|@t^)w(Z#+9Vt zX%yG*Px197NN97Q#PSquKW{+Fj9~02wnI{=3w9>zA=$+kDZXP!HFKskn;xWnHKO#X zo5*F7oBza`mb%PRTedl^mgTacrj2Mwl*kFB zkdllvsYiAzo^&5 zfYaev>=cOx6$8ym1{uN_T#$<;slOSb_{z}WH5CqQKRCmP!6C@{ zU5LDJ5mD`gyyZBetu`#HFk!jg0EJq_iUbv6WJ;`D7zU+8OXYMLW8cRxZZwqfkLGgK zz)vRhe&*`VS6t(K%EX32CYi4>xpE9CwgIGS+(;`vi}c8Ds8SlCnsp!}qLUfpRml8f zXV#Dw>t2^p-Djl6oyGNSIm|vU;|7a@InGRM)Jdo{M<6%mBSq~jbdo2`Q@lmq<{!83aSBI_bCs?%o6pO9ZELm%%L7&HM(n6Ld#IbZH ziDe-=l)Vh%j_FwJy!C_SqYF^c6Nt)zZ`kFSg0a(s-NsQ=wSM8A?AtI^j?gUcLbb+4 z%e`a*WM4`f$|aW=q$7wz|4`tf`ld4hIFl{}v%W$SQd<_d{-7Yv4uGDbqhI_&3j(-i8l)n^Q zO62@-x%4x`6^GX!u7+M^xTbLS!*$c`3^y3of4C_+li}uri63tL+uCsZK=Fq=_og@8 zT{)rP-oDC)`<+Dv59UQTJj@I!cvNTG@YvI=;7Oc(!;4R1A6~IDF#Ovg^Wp#U{|^|Z z|NFq${_p_fqS0g(&>|NkF9z$oJE b62jmd48-9;91z0b3S_$i#ejejM1V*D9sFw? diff --git a/zic.tproj/HACK/EST5EDT b/zic.tproj/HACK/EST5EDT deleted file mode 100644 index 46d19f7304b485b2d4a970bec68c93ffe0ffc958..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1267 zcmcJPdo&jY6vuxg8f z$^iV9Ai#`Mx8Y1s7oLslqs-6(%reY@Y_|r^QA~nd{d~@y%A#`%llfdnBAtJQoL?0} z7n)qTAkBdaOAPp8j5Zbh>Vm~Wdnk$4$5LA@DBG%tm(=IOWwSR}F3wP)(ux(mjZi5z z%9VAcaJAwOsdEY@t)lPhp6bO{&h@Bxe&=sSD-F9oC$8Q1tW<;i+gnkrw)(>c>5I5EW{iJc@GK|BYiKnx~v zt}}tS&dObe2NSRv{Q zS{P!>i@Y^S(N2RGo5;{d8q&OEg$5`|4zjYSG$;>Cp-Sf`@wREPR3HmEY2*DRYtsS>$ zg^{PA8od;cfEQ(;_vmi$sfk112hOlHFP*oQ>49I;VfO!N5kSZe4v5jE?RM6@!%u+% zHPkuCe1w7(tWc=hOv2$c_|;@Ng)~ZHX!|MJS=5ia>Mq0A$Ns|I*(V`vPXS`WLD=Kd zzGTP_~0E8iazUthYGqWCQct? zlW&qhoV3>?gDGK89ZljcAtG^BD4Gl DgG~*O diff --git a/zic.tproj/HACK/Egypt b/zic.tproj/HACK/Egypt deleted file mode 100644 index 6e3d7bf229b54dcbdc7f030ea5e941225020c879..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 955 zcmcJOdrS>b0LITvZ;@1pO6XQ@qLSLpRjAui=%kXHt4s1g9$tHvj0EN5QF8(A7A?b(4>KyRwb0a|iRurFe$c7l4xrpZm$$?>l z88&k10LFfh&oeP1^9z)GzRDYz;396)mP!^5OZcKHKulXOHp_Pc<`0VaViH3va$50{ z@LaGoMUIzwS^&!kYb+E75G%=3Y^|9AY|KWvP1hqL0;yb7?@nwx?%@@;6~L~hldn8` zjjSp#WcG1-)FEwzIr{X|)nTp7Nkr)y_e$ohTS{GQ-XfQwCMec^h{SJ7plkPKw6;tM zCACM=d>^uAmza$eD*EhVOaUgIXz+dz$ZxBa4< z_!s8$_#^dwFF>2GsNj~$&uHt3576(@GX$fmpnvjpw9T^s2FOmKK+AL(B#uMd)uUkW z(hL^dN2p9~50f=U(2!1FwzJri%4_V{u1qT$TBy&$;OuAp0$Z+U>dO)#* z9dz@jiU3!3$b2mD9Xt6B9?z{t oY0-}$5d0sj&G;V%Kx8kNx|^v5(D<9B(tto9l?F~tg6SRn0n=PtR{#J2 diff --git a/zic.tproj/HACK/Eire b/zic.tproj/HACK/Eire deleted file mode 100644 index 6b51dd87c6f9705d6b43491406c025d623fea543..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1285 zcmbVMdr;J66#Z@M3JVAql1Bn^4G|%Pg_MvaLR4CWjmM^&W=IKIZU!4MtY(Z;Su%`s zX(%#4FN#2jtMX6;O;O@88JY?zhA&b;RPdF&7TdL^X~xEy&Y5%PeCIy?`~=}2VP;5; zGUBR1Mi04DDzb9h%&qf|%Q(OAC~wZo=PfxCm_Mt*g47Y-nvjRv)--XUqMEk{599Xi zV4=uuDHgjoV2P&}mh=vAsc?!*TWxViPd}D5s&QxYNz@f9a2IQN_vbR)^W_OHPm16Q zO*vOad2^L~5$=@%@AFILYO6cE-$upz`%ZIBkASsjZ{vaU3-Ms}Dg1uVC?EQ!3J>Qx zVqIDe9$Br&qbe=dM;G!B0gJIAunrqlZQR%{<+LtOw<8vB)Evi~6+?XM+dbH~ZaMdFS&O&h<$NbS4)2C1;=Q;K zygz9i{}$|u4}?A*aFO7^rJs3lvcwG95VAZGefH1TFjtos~jM&=2J8+yPdqht0JG210>s! zL$a>Pg71=Z;HRmC=Ywitdd$}_!#N-P{nEf+pAG?z*%Z(b4>N~TDezz@ym($kvx?#< zs5X#ZS|38exlZ(QqAP`bIumBklThd~N0{T*MRP;-Fi+ASdtU_6s-jqUe}xMrt)BtO(X&94Xb&Iw zPK1=XgYcoX0I5E60jVQuF`z9zGnhGX6xSE}}7lU0?piBt;mSfw!ApfH0M1d&Mes2bOd5Q%;Vs~@sn diff --git a/zic.tproj/HACK/Etc/GMT b/zic.tproj/HACK/Etc/GMT deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/Etc/GMT+0 b/zic.tproj/HACK/Etc/GMT+0 deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/Etc/GMT+1 b/zic.tproj/HACK/Etc/GMT+1 deleted file mode 100644 index ee1e3cb16725fee577a986de843cac0f337b538b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58 gcmZQzzzP_Fq96`A05AjuVgLXD diff --git a/zic.tproj/HACK/Etc/GMT+9 b/zic.tproj/HACK/Etc/GMT+9 deleted file mode 100644 index fa3eddb79d51ae498d8b8d44e17aa7e1412b1cf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58 gcmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/Etc/GMT-1 b/zic.tproj/HACK/Etc/GMT-1 deleted file mode 100644 index 49a0ea82331a0457c55681666dabfd16fac626b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58 gcmZQzzzP_Fq96M017byZU6uP diff --git a/zic.tproj/HACK/Etc/GMT-10 b/zic.tproj/HACK/Etc/GMT-10 deleted file mode 100644 index eecf42da935a0f5f4e4adc82c6873a78276a650a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 hcmZQzzzP_Fq96kPq4DP-mx`u{8J^&jJ0?Ysa diff --git a/zic.tproj/HACK/Etc/GMT-12 b/zic.tproj/HACK/Etc/GMT-12 deleted file mode 100644 index bf30d4a36c2718d17528b56d058d80277ebeb343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59 hcmZQzzzP_Fq96Hq)$ diff --git a/zic.tproj/HACK/Etc/GMT-6 b/zic.tproj/HACK/Etc/GMT-6 deleted file mode 100644 index 8af873cf0bb2d15429e9a32954e4c4149bd9396a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58 gcmZQzzzP_Fq96<{9 diff --git a/zic.tproj/HACK/Etc/GMT-7 b/zic.tproj/HACK/Etc/GMT-7 deleted file mode 100644 index d0a2dc4e72f4c6fb66bcd0fcd6db4401c319a185..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58 gcmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/Etc/Greenwich b/zic.tproj/HACK/Etc/Greenwich deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/Etc/UCT b/zic.tproj/HACK/Etc/UCT deleted file mode 100644 index c9b6275a98a6a6af311ef37ee969dd2ce2224882..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKSOD|@ diff --git a/zic.tproj/HACK/Etc/UTC b/zic.tproj/HACK/Etc/UTC deleted file mode 100644 index fa05d4b179f1884a71109c6a39df6b9c5e7fb720..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKX#n&9 diff --git a/zic.tproj/HACK/Etc/Universal b/zic.tproj/HACK/Etc/Universal deleted file mode 100644 index fa05d4b179f1884a71109c6a39df6b9c5e7fb720..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKX#n&9 diff --git a/zic.tproj/HACK/Etc/Zulu b/zic.tproj/HACK/Etc/Zulu deleted file mode 100644 index fa05d4b179f1884a71109c6a39df6b9c5e7fb720..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKX#n&9 diff --git a/zic.tproj/HACK/Europe/Amsterdam b/zic.tproj/HACK/Europe/Amsterdam deleted file mode 100644 index eb44c23420d7f897666e855881a296b9e28a5309..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1058 zcmc(eYfO`89L3)bI?y2=P$=W7)>=h2QL&2j}Tmg;*=z4~jB8T#wF6XQ2#8^-%$?biO$MBHkY(Q#6ZZ>u6O@RzLMTrKh8*w#muG8=_CJ*zBBGo=5mX&N0;e0a*nTm zS5N<|hZxY&iNF>Mf{q?Xa3vA4YY%1>88CZe9_A!zA&=5vZkP&+KqcmR_(3UEQ~4x< z^M6!u!Jscgueoud?J2{|zwnLfVZK>$lZ#3_7@mKYi*-X-Vz6Opv>g#?hp{ZE4yq+a zs3uK_45()0{Y_Z$XBk&^s`1wMnT%@8VYGcE-`*F)RkeX!T_9&n#R{y6lTw`@fLO&S zHR?&kNxxyd{0GF3{e%RUZX`JRuy&*YiIy`+>hEIm!AhjGoZ!0RVx(4n&h_u@XIjx_ zrY|p|HYuL(%2JpSwtyKE;mq`jL*^ZCzW-!CHe7tntih?+Snma$?IE&FkC0RCKyJ<; zHtqhEAFR5BJY7HYLu#-&+QI_&3oHyG3x7VsEt3X**jLVv?rZt+=`0pqFTp2YMzgpv z9b31AP`_^(O4digP$0v$#la}mJi~S`0cDGPST_CuM$ZWv2YOLHHpCs)M(lLhxvQp! zyDfG6wA@V7K@$bZf41u@E~4F}um0_+?o<9R3xapOL_9`U3a%opg1fj}k$AkICj>7+ m2%IJHd71z0PNt-5g_vZmkfL!${HVpEb{2^!5zhBQV*Lve+Dn=M diff --git a/zic.tproj/HACK/Europe/Andorra b/zic.tproj/HACK/Europe/Andorra deleted file mode 100644 index 37e9979958551e0ba9a99ad56323191d06a6a2dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 624 zcmchVT}YDw7=^cNBvEn<%)m{pwWhW5CtYe=w$>chvUE#Vx|TVo1NoBqPE`7ppE-L{VWRql-qENKo`kNKj%CgZ9;J*F7%}9L{@tM52E(Kh+8fbfpyX z;upFpk#sBq*~Lr94H9|1r;+dSV0lX$R+uc1YYbSaQbQqCV%4H$P)hVv&X%#@oq~ml zrCj}Z0oO!-P&N9AYeTQNuKyW}dhW8=af2ncNtAk`Sg(zttYHY{vJt3DeNZO@sK^Pi zV!9QTzr3uvr^m)AD>Y#|wXrI08ql%&f|Q$`a_agkv86^ry(0%(6(4BOCs8ALN~8QW zj5F_1oAv;;@o{W>dllOw*I}Bt&mDt7)Qw%?PPZGof@fIYbdC+KcA7W1XfYYNJG+jJ zszNr-71Nqk1MABr+%sE%y|=%!Ik6Bemos6De!;%LH`qgQ?6)V-+V`0Us_&r9HbF<; zFxs^dI@52lLq>LdJkQRghX=>~JTz@#*R^K4o^<2zSuNdRGmdoT@#sJ~y6ZLYIJ0rA zBo{q~pE#Z=g10D(-mh=q%b26@`6KveCVAp!7$@T~_6|Q}Uu1-*{G$vE1}L7F_P3?&R!6MTC(QHY*#bUwV@WZmE diff --git a/zic.tproj/HACK/Europe/Athens b/zic.tproj/HACK/Europe/Athens deleted file mode 100644 index 4c69035e65809161435dd20ecb122c7cb4b37bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmcgqeJs=g82%kD-+GU5g^=VU<@+;|t~-;D4o8aPGawfh1ylXo!J9D(`LL-1!hu=!OJ zwmi84i{3u6Y*&%hjYit41X-7#BO7@k*(RmYwg?H?1qx}qix1gbI?xUSJ~?m&a9Htz z;|F^d!S1RTa4qVETl!tNODD*qu#-H4ddMs08hKkakdH?R z`K(ovpG7VFCR54(M==8W1hnUE0s>o75Y!WZz11NIuD8U#Ogn^B`O|(87lL#PI$%Ew zpE(Rg5C6-QR zTO+^Pn+l=>sW8)=PPuQTBH?#B&10z8)fB~x@2SLS6(wU&sdQliXYRF7*=P^S>-tfl zYQWjjW>nTxLW85h(bCk?RB!Hvb+U=`cz@@A benKK8j8GWM4hbVzm-<)-M~&Z(;c$KdQ~&bg diff --git a/zic.tproj/HACK/Europe/Belfast b/zic.tproj/HACK/Europe/Belfast deleted file mode 100644 index ba4a4d9985475233a70a0037d00e65295476090b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1347 zcmbW1eKgi*7{`B42oV>{%kp-a%9waqnUq-)BU$pSo@#{^YRq`njLe+QwzfKsbJ?+( zVO^DBB_;Hx7GMuEnz_8}ZkoNj~>ODVArNU`1Ry zp5LLs3(|P349MZ%TsB~pYXw$Io4C3~lP?+0qf6=Q=yHQO)qc8|t`rGW7c7OV)JgSG zo2Wr%2o2*-aBbTpHg2}z>pmSQH@9TDhl1qo9nj=ofK8Js+-#qM&12tTi%vAQ^bcU` zZ6p5Uavio+j`7WsK5j2G#E!IDz9oB`J0rGZ*J@k-Q$l>(Nt^Gu9mZ}G8|;}S;hu3V z>{Y~IU&~$WZwthM(^v6s@ngRCV-XJS4CkS}i8vhM!y`#Sc;7b+9|SGMhn6$>FLx_^ zBn5A&&J*eJmikc9K znl+O+W5^%1j?HH6dNIySonW1#`luUolOe;N^#aOSKOXoc$NfA@I>H84{bcA;MMf%D z$k;fajJuA|%cFZ}_Jve3xs?Z|1%+T%u^Y^j2`u(S07lBda_35T#ZLlOAr3Id&Kc(V zuAq6^#$atbpR6A)Ae$MwWFt2u+umV%tz?w!E;iEqv=*}erIZ}DpCR$?bP{*Z5ga$( z04G@qyzW*83s!#*3(c~@*(na36-nS?l146VA+TsXmR!#+gT<{+KkyAHsL!h_&f zdyZD7B!hp!K6)oA3RWe5K>=&`(CWxg3Vb7yB!1rXu8}{jv9qBykHjQ3@B-=Y`n2xh ztFZp~1KJ>;0q?OMY%CdoO-c75D6I~HgX9pB*hlZXpMcF9YiWx`286m5QkX_5g_{wD z_oUNSg^ae<#M1|D5{k&*K#^53@ZmRZ6qOqYA8oau=v@mTCSVE3!i?Z!M|0S|d<;I( z6Cl>XfMSO_Ax`HJ#no3r{Jk5r<7h4<)Roa^8RsdnFq=M)&!ME0Boe7jQ+Xk&PJ1e4 zPxS@5(>0!btgi7qsXZ_JzuA)~k9Cz_nTCZ(RS diff --git a/zic.tproj/HACK/Europe/Belgrade b/zic.tproj/HACK/Europe/Belgrade deleted file mode 100644 index 2c5053bdc002fc3dcf8eb0645ecb6e9b4ce0b1ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 zcmchVZ%oVq9L9fFoqx0TWJ_^(6*(2rAC*d{a_(9>M|E;klIjX4x{{*Ys5P@&d)SRN znxfsX952F)YUc04IbqFWjcJ5gYoo>NHg~-7!fT)B`#k&ZdHo2&KbhukJ@#;9SN~@NN|~vD6ukeq!>v*Ynj}y z#H!bNrr3(8=uPJ8mUO0`kuuE?%Jk+WtWk@pER|rbe2glk3u^I0W`w>$#`p(hdf!H- za{%i`FCfc)85+keu5YzK+ug|xm6h0NX=3)~XFc|_+9TS8a)er3V z6HpuF&)SK1sPmm--QYdcj}Pk=JhtKH~o=LGXoV dV}DW_BJvT0zthtzRXVqGb%G!gdCrYU^b3XU%1ZzM diff --git a/zic.tproj/HACK/Europe/Berlin b/zic.tproj/HACK/Europe/Berlin deleted file mode 100644 index eedf74e20a3ce29fd94f2112bfda24ae925b823e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 838 zcmchVdrZv%6vuzJT*)k7rEa>VNP38#QYp#p)>5R0M5WTpBhf9bkUUy5YkXO&wF=Q% zjLRRDSr7AErmh~Y+-Nq9gjri!9&2-NHfHm;@ArJqK07-*e;q;ir)FuVy6AL98y(NB zo+C-FRu7KVXq2q2Z|3>iSd@^8#o;lq^^;?X zvlr|v?Xh%@IqbzU+D~}W;jJAV)n;^hXuxGnU+G*w%H`#QTv76bE_rQqO}kFFL=D^( zP4MtmeYGE1wKFW>Dw;D>X&i!Ye=Ght1s7-1~Q=9l4~<; z8Cc?jb-`lF(xeEo8=+h_g<$bxhS9J(EK=6;NMSvTPZv`V>FNLW3_-`@>8>xDY4HCo2$nV??N1v)5dY0i ft|CK0_|^aH$mG#6f=sSUkd_2NB+{1d!ZiN`w(9*n diff --git a/zic.tproj/HACK/Europe/Bratislava b/zic.tproj/HACK/Europe/Bratislava deleted file mode 100644 index ff27e2c34d4be154dc3d5942966995d4bac2c8c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 806 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 JFoIbi0sxYzU2DiI>5kVH(f z5~Vf z-2)R{?UZR$2v&N1re^yXaua4|QueWh#D2X3r+ z!A<3l=~mQ1_pDZWq>R8*)dnwVJG^5rz{k1)zMduUozuY2vW9-68Swv6%z#cAw!BPa zU~?L!?E&0c8O)%1D{jlNXK=Ycwug!-%d$j>;{@fhIfRP)7-m0)u*r7_H@b&#T`zWw zUqyuW1|s{r8C6|{=$6aenV*kcRi_z~aF(&kY{qR?QV|)(-I8d=ySgxb)}4uFp-3Dy z;hq_1?7j1aN&00-Zd`$sw$Dh_Oe3vEhx9Z(GRi)3U(j7-rt~w*whq}+EpwLKX0A1v z`@WWWb1LrdRrA28f(Nf9QTeD4ht5cu-yDa-dA2O5^g&@vAXGUL9PzM0k^CEut`Jb{ zX2#;FHz+ZlWy#{c_5>)Kgb*TXVx15c=%sHxUa5D5#6{<3JH`2SlFtn5UF c4>g7${yl$@KU^k{QwTD-!f+-s$WVs<30SV>rT_o{ diff --git a/zic.tproj/HACK/Europe/Dublin b/zic.tproj/HACK/Europe/Dublin deleted file mode 100644 index fab6a199383b6d18fd92633f7831c835c51dd4ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1285 zcmbVMc~I456#Wqo;UU6>WQp|>B0`7{QbLjlQ3yn0dFe|cq!cV(1TSJhBF3pK8HTwu z6d9sdMIb~(0Y%URA(qL|L|ic32w7!Q5@azRjs25jP4~<>bG~zzKR-cuVrkB#N-C>! zhDs0F3rjPyFU{56bxy)LxwX7|R}SyVGG_jw68FYW^1jWxaDP%G=lWOh0rv?!km)Yu zS#QLAn|ds;v&VwIF)kEZxUf|p5B3aUQG*;0HC@2se1AO5iCprf1dn`uo{z@(ajD`c zmjyU*xz7eXCILR~6wehpBYZ+n#wP|Za%GQzRab`bs!9Jj=Hfukr1uIP3_r0Y zd?|NN%*CFmSnO@Pi+%0E*k5@L@0LE~f$xvt;I>E}+LMgK;XXW)5{CDDBk+Eh2aa0K z<3HT3@PRPMV-{*ScJo&rpYFnk)ulYqt;&;02YITYDn>P?9!0h?R0}A;Ibv5-m!zV4 zk12{lj^f5?)Ex51xkrsz>%0W#WlXYmi5}|2UT4_pz`B9etd|J$C_uRaEVr$N=l!H$6}|)( z*gJ!@?;2XDWdt^Mi^*nmDcNf3kZr30+4T(53uR+u-_$~jGuz1FhjLmHcakJKvPjak zKyVDb3QmeLc+ss2mIi$b%gl1X*(m{>r&7ShB$Hg)!(sVEJh`6ogqN?$XhmKaxmCH+ zE89KDJ=>ICjj$q*&zHkWFE#SqWCE+KyJ)rN6nLpMk+;a&Y@2eb15Y~g;Ye(s6K{B zP4(X~M>K=~FgJTiUHs338seux^t9&x?LB(*P)GR_X;`R;1VI~AG?Xtv>#@!xf910( g{Oy%9tJX>dpJ1u5a)#bBUJz7N1eIBxU01q40oUcSiU0rr diff --git a/zic.tproj/HACK/Europe/Gibraltar b/zic.tproj/HACK/Europe/Gibraltar deleted file mode 100644 index 6e6dce785a36e4bd28fd3a4d7d218810d1a28117..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1099 zcmchWZ&1?(7{`ATSJoLlc(Iw|&tn7#5zeKA$Re3QBrbuaQ$#TSsJRFiE#{xNPBYKr zxTlUH575V4$PrAjp(vmse-)e{ju0XULPb5Z%u|lWwb}K~H@)fmz3<)UzIWdj&x=P8 z9;+uDtus!wIO1eUv0oJz_lmLPlAKFTO?;rFln)loVgB?q9y0vJ-(-~F;qC2gQrGgg z5tCTvn~F#LTd_Pa2+MCh`zF4`e%Ea5 zzjYf2#-#jHhZP5#C-`T}O&&5!aJaCOf6>3eBU^HCG$D|G)ew&hv&oT^hU)rvabvD0nd_ z1bjXG!Efel@E5Dd|NcUnH|9$LHVFl`JV`HE9#W8LoL(;Mr{LWkG(V@FmL~mtf!OHwy6u){OCFn9J@l_pZ;$rA+shU;=1<(~vFEw^EP-aSYuv_fi%4L0n&N$*6QgtX*NO84Fm8A>x{&Zwb{oD@sMZ7EM8UF%kOZ?BTF$`axIP2QBfXAx|T4+njw6h2ts1vya@@S&RkhWYMf zxH|&5t`8`;s~L=UuF|$+Ww6~^M?3bPqn+kb`q*fqyn;LuME}v#gn#W^PJ7(iWxDwP ywIH~H$ocAmFkKKlP&C8Y2+urXw|_V?Q6t2x&a(ne$=G30_# zNJ&OxMA+)V>OoEV#n6Tj5>^r<{f7i579r$%>Y?ZExZ^nP@dV+Y5YM$UfY|$9vtUcJE?nQj=c_f5%A~CK3iL*8&1v{8DUV`Lb^-Ss4VAHF7s$52@ zdsDc%HI1nkrQA{>V_Hixw(7*xlm%m(`~$U`S?I)1nJ#;S^vU)srrt$q(J;%xI#8~5vts^jR)&z3A1}}} zYvrNAMjjqF@W{0Snx9nTXq%cAmmXE7Fdl17Ky{7^)(Qz~Vnb1@{fRn%0rfEftpD~F z4NGR&F!BhElVd!7%Y_r3UN&_+V6(fECmWr#wcF?;^6~Zi-xLIi$@{D*rN~bZq~XGX Uzw`DigP_&wy=L&PM4~_T8v^mjUjP6A diff --git a/zic.tproj/HACK/Europe/Istanbul b/zic.tproj/HACK/Europe/Istanbul deleted file mode 100644 index b05d65a03d1fa419861f1d789992381b72e91906..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 993 zcmcJOeN4=89LK+Rb)9R)M^suRBzF-il`bVowW$2mA(Xzjo|N=JE8%Xm=ArR1=V`Hp zoEDmK7RoWFd2fw_E3GkJW`{DD@rNrmaCJ#)dL&ZEv_4Y)s8q!oWHQ?DsGlACx|u(IEr4rL z_0pE_&Ft1pGret4bFHn7wC!m#cc@6lYhkvrsIrSBt-`CK5Mot)wfAw|^&Q4q%`TrqP^ZotzHT?%)Phx>Kks;heJf z>W3tTkfCvF^v>QrY8Ppm-qq%cdYE{s-fgpnbL-aVJ#OA*o;A+g@ahf3Yi$V`k*_2p z)8>*<39-aGd@>pBCnG){Ze)yuJ&}rn)l!v?mzsl6_S6S`jV?I$h8V}`zMx;-OB}E1 z#0izHIC0fQ^jDt1fOHcC7VBVAL=yxh?}lK{0}v8e1|j__2zA$BXwMRme=EhXOVKc; zD;2}F85q$NhEuDeFtWx2r)7C#RHYoI$BHmo=?*h|o?}dOKg5b|VVw6vi0gd@@ixs6 zZ)ky;PY%PZ#s)}eyMl?^sv+t4L7ZJs09^G(oHKt5Cg*2j%H(`hB*fud*Cd?h=Zo_` z`(vteETncg;R3S^7M|_HMMir_s~rsKx;L;`^${{O2A~;6ShDUFE{!|~%hKCW>9r3s zBN{Plz!}W;M9hA%2Xp$1F}I~0m-i?zuYM8c-zeeELvfZX zlmrZiRWV;-^a2-D4;l_!-OCbtvyO;hK|Ls4z6)+I?4XUE={pHPndo6)`vMa*G-taWb1@^J10z--!gr|3C_X^XP$ct zoLwnC;oKr;f%B701THkG3S9WbSa5M_OTwkDwE>rIt341^Uw%PM;*Ntj$L#>|U;GCo zUh!R!yzT5Db!PGf={*ZR$gG+8L3U2l2f3c&5AroB9~5#zKPbkyeNgf-|DbH6@j*pL z@`I`j*9SH3-yhUj)eF?WN)%{36>re2*x#Ue<${COk!Ps^!gGo>agQ;vkgPBnlgW2Cg1`Fx728+AF43@t$ z8m#u3GFadCYOq-r*kHR`r@^kxxWRrlUxP!MXoF*mHiMJv_Xg(_UIrJ{n+>kc?-|@! zcQ?2zUu1B9cZ0!`c{79Oxm^rikEb$tubac*b7o_MZ(kjQ-Dx- zM0P{gUAKnp6}}BQ$C4RxJMehtiVNEqD&L)MsM;`tq59m~hMJjM8fw?|H`G;5YpCxlY+ztyVunFh z7FKpP2;|^If?V7jZ0wvIJY3wgfeZ{X3XH(S$tS?Tipth9U<8YR#4Q{cIT;wV3_$4^ wLc&BC1wpzP#2}=zYj6mIvug;0Z?Fpxdo#F#1YCgv3=E7QYk(w#2C*Rk0ALgGhX4Qo diff --git a/zic.tproj/HACK/Europe/Kiev b/zic.tproj/HACK/Europe/Kiev deleted file mode 100644 index f4c073c9f39b4aad3e639c88a878721a9e90d52e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 802 zcmb`FYe}R$ELd|nFJ)e{yp-2Ao$Vs#rB}C^rRJ=8sg~t!Xljcxi4Zxa z6q1_S)DRIPtq&Smj4+V34@!wiP*Nc#FO-Oh&^tu@(#M|XJcl38|Nrq2@=rOltvz<# zU}I;G_SjWTN8s{Q$BInx=ytcF^JAH%i-_mDB+sVIP^~e?Hd%TEMn#X5ujv={=|{{W zoxrcpw#W68Ovs(3g@1O9yDqrcM6+_)-pOX0+gK+f9%y3R+io%*4P}gHjh^u`XqkQ4 zDrSFjB;zgdXAT637#}f@@pWEfe7nWtejI1oZ<(j_pZ`e*OfBjHE$``r!&Y68`6+#< zWk`3pu9*%lzo!e)SJ0t3GZ0of3`eA+a5VisguAyxL|7$6teYUptp%gz@*sN6h%qna zaBMacCB3;Q9gV@*`gn|cC`MUvGrcbMS)84{MhL89Yp zNVHDCiLZ|#X|NxXCtqPoV*{iPbm7V3VxSvtVcMy?m~O~Nb)*3`$qA?xrea1=0A{R& zV5UF?nICrJ>1BU7^ZYkvP4ghTlMgw=i*VNT3vyempv#?xyxIjk7xx0r=S-sBvla5C zgIK^F!9sV$!XFQ?XuT9KOjO~;ISpQVl7)u1C2;wU6pMS+aHYr-uhxe{Nty&o3xrS> z>H+1-RjA+-Fa`_I$b5lHmldqES)giZ2CohELbY`iYg*r6?O;1zuQH>l(S(F@AP$7G z$C2Z-;ceTu%yr!I4&MJaA%O!Fdx+vT;zUT)7{z7Ti|k}sM)BF#5F*&zn++whH}-A+ hsa0!8Qi_IX6)Y%~8j_+`ut{Q>EjC0^gq=-M)L+l7?uP&X diff --git a/zic.tproj/HACK/Europe/Lisbon b/zic.tproj/HACK/Europe/Lisbon deleted file mode 100644 index 84933f9aa3779995ac86991c089221bbbd0d9665..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1265 zcmb`He>Bx+9LMjCyAtUm^DE?Acjm`zgoH8E4Kt#+g_S9UmGpGOq19N-njGh2Q(Ixa zE~#@T{UQv>uaF;6v(m^NtB@a0!)Ru9@6PF*cFxXOf9(A}@6Yo(@AG+{KOYX~U!^Q- z<&mpT7CGx>)Q&)w$3BwvXH#N!_87@&Nh04Sh)AyFDrJL&B=7hL5j*#g{HXn;fUiQ& zc#EloH$fy*>GXWdSz3ISPcN|Ew%+iyTFK;I03l*ed zLPDyV%V>4^IeINOh}3+OO0S=$v^Fl1)pgaMh{V#4#u{=fMw8wu3YT{JBuhKb zX>8%K0 z`YtE455zHS|CeE`^r#>Ev*zXh_$}5?nIb~*e zb2v+Y1fi<2&;5)d$ zYi2fJsAmMPt7wA}Pk=_#)@c0D5KX!@(X??fzELuZW(C9eX6Ai-E4dZTqpQ#&^gON& z>;X$r30OH+g0;^{Sf`%@HkNTj4pzCaOJh28^0gi#vg&ZLM^y=G{gIY`QTA30nfG? z+?1XMUPXE69Tf$e(~@wDUn=@U?ndABktpw9gxXsK2x6N3fzlJOL-(7(L)5h?@ z)hXQGy%ct^Y7kg53Lhp+LQrN0>W(j40oBl;ix~KvPSF09nVcdj-QLKe8{s= UMgkcL|9|oMn>ZUving%K!iX diff --git a/zic.tproj/HACK/Europe/Ljubljana b/zic.tproj/HACK/Europe/Ljubljana deleted file mode 100644 index 2c5053bdc002fc3dcf8eb0645ecb6e9b4ce0b1ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 zcmchVZ%oVq9L9fFoqx0TWJ_^(6*(2rAC*d{a_(9>M|E;klIjX4x{{*Ys5P@&d)SRN znxfsX952F)YUc04IbqFWjcJ5gYoo>NHg~-7!fT)B`#k&ZdHo2&KbhukJ@#;9SN~@NN|~vD6ukeq!>v*Ynj}y z#H!bNrr3(8=uPJ8mUO0`kuuE?%Jk+WtWk@pER|rbe2glk3u^I0W`w>$#`p(hdf!H- za{%i`FCfc)85+keu5YzK+ug|xm6h0NX=3)~XFc|_+9TS8a)er3V z6HpuF&)SK1sPmm--QYdcj}Pk=JhtKH~o=LGXoV dV}DW_BJvT0zthtzRXVqGb%G!gdCrYU^b3XU%1ZzM diff --git a/zic.tproj/HACK/Europe/London b/zic.tproj/HACK/Europe/London deleted file mode 100644 index ce1bd2e5033b03697e263090891b395ce4333ed3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1323 zcmbVMdr;H`5dPtDB8sq(Jd)QEDjgx5q=qOFpb(0ez@?{#Kq_ip1Q!t}5#v;r48yDq zMTF$4goJpCf-f{dh=(GAc%&GLk^-WLC<($banm%@OpPQf*6W2x^a=gc_3IW1z`c~Q!_d6oRb&RpJ=HI?~`lejx^g!io9iF=c4IZt++fAk&3 z{OM7+&!rj*T-~ssXOIhpW-ioP;{NVFEUHoBfx1hm*(bw;tmZ>sO0oFsMm`)D!benx zxn!9;mjN zNXo*qTXa~dP-9hS9{=LC8mql4utw3sHLb>c&T0mo%UVh2n;fYA*Dcl>wWBL3&(pWFXH_pPr3K|VtlZ51NZGp!H3bo+@BhWj~2(^<48XoaGK12 z_&Vbg;QLiHAlz@oD)H9_|wHNb-Kx)s)4F;;PY5qCoMo0vvDbjYiTmH0riP zV^E@T?I=#{li{SpQ`w|Zij#MYu<0QSG>gB^knPUqq2+9$27Y1I9-gA;XG`ZEvhu1X zYtaR=u_+*%j)U~#U>Z%W+(EWC_kmrJ2J9=ggF`xjeHaTrBSWU|6czFLSABxQnhYvP7QrxyV5Ffe#R58}@;VcJ8STqD5 znG2BUVM&R7w;;*%2_-dFfx7o9Z8?+=$qi-nN%mPv(d5#n>O4x#NF~AGIWbQ78+zxs z=WvU}|6Vo}KMUiZCH`Mc5KO^9|H}lyP!R0UV1k~}kN@QLs(-j#2wEx^{1=Wj1_opI J{^c7he*%d}$vXf5 diff --git a/zic.tproj/HACK/Europe/Luxembourg b/zic.tproj/HACK/Europe/Luxembourg deleted file mode 100644 index 497a9b7c27a5ecfe744670cbbf9d388b156b781f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1093 zcmc&ze^88h9DY}=6y?)W+v(TqR+gkzD(OnGwkG`$EiFm8lF;R~*EQu3b2~0H=5f

!IpdCL#`}&t=4Sf;o@btCo_Rjs&-cF%!wd@t zv6UpDMU<4CO;ru;_13ApmJ5^l$l?0~YYK>s2@n??l3%SNG z$1}%wt`|;lnr$bIMO;&YFW(%!oIRx>zQsR}KRxyjzExr1TYtaFpSiW0ZM*Y~ZSQ`> zcAV~G&sOf_&wbO(o-cQ0JM&A~3t2_%MMDAG74FAh3QlG(hjg-647d31d2=*912J^H zR*Bv!Eq(h{0NvQoNZ%Qq>HGKy^zDtHn=vZbdk=B;=5#pho|U*SCNM<}hXL;3tHTpl082YoyyT-*!S_6~BZw~+h(O7bWMd2ZfLY_^dm zu1Kd3WA&s8)zKuMAo6lk)8sKOq?T);ei48vPrNX--x=PQY%s0qFZh^$!Ss@Q@HJh7 zUv4`z84Z|`a+my#O*AvCjRF>bO@Zze6y%>zK|_TU>{^20`>Sa7>pX;XXz8OL3<#}G zMOa%1=Ioe@@NzdqWU4UNG@Ir{%Aw70rTJb1&}oM#QhpUtss|J`_!C82by9S1H!XO4 zh+-^t6x(wSaeIm>zWyK<=HyU9@fTQ>v*!7i7tirkjdTvubNWL diff --git a/zic.tproj/HACK/Europe/Madrid b/zic.tproj/HACK/Europe/Madrid deleted file mode 100644 index ac2bd27bf3d2060f687a51c0a873f75505360c5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 947 zcmc(eYfy}F6vp3GOOiSvEp0_Bg(xJILbk0zrOQ$-)vKG^%HK*;ZjEs_X&$D@G)hZN zHK}!5mk}8fqH?K*Tz52boxCQ=Wty?uFyn*o&NI(Bzw>-J-wwz9v&;;s(Z(t^*vOKC zE`b%+^su9s>VzWActMkMhaKA<$1231SjC%op{l-2(3Z)BlbQwW)E=>Ldfyu140B>< z)q9yP+>~7}?_squVZsfctE|r3L%8XiC)^qx%5HV%2zR?*@C|wA_{Q4#eA97>{$BA! z{{Df-{DU1<{6jvUH79)LTLNnIZ4N>DwvLN}+2BUK*_T6X;Me!Oc}p4_R4vt8oUjuH zm-z6O`+EheT`E1LjbzqIE*PSeU}$I{4V(G{HnI;GKJ*!EO&Vd_RRc-;NsMULU}Wt< z*j>It(n>Aa7Zj00Hpp?yb{eHp)97W1d}Rmq5& zu7WZo7z=H~u*hv37WH@_#wLhj9u2|bZdY1z{tK42n$t3kHO1;aQe0LS#pgB=AKyyL zx4uWhtP7MF+khm;d`kA$BE{?+R@eh8-X6xvUNu(T&cy2HN~|eg3f0Z^w05sQQcI&~ z-AYHW-P34&gdeF>Y-z(}2TD_Xr;XMerMuf8U3f(qmOaS0e}ghR+py_WDQ#}5#+Ll+ z*s3kWw#*V_GZRc=^CBIA|5);E6vo-Hvb diff --git a/zic.tproj/HACK/Europe/Malta b/zic.tproj/HACK/Europe/Malta deleted file mode 100644 index 6454a6d392b355c2efff6b464273c38bef0e3489..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 941 zcmcgrX;91o9Q|)=sgPe%i*|*ilcdX0$l98;u3Dr+hvZuMTdYFuM!BXjk4dI!OHn%* zV%Qie#*xX$s@N!uM&r!nKjTlyx+X{oA>oG%wN&J?`xJBC;DXeRz-n2 zuE^NNY3uHC#Z@(2$-eLG(UMlSG_is!%c^FN#Ram*Wo~S}!k=q+9YOa_3Sl@Vq5FsY zsBxzYH7OmaS=P)wnBjwm;mu?eo7fijBV0?T29K=@sN1)S>u$Z(-Xm&edoJtRzkSoQ zy@h+*zrSqce(bDBWa`dyyyQKJ7TOq=KYJ_NFIUA0JagOokMv~+SdU{Zg$}G`n;&as z8V2hdgEa$NzF<(<2hHG%k71MDq#06h1(b9_W2@3)XvkrWoivt)d7NkLojc)R_Y^|@ zJqSNu#qf@^81bMKBX1srV@)lIPFIpxdz41yft+?^(`bc~#>B0lu`)S12T5t1R{*() zTxtBE;p8fi!1c2q++MoC-RJ<1x&iRie}z~1TTIAr!^E7s@ZMa5NhxRG6W>acm3s0G zt|q_80`eCZQ^4eO3g}hS6vuo_d6q;|dsLWKE1~I6q7kG^KydXm%-9`*nMESZN_9p^ z&QzKmDu5)#k>IQ(UPn z#p~bGa`i__$Tv`8f{~Ik-ywPCC0Y^RfE1@fS{Yo4RLd%?5(BH=9Kq^dCDznuVC^$G z)}4rj;`T;bzc(0Zx+vPP+6nA#f7-Yxh?J>9+T=5eHcPu{i!DPcZ+ob?7nE*eLVDvZ z%IIpvwsSh#Zm7nN!W+n}EJjvFIn)Q#V0eGh;#aod|4wt~_uNnLzsWG7(Y(Gv*$^Z6 TmzPMR2*!O`V#i7jw>Y9-7VN`7mqKrTZu9R?~T^Jgi*0JmncJ4MP}?GDo|{JkTLBhjIz)lL4-``UlbK|+xzl-@5_7r0sK=3=+%l<9W>VN zdpB|0IKtnG8QD$Hk6s

sG3Q#=u=VCNfC$u2m+zIBI5`t(_ScGfWe{r1FuTt7h{i z%W`^ zF+wwnk%bEoRcC-`@f5^l^+2poKg30qL)?BX2)(*dxTb=HJuM!akA>rwbQBpfQ9LKW z#O`QJ8gfBNDH~68g+em9izymskOsd+GGz;7wsV*o_!?3-S0Ih?5Ym<&L;CxhkTE?B z^2G#jMIaRK*uzwmboII1r*}Nz z%|(`7hhIj`I-zX?kTYHc?neYgk!aVgiBgCtm)=KZDttMl{!Fuq$@O#pP|up8=AuH zv58uSW|vRcY@UUd%>}$Xa~rNKO=0UDBeqTVV|&Xj?C7gSAZ);f$za+t8Fmaht+r?V zVFyPiI|s-AWq?RILH}T&2$%p#1q2I#9|6t)LJ8ppAX8eew?DA|-uV#(_xDb46{>7d ZC}^bCqROC=0!e1m(8Es=w0`v;`5jD@<@5jm diff --git a/zic.tproj/HACK/Europe/Monaco b/zic.tproj/HACK/Europe/Monaco deleted file mode 100644 index 92ccb0228a36913521629bf16feabf467d381ac7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1085 zcmc&zYf#j66#cKT0V;TbU^iI=U2)Y&9s(gjNXxQAF0jg`TZoH-NV(C^jhMwm#*r~G z#yK>Mj}TcEdAY8SP@o0O7oZ?n4H=Zvj84*P=+~G-kD=QC6w{YJ^sRH|oO|z?`}GLI zzhagv6(yp}C2?2OGRBW|*RcBDNp`gAch+!pl-cr5@?$%l?D#T2eqy_h zH^%PbCpRcrQ&=o-R@Lzq<097TQO;W@Vp!X_iJ!Wo=l1>-e)>i;cQh;c8Cw=R`<9fS ztJ=!Xvjyxu%U;&5cV`#UBlyLL2dpDn$2#W>u+BfaSl172?EO#kxbw3<-aXL4dpcWq zZ-a?lI<${}@Gj?mT#7-IV39dyC1yFbH2YLMc`uz}-i`V2d3!F+snmc<;^14L zf}cSS|BO_6eEF{kP=1F%|1ThOy9L?9UdZpC!4sd@F!yQ=g1UQ1VRumQkp`Mq4GP(@ zi$cv7n!i4u7U&G5Ow`cA@Hh%nsA$n_IjN*-s2;^&@mFD3G7^ZT*FErL`_Bk({02|e zj$v8lARnSeUN^w&a6dzQJ_`4fv#c!oZ=uy)% zpBs_bWI~cN0nhG9L2{h}D+`rKsa!$NrAeVK2%^-macI<2lqS6at@2CKPCTG=x6711 zJV4LiKS8S;ZKNBzgpB>wlxaVPtm0zQSMSE^b^EZ!ycyX~n_^^6o!9uGnb+nG`HoPnwRM`o6B_8=2qJjbE~P-OkJAy%F9VjW@@g`VPJwK zgjrr_&LFcz7C~AP6-8$IAR5SgSH{YM1`ee69v=e#_h4|BRZv32s2-FK`XdBdIPcl8|d+iTFju?PdoGcYhW5w~gL zFi0AP!I4}H;kjd|$0`b31t3`BK-fFBDctzj6h3WN2%p{+MU2itq~$ei?|KALEw^Du zZ9j;LIw9IHhT`hWxKq}PF=_R<%g=pCbfDKnKn7b3nUS85xx59kSmBs8^9>F! zd0_VaS;(3Ggt>iR(J=Z3k2KF2Fx3Z*-BxHCISXg%+n~9l5D3kMxG?ApR|b6pox09( zW3HQx?rseFdhvfdA<-Hd^@u@I!XQMROJfou6cJBCBnsMQLK1b(%?lu`zr9dIocPGQ!bN}cFRa*A}n>qt(gmM)|tQR$)^j_9D3N<(YS(jL~NrO9P2 zmiUl-2+eg&9ZAhXvpFM_99`tHHm8~S(r3@J=Y8J&_I`W?VMZD1>2#)bT%YNEZk<#s z)b$pncEq&lItL@sbxA_ac{!e*^hWm)M?6zopeNl3Ls#uN+!Te+r)3zaaK)DbJLqzN zuL&ZIhL2**Pm6JBFD4`p@C`anx*1|p*F#fHjm|7O6brn5(%fN)7G|$0G3cUX>^3d6 zSGn+c0~g&pL93g$VBOpTn=@x&TS?dzABMe3jm1gZu_Q_fhad%(y7q5x_gQfH10$|z{Z5yQAGxynC0)y&&~5)sx@TOWM{++r)vfT7wZnVkDfrmb z!`HI_zEh>}x2mT9KpFym9IIX>FsLzwvi3l(E)QXFoi*2FIWVLw0BggI>r@es4mdl9h>|k_NC1RS-aeZzsHdG#E?B-+K zsLEuVpNh(;aBh;sFy6(P@ssXMFb_k*3sY{HaKhHMaVGZ7LsEkYl3Rzdt#k}2)f%Lx z^dYU}6VrolV0&^WGwf=SDQjWYoa@ZCA+tZ!FlS259ghmRb3n;mO^H-J%){;q8FL%s zuqVfkd&_;07aIh1mIV7eY_VVQ0|!h5s+59Am}M}7MYF~K--2LmFVcUqF$D47`G@@Daz&g{kSmn>Gm&2U()Vv8 CcJq$_ diff --git a/zic.tproj/HACK/Europe/Paris b/zic.tproj/HACK/Europe/Paris deleted file mode 100644 index da4bd18ce7fe7dbc6bf1621d096c9bb07071329d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1088 zcmc&zYfzMB82wgQE(-X7!IFTO8?GA3MLK|kU=?JEa^7*I_gk5sQb}4^`jsC^Eq?QbDlHLyzj3^ z5dO0~9H~gLIvo^!U{$s@qgHL^wL>F(e^(W&>ltSU%I~xK1H;UceS{y}VPl6D`tZZs zG`t~tCqJ@Y&Kg6ad6S}+H|yuJ7S|HqG8V;JM-BYw6)kV;OX9~aHF0Z`oFBJjuoG`d z`3L1&_=ju``^dD1wQHT($<#1@D(pJzh}5vo>2}un;50jZqm_O9RW`SM-OIb|9lX1< znfKHi*qQhC@=xC9{H)o?&*f+F^ZImtAyLXM#)k9WxEkK4Z)1HU?iTyzpIHCs3cB1P z!@waWefCZi4QBlC{b2b`{<+DIzDQq=X*M-^9E~N<1ryA(AqQS>&!p*PDo|kzymJ-s z(fMOWS~5Mc=q`Nazr%0Fw~#qqhU``k{I4CylV4ge^L!Noy1FT_%}PQ0>uFX6D0ur$ znr$@EQ|oeQjz&lFcojVz8bcw03YzQTPYS6LiaSx5_j3s55BXuiMOQr2{wG2ke#NuZ zBUo7WDZ&c75T1Js5n00&X=%4+|E)|cKQL-hb<8-{2@$!~Z$v4e85`jH#Fk2WS) zk>_?2n}UE%zr2h52@_ti7i05P9kw*Dg|T-ly}Bm>1&x{XT7EFt?r7S&GM-F%GI~8? z78R=gqBpz+Dhl&O5&x0QUgIziUZCQ!VQf3mNN*0c?2iP z|AMot)J5vz=IrL~B6XiS?Qua6rbLK`>O~S~u?y~x^zX!r1W(8L&X#!pOZ~+Ce{#`l e({#cbRi-F9K{?6EA=#mVM1;ig@T5$BAo_>vdtwU! diff --git a/zic.tproj/HACK/Europe/Prague b/zic.tproj/HACK/Europe/Prague deleted file mode 100644 index ff27e2c34d4be154dc3d5942966995d4bac2c8c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 806 zcmc(ddn^r@&Bv~B z`A{=0?w_S)S2rZ>Dp)l%!Mc*LDLDb#?0l?9NW;o71?+s~SS9s>y~F{l4b0&nlF?zt zgO2a)>7+5^num+IR{f3A)(Nhw9^v}(Cv-08qKon>T@$r%%U8qQuM-~8HSn}*gqK?p zyynW_ZCOq4(Ny^SEab*+88*F&qi{W>>tb439C>m}ThVaI@SA8ZX0QKqy+p#3=I zvN;5a9y8eP4T2}%BSh~mLi&5KZR{dKRaX$!dxzmwm569>VPsAYwpX5H)Xvk4&Q52{ zhHNUrg1JK+!C0viV`p6$XBvdKVPo!^am4N$Um34iiiBn(B&t6nscag_)%{3G)*!X? zBlq~(8;=v@vtdy6GqR@XLqjNhgCG&6iNLot$`89krR%kR>}<4IzOJZNeW|aBYoKQ z{tm32lR0Z|VZd%M{K1NNqGHjUS+T>kkTyQ!ljHqww5fNNoUTlf^Mx^TsU0NOvTkzA zXeIaLQEZkCz$2gwp3W`svTTI+a)S5I68L;bhwp1S{KiAEWzY*-`xNAVErtS`LMZUK z2L+YekvPkQf)n&8L^@9ruNexpe@Rl45ennop|D>XgnyjGwl|Nled0ED+`W#7?q)=` zoPz9hHFj1PA*xV;=^)S~B5q&`AgR6o*#IPLUQ0Gd871mUgvx17#0#Fj;f&;-;D0LU0%!a{1!Dp1?9m?6K zIP~@bD%5?b9BM~Zj|zu7?~(FiFCD4BO4XH3RFivx7%*6(qo>Q$<>}}zkiYaV8W{dh z0;VeN4edG@UBJQ`e8AC-`$!`J1YEGstM*si- diff --git a/zic.tproj/HACK/Europe/Rome b/zic.tproj/HACK/Europe/Rome deleted file mode 100644 index ccee93192420ab93f0d459821b6b2ec0c7e940a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 951 zcmchWeN4=89LImxIVH)bs6&?`smMcmQp!W;YH>mxLg|q5aL(6B%2OWmux4*GtyP5F z2r(;Wg?Y%b>Ld<%SU1mP_T8|g4&7!m#=qY0y*_*Iz4yN#LHMh>cD5EQD(%FQyA=fM zd4cf}FRZTRMHN;2;I41%(7`5FtUksMZ>(fT5`x)Lr8le51oFDqld1lM6ow;my1g%e z8myDl4cZ8HN9Rn9%0_;7tRL=0HT_JQV29eOa1IkktYKZYr*p~B?WV5U{mi<1s>wzX%57Sr zO}4{lG27Y@Zf76D>`uDy9xqJXez%$TtT!`C>&F~UH#5h$4(4dco=3TMn?k@7Sceaiaf#; zG{`rIJY`-q*sc$GN#yYQ902c^p71d`V@S0%hL(SUZ^>H>%YB65+iEc)tqLQPPs1;< ziAL$l$v?c30%8wPplcBYjmn@Pa~6$u$;IfW^C_e~9if-xH0E(U!t_Z9uMEZ5>M*8iwKOefE2hudjabbh#06`hQbu8hGzK$$eK50iB;uVSDgJ>YW`FjkIp;rN zuF;kfiXAAi{5{Rf`bbH+22v*(Y5s4a@ww34TuIA!hC{25qZNzYz_J5r<@7MprATR&Uw=wdw9#q@fzn4fA)P;? z4Et7OG~A%f4^3EmR!{2;l~|vD4I9deurad)S$nb|h<>w`$m(ZdCH~XDhT<-g|8GH% bxr;hq%boWCR-qfV2Snrk{*nx*EJnmOh+nwI7<9WA%at#Qi_O^QTHEHVmd zlMpcjsSlH;h>*}B!um+015rtfNF`Az^=2$6=(lsY=bn4+{k($kPgskop$w=I%itaR z9J=P;Jhx7^bMMxzvezqR7UL1JZ<0a#w}Q@LGEnI_c1$O~)5+ESEmT~n=9+d5ofz4Qa!%^cu9X9bT}mKC1bn-!iD_my4`t~q-T>EUzr zE;e)x!ngGj{Hi;lENFp$&Hw`{PjF+{DQ-$FVW6UtK>>*jT2M1sUX0+WAa41t!qyRc zhD`b*v^Nl8!?xJgCPVo7kBHEGMP#cDqhclzoj=R%ZX<|^e!^I@9>lo}F>Yp<@g`>( zufNEhFSSe9@5!N#S){4iA2eSo zwXn33{x1rGpQ-pzf|pVddu+1AQV@b841Q66Cx%?SS!TRhY25zhRf%dLAwA0|X=))Y RQk+E*tpO4d1~m@9mxLg|q5aL(6B%2OWmux4*GtyP5F z2r(;Wg?Y%b>Ld<%SU1mP_T8|g4&7!m#=qY0y*_*Iz4yN#LHMh>cD5EQD(%FQyA=fM zd4cf}FRZTRMHN;2;I41%(7`5FtUksMZ>(fT5`x)Lr8le51oFDqld1lM6ow;my1g%e z8myDl4cZ8HN9Rn9%0_;7tRL=0HT_JQV29eOa1IkktYKZYr*p~B?WV5U{mi<1s>wzX%57Sr zO}4{lG27Y@Zf76D>`uDy9xqJXez%$TtT!`C>&F~UH#5h$4(4dco=3TMn?k@7Sceaiaf#; zG{`rIJY`-q*sc$GN#yYQ902c^p71d`V@S0%hL(SUZ^>H>%YB65+iEc)tqLQPPs1;< ziAL$l$v?c30%8wPplcBYjmn@Pa~6$u$;IfW^C_e~9if-xH0E(U!t_Z9uMEZ5>M*8iwKOefE2hudjabbh#06`hQbu8hGzK$$eK50iB;uVSDgJ>YW`FjkIp;rN zuF;kfiXAAi{5{Rf`bbH+22v*(Y5s4a@ww34TuIA!hC{25qZNzYz_J5r<@7MprATR&Uw=wdw9#q@fzn4fA)P;? z4Et7OG~A%f4^3EmR!{2;l~|vD4I9deurad)S$nb|h<>w`$m(ZdCH~XDhT<-g|8GH% bxr;hq%boM|E;klIjX4x{{*Ys5P@&d)SRN znxfsX952F)YUc04IbqFWjcJ5gYoo>NHg~-7!fT)B`#k&ZdHo2&KbhukJ@#;9SN~@NN|~vD6ukeq!>v*Ynj}y z#H!bNrr3(8=uPJ8mUO0`kuuE?%Jk+WtWk@pER|rbe2glk3u^I0W`w>$#`p(hdf!H- za{%i`FCfc)85+keu5YzK+ug|xm6h0NX=3)~XFc|_+9TS8a)er3V z6HpuF&)SK1sPmm--QYdcj}Pk=JhtKH~o=LGXoV dV}DW_BJvT0zthtzRXVqGb%G!gdCrYU^b3XU%1ZzM diff --git a/zic.tproj/HACK/Europe/Simferopol b/zic.tproj/HACK/Europe/Simferopol deleted file mode 100644 index 8d1224e21dfa9ce15ba5a3f9c31aff88a4d36680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 810 zcmb_aYeP9O6dyC+TKQPH)YNP~(eiN-6(i9?iz2fb zJ}Ojtm_M?@A5noK3ycgkgfPm$J|dAap-mHl`q??0d(S=h{=C3Hu|u2cqyuTC^A6X= zt8BOXH&yqlc;QBqdO%>AJFWy zo|9N{X5+1Xn2%d8nQ3^lQi;uEhsO4?nzb9e$l7-`unw(dtYeLmbt+0>cV$Gd&apwP zOQ;*WTfk#o?TpzyCTlF;fUn}OSgYI?t!VFS4!J-3P97smBpN0}$_&76Q=X+Qi$L)e$tf&lw=1o{;qaJ>XV+h!8ZCn0z(pF*AlVE=41h4v?q zXiPxjW`7F1W=4`+E*)s}z(Lt6NtLDucYRAT=@j8UY^D?~2OAWH86qNW}p`u!!u z40j=R@*c_C>JT^BL5GSJh;OZ+gtQt;EJ~xKpe#y`4W<+;38e~bDRtGE(z!yUztN|| zD>gVX`hkv4|3rpb51AwHkX65k?9Op0vR~j>?HnBsyN#U8r=)Z|j}sy_<#Gln&%S~3 zKAxlebtRpASx5!*5mb0fPDRgiaH_?diu+|aoo`91WM&!s06` zy$z|7oko?}C#uqnqI!9P&fL9%vr|J@|9Kg;ArhrhwSOV@o;BM8egyH>tBTY(1oIDxQaIKNa Xk|9qD*D6NqwZSHs4g4OojbVNP!Vu>M diff --git a/zic.tproj/HACK/Europe/Skopje b/zic.tproj/HACK/Europe/Skopje deleted file mode 100644 index 2c5053bdc002fc3dcf8eb0645ecb6e9b4ce0b1ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 zcmchVZ%oVq9L9fFoqx0TWJ_^(6*(2rAC*d{a_(9>M|E;klIjX4x{{*Ys5P@&d)SRN znxfsX952F)YUc04IbqFWjcJ5gYoo>NHg~-7!fT)B`#k&ZdHo2&KbhukJ@#;9SN~@NN|~vD6ukeq!>v*Ynj}y z#H!bNrr3(8=uPJ8mUO0`kuuE?%Jk+WtWk@pER|rbe2glk3u^I0W`w>$#`p(hdf!H- za{%i`FCfc)85+keu5YzK+ug|xm6h0NX=3)~XFc|_+9TS8a)er3V z6HpuF&)SK1sPmm--QYdcj}Pk=JhtKH~o=LGXoV dV}DW_BJvT0zthtzRXVqGb%G!gdCrYU^b3XU%1ZzM diff --git a/zic.tproj/HACK/Europe/Sofia b/zic.tproj/HACK/Europe/Sofia deleted file mode 100644 index 44c670e2bdd1285e50c3789471e89e5130a88025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 735 zcmZQzzzW!aq963bO6FyKN&U5~P_~#7`5|0-)NM4@QAa%I8L3+=62AMSr7-Z*6WRUA= zVvw&XW>CmUVNi?-Wl-{QV^Fp+XHe16U{IBjWKiSbVo+x_ZBVb@@<9D7SAxcqw*i`0 z-Xv%pIUk_ClUfrWHTfW=+22bRC>0<88*Jg~m45MZ;+G{JT^Q-EEYc!K?`CjkzrKNB2V z7%n)u-cE2%essY_b#H>J^N|Z~tn(Axm6u&`f4BRACv(RI&vSDhcsy3<&$qmJlJzdm-Z5 zi-gE8?=M7cJCzW9<>G~y`OhB2ZrOYxuKvV>_$gB_B*d?JkXXAZAj!VxL2~SrfE4+> z2dTDY0cjlF3F)#C0qHMt6Egl<1!SJ^Psq9}6Og^aFd^rd#f97s;e@~023Yqp8x|3h|S2sz@TNo d$O{t(v0Yt57@Wa4IE2B~6-Y2JGJ+5o000>l=QRKT diff --git a/zic.tproj/HACK/Europe/Stockholm b/zic.tproj/HACK/Europe/Stockholm deleted file mode 100644 index f0a2963bb021e274c61c9d3c24872ea3f869f848..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 688 zcmchVYe>@p0L1@GM-M_yO=meDwU%0z@1^E4n^UZ5>6Te)YR*TsRxY!xv=NC!47orO zGs#FK!d4%wKBz@cjBErk!b*yycZgtS4@PaD>vO;3;5hE%3Bo@SyIYSv9CF)}=briY zyS&pm^4ibQKIxyEi3JHi86f-2K>wGNcs-_M>L!E6uW;ehZZ5ieiot_JkoMUTa`qfT zZA4h(F@zgTSX@$xB^n)MX=*HuRzNO|z_R&4h!Cq7F`dZBw{k`~1G)VEY_914&gh@TQb-pR@n$GoRwM_vF?p;4DZd(+I;6sy z7e!3#Eu(TEm1|ovnBFPnx@s9Snp3boOH7qM7@6|-RI6Ob5=m*n-XX{9HgX)p z*f4$p8|{~%8M(#WRvYsA&U2H|h|RX+%-?#F1%@hWR~x9)WOIuokA=}uES!mDQ9u@o zp80XxbR@Q4|H@+LJd||%qO|`Dc37uS*5*KYnG+RFpSUyq1}aNOs1NHvmD0}YIoDVd zLe_j}XRXV`UBedc9@BBp#bO#B)M4)lC5^pW?5hpq{+1-v<)^_^Ey01fP}Hk`;GnO7 zhL`|0Oum8HXNKk{_h6YA<>9NnIN}&!W5*pf*}Hhu(nD*jm7-aKm-qjdAo#%ZF=@ES V`|qq$>jafrs}lr~8~02k`UA@@%DVsn diff --git a/zic.tproj/HACK/Europe/Tallinn b/zic.tproj/HACK/Europe/Tallinn deleted file mode 100644 index 7361b7a3a20b75d34e779bde19aca6196d651d3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 800 zcmcIiSx8g?6g|%+mvkCGY}_?X$8_BH(wrJcQD;gW*K#W-H8pod%jF^>Mxs+%7KvJj zCa4&hP-gfMCOO#zMui$e*kWLhK%_-zrkuZiyN7e{x#xV`p9}o6Ow_K1nrcu}qwRXr zJe0i;6pFs)ZpAIQmkv~vNan`xuRfdYj#GY& zUD^EtOV-)O5-ujj;Ohqvf769r*LZZ`l_9x3`A+T=>m(RhB9AU5c{WdzSLGOa%lpVD zV;;WcgYXL*g?~aT0&F`F=v#om?J@*gw@~nk3?V=B>ELt#4lTt{=wLjBO$q35iywvG zI^IKL&a=qn=irzpzlC89RoAX@hxq8A<_=KWQ~j`cvIyi3yd z1{@pdq~pceh-<5&_>?+IC`ut&P$nfxLMVwRq-23LC2u)Ws(CO{U+YoYrWH<1exQ?! zzmVRqi;RhP$ZT9gR@V%&v!3Eq{W6^nA4X2bW0Kon!kMss$~7FKJliJ9`*e}=x8-zp zu8;~=BB}6>l!|6^aIV#hiU-9g$v30Y7Cy@2JyD)(gbE)nD#c$=#r=kAF9WJ(7g59c zOf{-W)Nahv`SI(xurNw>Hzufltb-bAuTf)r8R;@Q(9_?g!{{*j27h5_v;*Va{~G|$ zU-O1G4vZea;lfDUZ5&_Y-5O*hR_+iT5BIqmh5%+eMq79nzi zVMz%_A|1IaQ3ndmQwD&{Qhx*v>;W_8wf%EMU@>iVfEo+u` zyV>m0H4s@jR(*=L%x1#)RRNCQnM0l=j^TYyqWD}L!=I>~Sv8kKJDbuemuFRst09Jmo>(r`IG5Q=aL=w3o*XN)T>i1WVQ#Au-UxDK)j$a-H!Wc}s}~ zdx_7*v&6UKB=KvmC;nOuSy!A-)+^*BATfq)2$7ILk&tY3<`XeD>V#N7%7_;tQSvSj zgKSyudAOPcgLNE{18YVR*?TMAVsJtJDmUd0i0Y(*w~FI*4A@ zL#(#}W2Z|Y?nfiWkH{clst^X^VsHaxTg=-moKZ7E@)* zAm={8w18KTHvb+n93DW1bqsdCxeS@c0Z>@(VOD1cWDj1#oSGWg)zON%yU$>rwhWaq zT2v|0Fkg_31tCFLuo#Ago^mLB?v8sFB(V3^S1hvep}5x#N=%<%pZ*J|4OXDkHYjcR zi2IXo!+{bDYW%vPOlrh(-c79VL9F<24l9@I@ZeYz9-3BR)s-UDKCXr8(^9PISHj^+ zKcw5Epf)!V>dFOBAMOhcso&v<8-d19Pi$mfgU)pkbrTPvX?_xq4)wz^s~MZSN3q4& zgU6ftP~WLX&WeA^!SS~^+?D@Rgt(t)-_;d}BOxMx4)53evthF$OGRX G_V5#9u;qsU diff --git a/zic.tproj/HACK/Europe/Vaduz b/zic.tproj/HACK/Europe/Vaduz deleted file mode 100644 index 2caec2d579ed361d7ce6aaa84a1e68d8a9b9dbe1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 647 zcmchVTS$`u0EPc$qYEL<5RhwU$~dFR7_*nf-3VT9$6vN^P0*QZ376V=HY$A`v1d z7=@H%Bobk(2df9Q=!%hzAVye8kaQ0TOe|v1Mz1}0&iUYQo{u2>QxTyxOjwQ(;XWr? z`IRvX-cT0tjIzl)j2*wug)h3f=)oDr4Guxx=R^F3i%4iE6wN1)Xm?<7MKzWf%}{D| zSgOv3N}hye^J0-C6`3@Z$>jGcrUYWR{Lw6~=>JJ|&u6amzT&FZr%Y`cWSZ?7(1u8a;~pc zvY<5=8}w3&wm1~3K2j$Jp_e|PLHQPji4Q1>xQ8PDFgA`~#wOoY7)S1Mb4NRh`z~=y zLj$(9pJd7Q(=4^u(6q)*v(dn9vSOC0Q&={gMoY9FmY4InV=5UtZ~b6-U@j`UqfpuZ z4ZA#(uzLO2Z4IER;aHdAn`TZSSk<)ZNe+c))D39Lg w#WDW?n>+8b#n;8-?jCwNJe17%-xh>Ogs&t|l+66wMV(m?btbbQNF<^B0e_pmY5)KL diff --git a/zic.tproj/HACK/Europe/Vatican b/zic.tproj/HACK/Europe/Vatican deleted file mode 100644 index ccee93192420ab93f0d459821b6b2ec0c7e940a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 951 zcmchWeN4=89LImxIVH)bs6&?`smMcmQp!W;YH>mxLg|q5aL(6B%2OWmux4*GtyP5F z2r(;Wg?Y%b>Ld<%SU1mP_T8|g4&7!m#=qY0y*_*Iz4yN#LHMh>cD5EQD(%FQyA=fM zd4cf}FRZTRMHN;2;I41%(7`5FtUksMZ>(fT5`x)Lr8le51oFDqld1lM6ow;my1g%e z8myDl4cZ8HN9Rn9%0_;7tRL=0HT_JQV29eOa1IkktYKZYr*p~B?WV5U{mi<1s>wzX%57Sr zO}4{lG27Y@Zf76D>`uDy9xqJXez%$TtT!`C>&F~UH#5h$4(4dco=3TMn?k@7Sceaiaf#; zG{`rIJY`-q*sc$GN#yYQ902c^p71d`V@S0%hL(SUZ^>H>%YB65+iEc)tqLQPPs1;< ziAL$l$v?c30%8wPplcBYjmn@Pa~6$u$;IfW^C_e~9if-xH0E(U!t_Z9uMEZ5>M*8iwKOefE2hudjabbh#06`hQbu8hGzK$$eK50iB;uVSDgJ>YW`FjkIp;rN zuF;kfiXAAi{5{Rf`bbH+22v*(Y5s4a@ww34TuIA!hC{25qZNzYz_J5r<@7MprATR&Uw=wdw9#q@fzn4fA)P;? z4Et7OG~A%f4^3EmR!{2;l~|vD4I9deurad)S$nb|h<>w`$m(ZdCH~XDhT<-g|8GH% bxr;hq%bo{m$_=eytv%MVR_W&& zmcw>2s~BOKIw>bbvuWhlT3cGo+FXCy_}Ay{?Y({X{qqR~e`TTmI`4VT={?_#YfVHc zwYt%%x)C+&TRV99F4?d&g3WnWXbDPSuW>&6Cc@BvRYYyG49_omVBoX^UMMXv*c64K zG;6*L9fZ!O2d|tp7?xV$wQ)68+!9ZjOTN-#`CE#N`YD>eN6YaWTshQ8tDXzA?&^lP zT@9PM2G~{*b|t4^pQFU8#5Al9S3u$?#~P^@9K?=TYhnpUp^T0*9(4NPKxdr=*F9du z^_m})wtnV@s!?t%dq$UnF1n^)r(4np+?5(^^6!L4Of@`h>fz;H1g|+2ysfL~J(dce zUxoDTmSM}Ac>1*^)4$V~Tgw9(P%GxPObG+ae6T%ONLjiyf*d9&m(3wq_>>`%cLJ;bq)2rhrHTRrLnFg^ l{~?0~!v8ISKx}WIU#%$w!hdy{JXRr)$rbuH13miC=Wl2Z>x2LR diff --git a/zic.tproj/HACK/Europe/Vilnius b/zic.tproj/HACK/Europe/Vilnius deleted file mode 100644 index c8f5461307ecbfe0e2edff2e8cfa1446b4703bd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 807 zcmZQzzzTSQq96Qc~0f|?97bI^xJ4l_Gd_j88f)6rlCVr5e z)AT{Er}%?>P09y_oX`)7F>W7}e9S*6+h}}H(UJV1D#P_bjr;cpbyoEP^{)~I8c)R= zG_P_rXdU_4puOc)gU*uM4Z2g#H0ZVLZO|`S*I3mGh=+ZrtH1~XXx&S{l`*$L?!Lk?&?m zwO!DV#<9F1UACzq{Y7U(#^02N%oEuSS$EwUvRC*vADY8!9erW2k(0x}j>r42J4+Ya422 zZfU4p*WXZAIjy0-udsoUiJ6Ioot2H1jfDdOIk}J^HxDf#1B37ePzn^wU|?Zj;1gir zU|^6@VBle3&@x~UK!`AkfW$$hg#)7`Ocuswl!fRD_YGn224ZK|5C&Hu_6_z1vV%bk U7oY%;0S1hW3=E7w0O3JN0QYO<8vp9)*l_j!D z=4vBhW7s4`DUXa9Lh2SVqj4`k+57=MXXkr9=lp(vf1<0tYFfidb!*)G=oy!mVgs?P zxc!N$T^-k+XbR~RboZ+$pF#){HdZA zR>@im^OGJNXplWz^)so>E>YGVt57|1-v6S*bx75zm++!n`T*ViO1^t}itk&C*fX*S zJ(n-wYN_*5_&pM9reFx{75ENx&|5kaGD1B}S@rYOaU z#&QdqNcCwN;)RhOJv6iHqPb}^#lmY8f2!lCSLL*Lm`}?adues$9IUI$U{i7sqjNGa zCT$DGCdx4`Is&%Afw1%Q#&|a;*jrn`!9X95I-YbKbfD8~F`e6W>2mWMU6t?YR`HY* z3Ys`Evytv8wVWg`<>Z*Vn6kMN9{x3$8nzFfHhJ)xvL0ST$?&ntqEA;irhSj6Z=)xs zKb=p%%24_@xN%072WJ)=aaNoeXJ@)%j^rx?aUKN%S!MSvt+6H-VtB2kMP Jff~*H%`a%k8^!M|E;klIjX4x{{*Ys5P@&d)SRN znxfsX952F)YUc04IbqFWjcJ5gYoo>NHg~-7!fT)B`#k&ZdHo2&KbhukJ@#;9SN~@NN|~vD6ukeq!>v*Ynj}y z#H!bNrr3(8=uPJ8mUO0`kuuE?%Jk+WtWk@pER|rbe2glk3u^I0W`w>$#`p(hdf!H- za{%i`FCfc)85+keu5YzK+ug|xm6h0NX=3)~XFc|_+9TS8a)er3V z6HpuF&)SK1sPmm--QYdcj}Pk=JhtKH~o=LGXoV dV}DW_BJvT0zthtzRXVqGb%G!gdCrYU^b3XU%1ZzM diff --git a/zic.tproj/HACK/Europe/Zurich b/zic.tproj/HACK/Europe/Zurich deleted file mode 100644 index 861606f6b153a36fa00a7e1d3728d55d7d45de6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 685 zcmchVTS$`u0EPdxMiwE*LT95gdFc)(`#g;qbk2y}#ls0~WraRQ!z6sXGiDyUs-~I=J}Z83y(CLDuDf z{K7>9w-6x>#}R5WV@Yv2mS*dqNYx@tsY19c5)tzQ5h>9yayo%gQQi(!yag(^6-hxhCXJRM`F9;t z`ZQScx{#^%QmT7WxVAZ+Y3F5JXH+n~DH-cCB-9v!up#^-wHh}vBm>M;yhY~32V{xw zBg@&3jboRw$#E6g!*{v4wFNm{m$;?68e3aVGI#rF=9wy(zuH7yb|$w;b6B8^X2DD> z3;i=t_;LYvOh;kot?w*y%|mgAA40~K zJ~vq@Co4alW0l*?J^l6EJF4TpD@8OtslonJYF69xaiA)M2b&X7lbZ^&QHn!x!Kl^# z!eKuFbus>|n|u$8?+h)^AEAC?ghy`Jan#wvhPDT6bhPtWeJ8E0Rth4oXNmu}1wj@n Z@*K<;g5+=3X!CV~MyvBoBF`=o{Q-J&%(?&o diff --git a/zic.tproj/HACK/Factory b/zic.tproj/HACK/Factory deleted file mode 100644 index 1be7c8e9a543c9953d51f194cbc9570d7e2344cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93 zcmZQzzzP_Fq96Qf*6W2x^a=gc_3IW1z`c~Q!_d6oRb&RpJ=HI?~`lejx^g!io9iF=c4IZt++fAk&3 z{OM7+&!rj*T-~ssXOIhpW-ioP;{NVFEUHoBfx1hm*(bw;tmZ>sO0oFsMm`)D!benx zxn!9;mjN zNXo*qTXa~dP-9hS9{=LC8mql4utw3sHLb>c&T0mo%UVh2n;fYA*Dcl>wWBL3&(pWFXH_pPr3K|VtlZ51NZGp!H3bo+@BhWj~2(^<48XoaGK12 z_&Vbg;QLiHAlz@oD)H9_|wHNb-Kx)s)4F;;PY5qCoMo0vvDbjYiTmH0riP zV^E@T?I=#{li{SpQ`w|Zij#MYu<0QSG>gB^knPUqq2+9$27Y1I9-gA;XG`ZEvhu1X zYtaR=u_+*%j)U~#U>Z%W+(EWC_kmrJ2J9=ggF`xjeHaTrBSWU|6czFLSABxQnhYvP7QrxyV5Ffe#R58}@;VcJ8STqD5 znG2BUVM&R7w;;*%2_-dFfx7o9Z8?+=$qi-nN%mPv(d5#n>O4x#NF~AGIWbQ78+zxs z=WvU}|6Vo}KMUiZCH`Mc5KO^9|H}lyP!R0UV1k~}kN@QLs(-j#2wEx^{1=Wj1_opI J{^c7he*%d}$vXf5 diff --git a/zic.tproj/HACK/GMT b/zic.tproj/HACK/GMT deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/GMT+0 b/zic.tproj/HACK/GMT+0 deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/GMT-0 b/zic.tproj/HACK/GMT-0 deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/GMT0 b/zic.tproj/HACK/GMT0 deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/Greenwich b/zic.tproj/HACK/Greenwich deleted file mode 100644 index 653697bb1d14b6427380aa14454473aa16884086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKHURJd diff --git a/zic.tproj/HACK/HST b/zic.tproj/HACK/HST deleted file mode 100644 index 3e79673e1959836862d20e508a9068bbac207866..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmZQzzzSG_q96d_-VQ0 z79ZP+TQ{Y5+x?uyqtcz3+H@4w>h^!Gd7oygI6Uw(1N zhZTMrAHz5A_|##b@!8>m#g_~rjjsxuEWWva(fF=fXYoTcQR63Tg2m6T&Kkd-I$8X_ z7r)}qxwsvF_c^Zkx6Wb5|9Q$Q82XfUFxIiIV9I0J!5sU11&i;q9jxvw8f@mw7VK)z zG&sbbT5z(R(BS-b+=A=bDh=*yD=m1A^=R;J>$c!qmZu>&+tNZPKWBw-wX}tZzuyWb jMk+uChHMs4NY_nZ1kwc!44gi`Aq*bg!5|_8Bm)EhnTeGa diff --git a/zic.tproj/HACK/Iceland b/zic.tproj/HACK/Iceland deleted file mode 100644 index d810ba49b63f612f0d7bbf8a38453f7bb416739c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429 zcmZQzzzW!aq96d00*1G@I&z(`%d-oVjyW;cSn}f^&P;E1b_^TX12{M1_mqFBV*CUAy42_NfI| zQu`NNwY;cs&9!jBb;->NH&lZc-1s?F;TB(k!mXR-3b&t%FSxTaQsM476NP(=N*CN; zC#LYADSW}h-X98&k}MZI&b_7Z#7TO=Q{O!b&lLYIcy4xM!3%CFg_mNx7QB4*N8#1C zISXE&x~K5wTHS)Ts}3l<+m^84eb*v|57V3$e9UT5_*5US@Hu$Ff-muo3SW(z7JRc; zR`@QQvfzh2tHO`ZZVP_?d#>>7vc`hnFPInn+2g9f#0Z7VEaX7e|Nmd-0K*Xo7+L=R i|M-D{6P?Y#8{`|p;29hYB0?D4fgF%(Mn(|DzyJUfDx75i diff --git a/zic.tproj/HACK/Indian/Antananarivo b/zic.tproj/HACK/Indian/Antananarivo deleted file mode 100644 index 2ab643c3103c95c55e99ec5e85d7c56ea45393d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmZQzzzSG^q96oc^G^JH_RAyV0|y?h-s!-|1Qgck0m*9_fTS%P7&#zpAKwrL QS4R*I4gpFtGJ+HV07ftkZU6uP diff --git a/zic.tproj/HACK/Indian/Chagos b/zic.tproj/HACK/Indian/Chagos deleted file mode 100644 index 020c37fa2beb14683dfcfa1fcd723d486c840084..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq9683D-v diff --git a/zic.tproj/HACK/Indian/Cocos b/zic.tproj/HACK/Indian/Cocos deleted file mode 100644 index e775684b0c01fb1cd0b8f8dadc50104294868e14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96hv@dJ>fF##m1Wx&AV;~T=@>KFpzG5`R8+6FTK diff --git a/zic.tproj/HACK/Indian/Mahe b/zic.tproj/HACK/Indian/Mahe deleted file mode 100644 index a908e47aeabf0b05932d58d319797842f95337f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96xl23t(XJ^$lV04GRHr831{U1~UKv diff --git a/zic.tproj/HACK/Indian/Mauritius b/zic.tproj/HACK/Indian/Mauritius deleted file mode 100644 index 098d460f5db2e86a88167480a4cc96271c27b99d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96uUw}j{92i)9d_x#~LqkAZ1^{2c1u_5t diff --git a/zic.tproj/HACK/Indian/Mayotte b/zic.tproj/HACK/Indian/Mayotte deleted file mode 100644 index cca9e108621122320a3541a53921919e0667c727..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 tcmZQzzzUdvq96hvK?2Cp$^eOK88EQ;_=YgJI);F_3;<`d1vCHv diff --git a/zic.tproj/HACK/Indian/Reunion b/zic.tproj/HACK/Indian/Reunion deleted file mode 100644 index 2e4665f8c7a46ef909a13b3f36661df8705e813e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 scmZQzzzUdvq96;uILU8g|ZVGH#tsdp7Qq4+FxR!y}Is%&VuDTbbB^==r!K9(9eB(!XTM%hoQfu zhmnhug|Xp04->WH7N$ZMPnfa)+F|yE)x-Ryo`uC#ixZZo5_ec_-+RJ(&9fagGd_CQ z_DNaTRjHh?&-dNo5FO#+7|>|pWP8`c*_h43MPA^9tBBxs1Yay!y*YkFi{2(rlByUrtP({+pNc@IzI zOySy*+aT(ZS88XGpXhO-Agpjlq4U`jMHb(76st0Nlt^h=l(LzeDE%F~qwINxNBNzJ z78NJodQ|Qgv#46FaH4vF=Z>155Rcl%T8p~e_7n9<8+I@v6*JBXweWMD9` z03{3{$-=;3XaPzcZUKxu3=9?yAhx{+hz%h@vOc~c3?V@583e+?At1d#z{m)p85jU} CZNjSn diff --git a/zic.tproj/HACK/Israel b/zic.tproj/HACK/Israel deleted file mode 100644 index 08c0c58a98c20fbb29a604b89121cb6a8672b6f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 803 zcmc(deN4=89LK*Wn^Vn%H6wTDsZ&W;*Mp~$r@JoFujHsyA9UxT&!G_+4!tl{Z;s?+Lv_I%J4PjkvG+irtZ=QCd|zwZ?#6!b3YW``TMf>h2Kf9voq_< zXu%Io%_fU{lvpg`Ol-(S@o)tj|Lr5#UsE!d`$IS*XMjl>MnMV}1=-O`n5n5@v*N;F zw$y>miBZ5@vP^Jw_>8VE`{t;9f3e9(Q#(KS#toFRO7uLb>2|&@!_*I~JB+EvA9R zcOdB4QM$}<1%uQ5>2jeIR;)Ggm4P*|%CnlTmRL|V;R9C_7f=r*^N^kr&@>m*&_}Jf zrmBUnEfYgn!8p1udkKbToumhy}_ z9kAEgjc1OFhs^JBG|O@h_qFHq{q=Qlp!P96czp;Bg&JziGvXnmfget(gfXH&XZKhC lmk}Zxvd!9EA+oO8MMlJgEDRPohK5BE%_?iw+uAC>`2{_6EoJ}! diff --git a/zic.tproj/HACK/Jamaica b/zic.tproj/HACK/Jamaica deleted file mode 100644 index 64be57cf3e652d96aeea5caee79fe1a2ad47b96d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmZQzzzUdwq96h*|PH5ZC1XAfcq0Aj$FegA@~Y o0wWU^`2YV7pnd=U@7%z^^8f$w1B@Krz99^*!9eU10+ay(0Nl(j#sB~S diff --git a/zic.tproj/HACK/Japan b/zic.tproj/HACK/Japan deleted file mode 100644 index 6d77fe83a016fd07bcf04ff27156342ad9eceb64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 scmZQzzzUdvq96|3@Z*WF!*|eFnEVM Jh5*%p002Rt3y%N* diff --git a/zic.tproj/HACK/Libya b/zic.tproj/HACK/Libya deleted file mode 100644 index 865e083e61b0b24d17abf938c9b7682b765a7aa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmZQzzzSG^q96mDctoi9*!VSb=u!t_B^)jUDXVfzOozmEyVE@lNLrdbb|7{QPkN<(-c5-7sVz`zp& ia-oa@BhZ0-0t}oWHUqDZZwQ04YcPliVQ>Xv7ytl%d_2+s diff --git a/zic.tproj/HACK/MET b/zic.tproj/HACK/MET deleted file mode 100644 index f3bcecb97442e34726c380e3d250d117d745fe5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 755 zcmc(de=O7i0L8!3tu*N&P8=#-M=8HAaQ7)&W zRz@d{8=cj$SQ_$+Eim{s+d+z_?$d4T7MHzhr~Bjc^yuw_q|*e?mNt0R5#H4& zvAjfw6>@_g+7ciL|{vth)S&oVx{9$DQ6KUdd_&CcZi?(hy>e*NHF(f>)2H! znrf%3%gn5Nfv!- zWbv$y`}(W6e^kQ**D_i1tPBUwC|KH&hC{{PJX{-wvXm(33dJ}QN>8u6hyIQ)wuSsGsUG4#uv(9opc?pkCi}z*bfuE3?OMz94A|Rf#lD=ykX=iq;%Nw z#ut}i(*-R~z4L_9D*AbI<0VSZyw4e>M<_G853`c;Dcj>7<^;r0uIU+6Nb*22v=8(2 zqap8kI_7`$gss;?aob}{*j}H;1?K?@i-Wmne=mUG_h^j!BY%tk;i^<;Y6PHCRWS(1 YTxV?S$^61WwsMrnQ9{DiPb5(D3su<*&;S4c diff --git a/zic.tproj/HACK/Mexico/BajaNorte b/zic.tproj/HACK/Mexico/BajaNorte deleted file mode 100644 index e23f80bdb1cb4bd167657ad95e89be0d4a0fdcbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 997 zcmdUu`BTgR7{74h^&8NqL5!SpWDgWpS> z>4P*J>&=6pLF|qV+6mAovcbkmOZfDm6F(RJgfA6!_*L~Bn$#VvNw^H(vTIqJcAdV* zmGh6N6Vx1VoLi=Dr=JcP+&cO={4$H-ww@W#*18Sb8)BfNY8n2%H48dRrKme?2SSbn z4R)D=VQMezmN1%(qQ%@j$b@=$8MDaoGl}+kvoSm%l2}$Vl7%kgo33^j{V&x!2robv>F~l1C6cF+R%lpwaz@~%>c5g z?9YR*|DqvJd05WJZX_4 z3!|0uVX-V8mqbp1rIKJ=<~bB%%-3-25Ce$S2J-UXZ$VM%#4BFjgq7zlcvZz~TCHl~ zHK%S+TtXGc?>I>b^O|vO%uY&le}+jj6_jj!5mOv?KuX(TOf_2$snwfteUmS2xDOwu4`cG=PwrmL*#}Q7bPfimu{$6FsyreQA>+W`j z>`iPFa*kbY$es9NLf*2i4f%zqCKR+yZzzmM(K*-&hCQlP{wx}j8RwLqDE1w+}d zUV#e!D29q#`2v;iZ5XO{1qxK3mt&||oI9a*Jp)5sv;TzpzDEp;Z%I?KK~4*8gd+-QD-WuK!+x{p^Ad4*3Tf99wz|octFx zIH%+nxahYuxVi)uxbdeoxT_c!xc_Ko@MIA!@Vt@A;Pv=>f%gt~2A{LSAADzMGWf0e z`oX_~n<1d*`iHM=&XW>2kRRmzt$8) z9hle5|KGWRk;lh3guypBguxkv KT|z*q0}KF`-^?Ze diff --git a/zic.tproj/HACK/Mideast/Riyadh87 b/zic.tproj/HACK/Mideast/Riyadh87 deleted file mode 100644 index 1dac2ae5e8c72200bf6114284a5b11a13187a086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3655 zcmd_t={J@O7Y1+{qCruHMA=(qemotT%q7ZDQHoQ>RD_T;(10Q*LkAU=kRg$1(m+B* zD$3NMj^;EEnqTSk@_Me%?|*RiTK8}5b$z?{UVGi^78Cow^?4u_Jp(n!X#i0#q5e}i zS^b~rCiP!!e(HS_rPTX3WRuu+GZG)uP7(pZBzZ}i2FvD?PSAEgETCNpcyEB>%39Mw@RUh2+7c_#}gr4RvTtOgX8v&m~pO4pIyErg1kvlDcXH zQIG_2^=_IVr%V%GqnCAk&hj?lhqp+Ed9m;uM)Q>XDh+ zQ8Eu^vZ&clGv!CoET3IuRn|w=QtQdaElXXWjAQK)D-e@ zDWDZa^0cyd2l?7}lV9dCTK%Ds0xYLfU`jr%d8ReHmRV7xWEn-ds8e)d3T^KlL^1a3DE3en?fkHm{;+7E zT`8s%|MWB^8fj2c>;c-{F@%z}q9`T&JEb-R(q7f4v@gh&(yDLMe!1CnV0kqiESo}y zBu`SNi!Nmq7EpFCQI7o~%FR@wybq~Vkdj2F)Kck8O*);GSEX}4IduN)Br2CGrV3Xf zT`W3Fl|L=0%AuC3v*uGxcN<-q=}uQuUs7$?TDmsnC)LNr()D{I=%&sAYS^MdjkiwI z?eV766w*M=R~A$2s7KVcGKlV+>!Eh(IOXtsnEBQeEQy}O+Aih=tr&@^?tcR|5(qVUuiA$-&aehe?}*ZC3vxfU?odNzG0cL zV3w`$XZh0SJgVP|6`VR*F>eVgeQn_}HV&+kUe9A+o3Wbl1s<0u;PDUgnG95zqmo&p zRf;ESY~e{^pIP&o4{IykW1ZD@tXpxB^@r)Pz&(=3$HY-}9ICJA5I^noXv3!2#?%9Jfz3VD{sXtoNA;@NfY*hXm)&+)6~xfQx> zH#D8?-No6V)Su_|wetd}S?riw%1&Puc#(B9JEy(p#jl*%WkwCVCg}0+_xJNMfdson zhOm2c2Ya#=d#yXc-gRTyM=_39`1bJ1@)hhmq?!HPOnG%l3H$er;XucDUX$~kgTDB3 z$n3kkHqDkpUsiC~3|(Fye~35Sm*-9TJ2-sX4~}T|=PmS@x2{{l+iDv*N^urP`(EPh z<%S$Hq?BXbCh*RZY>w+w;rLtyPO=`!sR;_aPoTnSk=dNyGJy|p5g!Z_a7Nt)&Qvnv zEWdiru5jXj2Nx`q=c9Q!T=-4M$84&(c>f|k{`w`Cnrz?`NkjPL z!z?~6oW^IO8@Q~^lg~});qx0(_`-D^t{8KbF9x`AW#u=nlHJYKUYcBUs*bOSd+=4~ zf4H{bAlLO6a=mQ}U(X2U8}Em6gLyGGCfo9@Coj3lFqWHRHMphyGPh}Y@}2Ns{8vL7 zcc>Zh-Jn*!R};dW^0M4naeI)sgrwA9X_+BIhYgn;tU!XeHKsfm~L!&8Er;U=IKEv3=)Xdz%a^@@|>o;uNOT@LZ$b`rJ;l8H$+yZ;=VoRTVS zwP)`>nSFcrSV^bOP8n>SW|NdCnP8i~-`-)@frA+_I}T-LWp8zjIP8{_>+KWj7Z9A6 zf281OVbQVT<0YjhPM$h_rtIvw^B2l1E>>Qus;;?w=(%RPA z(%f|C_Fs+d9e3;R)z$vpdH+GxrOJno9zQwv^x5gI=PzEqdj00@yZ0Z~26TsQ^!OO@ zX`A!Hn1chKB)xkBi0R1<8c_EO{2NxnJQxcD;UZ`Z2}+C9>4u%~3M_>O;Z7I|J)j*l zftpYm%81nNg>T^#*b1-1Dp&@O!6PsOroj}L2;<;(co?35!F+fI*28xA2L2GKI~=M)A+&(La085oS+E3NhRv`G_K4IQ497wpXb$H= zHy8pV;cl1Ka12?fdW_!@4|PmU!-6( z)Q2=SNG`xe*a_c2+=5VA z)C-m1Bq)Ry&=z7=LQGE>hy*tx#Ds;hNHB9D<|)iVk_WLDVF`L{N{Af^jnD^9hRPxZFW@a$1~cGRxB}WhEjU7?{wLT5!=ac+y}ChS RmX-tm5dX3oc=dl*{SVm^RiXd@ diff --git a/zic.tproj/HACK/Mideast/Riyadh88 b/zic.tproj/HACK/Mideast/Riyadh88 deleted file mode 100644 index ee7474e57a5403b14bd1ec9afe89dad37e553a08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3580 zcmd_t`BzT+7YFbLsYIEIggSd`&{I7sL#8Jwb5v+hp(sP9iZn>1NTG<*K#3G3C7~!K zl)1PE@Po-C9$vSi*&GJIS zqFmugk&W<7;knT0yjf^Et|>JCC=_1U+6yfQ-v}>1Y!O}i*-CHBn+gkuQEur9$xQ9{-+hGf%_NRy4_XiC^xnp)FH(*=8);a^I&R}5&DdNSE9RUrFfKbo!loaVUA zqPZu^$+1I3&UOdLB}0kkwFi@%^-FS3aH9FIs%fExIeA29l4pZDEjHRlUK_uXcg-?d zs#8zP{HN3M%N4Xj-IP`?$);7s{b`MIEcv?rCchH_Q>_p|A#B+H7=)!o##^OHCq03cYCCmF~31z8CHNq(KQbsg#(gL;G8g zQu1g+N{Pv*)F;E~pm7PMZL+5H+G~_Sv+3~KCv@cM5<05UMp?@OD7)l09ao8^ocaAJ z_vB&9lQE)`4i_l@$RsNGTtkJE7trbbuc_!wAe|j6OXqg(rs8MXbY6U%E`(c9>Agz2 zIK+X<1DdF!+J`Fpf2Yen5p<=rH&yjGK-CLHbgkeF-H@}Pn{)2at)nh<`^$5xnd(Qi z$v^3C+gAExyc*q)O{Ti0!SvAd7(I$Gqx$>js6o$)o&;9W)9W*+aX>9Kt#qX3vd8p7 zZ6URIw9w1K<@6@&J$;lcr}kzq`fS!nU+NyyH+@I?9(0p_+?Y)NXkDUTt42}B#XOej zX~43cX)JfTFL&t@!wQZ+xofr`D}HNb<>@ZmE%gqoytCvUk^)xUEwEa1Johq}=iZU) zxKCXZtLru+YVb$uWsJy9*Eb=F581 z9#?23o%+lYc{jG4Tg?-)%-QN|I$KXuVVjgdp49f5r;MM=Q)4T5T9YZyFg?h& z5vn}%ehAy?wy}MnJ3Cyv&2t7wc+&5er*71U` z_UtjWiak@t@uIdu_8M=@-m%AcNfYxj(==Wlp~*h?_wlO0IQB2w#{nM693-E{!HxzT zl9k6BzM1jHX{8*NI+-`Ut>tiuD{qNw;fUt7yw&U%Z;RZ?Q4h2@T0e(lf+f7;#%9Xf-L-G0M4+EJYAr^6>IFY?L0?ws%agA2|jaiQ`^ zKJ9v+i%$6SnU0=(&h8`^XV`K{`=5NlCW1>71ul~`%gV`jQRu3uq})xVdk8q~MufOI1t$~9EYwHNaLv;1@^>l}@0SP+VLk&en#wMEm#luX^%=-)mKABfB2|A^KrwI zr_UOjnv=X1u6XYBqUGhf_*WZ3cXxi5M2|X=5vj{|YWNR)1}k7TjD^0?8A_lo>@Ica zC)fz9U?EI{F>pOx1ZP1@D1rlF52*$n@B?gu58y3W35(%LmybIG|I9vv&LsQsCs?p!@A)E}mNfo_?ci=i% S8B5E~pMn2Gbw2!mq5cJ#I8Gn{ diff --git a/zic.tproj/HACK/Mideast/Riyadh89 b/zic.tproj/HACK/Mideast/Riyadh89 deleted file mode 100644 index 6f12699d139b010ce6cddac921c4336e5e90ac75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3580 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 I^v62>0HPs3KL7v# diff --git a/zic.tproj/HACK/NZ-CHAT b/zic.tproj/HACK/NZ-CHAT deleted file mode 100644 index 32ce2424b733dc75b4ad81b83370b4f8401a2ef4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 547 zcmZQzzzUdvq96^QiMaPEdcO@<8M5(FDyyY!9@~E>F;2t(>59hN zH#v@7fu5W^&*U1ETB{RG%)B3%a`h&diRnHt`@Hgj`8WOt7MHspSYG}3 zz-n{u1MB^K2{x1cAK1?OkYHDA_`tsIQi4N_UxH)YmINmog9K;0X$dYeLJ6*N6$!4t zza+S`PkG>e`&xp>^Rfq?yLTjb9gle6z2wRRpXF8$d|S3X@N1WO;GZ(%K|q0JLZD04 zgP;KEgkY7J2O;`@6GB<+9)$7VPY8P(oe=*1U_!)M+l0vTixZ;O$|pqc*#97=moXuB z#=-}2IgbK{}&bLi*MA2N@4F z5;C`DKFB)Am5@EJEg@&Yn}poDjD);~a|!uzUI_)6uO1ZI=_C|+o_SC#$Cpr|x$Z$J zyVip;&Iu37p7T5?e_8aP;@GN>8u6hyIQ)wuSsGsUG4#uv(9opc?pkCi}z*bfuE3?OMz94A|Rf#lD=ykX=iq;%Nw z#ut}i(*-R~z4L_9D*AbI<0VSZyw4e>M<_G853`c;Dcj>7<^;r0uIU+6Nb*22v=8(2 zqap8kI_7`$gss;?aob}{*j}H;1?K?@i-Wmne=mUG_h^j!BY%tk;i^<;Y6PHCRWS(1 YTxV?S$^61WwsMrnQ9{DiPb5(D3su<*&;S4c diff --git a/zic.tproj/HACK/PRC b/zic.tproj/HACK/PRC deleted file mode 100644 index 2f0c5ec3e0248cdb933e2f94d26528b049b766b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmZQzzzUdwq96Yfa0pBz7Euxm4DTvGnP#E1qN7z!T%4QHsEz{tYD WP|(1@;o}>^;Oqj#!66_CAOHYh`5}D( diff --git a/zic.tproj/HACK/PST8PDT b/zic.tproj/HACK/PST8PDT deleted file mode 100644 index c9ccbc1714b240e525e2e7ddbe8ae785e7831487..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1017 zcmdUu`%}yT6ve-rSS7k*lNGMS+C)i_5Gk$AqwOI@4|$aJs+8olg+zn8F=oQZ#V{I@ z7^XxrMuR4eHAs;>OCBYqB)c|0`v;smpEGC9Z|8?A2>+C^q3xzyMFzSv`^FB%g#Wd>+SA(rf6OQt^0iz|4 zP-d3{GTj%Jo2G!gwvz1{m%-SQ0=9pwp>a8fc>I;6-60J9);j128k@1$(6C z(k$N+_FS=#yd0Qkd#xjH^PQ})^(95e2~-+SAZ67K^m#Xc<`yo;c@>T@KYKPV$g=?7 zBpIsqw}M}!C;P8`3IQIYIB;GeEF2-`Ap4`RNchOXl4}%PSI!}A*|fMckC!~zLZP`2 zFzjk5g{NP@h{Nu*RGop5nkBGI8H>xqr^5=lKdy8i4pA2CIeM4~qFYqF>i1hvYn^!Y z%e%1V@<3i&_L|mZ{owUy?@&x!700HXp}56uxFKo}#k)Pj1aCEMlony4LmDJ@9>XN_ zRghG@9XB`mz?SO~xV6$Aww>O}+w=Q@W>**|XEcK#5=2Hl4EDdBUVofKf?l7QA{hV8 Zz5lwI$}3P%1sGUlKow~CW5Y57e*lzcSWW-{ diff --git a/zic.tproj/HACK/Pacific/Apia b/zic.tproj/HACK/Pacific/Apia deleted file mode 100644 index d6b7cd8b729928880ead7d726e4776bd740f4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91 zcmZQzzzUdwq96jR?T!@6Sl}sNt=lFxBl5k#`!tig!Ej zv$b?cY^$nc`<|O(M?on&m1o6!J2Tkjq7l2-m!QW2Vy{y=dcWnVq_PQ0>#AuoUJcWV zpEMh4r@7_@Ewoj%OlYH3`B6?$oafY>Bu=v}HrR5iES= zz(r$Skarl-vA+h3FWbYZ{y3bA4dGIf0@vhGxTS4?duSh)M60>f@iLZquA_%Z2|TTx z>G`Ra%fDLE>v1u?pMIoIQyN#aTEO>I82u_fK#}Fnm6}Ib6|cnVgl4Sqb;DZ4Y53br zMSyJ%0)Bi(kZ~Dx%6@A_262Kz?|%GgMK=$ar% I^v62>0HPs3KL7v# diff --git a/zic.tproj/HACK/Pacific/Chatham b/zic.tproj/HACK/Pacific/Chatham deleted file mode 100644 index 32ce2424b733dc75b4ad81b83370b4f8401a2ef4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 547 zcmZQzzzUdvq96^QiMaPEdcO@<8M5(FDyyY!9@~E>F;2t(>59hN zH#v@7fu5W^&*U1ETB{RG%)B3%a`h&diRnHt`@Hgj`8WOt7MHspSYG}3 zz-n{u1MB^K2{x1cAK1?OkYHDA_`tsIQi4N_UxH)YmINmog9K;0X$dYeLJ6*N6$!4t zza+S`PkG>e`&xp>^Rfq?yLTjb9gle6z2wRRpXF8$d|S3X@N1WO;GZ(%K|q0JLZD04 zgP;KEgkY7J2O;`@6GB<+9)$7VPY8P(oe=*1U_!)M+l0vTixZ;O$|pqc*#97=moXuB z#=-}2IgbK{}&bLi*MA2N@4F z5;C`DKFB)Am5@EJEg@&Yn}poDjD);~a|!uzUI_)6uO1ZI=_C|+o_SC#$Cpr|x$Z$J zyVip;&Iu37p7T5?e_8aP;@G9Fbi$iDpo$$S~F(v)J!wmnYDJ>d~>Zo>)&3_o@dXVzaNJAEA}g^)mExjZ0*iH zuVt0&!&)-~HORSSG~37u&{nNA+lkd^A6cyDGJDa%Gg3MBJ zSkuqZJ5?^h+J-NB=Zr~MSHYV3as9CV{AaVkzX>)R8Z^7`d(m}ktJ!s-5ry1h6prOn z(M&RK>{LgP(#5El`)F)kT*0s zt`iRm+G$Midx%-Arm_4Ei2aa5;}-5ieD7^?c+3C^_1WY|XA&q%63NjT2_$NR2{Eeh zm{dTHYr;_J{++18g{ZdY(4={Fc_8xNul656i&60%ZqoQsQ(rzo@_^B zVXMYQjYnpdJzWPRh zLiTP4#pqoDO5SrFl&$9ksA$(as7lubsBtGcsQpd|P=D?0pz);Uf@Wi&gVsxr3)+ds n4or+#AOpkPGa#E+9AIQ&V3@Umfz!t~gdr?67(|4CWPktw^sOwc diff --git a/zic.tproj/HACK/Pacific/Enderbury b/zic.tproj/HACK/Pacific/Enderbury deleted file mode 100644 index d655d53fd122f147fe2dc3dd85f11925e75e58a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83 zcmZQzzzUdwq96|3BP;f#LuE)BvD3!?p_y3;`bgAs{vo F008rG3ON7( diff --git a/zic.tproj/HACK/Pacific/Fakaofo b/zic.tproj/HACK/Pacific/Fakaofo deleted file mode 100644 index 48065aaf2b99643e178e4a4911e686b0b27be02b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96(;z2tB!H3W|Nk{Wf&c$^ZeU>f|9|xY1`Z$J5C&K0 O5C(TgpAeuF2mk=srVrx) diff --git a/zic.tproj/HACK/Pacific/Gambier b/zic.tproj/HACK/Pacific/Gambier deleted file mode 100644 index ff76fc1d32d31c382b86f36308e6525994a99829..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74 vcmZQzzzUdvq96~Q diff --git a/zic.tproj/HACK/Pacific/Guadalcanal b/zic.tproj/HACK/Pacific/Guadalcanal deleted file mode 100644 index fe7cd22e3ac9f68c5aaaaca366e16ba12307719c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ucmZQzzzUdvq969!?g4V9egTQj+Q7i#;~T;d>=XjxG5`Q{_y%AA diff --git a/zic.tproj/HACK/Pacific/Guam b/zic.tproj/HACK/Pacific/Guam deleted file mode 100644 index dfa4a0b1197d1cc29d40dc834733a95a5b2c8100..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96tYyu(x diff --git a/zic.tproj/HACK/Pacific/Honolulu b/zic.tproj/HACK/Pacific/Honolulu deleted file mode 100644 index 47e56ddbe7b81d8353d090d1d0b58f4a7cf753ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmZQzzzSG^q96T@c(~t0+3=j@_>QC$I~wa#0CNY D_E8E` diff --git a/zic.tproj/HACK/Pacific/Kosrae b/zic.tproj/HACK/Pacific/Kosrae deleted file mode 100644 index 41641443f44d5a6a91463561c631436d7e949d3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75 wcmZQzzzUdvq96V0F7J+JOBUy diff --git a/zic.tproj/HACK/Pacific/Kwajalein b/zic.tproj/HACK/Pacific/Kwajalein deleted file mode 100644 index 8faa2622a8fe87a9575f0ec5364de26ff3aaef04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87 zcmZQzzzUdwq96|3@Z*WF!*|eFnEVM Jh5*%p002Rt3y%N* diff --git a/zic.tproj/HACK/Pacific/Majuro b/zic.tproj/HACK/Pacific/Majuro deleted file mode 100644 index 9b1233f7ae8bdb7473fde00db54ee8f606ec8ef8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69 qcmZQzzzUdvq96k$HCG5`QwkOi0k diff --git a/zic.tproj/HACK/Pacific/Marquesas b/zic.tproj/HACK/Pacific/Marquesas deleted file mode 100644 index 548b18bcfe064af16966ebf88af89850da8614b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74 ycmZQzzzUdvq96ew|9`>)28RFt<2*oQY5)U+UuXzW2?ziH DEME+n diff --git a/zic.tproj/HACK/Pacific/Norfolk b/zic.tproj/HACK/Pacific/Norfolk deleted file mode 100644 index afa6adfd207743bfeed0bbbae9a3a16f1e4ddf4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73 ucmZQzzzUdvq96sngS63 diff --git a/zic.tproj/HACK/Pacific/Pitcairn b/zic.tproj/HACK/Pacific/Pitcairn deleted file mode 100644 index f641bc054816fe37642b74f2f0de7ea8fea1d5fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96kPq3<3UrAwV7g6)ysm diff --git a/zic.tproj/HACK/Pacific/Port_Moresby b/zic.tproj/HACK/Pacific/Port_Moresby deleted file mode 100644 index b568445a9c95b5315db1315fcc40611d68731972..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96tW&$4o diff --git a/zic.tproj/HACK/Pacific/Rarotonga b/zic.tproj/HACK/Pacific/Rarotonga deleted file mode 100644 index 8b90662dd2ecd0b8c92aef9d2a145c580c7735fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 zcmc(dT}TrE6ouzn2o`9%yzk$+_ZIBf#pzO2^Bn&fV5+U=q2eXEE zLH6ovJlypej!Zv6m1PNXhKBHH!6!P_{g{u-7fD??$eN%@%GEeIck>o$rKPN0uu;A! zhx5mas9-&obpy?yUsT~qn-NYuL_BR!LSdf}&!hpIwXUNf^cNWQb7=hb7K)R`uz2+c znfA`IY5EPBJ)?YX=qZ(~^zeD-Jt}qAb6Lp^y5Q1tx#lidI_mJEv=b`IbXX~}K$R*P ztJc*}6CI2-vofgt^A+nx0-^rhGG6M7C+pl6H#F>|#?e=NS^t5WZcg!)r03LJ?PA;R z2h?(+m0LXXU{AS?_LXsH3$|mMyB8c=CTw>#f^#VguU##K>yr}fC{jRY|27H({)@a` ct4Sd6dTr(YY_AOvsdYwyT9;=q`X1-!FBCe?jsO4v diff --git a/zic.tproj/HACK/Pacific/Saipan b/zic.tproj/HACK/Pacific/Saipan deleted file mode 100644 index 018b301d16e15c481537c1e5e0d1be6a498c3521..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69 pcmZQzzzUdvq96c7cH*#6JYYWB>qaI|eNP diff --git a/zic.tproj/HACK/Pacific/Truk b/zic.tproj/HACK/Pacific/Truk deleted file mode 100644 index 66e429f4cb90184fe83809a3d596d4e95ccf9f7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57 fcmZQzzzP_Fq96Q@ diff --git a/zic.tproj/HACK/Pacific/Wallis b/zic.tproj/HACK/Pacific/Wallis deleted file mode 100644 index e130fc2cc4de7b887662a314d9694faf3b7e1c99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq967eKn?&B!vbLd diff --git a/zic.tproj/HACK/Pacific/Yap b/zic.tproj/HACK/Pacific/Yap deleted file mode 100644 index 9490fe2d7625ce7c935151219814716b20f82836..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70 qcmZQzzzUdvq960F934tCV)hH7BDbGItGM**bD$;lLfK> diff --git a/zic.tproj/HACK/Poland b/zic.tproj/HACK/Poland deleted file mode 100644 index 7fda6e6be233bb32ae3e8526f3f503f934e478c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 961 zcmb`GdrZw?7{{N}g=)!D$zI(p=yw9G0Ux2@2!fpBCspp3GiIolR z-PNW-S+(|w?&xDR)hJu&*af2F1r=0V)e3b)Hr@m8adG$+J(yJRkQ zvqssSvXa!h2is)#)_+gEFH*>~Yf1OO?ZAtN9;3QP##>+XO7BANU^9FF@+9lKQ_lJ) zltcf;bMWDm5(cWu;N$%`(B1S4=9yZZZ!-V>mnQ*9yO?q9&tnZaDn``@+?WMC|ce)nr zj~)SsqP^gln*oy*a+ney4O7EIKosB$(>z_l$<7*_O-;bX(3`moJ2TfeLguD5V(uMZ znMZRU^He@%(@VS9jDmJHGgHmHg0zO3oozG}K z&a*A0c|GgU?^_o6w~KN9(-;a+B~oCUKP@N>rl4v&T9_=N-~vBf6k|ojVft4vOw)-=Uf1JN^(hSRx=azpMY!yA9W75u!4*aOD01~dTB%5) zC|?Ch!$T=rxQteLy3wi;FN(1W!I*~@6g%vSajlx0hYhJ-GXJ62*+pqi46T4({bR+OcCg}cl~XjgX!W)D23oF*0S*0fP> z3;C7S>M diff --git a/zic.tproj/HACK/Portugal b/zic.tproj/HACK/Portugal deleted file mode 100644 index 340fc401f7b1d391bcd9b343a25d556fec0fefa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1264 zcmb_ceKgf~7{52}N~8z#)+N8XGcU6d62?q-m=VP-tV|)Sq;EGIT8-t-njGh`sjV4ZWJ;-_L0m#niI3K#z}T-68R=UOmd2@QZ`6La*vOaJm+4LAGMzp2vq19 z?>t(>n#c?R|N)Ax&tALPZb17C!((xZOtPvUpk!C*Uf$j6lZc_W{FXsN1D=9@6X%Bz^+d1Yo~ z^mk_T{y6jG<^yKzyIah7(RF6x^d)98C6A$pzGR;6kubl6TwtesS$0~O&dyjJWq%bM zWM?%(**S%+?A(+qtMaWWXGJETqk3G0vr@7l5u%L~)k1X>)kQj}A)HTq+3Gjc6g)vK zjXu;?=s@kMYp63+!|L8)aaBV)@~dk=ueb#CvvOc{DuTh`Pk@OO!%P*GlKmtY8FR&$y3oNZQamx*9D)&*Qql zUa%CGf|X+xSo@rW_4?UhV;KiF3khJ$&p_M$U0^pKi}p1_c=JbpbSMl$$0~b#E7=*H zGWGE7FabJC>|moS4~3z8c*pQDx(FA*mDh@Hf&p-wcm(bWb>QCF0`CpwgGWgbc(&K# zrnFS>D$Ygks3_Q+nuJ^YQqU)IH~MafM3JW(Zq@d}ZDuC8ZPo()HC@5~t~v(H7{mKl zr*V7Fa@fJDL15_^e2_2&K^dK}GpGl49T~-7r*a4hY{yW8Q?T2y1jCk8#(`LK zO^l_35T`neab1lNKhcYaE*8Q^omF`FR6QOk$;OZ43os!q0he%>C@8)ld9u0Z^+J0u z{n!1a%l@L$^8cTUi?c-j!>9sRQQkR9|MYqccZEFRsQ+DMiPrNoo|{A*KNnwlkxTXx T%8XE+$iU@t<>Jb{408J?rx(6` diff --git a/zic.tproj/HACK/ROC b/zic.tproj/HACK/ROC deleted file mode 100644 index aa2b3f056c83b53ec02720a2fedfdfbe4ed42037..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268 zcmZQzzzUdvq966#vSPTV{IKA<&3=X(Y-t5I zWj{6Cd_METt^aBaw@;icxbq;g;qEGi5BG|S8SZaQDR@xR%J6X7^be0>cQiaMKV9&| z?hV6J1BHTTiiHf%g_ah)U|Q1f;`5CUFCX7vcy*Ph;Pp}NhBw>nKfL|^hvD6fBOl)1 z)NlAu`J;gSPZ$Ho+pYr6yPXYO=k|UO-gA{f#7y7=10#`;p>6^r&_e|c3@pwrAq>vJ JAwV7j0|2e=Uc3MR diff --git a/zic.tproj/HACK/ROK b/zic.tproj/HACK/ROK deleted file mode 100644 index 9a2cd24bd0f83f8c70e6d6d05d426a1208f3ea7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmZQzzzSG_q96?fbV$iT?V#LU3R0)z|<Lx%)MivH!f(8(~X8|LNcW?-U Kw@V0!3k3jUIv^1M diff --git a/zic.tproj/HACK/Singapore b/zic.tproj/HACK/Singapore deleted file mode 100644 index 41cfd6251f5460d4d2ae16f8fc7d2336ff866187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmZQzzzW!bq963$PVPvC!W$=dG2t%TnR-*@?Th#P2fFfuVSv9Pi+ zFeJu+^duE9urM&BD}czl2@ISJ44D-mHjw0HU?^x{;0^W-VeobI31RRG4q*s(4*}^y F0ssX57?c12 diff --git a/zic.tproj/HACK/SystemV/AST4 b/zic.tproj/HACK/SystemV/AST4 deleted file mode 100644 index 2fd8b8477afeacd340a149565dcefdfb07eea298..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq960673Ep9FOP diff --git a/zic.tproj/HACK/SystemV/AST4ADT b/zic.tproj/HACK/SystemV/AST4ADT deleted file mode 100644 index 91f7b54d1b997becbd93389138ed973c6e0d6a04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1428 zcmeHH*;@|?6#b=Wlh8uNAWKCHDJeo}nJBIn)FfA8NVJeLlBjHLN|+WcqNIgHT1aLT zD!EEgp=+{L+GMLFdYgy&6Xu-nobP<+@jM)X;6E|!XFH^y5E}i{hO$^d&P+a#EJX(+ zM{;05Ck1(QaIou0IOHIShb=nbh<-aBRUo{i+Fs9kj8;7*SAT1_XN?f8`Sd^&Bc$A4-oQjD?!$13SToa8)=>sNsIw()qT zp&t^;`!KQaIV4?thRLzF;OwztObKkHbFN8ve&bC_wYkA*OB3nB+yqXadVns<1aOA% zM#|`M=FDbO%BnHp>`G_2lskhjXPQ7x{8GFUIsW z1xgiIDEp3zMBZ}I$8x&y>OS9moJqxZGWgcja4I<$#f3Zh|>D6Sg- z;#r4SqRST~*#}3~N0U^EJ&r2aP15P!JUV7AjXAo8$L=v8nXURPYd?YHER6(Vl|VtPi4}zgK(YH9D!pui36Eaj#M`&wmz)xul$-*SBhTWL1Hqu|8H7_^lWCem z5>Hw$O&ORXla{|Rt z+v`2db#6l)>nhMSet`3|FN2=)C7iERN&1o%tlyta25niqpz$~@tcYO4A}?B$;mM2R zY-ve|4I2e{g7G$8Ug}~4CbrgSYN88fIyz`RZ5;e6D~}e!y zR=GEDMP@y%jDN}yT12b-3fbE24B0rwv#sTRvRmlStJOEqnhD5j<@~{Z_&&7%gy8Uc zJ^of}434EnxbE6Ca5_H~*Pk2#7(5&|_$!mM%Uj&&BtkALgn5(U8``Y#ntz{okG4qN zKJ+)+76z(-Oy|EO4zx21@1DN1K#sy z<8Cc0@{u2lzS3IcJE+NfI>*o-O`~~lRS)?Uf8c%Dwd9}hnD>WYCxOua{PzNbgS8|i V7#zG?A`me$u@xBE*bW`8;0Ji2L`whw diff --git a/zic.tproj/HACK/SystemV/CST6 b/zic.tproj/HACK/SystemV/CST6 deleted file mode 100644 index e15d3eb382ef28fc67ac321cc536d871f1a7e798..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96q>>g=(jo~()+?2zE-8g{lN2gT${~`n92G63XcdJP2}uc|(t_(+ z+N44%C0W9eB~hu~?!)~FcjlY<=9|ZP7=ZtT;IH<#enDWwFZ-QE>DpolNmS`~7}q+N&eV>@ zvt?r_KJP0gr1VkZ=~_H@u!hd>`N9|6Z_!2PYEH7QhD*lzoUEA-m#3WJ6zMaNIwY7= zyMiI@y(3?#bcFQsAiSDs3>j(b@mkzEx*lPKnE?ywhR0OQvY$fP7DF+|K$vc-G-0mX zN6M2C;(TEt$nS3CTMdnH`&kL!DJ+448!3GELJHhF7Qy%TM!%UHN!D-^8_$Ks_2 z>F;@4ute2^{*kxDQpsgh`h5-J%fWf=9&cf&90uGBXpl)p-uQ@^MS_xHKLK$97N zduayWOH}yBO%)hSmSi|32?F~%SkSKnhIkD_Ax8-kUfzyF7qpSc?8hi_NQuO>;!y0$ zc@XDgDDn0v4Xe&z$-BNZJU5!9E=R+N7#|*azz0V8+p@HqEsS2R%Q9xVFh)<7$12Oh zI7J;CFZvB+1;?Z8=W!%gKY$aS^ppI(I-Gdz6-`PkK!vC~G&v*@6}=K@iu-MzYIhr^ znaA^V{diEC8NxGULqJ*FnU(vUVP=adtJIjntV$t;#Zxu$&(RuWCM1Jq-J{9;{TEzP*-I7`(!4bD zB`r(qVavE4SRV0$R|LEOE00{Zw$B9{i&$Q15DT`m0(sShK=@1MG_Dqoq18PBX!l_k zt*LTA`=Yh9HfsSoT%1qqjw|B&(8=T&WXMh%hmf;_0&iHR02>Vjd6SwTxX3rKt7HSX zelKRXwqkIvOXkfL$>333gj=!;X=~CY^gNM77tvmTFT8h5f7PMX6 zjs3=`(GIC4ykl?)_;;xC&Nr&C>yZ=(6i7i}dM5{+?S$aSN(O=d`R@e=2Xiw7U~n)s Q0fdZAY{1ys=J(;kPZ5+H{r~^~ diff --git a/zic.tproj/HACK/SystemV/EST5 b/zic.tproj/HACK/SystemV/EST5 deleted file mode 100644 index c21337a284ad05eea9a72a6e3a67ac55ac7f5ed4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96_` diff --git a/zic.tproj/HACK/SystemV/EST5EDT b/zic.tproj/HACK/SystemV/EST5EDT deleted file mode 100644 index a2c15f9af8ebfab22b83cc986fc015b0594ddd5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1428 zcmeHH=UWd782z;ELxmHOR$yC3eKaL;+pdCqe_o)1SL_)m!Tx4+d7k)i$eJ4^0Oo5lMQRVX-G znM3yWQYil7FfV1;@2G?atbf6uhCO&tqYlEAYB55p03y2bF|s)c4pk*$)QdbioE?Hk zZk?m(q_ceVXfPcM-p9v%J?Mn{T8^=uM<>m#_>}Hsid9qR(<)XFCvAywJ?aqOItkCz zNI^oeB%aM_g>%3^KZvf!G$=!e>{*Lga+_m0derq!;K%g1VG^u ze|&7>22V6y@u})uD3US5qTcaP+@^*lwGvQTDvr+z$5C14SpNHx7(I^>r-uj5|-fG zC>?kgsErMNi>c9d7&fiaqWAMP`NPbi^if@wn-$urWx!W%`Tmkx-xV{ZAbh$*^jzpjj>zOfx3UL=AMtU z>DOx`?tP+4eOaSecv(n-lYK05;4O*z5sP6Th(j+*EF&0TR*wU99>BmuN+_it1ya|K z^B~?2(iDb+tCC2jU_B1W4kg*EAv`qJlZG8!$HR9mpb;DAvz)^elDF1i1;fEKQbU>* z)igj!vW=BRr9ruU5URXwgHg{vq3ZoI7@hVE$0Vk~*yx)$Zr?Fb^Ery+y>8G1$5fuU zFq$SA9bxq;+i0?~FKY~1K^oomJf&qOO|3TIY325ynWM;B=?0*EULSRiDZ=!Sk*Mq2 z4Kv)kP|x-a=$qG|fo>kmRJ(_>RI15Px{3{Z?vhb!F3+w>AmidQY?8Z|<|GHPX`DNm zMXceup+R82$$~9B)_|owpp~Ts%+oW+`4c9>0=WrjEj|#eI|kswhGtk){t*|KO3;$@ zBD6{QKuhD_^RmdNwA}v*+j=LHo%1!eUwnvG7)SETX&5Blc0vvyYy_?e)FF3|PF(9coIGrX@j8s2dhgG>c) z=*^;yZFktK_B3rOjb-n`JFq!36SrK7g{?8C5clr^pB=l=*V6^It#rme=9$8FgE_cE z+ll-X#^O#{6WS>>=3QUL(C+%tyr)cr{PP7IklH|j3GX;4>JbS<{^!3J5DFg`hzNwj T?3)5{D@%KUm7V?X!xj7k>Qq$* diff --git a/zic.tproj/HACK/SystemV/HST10 b/zic.tproj/HACK/SystemV/HST10 deleted file mode 100644 index 5f3ab4cd2e742828ee39dd1ffcaf929f3b3bd7bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96dCqyxb1u)t0r*dd541lu05Ke}pIMsnZ811)9_%}; ziy^_v5bCRh`#tAUn7x1xn2)A|`idN`-b)cm-#Aj{DMfy3;;6S*DZ1eb$J92#q2g5L z^H<>TsmpleNGcrNmx8g|f+21LVZ41ksTt3AD-7XY;R3v$F&-YokHgw9aj5eX z!+Q4?cxd|yADLCaW5G>)qS;Ih3YpkAyqp?;+~B778T9mdIzPL6ke**Xz%Oz=>1B!s z{}p3F%|XlfmA?nHIBM|gHOruNi8;Q})qu9CGx4pWEVN4v$M)_|(9!x4|9(^l?<#8X zec1>4koTTHraqughwk&|y#@5e`#g6##ZlLaSngivPd!?G{B>F^e3Meoj)+0+tb+ zC7GOj9P;rL4Sku$zciG=uxlYayf_VHvri%>gusaKeK>NbJIHysp}gG^P*}PcN9n19 zqWUx(t!73_GDA>Vd@3n_p28~4GBl=EnpLlN(AfNT9+y@_;}2K!gy1|<^UdXnp4BkP zz6vLs=fV{I9Gp6xVVd$GR3EYp)O&q#dbinWiNJwBS_98h=>ff=-Kf{s0QwzIaDG!M7*v(ug3@F#6rR9^ zNqfO4G6)xiCXw-GXEbr!L#8%?Y-Z|2i|07fgNup)U7u8eAhRe`V3%Ih{*JKRDWi?d*Bkd3QnM!}jfk+@bNi|iyb*{&;s z>|clTx`$rmaC0-Szqp(n(=FL4PMe(fYq3j^C2VjX!LE*4;I>>7-3>>;Moq-uRKLKc zVV`kR|3mP2SC5|0F2UxSLiDPrqb-HCyfxz@dBle@4HtwYDs{{D=#p`It zTzmG@3IP961{@%34*?=O-1)%(cD!5RKmWaeNF+Qd U1|m^1gM_824Om*+{5)Lv2ZRgh`Tzg` diff --git a/zic.tproj/HACK/SystemV/PST8 b/zic.tproj/HACK/SystemV/PST8 deleted file mode 100644 index 891dc921ab582dcf6a1fe6ebcb2e662ef9aff772..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96>gErTqfY|)}5-{fvC<|oWK&pFR|&gHo{0>OVmyubaWeuzQ8{mL>sE_mV2<8xqF z+-%&vQyYYVTDZsGio#tjd9Tel+GjeJBXngbQbn4hWLqh!r-h?iDrkRwImcABKx|<) z)5UU#OS_K;4rIf@U1#yo##o478G{K61L5$j4S2-J3682S#Ke*7DM@}EC-pi~@_PqP zX*8zPaw9%gq)eQp#K#lAQCegdpAag+N&h-d_v(TSr%pU&SqG<$pJ1lO6*x1r5VItb zA*($J&%O$S?CNcJt|F0gay{_;*-*NWyp=CTyHjrHa=sKWgYw)gINw&CE}N-wfu1B4 zs!H$`Wi=?0LM-Z(fUC{oc&(-xuHSx*#h32Djgw_qawrpS3Qyy$ZKZU3RV0=!KSgDB z8GOe)g6>Y($M;69q5FgU`F@`rm4CG5il+utS*gzt%533b{(Sr^LmwU`Ou(vefa=YP zSmXT_Y8QRM$FpnTiAgoq>9YA0EGek7Z5x zsko0m=ltNdW6$YJ>@)tly@cA=-{2096V$mNjk_%N&^H4icWb9XkD?EMml4AE?%mk? z&If+fd1K$*dGNDfE{aa;g5Zb_itQT+;=%GL5vWa)o?0yBC`SWk%CfZK2a?`z$+9K| zB%57~a&6~HzA1+X)>p!y8*!{qm;;KL=Mav@!QcqOAt9S!sNY6Za#;k**3LL=>J%8R zGZ{yyJJD~lBTz-$gjBvx;*l?hlWNs49#zsqqc3#xnB$FvaSg1t^BSoKUS$pc2GDe^ z$FVk7VVr3ZYU!qewn_@>$n5}~@7qzgbtQ~%@I<}pFq&}167_RekiiKLHas|sChnfe zMw>Lr*h_;aISn8aODUdg^p2*ezvbUmrC{nnNu1jI7EIs2!D)^6z^wc(niplk^sF;z zk+dIXL`CCFVJ6L5vkom+MUj+)6`ud7c}&r!QlV`02D_k2!mWErXTbW7x~x99G$zq4)GL;G;hpSC1A0 zUj+gB_PqkXk1x^xX(_C!yo~{6FKBIk6R*p-Me7r8@`mtq3fz2>H~Q?QO^d_%k2!wy z=VV{rY!D7X!)!QM(HDY6t1;xW4QzRCjawh;L1^)K+?JyNVaEpH_Lw#hi2cuhFCY@7 XkeEOuirpcQbg*(3I5;`~I$Xg&QQ-Ks diff --git a/zic.tproj/HACK/SystemV/YST9 b/zic.tproj/HACK/SystemV/YST9 deleted file mode 100644 index 554d032f1e891b582b2749f424790662ab7cf6e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 ecmZQzzzP_Fq96ha(5BW9*J3IJzMb<5uj0WAptnUfltXE3U^A@_v*s$d?m(*HL1#JttMq zqvWEwoRUA0C|!|HCWzCiFfl$Is0e3V>iMjr7^GVD!*fRUkT$Ch&rf^|7i1n`dcO;h z-hLi0)`Y{Q(lEUIG>xugZbiO$n64&$QM_|{LW!;qi!hPENh2b55D2;ta7+>rVQ`K=EA+e9K7#WN)H_4@!{HRDlpID zNBYO;u}U028M~Vbhxl;e&oxxkV#`n8=u>gA9zQFvh37do_##ygUdGMAlHhSr>OB_A zoCHw5Qiv4`KEf-_5BOTOk1A#FW0ll2zY3W8dD6Rxw~4E2kg@RPO)G)!HLjiY8jlY|mBbq#^$PlNGuMH{pfv|{U> zLDa?r`AbR*eU19e-}XJH_U+HOW8GEiT*my}@CbFO#c=mDh9A;i+%q5sdb*>rx4{ek zdF_cmAFqPGYb#NhHX8)-+9(nt2ckY>u%Cw(i8*MpxW#DdKW`LEU=K+|Sg@pK0ZCpe z#(`gM(V+J?d2nSl47roSQh7H)`uq(XdOQV&g(lJqWc7=DqVzWa_KmIU?fcMi9n?$cbHMN9hFPNN#(i)s%CB@wbNS}k1VH|2bZzB zr#j8rIFmIjN06qG3~Q->CvC+}o~Q|swRDt^Wd0>!!4Gj|# zU~bq6oEMl&^Id(>$niKCTgCGNvWf3OK1M3kZc#`$Yso UVSu|p%*NPCU}I_Z=WqqT0Qi>*hyVZp diff --git a/zic.tproj/HACK/Turkey b/zic.tproj/HACK/Turkey deleted file mode 100644 index b05d65a03d1fa419861f1d789992381b72e91906..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 993 zcmcJOeN4=89LK+Rb)9R)M^suRBzF-il`bVowW$2mA(Xzjo|N=JE8%Xm=ArR1=V`Hp zoEDmK7RoWFd2fw_E3GkJW`{DD@rNrmaCJ#)dL&ZEv_4Y)s8q!oWHQ?DsGlACx|u(IEr4rL z_0pE_&Ft1pGret4bFHn7wC!m#cc@6lYhkvrsIrSBt-`CK5Mot)wfAw|^&Q4q%`TrqP^ZotzHT?%)Phx>Kks;heJf z>W3tTkfCvF^v>QrY8Ppm-qq%cdYE{s-fgpnbL-aVJ#OA*o;A+g@ahf3Yi$V`k*_2p z)8>*<39-aGd@>pBCnG){Ze)yuJ&}rn)l!v?mzsl6_S6S`jV?I$h8V}`zMx;-OB}E1 z#0izHIC0fQ^jDt1fOHcC7VBVAL=yxh?}lK{0}v8e1|j__2zA$BXwMRme=EhXOVKc; zD;2}F85q$NhEuDeFtWx2r)7C#RHYoI$BHmo=?*h|o?}dOKg5b|VVw6vi0gd@@ixs6 zZ)ky;PY%PZ#s)}eyMl?^sv+t4L7ZJs09^G(oHKt5Cg*2j%H(`hB*fud*Cd?h=Zo_` z`(vteETncg;R3S^7M|_HMMir_s~rsKx;L;`^${{O2A~;6ShDUFE{!|~%hKCW>9r3s zBN{Plz!}W;M9hA%2Xp$1F}I~0m-i?zuYM8c-zeeELvfZX zlmrZiRWV;-^a2-D4;l_!-OCbtvyO;hK|Ls4z6)+I?4XUE={pKSOD|@ diff --git a/zic.tproj/HACK/US/Alaska b/zic.tproj/HACK/US/Alaska deleted file mode 100644 index f3ffb589e67e6ed1a2cfb4e77dc836c42162f953..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 826 zcmchLeJs>*9LImoaj2X;lsxq%oD=zY3>ClQoDRh~c}Sij^6XL~QqmeL536iUYhP+)}OuKd%yPjd>H1hG1Pu_)1^r}o!hG$ z15}e)VX!tCNjC?xSxt`wnDz)(ufYvCl>$~@Ax3UixXM80iiRQ=70=rUc}*EAW3weR zR?e~}-zIR|yjrz=W)XI%lq%C9HSl}KS+fo$>}>2~&8u3#BEOlnOi_T9w2a*qB!}I? zc-Gpf6!#eWu{InT+N^}3?MD}CH|dP_&w13L-w^k9EmBeu1derT>Xc{;`wG4iXa5aw zi5e%aRv$p%-bVzR>nJp7Cc^h~=)P1&_CI}w9#gld=lw1`Fi=9hYU>g1#8K}&3O?mN z)Hm`P_{lA)zaR$!e16b_JP8EaS&+alZVBuAJDXF@zlu6YgSIq*r|N;;n1_)hXC zSuB{FB8B}8v|64st@OK+h}?4Cpa&;NH5roL50^{QnA(x zmHY})`R*oEEhm#p!^KejDwxzfXvE8p>_}~WAzo?TBzg=-|6euW{>N%G<(Ukl(bSdc oakt!f%S||rBj&Do)?lOcwN8Ox>Cn zrhV^OvoGUlKB3cC=%!&Ysx?b)>cFyhjJ4`egSBdiwW;fZrNy1BZDtb)VwJ32und+7 z^H_V=MqF+h&N>+6qQex6D_;9kN39<^-4#&h0b5*ocABoLjRu!y9d%6;f?LTC;x00W z)p28Fjo=e_cn%Q{&J=}aokaNJBYJ*NlC`%-(Cf)*x~{t)y{|M-ALUUb$8)G}(Pi+f z0qP&!1_3FqG|;0OME-ob-b4yPjxHoDJzNu|xlElS%T06;KcsN(yZbVUe>FDVi$7opT&1 z)=IGC`72U7K(Oro94$X)gB9mr(n|R^tU7Rq%CoJZy0C}VgnWfvQTyp`hf%2YIY(+| zZ-BzGg(${5pzd=a**jDZ^^apnL(eH}?Dr(feRbG$#Dee`1H*sCi2onMaRn^Ha9m9u okH6rH7Tkj4nyYwLdS?WZ6e%M~monk=J3La##E2Kh{Picl0rdb8Qvd(} diff --git a/zic.tproj/HACK/US/Arizona b/zic.tproj/HACK/US/Arizona deleted file mode 100644 index d684fb39956e69e6b7c1d5eb98391c0d965328e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmZQzzzUdwq96=FVp8wdb|n;^&l diff --git a/zic.tproj/HACK/US/Central b/zic.tproj/HACK/US/Central deleted file mode 100644 index 7ffb1d8e28afd09b3260c5f56595d5dd9ebd376e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1262 zcmc&wZ8R1J6uv|Vy_V^NlBxAhGA;Q?5<~A^CFLU@H6~vv%O&~P#O*N6P9-&`uSHU# zgffd1lFZSZEk-_KFEtq}Hzq=_v2%7#KX#6vd+vGeea?NJbAMcb|AgG+c8XKzo#d2O zOUqh8>9=0v`NY|jai$F~JP3!(_+h?iS5KFGTR6+P1ukox#B8Hd$d(rJ74>s)r6ZNE z4#q)lStMU;@PWKE56&;Nfr8kzeEmCbx)JD(g)!Fjy~rGkb}XSEgbVSeg*+9{lwyh2 zGb-tpV5z(ulvY>b?Wf&vC%=Qss%oG-xq>S^o8WGN1y&{;hI@_)T;;bH?i&VhwZk{` zqu>*+F$kub5r3>z-AuL3B7E?*lSx)=ewY!e zf^t5}B){ba&a`??3M+p>g(E^zQoDgl*D_%ie~ZeJ6Qt5oz^WDdX?DqR7UUcUwbSAJ zPEt6`iQdNQLEGS64>Q&fo59>QnmkWW6Xxrh;sV8S(3D+(ngjDmt8)w&J{+Y*ciU0> z`eRz0QI0wh0(kFW2I{)LgeAN0@KWOjc;7yqmuVD%aQQ(NN*|KmEML~^D5T}RcC25P zN-G+6qCr|DeOPFVhOr*B^29RyC@=z6?NdY}kvpt*>P2IrIhd^a2~8Cif|*tin{`WJ z%~&m)S4&`RTP|DVkJGx+qimVnLF>;VTZL4Rb;1$+*zp3{_=TXYVFKCNZp96P01_=V zLeWS(h~+d;-0TnbPlj=0u?RNRsk6f=J=mN(#EwzQu;uV0-s&SHr{EHHwpJpSO=sCv zr;oO+IKXaDNA4PD&|Q*G9z!wcS&>598@+HxP9A((WQATy$G|&P7e5OM1D{w+-YIqg zUoRc@(=!2oOIZ$><3xdro^s&8YTEUtnuF@+((d+b-gA9~f~)W2=P9kUH|sKngx)4h zOu|sl76=R2gZs=&A$)@a?$I2dJ2K>b>8~E~P0mo!|(}BE~ z92;*wp)&=Y) H=fC(HgUa5f diff --git a/zic.tproj/HACK/US/East-Indiana b/zic.tproj/HACK/US/East-Indiana deleted file mode 100644 index 3961e6565c64ad60c80755558524f8e3d97afdf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 269 zcmZQzzzSG_q96SQd<_d{-7Yv4uGDbqhI_&3j(-i85;;Fy zF8$1K#o_gbtD#pJt|^@TaNTq}!wrV@A8v}yWVrcY;)h%Rwl>^8Q2gP}z3B~iS57Fn zx399{erHj^gL%;n4>Lmw9@W`4JoYpzcoHYy@Zyu$hga+j4F7h>eE7fo{{x2U|2{Cb zKYYNz$iT=1#!NsO88S06vjE}$|2sD@GW`F)dI19qn9Ttq8F>ExKYoBwz&SjG!8sU+ OT|yXKfwU`-MgRa~zhqwk diff --git a/zic.tproj/HACK/US/Eastern b/zic.tproj/HACK/US/Eastern deleted file mode 100644 index 2ddcd429597596a11eec0ed36090b472b3171347..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1250 zcmcJPdo&jY6vuxg11ow4pW{b z@+#6$>6h7BMF~aMV~UcSQbrj2yMO$#&pn@WzUQ9rxqn`P;JwV5-p)9~z_c@2E+cmt zW?p^*Oss9o&s)68b4Sya;oQ^B~u~k@J*OAm6Z%^CxrY?7~z&+nG$~ULhCO zgwgqCH!jL>q~bCoz7VHNCBL|0X{ZB~#TsI{y$)1tQO1j!^Wl=kTdb61s8Vags=g+u zmKfn`Q8`@ceZapJ-=UiNDy~f{rMm1>d^IASt|cDi>&}r>9~8hh^t?&r6pJ?%%&9@w z9~(x!pi$l$8(YobkM9|qV4Rxw_wqgK4!Z9t;ueisdSIN-t%59SQ~rV5D1q81^YCF^ zFg@x_!H$A&p|fTOK28Y&%5cK2Fgxgu)59L&8tC<3fPZ_fqdt3Geqy3XPc;>|fAKI4 zNWSEOH}~jSUo$^%xk!Ve3Vu=B3`50D$e9)JGOZkk zi=%6z=pTg*I412wW24?Y{?vlrwVLxpgE~!CF6F7bDH0r?WU=Hf5|1LDgOeZu6FAp} zK+^g#O6gw%sUs>lPca+jolj>OP6Ao_4&~ZTlYCt$&aX-&g@OcDJP|?*Qi542=5tyY zX3vX!v`Ja0#f#14=mRZTUa~?9RHO%4Ra_QShh*+eU9o^Z^N>Zzi@e031~zL z_`^fTV1;Kle-vI!D~;=UmBUe5t(?o6+IvZJ@;YkCc#>9U4r&jW(At`0)M@qr-Hb3? zSGFGX;v7-`*b?|SG?WeYjDexOkd53PfwAUVUT;tXCQ|Zjs@6`XeM4+Eeud0MciG}$ z25l&QftJN7!(LLdXZ>rvk~kRywQH;DzG2j$3h7y z5Vme+hn{|LtTg3Kx8{=5&#L@I;S+L>ddDt@e<#;K6?EHqj@+%s(PPsQ^3>?S%{md} zC8$Mj<-_1jS?Dve3w-Mm(C@wrY$?d(trZ5~pK^!;eq00)ww(jx^l6*Wmbd#WQIM7< z2V1_T5G5N7Rd1ot;nn!%L?wkaNn?1&N!n2|fICH(;H#s5;;!5i5V5-mG3fy8_HE=n zAzNXuc_Ht!vx5DqsT`^2N0DR5(F&Fn-R{OQL(A#w%SL?Qwiv~pam9m0JrtKSmpoU}~!BfSQd<_d{-7YxY@vq@hBIk#zp;sBMDV+Uq z-E=#{4Tkj}Zi>!ixcOk>hg<))Hrzf?{Nc{M=?!;RPAIsyud?BOXHmg}dC?6IGeZg< z)!8;Y_B1Pa5+~pAG~DLHGj|(?=jL)BUZ~44y!a&c;T1ar!>fxwKD>VRh~dq(BOl%# zJHqg8|HFd!>mM|Hn18t7WB;LsFY)aKzkZ}M{C?s2;m-|EhQBAYKm6OF&G3H(?+1n% zybO%(?>{h=zh_`BNWp^n&?&rb*;t^>i;e_XmTZgU|V!I+`!22|NrU*3@l(a X2Z&_gaSjh*a1I7ymk; diff --git a/zic.tproj/HACK/US/Michigan b/zic.tproj/HACK/US/Michigan deleted file mode 100644 index 7eac631161099b1332e7c0286a76557bd49ff059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 794 zcmd6l`%ldQ7{{OKQsfbSHq;xx_i}H3oPEv10N|aVES!E5I*pS

6E)=3S1 zdxiTu8GAuV&pl3YpU_B3ws9a) z8L+oyKY70&VISpXTG-XYzAq1vU&|NtzqFMW?S71l52jH-UK=i{Du<;JdoeI06(r6@ z7$gaVV8eI}v9X1a@9SBrB?4(*9ET2mg5~Yr9QII~!uMP7ilz?~vGE5-*4(A2RCA2Z zIYTi4N|c4wQta#jjC0DPmBKZQH?4tqYQ%(ZxscddiAhf*Vb$rwoP6FDQmQL>^*$2- zMLMUJxlo!kh|^PyDMM_}nf_lX%UFVPt7jx1wZk<(+ey)@gV_TIXl?5d=5$?vb@dN0 z_hbX)e`v{b5&vx1IFb*EE9|4$o*h0BD% R7?}{HcICJdnfl-V@*4^9BA5UG diff --git a/zic.tproj/HACK/US/Mountain b/zic.tproj/HACK/US/Mountain deleted file mode 100644 index fc45907a08f34a2225e5557f3083d2dad235602d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 860 zcmd6m`7ag#7{?z+u9Qbb?u774y%IT6AxGqnT;<9Ukz8+d@Dynpd2}o#a?QxP*HSuI zo9R%SW)n-Y7O7RMwcKy-Tfg=P^!e`l-Dl7555PZ>lU${ha#2#LtJX9*@}+h~sx8*z zx(gqvK4Fd>%YUH&EqUJU_nPAFT7g^YAv;h=LWpzDdDALE}N3M}kh!~Aio`Z?)J6z#?6-+fAqnQPR z+1y(esAPg*sFN+mgJI>v2DW^)k5<(jV3(pQa`nH? zo8u3YoA4C7yG4_SS~h!{xRB>W1$xOFlUIKhdcU7XTiZg=r^g6z@!@L#`Gx*maB>7d24rL<`MXm4eY!I_vcij4nsK9YA6{{(+zSjEauatBH}c2 zK69d*s?x<=6E+o|tKzXXIiKoO)m&dr@T#GhU*}z>hO%S)COwlHbGP$bMGQ451G!o5 zL+^s;@_VT*eUJrUi;*|9N*uAZ(+1jvrr1^^f=?e*__?SXzEn2i*X)b6Yfo@r;H*D##>hNePa&p!Os8V>!n8}Rr2#h@yY zq57gZ2y&#Tb@?B|lki|~JsRSo%R;NqB+PJSU3g5o`FBvSqmc9)3)tZ0 zBN$em&BJdLfMMPhgyY#TBAw7^M;we)Y{gN5D?lXoL*qHKVYJj9O(yx$7+n(-Yuk~y z)0W3JjV99?V;)!0OXG`rc*2=_!i4EKG37Q*@*jqiH`alfT{}+kxCK*1)hIE~1&Qhl zOZAdL+VF(U+t$MLvLd#4s-zjYM|oy(C|N4EvDMLqG%Ml=TF04@jVvB*eTR^p#2@Xg zTWPk?0Ub;SgF}lL=lp5`$I5=3TmJy&6`Jt;(o5i!)yK{!GhjjVD|SiEqlKPj?7IFC zxmhy1yKSLGhI?6N=1H=i(Y!I_vcij4nsK9YA6{{(+zSjEauatBH}c2 zK69d*s?x<=6E+o|tKzXXIiKoO)m&dr@T#GhU*}z>hO%S)COwlHbGP$bMGQ451G!o5 zL+^s;@_VT*eUJrUi;*|9N*uAZ(+1jvrr1^^f=?e*__?SXzEn2i*X)b6Yfo@r;H*D##>hNePa&p!Os8V>!n8}Rr2#h@yY zq57gZ2y&#Tb@?B|lki|~JsRSo%R;NqB+PJSU3g5o`FBvSqmc9)3)tZ0 zBN$em&BJdLfMMPhgyY#TBAw7^M;we)Y{gN5D?lXoL*qHKVYJj9O(yx$7+n(-Yuk~y z)0W3JjV99?V;)!0OXG`rc*2=_!i4EKG37Q*@*jqiH`alfT{}+kxCK*1)hIE~1&Qhl zOZAdL+VF(U+t$MLvLd#4s-zjYM|oy(C|N4EvDMLqG%Ml=TF04@jVvB*eTR^p#2@Xg zTWPk?0Ub;SgF}lL=lp5`$I5=3TmJy&6`Jt;(o5i!)yK{!GhjjVD|SiEqlKPj?7IFC zxmhy1yKSLGhI?6N=1H=i(pKX#n&9 diff --git a/zic.tproj/HACK/Universal b/zic.tproj/HACK/Universal deleted file mode 100644 index fa05d4b179f1884a71109c6a39df6b9c5e7fb720..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56 acmZQzzzP_Fq96pKX#n&9 diff --git a/zic.tproj/HACK/W-SU b/zic.tproj/HACK/W-SU deleted file mode 100644 index 38651468ac9724fa40287d4492995762de4313ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 815 zcmb`FZAeoA6o&70TP{sAXl~0nHPg*$rmJ+;=2qJj)78{zOI@0utNb{r$xKZR69W@0 zq0I7w<_t1hWD%q#QBh>JA0omO0tqU}4v|TU(Y=IV(9hn(d(Ol2`w+xGvw^a7=`>QM zS=f~=oW2qJ?P|B=E3bPorlqIJ$m^XhVfPW<;y$@eW%Vi&&8WC+r=GjCag6ub)4_MDRa?d{JA6iZQ83t!zSqy8u(bmHYV*;*I1K}` z;&5wHGzQAWxGjv2K>{}nc3(yjO9Y|?9*9418$v8k8$u=>D#`Qv5uw8~5N3S~+dG~> zc+*|jQP~R-`Rx#C8bN9K72K)l#$74ZxZAe@qokP_wUUc69}CE4H5jv;0eeP+aj#Pj za+?|ykA)E190bZP0#t>ru&+sg`?a4yo%ahhL2p2-evfgiI}jiE4CCitV*=iyLkGU{84Ao*}9q!cGWYP22Ft4P;@mD4|F)M?Ux0F!)(tsr`0Z?j-!ZI@hpqYoKlKrr}U6grK+JT;IaGUugQmTQe^+K5D?hMZs& zQj*aa5w?1;dQgk57?}hy!b*aqdq`kn7lhnEy%-?)ZYw~er0&*8;S#;Q9OBvlJV0-uM6*B+W zm^G-vhSz1x_86(`&*H}RT;`mQ;-*?DbK5epStFv#6p1|9N2*mb(1@N;D}4*?#0TUD z-b4P#5Vnk8##ZlD=!WmIpwo%M-b>up(17jElPofvVzIe~CF{-9>$KbpKX#n&9 diff --git a/zic.tproj/Makefile b/zic.tproj/Makefile index 0c7fbce..3340739 100644 --- a/zic.tproj/Makefile +++ b/zic.tproj/Makefile @@ -16,8 +16,7 @@ HFILES = private.h CFILES = ialloc.c scheck.c zic.c -OTHERSRCS = HACK Makefile.preamble Makefile Makefile.postamble\ - datfiles zic.8 +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble zic.8 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/zic.tproj/Makefile.postamble b/zic.tproj/Makefile.postamble index 78bbf07..b4a42ed 100644 --- a/zic.tproj/Makefile.postamble +++ b/zic.tproj/Makefile.postamble @@ -160,7 +160,15 @@ TDATA= $(YDATA) $(NDATA) $(SDATA) DATA= $(YDATA) $(NDATA) $(SDATA) leapseconds # yearistype.sh USNO= usno1988 usno1989 +Embedded=$(shell tconf --test TARGET_OS_EMBEDDED) + +# Embedded zic is probably not built with the same architecture as +# the build host, so we can't use the recently built copy. +ifeq "$(Embedded)" "YES" +ZIC=/usr/sbin/zic +else ZIC=${DSTROOT}/usr/sbin/zic +endif ${YEARISTYPECOPY}: cp ${YEARISTYPE} ${YEARISTYPECOPY} @@ -199,8 +207,9 @@ ZONEINFO = ${DSTROOT}/usr/share/zoneinfo # ftp://elsie.nci.nih.gov/pub/tzdata*.tar.gz # the tzdata*.tar.gz file is automatically unpacked and a version file created +# /usr/local/share/tz/tzdata*.tar.gz is installed by the TimeZoneData project DATFILES = ${OFILE_DIR}/datfiles -TARBALL = $(shell echo `pwd`/datfiles/tzdata*) +TARBALL = $(shell echo /usr/local/share/tz/tzdata*) DATVERS = $(shell basename ${TARBALL} | sed -e 's,\..*,,' -e 's/^tzdata//') VERSIONFILE = ${ZONEINFO}/+VERSION @@ -222,9 +231,15 @@ after_install:: ${DATFILES} chmod -R og-w ${ZONEINFO} install -c -m 444 ${DATFILES}/zone.tab ${ZONEINFO} install -c -m 444 ${DATFILES}/iso3166.tab ${ZONEINFO} +ifeq "$(Embedded)" "YES" + -mkdir -p ${DSTROOT}/private/var/db + -rm -f ${DSTROOT}/private/var/db/localtime + ln -fs /usr/share/zoneinfo/${LOCALTIME} ${DSTROOT}/private/var/db/localtime +else -mkdir -p ${DSTROOT}/private/etc -rm -f ${DSTROOT}/private/etc/localtime ln -fs /usr/share/zoneinfo/${LOCALTIME} ${DSTROOT}/private/etc/localtime +endif mkdir -p ${DSTROOT}/usr/share/man/man8 install -c -m 444 zic.8 ${DSTROOT}/usr/share/man/man8 echo ${DATVERS} > ${VERSIONFILE} diff --git a/zic.tproj/PB.project b/zic.tproj/PB.project index b20b6db..f39880b 100644 --- a/zic.tproj/PB.project +++ b/zic.tproj/PB.project @@ -4,7 +4,7 @@ FRAMEWORKS = (); H_FILES = (private.h, tzfile.h); OTHER_LINKED = (ialloc.c, scheck.c, zic.c); - OTHER_SOURCES = (HACK, Makefile.preamble, Makefile, Makefile.postamble, datfiles, zic.8); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, zic.8); SUBPROJECTS = (); }; LANGUAGE = English; diff --git a/zic.tproj/datfiles/Theory b/zic.tproj/datfiles/Theory deleted file mode 100644 index 6d5efa0..0000000 --- a/zic.tproj/datfiles/Theory +++ /dev/null @@ -1,506 +0,0 @@ -@(#)Theory 7.13 - - ------ Outline ----- - - Time and date functions - Names of time zone regions - Time zone abbreviations - Calendrical issues - - ------ Time and date functions ----- - -These time and date functions are upwards compatible with POSIX.1, -an international standard for Unix-like systems. -As of this writing, the current edition of POSIX.1 is: - - Information technology --Portable Operating System Interface (POSIX (R)) - -- Part 1: System Application Program Interface (API) [C Language] - ISO/IEC 9945-1:1996 - ANSI/IEEE Std 1003.1, 1996 Edition - 1996-07-12 - -POSIX.1 has the following properties and limitations. - -* In POSIX.1, time display in a process is controlled by the - environment variable TZ. Unfortunately, the POSIX.1 TZ string takes - a form that is hard to describe and is error-prone in practice. - Also, POSIX.1 TZ strings can't deal with other (for example, Israeli) - daylight saving time rules, or situations where more than two - time zone abbreviations are used in an area. - - The POSIX.1 TZ string takes the following form: - - stdoffset[dst[offset],date[/time],date[/time]] - - where: - - std and dst - are 3 or more characters specifying the standard - and daylight saving time (DST) zone names. - offset - is of the form `[-]hh:[mm[:ss]]' and specifies the - offset west of UTC. The default DST offset is one hour - ahead of standard time. - date[/time],date[/time] - specifies the beginning and end of DST. If this is absent, - the system supplies its own rules for DST, and these can - differ from year to year; typically US DST rules are used. - time - takes the form `hh:[mm[:ss]]' and defaults to 02:00. - date - takes one of the following forms: - Jn (1<=n<=365) - origin-1 day number not counting February 29 - n (0<=n<=365) - origin-0 day number counting February 29 if present - Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12) - for the dth day of week n of month m of the year, - where week 1 is the first week in which day d appears, - and `5' stands for the last week in which day d appears - (which may be either the 4th or 5th week). - -* In POSIX.1, when a TZ value like "EST5EDT" is parsed, - typically the current US DST rules are used, - but this means that the US DST rules are compiled into each program - that does time conversion. This means that when US time conversion - rules change (as in the United States in 1987), all programs that - do time conversion must be recompiled to ensure proper results. - -* In POSIX.1, there's no tamper-proof way for a process to learn the - system's best idea of local wall clock. (This is important for - applications that an administrator wants used only at certain times-- - without regard to whether the user has fiddled the "TZ" environment - variable. While an administrator can "do everything in UTC" to get - around the problem, doing so is inconvenient and precludes handling - daylight saving time shifts--as might be required to limit phone - calls to off-peak hours.) - -* POSIX.1 requires that systems ignore leap seconds. - -These are the extensions that have been made to the POSIX.1 functions: - -* The "TZ" environment variable is used in generating the name of a file - from which time zone information is read (or is interpreted a la - POSIX); "TZ" is no longer constrained to be a three-letter time zone - name followed by a number of hours and an optional three-letter - daylight time zone name. The daylight saving time rules to be used - for a particular time zone are encoded in the time zone file; - the format of the file allows U.S., Australian, and other rules to be - encoded, and allows for situations where more than two time zone - abbreviations are used. - - It was recognized that allowing the "TZ" environment variable to - take on values such as "America/New_York" might cause "old" programs - (that expect "TZ" to have a certain form) to operate incorrectly; - consideration was given to using some other environment variable - (for example, "TIMEZONE") to hold the string used to generate the - time zone information file name. In the end, however, it was decided - to continue using "TZ": it is widely used for time zone purposes; - separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance; - and systems where "new" forms of "TZ" might cause problems can simply - use TZ values such as "EST5EDT" which can be used both by - "new" programs (a la POSIX) and "old" programs (as zone names and - offsets). - -* To handle places where more than two time zone abbreviations are used, - the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst] - (where "tmp" is the value the function returns) to the time zone - abbreviation to be used. This differs from POSIX.1, where the elements - of tzname are only changed as a result of calls to tzset. - -* Since the "TZ" environment variable can now be used to control time - conversion, the "daylight" and "timezone" variables are no longer - needed. (These variables are defined and set by "tzset"; however, their - values will not be used by "localtime.") - -* The "localtime" function has been set up to deliver correct results - for near-minimum or near-maximum time_t values. (A comment in the - source code tells how to get compatibly wrong results). - -* A function "tzsetwall" has been added to arrange for the system's - best approximation to local wall clock time to be delivered by - subsequent calls to "localtime." Source code for portable - applications that "must" run on local wall clock time should call - "tzsetwall();" if such code is moved to "old" systems that don't - provide tzsetwall, you won't be able to generate an executable program. - (These time zone functions also arrange for local wall clock time to be - used if tzset is called--directly or indirectly--and there's no "TZ" - environment variable; portable applications should not, however, rely - on this behavior since it's not the way SVR2 systems behave.) - -* These functions can account for leap seconds, thanks to Bradley White - (bww@k.cs.cmu.edu). - -Points of interest to folks with other systems: - -* This package is already part of many POSIX-compliant hosts, - including BSD, HP, Linux, Network Appliance, SCO, SGI, and Sun. - On such hosts, the primary use of this package - is to update obsolete time zone rule tables. - To do this, you may need to compile the time zone compiler - `zic' supplied with this package instead of using the system `zic', - since the format of zic's input changed slightly in late 1994, - and many vendors still do not support the new input format. - -* The Unix Version 7 "timezone" function is not present in this package; - it's impossible to reliably map timezone's arguments (a "minutes west - of GMT" value and a "daylight saving time in effect" flag) to a - time zone abbreviation, and we refuse to guess. - Programs that in the past used the timezone function may now examine - tzname[localtime(&clock)->tm_isdst] to learn the correct time - zone abbreviation to use. Alternatively, use - localtime(&clock)->tm_zone if this has been enabled. - -* The 4.2BSD gettimeofday function is not used in this package. - This formerly let users obtain the current UTC offset and DST flag, - but this functionality was removed in later versions of BSD. - -* In SVR2, time conversion fails for near-minimum or near-maximum - time_t values when doing conversions for places that don't use UTC. - This package takes care to do these conversions correctly. - -The functions that are conditionally compiled if STD_INSPIRED is defined -should, at this point, be looked on primarily as food for thought. They are -not in any sense "standard compatible"--some are not, in fact, specified in -*any* standard. They do, however, represent responses of various authors to -standardization proposals. - -Other time conversion proposals, in particular the one developed by folks at -Hewlett Packard, offer a wider selection of functions that provide capabilities -beyond those provided here. The absence of such functions from this package -is not meant to discourage the development, standardization, or use of such -functions. Rather, their absence reflects the decision to make this package -contain valid extensions to POSIX.1, to ensure its broad -acceptability. If more powerful time conversion functions can be standardized, -so much the better. - - ------ Names of time zone rule files ----- - -The time zone rule file naming conventions attempt to strike a balance -among the following goals: - - * Uniquely identify every national region where clocks have all - agreed since 1970. This is essential for the intended use: static - clocks keeping local civil time. - - * Indicate to humans as to where that region is. This simplifes use. - - * Be robust in the presence of political changes. This reduces the - number of updates and backward-compatibility hacks. For example, - names of countries are ordinarily not used, to avoid - incompatibilities when countries change their name - (e.g. Zaire->Congo) or when locations change countries - (e.g. Hong Kong from UK colony to China). - - * Be portable to a wide variety of implementations. - This promotes use of the technology. - - * Use a consistent naming convention over the entire world. - This simplifies both use and maintenance. - -This naming convention is not intended for use by inexperienced users -to select TZ values by themselves (though they can of course examine -and reuse existing settings). Distributors should provide -documentation and/or a simple selection interface that explains the -names; see the 'tzselect' program supplied with this distribution for -one example. - -Names normally have the form AREA/LOCATION, where AREA is the name -of a continent or ocean, and LOCATION is the name of a specific -location within that region. North and South America share the same -area, `America'. Typical names are `Africa/Cairo', `America/New_York', -and `Pacific/Honolulu'. - -Here are the general rules used for choosing location names, -in decreasing order of importance: - - Use only valid POSIX file name components (i.e., the parts of - names other than `/'). Within a file name component, - use only ASCII letters, `.', `-' and `_'. Do not use - digits, as that might create an ambiguity with POSIX - TZ strings. A file name component must not exceed 14 - characters or start with `-'. E.g., prefer `Brunei' - to `Bandar_Seri_Begawan'. - Include at least one location per time zone rule set per country. - One such location is enough. Use ISO 3166 (see the file - iso3166.tab) to help decide whether something is a country. - If all the clocks in a country's region have agreed since 1970, - don't bother to include more than one location - even if subregions' clocks disagreed before 1970. - Otherwise these tables would become annoyingly large. - If a name is ambiguous, use a less ambiguous alternative; - e.g. many cities are named San Jose and Georgetown, so - prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'. - Keep locations compact. Use cities or small islands, not countries - or regions, so that any future time zone changes do not split - locations into different time zones. E.g. prefer `Paris' - to `France', since France has had multiple time zones. - Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and - prefer `Athens' to the true name (which uses Greek letters). - The POSIX file name restrictions encourage this rule. - Use the most populous among locations in a country's time zone, - e.g. prefer `Shanghai' to `Beijing'. Among locations with - similar populations, pick the best-known location, - e.g. prefer `Rome' to `Milan'. - Use the singular form, e.g. prefer `Canary' to `Canaries'. - Omit common suffixes like `_Islands' and `_City', unless that - would lead to ambiguity. E.g. prefer `Cayman' to - `Cayman_Islands' and `Guatemala' to `Guatemala_City', - but prefer `Mexico_City' to `Mexico' because the country - of Mexico has several time zones. - Use `_' to represent a space. - Omit `.' from abbreviations in names, e.g. prefer `St_Helena' - to `St._Helena'. - Do not change established names if they only marginally - violate the above rules. For example, don't change - the existing name `Rome' to `Milan' merely because - Milan's population has grown to be somewhat greater - than Rome's. - If a name is changed, put its old spelling in the `backward' file. - -The file `zone.tab' lists the geographical locations used to name -time zone rule files. - -Older versions of this package used a different naming scheme, -and these older names are still supported. -See the file `backward' for most of these older names -(e.g. `US/Eastern' instead of `America/New_York'). -The other old-fashioned names still supported are -`WET', `CET', `MET', `EET' (see the file `europe'), -and `Factory' (see the file `factory'). - - ------ Time zone abbreviations ----- - -When this package is installed, it generates time zone abbreviations -like `EST' to be compatible with human tradition and POSIX.1. -Here are the general rules used for choosing time zone abbreviations, -in decreasing order of importance: - - Use abbreviations that consist of three or more ASCII letters. - Previous editions of this database also used characters like - ' ' and '?', but these characters have a special meaning to - the shell and cause commands like - set `date` - to have unexpected effects. - Previous editions of this rule required upper-case letters, - but the Congressman who introduced Chamorro Standard Time - preferred "ChST", so the rule has been relaxed. - - This rule guarantees that all abbreviations could have - been specified by a POSIX.1 TZ string. POSIX.1 - requires at least three characters for an - abbreviation. POSIX.1-1996 says that an abbreviation - cannot start with ':', and cannot contain ',', '-', - '+', NUL, or a digit. Draft 7 of POSIX 1003.1-200x - changes this rule to say that an abbreviation can - contain only '-', '+', and alphanumeric characters in - the current locale. To be portable to both sets of - rules, an abbreviation must therefore use only ASCII - letters, as these are the only letters that are - alphabetic in all locales. - - Use abbreviations that are in common use among English-speakers, - e.g. `EST' for Eastern Standard Time in North America. - We assume that applications translate them to other languages - as part of the normal localization process; for example, - a French application might translate `EST' to `HNE'. - - For zones whose times are taken from a city's longitude, use the - traditional xMT notation, e.g. `PMT' for Paris Mean Time. - The only name like this in current use is `GMT'. - - If there is no common English abbreviation, abbreviate the English - translation of the usual phrase used by native speakers. - If this is not available or is a phrase mentioning the country - (e.g. ``Cape Verde Time''), then: - - When a country has a single or principal time zone region, - append `T' to the country's ISO code, e.g. `CVT' for - Cape Verde Time. For summer time append `ST'; - for double summer time append `DST'; etc. - When a country has multiple time zones, take the first three - letters of an English place name identifying each zone - and then append `T', `ST', etc. as before; - e.g. `VLAST' for VLAdivostok Summer Time. - - Use "zzz" for locations while uninhabited. The mnemonic is that - these locations are, in some sense, asleep. - -Application writers should note that these abbreviations are ambiguous -in practice: e.g. `EST' has a different meaning in Australia than -it does in the United States. In new applications, it's often better -to use numeric UTC offsets like `-0500' instead of time zone -abbreviations like `EST'; this avoids the ambiguity. - - ------ Calendrical issues ----- - -Calendrical issues are a bit out of scope for a time zone database, -but they indicate the sort of problems that we would run into if we -extended the time zone database further into the past. An excellent -resource in this area is Nachum Dershowitz and Edward M. Reingold, - -Calendrical Calculations -, Cambridge University Press (1997). Other information and -sources are given below. They sometimes disagree. - - -France - -Gregorian calendar adopted 1582-12-20. -French Revolutionary calendar used 1793-11-24 through 1805-12-31, -and (in Paris only) 1871-05-06 through 1871-05-23. - - -Russia - -From Chris Carrier <72157.3334@CompuServe.COM> (1996-12-02): -On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar'' -with 30-day months plus 5 holidays, with a 5-day week. -On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the -Gregorian calendar while retaining the 6-day week; on 1940-06-27 it -reverted to the 7-day week. With the 6-day week the usual days -off were the 6th, 12th, 18th, 24th and 30th of the month. -(Source: Evitiar Zerubavel, _The Seven Day Circle_) - - -Mark Brader reported a similar story in "The Book of Calendars", edited -by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But: - -From: Petteri Sulonen (via Usenet) -Date: 14 Jan 1999 00:00:00 GMT -Message-ID: - -If your source is correct, how come documents between 1929 -- 1940 were -still dated using the conventional, Gregorian calendar? - -I can post a scan of a document dated December 1, 1934, signed by -Yenukidze, the secretary, on behalf of Kalinin, the President of the -Executive Committee of the Supreme Soviet, if you like. - - - -Sweden (and Finland) - -From: msb@sq.com (Mark Brader) - -Subject: Re: Gregorian reform -- a part of locale? - -Date: 1996-07-06 - -In 1700, Denmark made the transition from Julian to Gregorian. Sweden -decided to *start* a transition in 1700 as well, but rather than have one of -those unsightly calendar gaps :-), they simply decreed that the next leap -year after 1696 would be in 1744 -- putting the whole country on a calendar -different from both Julian and Gregorian for a period of 40 years. - -However, in 1704 something went wrong and the plan was not carried through; -they did, after all, have a leap year that year. And one in 1708. In 1712 -they gave it up and went back to Julian, putting 30 days in February that -year!... - -Then in 1753, Sweden made the transition to Gregorian in the usual manner, -getting there only 13 years behind the original schedule. - -(A previous posting of this story was challenged, and Swedish readers -produced the following references to support it: "Tiderakning och historia" -by Natanael Beckman (1924) and "Tid, en bok om tiderakning och -kalendervasen" by Lars-Olof Lode'n (no date was given).) - - -Grotefend's data - -From: "Michael Palmer" [with one obvious typo fixed] -Subject: Re: Gregorian Calendar (was Re: Another FHC related question -Newsgroups: soc.genealogy.german -Date: Tue, 9 Feb 1999 02:32:48 -800 -Message-ID: <199902091032.CAA09644@netcom10.netcom.com> - -The following is a(n incomplete) listing, arranged chronologically, of -European states, with the date they converted from the Julian to the -Gregorian calendar: - -04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman - Catholics and Danzig only) -09/20 Dec 1582 - France, Lorraine - -21 Dec 1582/ - 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau -10/21 Feb 1583 - bishopric of Liege (L"uttich) -13/24 Feb 1583 - bishopric of Augsburg -04/15 Oct 1583 - electorate of Trier -05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg, - Salzburg, Brixen -13/24 Oct 1583 - Austrian Oberelsass and Breisgau -20/31 Oct 1583 - bishopric of Basel -02/13 Nov 1583 - duchy of J"ulich-Berg -02/13 Nov 1583 - electorate and city of K"oln -04/15 Nov 1583 - bishopric of W"urzburg -11/22 Nov 1583 - electorate of Mainz -16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden -17/28 Nov 1583 - bishopric of M"unster and duchy of Cleve -14/25 Dec 1583 - Steiermark - -06/17 Jan 1584 - Austria and Bohemia -11/22 Jan 1584 - Luzern, Uri, Schwyz, Zug, Freiburg, Solothurn -12/23 Jan 1584 - Silesia and the Lausitz -22 Jan/ - 02 Feb 1584 - Hungary (legally on 21 Oct 1587) - Jun 1584 - Unterwalden -01/12 Jul 1584 - duchy of Westfalen - -16/27 Jun 1585 - bishopric of Paderborn - -14/25 Dec 1590 - Transylvania - -22 Aug/ - 02 Sep 1612 - duchy of Prussia - -13/24 Dec 1614 - Pfalz-Neuburg - - 1617 - duchy of Kurland (reverted to the Julian calendar in - 1796) - - 1624 - bishopric of Osnabr"uck - - 1630 - bishopric of Minden - -15/26 Mar 1631 - bishopric of Hildesheim - - 1655 - Kanton Wallis - -05/16 Feb 1682 - city of Strassburg - -18 Feb/ - 01 Mar 1700 - Protestant Germany (including Swedish possessions in - Germany), Denmark, Norway -30 Jun/ - 12 Jul 1700 - Gelderland, Zutphen -10 Nov/ - 12 Dec 1700 - Utrecht, Overijssel - -31 Dec 1700/ - 12 Jan 1701 - Friesland, Groningen, Z"urich, Bern, Basel, Geneva, - Turgau, and Schaffhausen - - 1724 - Glarus, Appenzell, and the city of St. Gallen - -01 Jan 1750 - Pisa and Florence - -02/14 Sep 1752 - Great Britain - -17 Feb/ - 01 Mar 1753 - Sweden - -1760-1812 - Graub"unden - -The Russian empire (including Finland and the Baltic states) did not -convert to the Gregorian calendar until the Soviet revolution of 1917. - -Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen -Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend -(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28. diff --git a/zic.tproj/datfiles/tzdata2007h.tar.gz b/zic.tproj/datfiles/tzdata2007h.tar.gz deleted file mode 100644 index 55fccf4f75fc170ff188c93b11cc1b4d15c443d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162187 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 +#include #include #include #include @@ -71,6 +72,7 @@ usage() exit(1); } +int main(argc, argv) int argc; char *argv[]; @@ -83,7 +85,7 @@ main(argc, argv) unsigned int infoCnt = sizeof info_buf/sizeof info_buf[0]; char *zname = NULL; - int znamelen; + int znamelen = 0; kern_return_t kr; int i, j; @@ -249,7 +251,7 @@ printzone(name, info) { unsigned int used, size; - printf("%.*s zone:\n", sizeof name->zn_name, name->zn_name); + printf("%.*s zone:\n", (int)sizeof name->zn_name, name->zn_name); printf("\tcur_size: %dK bytes (%d elements)\n", info->zi_cur_size/1024, info->zi_cur_size/info->zi_elem_size); @@ -290,7 +292,7 @@ colprintzone(zone_name, info) zone_info_t *info; { char *name = zone_name->zn_name; - int j, namewidth, retval; + int j, namewidth; unsigned int used, size; namewidth = 25; -- 2.45.2