1*b985414bSchristos#!/usr/bin/awk -f 2*b985414bSchristos#- 3*b985414bSchristos# Copyright (c) 2017 G. Paul Ziemba 4*b985414bSchristos# All rights reserved. 5*b985414bSchristos# 6*b985414bSchristos# Redistribution and use in source and binary forms, with or without 7*b985414bSchristos# modification, are permitted provided that the following conditions 8*b985414bSchristos# are met: 9*b985414bSchristos# 1. Redistributions of source code must retain the above copyright 10*b985414bSchristos# notice, this list of conditions and the following disclaimer. 11*b985414bSchristos# 2. Redistributions in binary form must reproduce the above copyright 12*b985414bSchristos# notice, this list of conditions and the following disclaimer in the 13*b985414bSchristos# documentation and/or other materials provided with the distribution. 14*b985414bSchristos# 15*b985414bSchristos# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*b985414bSchristos# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*b985414bSchristos# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*b985414bSchristos# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*b985414bSchristos# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*b985414bSchristos# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*b985414bSchristos# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*b985414bSchristos# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*b985414bSchristos# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*b985414bSchristos# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*b985414bSchristos# SUCH DAMAGE. 26*b985414bSchristos# 27*b985414bSchristos# $NetBSD: include_nis_nullfs,v 1.1 2018/01/09 03:31:14 christos Exp $ 28*b985414bSchristos# 29*b985414bSchristos 30*b985414bSchristos# 31*b985414bSchristos# /etc/autofs/include_nis_nullfs 32*b985414bSchristos# 33*b985414bSchristos# automountd Directory Services script for NIS 34*b985414bSchristos# 35*b985414bSchristos# SYNOPSIS 36*b985414bSchristos# include_nis_nullfs <mapname> 37*b985414bSchristos# 38*b985414bSchristos# include_nis_nullfs <mapname> <key> 39*b985414bSchristos# 40*b985414bSchristos# DESCRIPTION 41*b985414bSchristos# 42*b985414bSchristos# This script provides a Directory Services map for automountd 43*b985414bSchristos# based on NIS. Please see auto_master(5) for general information. 44*b985414bSchristos# 45*b985414bSchristos# The first form, with one argument, emits the entire named NIS map. 46*b985414bSchristos# The second form, with two arguments, emits the map entry for the 47*b985414bSchristos# key given in the second argument. 48*b985414bSchristos# 49*b985414bSchristos# This script attempts to determine the names and IP addresses 50*b985414bSchristos# of the local host. Map entries matching the local host are 51*b985414bSchristos# rewritten to specify nullfs mounts (instead of the default 52*b985414bSchristos# NFS) to reduce access overhead in the kernel. 53*b985414bSchristos# 54*b985414bSchristos# If a map entry contains multiple location fields, it is not changed. 55*b985414bSchristos# 56*b985414bSchristos 57*b985414bSchristos 58*b985414bSchristos# Populate list of names and IP addrs thet mean "this host" 59*b985414bSchristos# into myhostnames array 60*b985414bSchristosBEGIN { 61*b985414bSchristos # 62*b985414bSchristos # Set self hostnames 63*b985414bSchristos # 64*b985414bSchristos 65*b985414bSchristos "hostname -s" | getline; 66*b985414bSchristos myhostnames[$0] = 1; 67*b985414bSchristos 68*b985414bSchristos "hostname -f" | getline; 69*b985414bSchristos myhostnames[$0] = 1; 70*b985414bSchristos 71*b985414bSchristos myhostnames["localhost"] = 1 72*b985414bSchristos 73*b985414bSchristos "hostname -f" | getline; 74*b985414bSchristos localdomain=$0 75*b985414bSchristos myhostnames["localhost."localdomain] = 1 76*b985414bSchristos 77*b985414bSchristos while ("ifconfig" | getline) { 78*b985414bSchristos if ($1 == "inet") { 79*b985414bSchristos myhostnames[$2] = 1; 80*b985414bSchristos } 81*b985414bSchristos } 82*b985414bSchristos 83*b985414bSchristos # debug 84*b985414bSchristos# print "--- hostname list start ----" 85*b985414bSchristos# for (i in myhostnames) { 86*b985414bSchristos# print i 87*b985414bSchristos# } 88*b985414bSchristos# print "--- hostname list end ----" 89*b985414bSchristos 90*b985414bSchristos if (ARGC == 2) { 91*b985414bSchristos # mapname only 92*b985414bSchristos while ("ypcat -k " ARGV[1] | getline) { 93*b985414bSchristos proc_mapline(1) 94*b985414bSchristos } 95*b985414bSchristos } 96*b985414bSchristos if (ARGC == 3) { 97*b985414bSchristos # mapname and keyname 98*b985414bSchristos while ("ypmatch " ARGV[2] " " ARGV[1] | getline) { 99*b985414bSchristos proc_mapline(0) 100*b985414bSchristos } 101*b985414bSchristos } 102*b985414bSchristos exit 0 103*b985414bSchristos} 104*b985414bSchristos 105*b985414bSchristosfunction is_self(hostname) 106*b985414bSchristos{ 107*b985414bSchristos if (myhostnames[hostname]) { 108*b985414bSchristos return 1 109*b985414bSchristos } 110*b985414bSchristos return 0 111*b985414bSchristos} 112*b985414bSchristos 113*b985414bSchristos# 114*b985414bSchristos# Lines are of the form [key] [-opts] location1 [... locationN] 115*b985414bSchristos# 116*b985414bSchristos# indicate index of key field with first positional parameter 117*b985414bSchristos# 1 means keyfield is the first field 118*b985414bSchristos# 0 means keyfield is not present 119*b985414bSchristos# 120*b985414bSchristosfunction proc_mapline(keyfield) 121*b985414bSchristos{ 122*b985414bSchristos optionsfield = 0 123*b985414bSchristos locationfield = 0 124*b985414bSchristos locationcount = 0 125*b985414bSchristos 126*b985414bSchristos for (i=keyfield+1; i <= NF; ++i) { 127*b985414bSchristos if (!optionsfield) { 128*b985414bSchristos if ($i ~ /^-/) { 129*b985414bSchristos # the first options field found on the line 130*b985414bSchristos optionsfield = i; 131*b985414bSchristos continue 132*b985414bSchristos } 133*b985414bSchristos } 134*b985414bSchristos # Assumption: location contains colon (":") 135*b985414bSchristos if (optionsfield && ($i ~ /:/) && ($i !~ /^-/)) { 136*b985414bSchristos ++locationcount 137*b985414bSchristos if (!locationfield) { 138*b985414bSchristos # the first location field found on the line 139*b985414bSchristos locationfield = i 140*b985414bSchristos } 141*b985414bSchristos } 142*b985414bSchristos } 143*b985414bSchristos 144*b985414bSchristos # 145*b985414bSchristos # If location not found, do not modify. 146*b985414bSchristos # 147*b985414bSchristos # If there is more than one location, do not modify. Rationale: 148*b985414bSchristos # Options are applied to all locations. We ca not have "nullfs" 149*b985414bSchristos # for only some locations and "nfs" for others for a given 150*b985414bSchristos # map key (i.e., a line). The usual reason for multiple 151*b985414bSchristos # locations is for redundancy using replicated volumes on 152*b985414bSchristos # multiple hosts, so multiple hosts imply fstype=nfs (the 153*b985414bSchristos # FreeBSD default for automounter maps). 154*b985414bSchristos # 155*b985414bSchristos # Hypothetically there could be a map entry with multiple 156*b985414bSchristos # locations all with host parts matching "me". In that case, 157*b985414bSchristos # it would be safe to rewrite the locations and specify 158*b985414bSchristos # nullfs, but the code does not handle this case. 159*b985414bSchristos # 160*b985414bSchristos if (locationcount == 1) { 161*b985414bSchristos # 162*b985414bSchristos # We have a line with exactly one location field 163*b985414bSchristos # 164*b985414bSchristos # Assumption: location has no more than one colon (":") 165*b985414bSchristos # 166*b985414bSchristos n=split($locationfield,location,":") 167*b985414bSchristos if (is_self(location[1])) { 168*b985414bSchristos $locationfield = ":" location[2] 169*b985414bSchristos if (optionsfield) { 170*b985414bSchristos # append to existing options 171*b985414bSchristos $optionsfield = $optionsfield ",fstype=nullfs" 172*b985414bSchristos } else { 173*b985414bSchristos # sneak in ahead of location 174*b985414bSchristos $locationfield = "-fstype=nullfs " $locationfield 175*b985414bSchristos } 176*b985414bSchristos } 177*b985414bSchristos } 178*b985414bSchristos 179*b985414bSchristos print 180*b985414bSchristos} 181