Handle hostnames with upper-case letters
[webmin.git] / nis / nis-lib.pl
1 # nis-lib.pl
2 # Common functions for NIS client and server management
3
4 BEGIN { push(@INC, ".."); };
5 use WebminCore;
6 &init_config();
7 if (-r "$module_root_directory/$gconfig{'os_type'}-$gconfig{'os_version'}-lib.pl") {
8         do "$gconfig{'os_type'}-$gconfig{'os_version'}-lib.pl";
9         }
10 else {
11         do "$gconfig{'os_type'}-lib.pl";
12         }
13 if ($gconfig{'os_type'} =~ /-linux$/) {
14         do "linux-lib.pl";
15         }
16 &foreign_require("init", "init-lib.pl");
17
18 # init_script(action)
19 # Returns the full path to some init script
20 sub init_script
21 {
22 local %iconfig = &foreign_config("init");
23 return "$iconfig{'init_dir'}/$_[0]";
24 }
25
26 # get_nsswitch_conf()
27 # Parses lines of nsswitch.conf into an array
28 sub get_nsswitch_conf
29 {
30 local @rv;
31 open(SWITCH, $config{'nsswitch_conf'});
32 while(<SWITCH>) {
33         s/\r|\n//g;
34         s/#.*$//g;
35         if (/^\s*(\S+):\s*(.*)/) {
36                 local $sw = { 'service' => $1,
37                               'order' => $2 };
38                 push(@rv, $sw);
39                 }
40         }
41 close(SWITCH);
42 return @rv;
43 }
44
45 # save_nsswitch(service, order)
46 # Updates the line for some service in nsswitch.conf
47 sub save_nsswitch
48 {
49 local $lref = &read_file_lines($config{'nsswitch_conf'});
50 foreach $l (@$lref) {
51         if ($l =~ /^\s*(\S+):/ && $1 eq $_[0]) {
52                 $l = "$_[0]:\t$_[1]";
53                 last;
54                 }
55         }
56 }
57
58 # table_edit_setup(table, line, splitter)
59 # Returns &table, &lnums, line1, line2, ...
60 sub table_edit_setup
61 {
62 local @tables = &list_nis_tables();
63 local $t = $tables[$_[0]];
64 return ( $t ) if (!defined($_[1]));
65 local @lnums = ( $_[1] );
66 local $lref = &read_file_lines($t->{'files'}->[0]);
67 local @lines = ( [ split($_[2], $lref->[$_[1]]) ] );
68 local $i;
69 for($i=1; $t->{'files'}->[$i]; $i++) {
70         local $lref2 = &read_file_lines($t->{'files'}->[$i]);
71         local $lnum = 0;
72         foreach $l (@$lref2) {
73                 local @line2 = split($_[2], $l);
74                 if ($line2[0] eq $lines[0]->[0]) {
75                         push(@lnums, $lnum);
76                         push(@lines, \@line2);
77                         last;
78                         }
79                 $lnum++;
80                 }
81         }
82 return ($t, \@lnums, @lines);
83 }
84
85 # table_add(&table, separator, &record, ...)
86 # Adds a record to an NIS table
87 sub table_add
88 {
89 local $i = 2;
90 foreach $f (@{$_[0]->{'files'}}) {
91         local $lref = &read_file_lines($f);
92         push(@$lref, join($_[1], @{$_[$i++]}));
93         }
94 &flush_file_lines();
95 }
96
97 # table_delete(&table, &lnums)
98 # Delete a record from an NIS table
99 sub table_delete
100 {
101 local $i = 0;
102 foreach $f (@{$_[0]->{'files'}}) {
103         local $lref = &read_file_lines($f);
104         splice(@$lref, $_[1]->[$i], 1);
105         $i++;
106         }
107 &flush_file_lines();
108 }
109
110 # table_update(&table, &lnums, separator, &record, ...)
111 # Modify a record in an NIS table
112 sub table_update
113 {
114 local $i = 0;
115 foreach $f (@{$_[0]->{'files'}}) {
116         local $lref = &read_file_lines($f);
117         splice(@$lref, $_[1]->[$i], 1, join($_[2], @{$_[$i+3]}));
118         $i++;
119         }
120 &flush_file_lines();
121 }
122
123 # date_input(day, month, year, prefix)
124 sub date_input
125 {
126 print "<input name=$_[3]d size=3 value='$_[0]'>";
127 print "/<select name=$_[3]m>\n";
128 local $m;
129 foreach $m (1..12) {
130         printf "<option value=%d %s>%s\n",
131                 $m, $_[1] eq $m ? 'selected' : '', $text{"smonth_$m"};
132         }
133 print "</select>";
134 print "/<input name=$_[3]y size=5 value='$_[2]'>";
135 print &date_chooser_button("$_[3]d", "$_[3]m", "$_[3]y");
136 }
137
138 # parse_ypserv_conf()
139 # Returns &opts, &maps
140 sub parse_ypserv_conf
141 {
142 local (%opts, @hosts);
143 local $lnum = 0;
144 open(CONF, $ypserv_conf);
145 while(<CONF>) {
146         s/\r|\n//g;
147         s/#.*$//;
148         if (/^\s*([^:\s]+):\s*(yes|no)/) {
149                 # Found an option
150                 $opts{$1} = { 'name' => $1,
151                               'value' => $2 eq 'yes' ? 1 : 0,
152                               'line' => $lnum };
153                 }
154         elsif (/^\s*([^:\s]+)\s*:\s*([^:\s]+)\s*:\s*([^:\s]+)\s*:\s*(none|port|mangle|deny)(\/mangle(:(\d+))?)?/) {
155                 # Found a host and domain line (new format)
156                 push(@hosts, { 'host' => $1,
157                                'domain' => $2,
158                                'map' => $3,
159                                'sec' => $4,
160                                'mangle' => $5 ? 1 : 0,
161                                'field' => $7,
162                                'line' => $lnum } );
163                 }
164         elsif (/^\s*([^:\s]+)\s*:\s*([^:\s]+)\s*:\s*([^:\s]+)(\s*:\s*([^:\s]+))?(\s*:\s*([^:\s]+))?/) {
165                 # Found a host line (old format)
166                 push(@hosts, { 'host' => $1,
167                                'map' => $2,
168                                'sec' => $3,
169                                'mangle' => $5 eq 'yes' ? 1 : 0,
170                                'field' => $7 eq '' ? 2 : $7,
171                                'line' => $lnum } );
172                 }
173         $lnum++;
174         }
175 close(CONF);
176 return (\%opts, \@hosts);
177 }
178
179 # parse_yp_makefile()
180 # Returns hashes of makefile variables and rules
181 sub parse_yp_makefile
182 {
183 # First parse joined lines
184 local $lnum = 0;
185 local (@lines, $llast);
186 open(MAKE, $yp_makefile);
187 while(<MAKE>) {
188         s/\r|\n//g;
189         local $slash = (s/\\$//);
190         s/#.*$//;
191         if ($llast) {
192                 $llast->{'value'} .= " $_";
193                 $llast->{'eline'} = $lnum;
194                 }
195         else {
196                 push(@lines, { 'value' => $_,
197                                'line' => $lnum,
198                                'eline' => $lnum });
199                 }
200         $llast = $slash ? $lines[$#lines] : undef;
201         $lnum++;
202         }
203 close(MAKE);
204
205 # Then look for variables and rules
206 local ($i, %var, %rule);
207 for($i=0; $i<@lines; $i++) {
208         if ($lines[$i]->{'value'} =~ /^\s*(\S+)\s*=\s*(.*)/) {
209                 # Found a variable
210                 $var{$1} = { 'name' => $1,
211                              'value' => $2,
212                              'type' => 0,
213                              'line' => $lines[$i]->{'line'},
214                              'eline' => $lines[$i]->{'eline'} };
215                 }
216         elsif ($lines[$i]->{'value'} =~ /^\s*(\S+)\s*\+=\s*(.*)/) {
217                 # Adding to a variable
218                 if ($var{$1}) {
219                         $var{$1}->{'value'} .= ' '.$2;
220                         }
221                 }
222         elsif ($lines[$i]->{'value'} =~ /^\s*(\S+):\s*(.*)/) {
223                 # Found a makefile rule
224                 $rule{$1} = { 'name' => $1,
225                               'value' => $2,
226                               'type' => 1,
227                               'line' => $lines[$i]->{'line'},
228                               'eline' => $lines[$i]->{'eline'} };
229                 if ($lines[$i+1]->{'value'} =~ /^\s+/) {
230                         $rule{$1}->{'code'} = $lines[$i+1]->{'value'};
231                         $rule{$1}->{'eline'} = $lines[$i+1]->{'eline'};
232                         $i++;
233                         }
234                 }
235         }
236 return ( \%var, \%rule );
237 }
238
239 # expand_vars(string, &vars)
240 sub expand_vars
241 {
242 local $rv = $_[0];
243 while($rv =~ /^(.*)\$\(([A-Za-z0-9_]+)\)(.*)$/) {
244 #       if (substr($_[1]->{$2}->{'value'}, 0, 7) eq '$(shell') {
245 #               $rv = $1."\0(".$2.")".$3;
246 #               }
247 #       else {
248                 $rv = $1.$_[1]->{$2}->{'value'}.$3;
249 #               }
250         }
251 #$rv =~ s/\0/\$/g;
252 return $rv;
253 }
254
255 # update_makefile(&old, value, [value]);
256 sub update_makefile
257 {
258 local $lref = &read_file_lines($yp_makefile);
259 local @n;
260 if ($_[0]->{'type'} == 0) {
261         @n = ( "$_[0]->{'name'} = $_[1]" );
262         }
263 else {
264         @n = ( "$_[0]->{'name'}: $_[1]", $_[2] );
265         }
266 splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1, @n);
267 }
268
269 1;
270