xref: /netbsd-src/etc/autofs/include_nis_nullfs (revision b985414b8f8688f3bfa6718c583260b26b0bf1d1)
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