Git init
[framework/connectivity/netbase.git] / DebianNet.pm
1 # DebianNet.pm: a perl module to add entries to the /etc/inetd.conf file
2 #
3 # Copyright (C) 1995, 1996 Peter Tobias <tobias@et-inf.fho-emden.de>
4 #                          Ian Jackson <iwj10@cus.cam.ac.uk>
5 #
6 #
7 # DebianNet::add_service($newentry, $group);
8 # DebianNet::disable_service($service, $pattern);
9 # DebianNet::enable_service($service, $pattern);
10 # DebianNet::remove_service($entry);
11 #
12
13 package DebianNet;
14
15 require 5.000;
16
17 $inetdcf="/etc/inetd.conf";
18 $sep = "#<off># ";
19 $version = "1.11";
20
21 sub add_service {
22     local($newentry, $group) = @_;
23     local($service, $searchentry, @inetd, $inetdconf, $found, $success);
24     unless (defined($newentry)) { return(-1) };
25     chomp($newentry); chomp($group);
26     $group = "OTHER" unless (defined($group));
27     $group =~ tr/a-z/A-Z/;
28     $newentry =~ s/\\t/\t/g;
29     ($service = $newentry) =~ s/(\W*\w+)\s+.*/$1/;
30     ($sservice = $service) =~ s/^#([A-Za-z].*)/$1/;
31     ($searchentry = $newentry) =~ s/^$sep//;
32     $searchentry =~ s/^#([A-Za-z].*)/$1/;
33
34     # strip parameter from entry (e.g. -s /tftpboot)
35     # example:          service dgram udp     wait    root    /tcpd /prg   -s /tftpboot";
36     $searchentry =~ s/^(\w\S+\W+\w+\W+\w\S+\W+\w\S+\W+\w\S+\W+\S+\W+\S+).*/$1/;
37     $searchentry =~ s/[ \t]+/ /g;
38     $searchentry =~ s/ /\\s+/g;
39     $searchentry =~ s@\\s\+/\S+\\s\+/\S+@\\s\+\\S\+\\s\+\\S\+@g;
40
41     if (open(INETDCONF,"$inetdcf")) {
42         @inetd=<INETDCONF>;
43         close(INETDCONF);
44         if (grep(m/^$sep$sservice\s+/,@inetd)) {
45             &enable_service($sservice);
46         } else {
47             if (grep(m/^$sservice\s+/,@inetd)) {
48                 if (grep(m/^$sservice\s+/,@inetd) > 1) {
49                     &inetde("There are several entries for $sservice in $inetdcf\n");
50                 } elsif (!grep(m:^#?.*$searchentry.*:, @inetd)) {
51                     print"\nTrying to add the following entry:\n\n $newentry\n\n";
52                     &inetde("There is already an entry for $sservice in $inetdcf,
53 but I don't recognise it.  Here is what it looks like:\n
54  ".join(' ',grep(m/^$sservice\s+/,@inetd)));
55                 }
56             } elsif (grep(m/^#\s*$sservice\s+/, @inetd) >= 1 or
57               (($service =~ s/^#//) and grep(m/^$service\s+/, @inetd)>=1)) {
58                 &printv("Processing service \`$service' ... not changed\n");
59             } else {
60                 &printv("Processing service \`$sservice' ... added\n");
61                 $inetdconf=1;
62             }
63         }
64         if ($inetdconf) {
65             open(ICWRITE, ">$inetdcf.new") || die "Error creating new $inetdcf: $!\n";
66             open(ICREAD, "$inetdcf");
67             while(<ICREAD>) {
68                 chomp;
69                 if (/^#:$group:/) {
70                     $found = 1;
71                 };
72                 if ($found and !(/[a-zA-Z#]/)) {
73                     print (ICWRITE "$newentry\n") || die "Error writing new $inetdcf: $!\n";
74                     $found = 0;
75                     $success = 1;
76                 }
77                 print ICWRITE "$_\n";
78             }
79             close(ICREAD);
80             unless ($success) {
81                 print (ICWRITE "$newentry\n") || die "Error writing new $inetdcf: $!\n";
82             }
83             close(ICWRITE) || die "Error closing new inetd.conf: $!\n";
84
85             rename("$inetdcf.new","$inetdcf") ||
86                 die "Error installing new $inetdcf: $!\n";
87             chmod(0644, "$inetdcf");
88
89             &wakeup_inetd;
90         }
91     }
92
93     sub inetde {
94         my($response);
95         do {
96             print @_,
97 "\nDo you want to ignore this potential problem and continue, or would
98 you rather not do so now ?  Continue?  (n/y) ";
99             $!=0; defined($response=<STDIN>) || die "netconfig: EOF/error on stdin: $!\n";
100         } while ($response !~ m/^\s*[yn]?\s*$/i);
101         return(1) if($response =~ m/y/i);
102         exit(1);
103     }
104     return(1);
105 }
106
107 sub remove_service {
108     my($service) = @_;
109     unless(defined($service)) { return(-1) };
110     chomp($service);
111     if($service eq "") {
112          print "DebianNet::remove_service called with empty argument\n";
113          return(-1);
114     }
115
116     if ((&scan_entries("$service") > 1) and (not defined($multi))) {
117         print "\nWARNING!!!!!! $inetdcf contains multiple entries for \n";
118         print "the \`$service' service. You're about to remove these entries.\n";
119         print "Do you want to continue? [n] ";
120         if (<STDIN> =~ /^[^y]/i) {
121             print "\nOk, I'll stop ...\n";
122             return(1);
123         } else {
124             if ($want_continue == 0) {
125                 print "\nOk, I'll continue ...\n";
126             }
127         }
128     }
129
130     open(ICWRITE, ">$inetdcf.new") || die "Error creating $inetdcf.new";
131     open(ICREAD, "$inetdcf");
132     RLOOP: while(<ICREAD>) {
133         chomp;
134         unless (/^$service\b/) {
135             print ICWRITE "$_\n";
136         } else {
137             &printv("Removing line: \`$_'\n");
138         }
139     }
140     close(ICREAD);
141     close(ICWRITE);
142
143     rename("$inetdcf.new", "$inetdcf") ||
144         die "Error installing new $inetdcf: $!\n";
145     chmod(0644, "$inetdcf");
146
147     &wakeup_inetd;
148     return(1);
149 }
150
151 sub disable_service {
152     my($service, $pattern) = @_;
153     unless (defined($service)) { return(-1) };
154     chomp($service);
155
156     if ((&scan_entries("$service", $pattern) > 1) and (not defined($multi))) {
157         print "\nWARNING!!!!!! $inetdcf contains multiple entries for \n";
158         print "the \`$service' service. You're about to disable these entries.\n";
159         print "Do you want to continue? [n] ";
160         if (<STDIN> =~ /^[^y]/i) {
161             print "\nOk, I'll stop ...\n";
162             return(1);
163         } else {
164             if ($want_continue == 0) {
165                 print "\nOk, I'll continue ...\n";
166             }
167         }
168     }
169
170     open(ICWRITE, ">$inetdcf.new") || die "Error creating new $inetdcf: $!\n";
171     open(ICREAD, "$inetdcf");
172     DLOOP: while(<ICREAD>) {
173       chomp;
174       if (/^$service\s+\w+\s+/ and /$pattern/) {
175           &printv("Processing service \`$service' ... disabled\n");
176           $_ =~ s/^(.+)$/$sep$1/;
177       }
178       print ICWRITE "$_\n";
179     }
180     close(ICREAD);
181     close(ICWRITE) || die "Error closing new inetd.conf: $!\n";
182
183     rename("$inetdcf.new","$inetdcf") ||
184         die "Error installing new $inetdcf: $!\n";
185     chmod(0644, "$inetdcf");
186
187     &wakeup_inetd;
188     return(1);
189 }
190
191 sub enable_service {
192     my($service, $pattern) = @_;
193     unless (defined($service)) { return(-1) };
194     chomp($service);
195     open(ICWRITE, ">$inetdcf.new") || die "Error creating new $inetdcf: $!\n";
196     open(ICREAD, "$inetdcf");
197     while(<ICREAD>) {
198       chomp;
199       if (/^$sep$service\s+\w+\s+/ and /$pattern/) {
200           &printv("Processing service \`$service' ... enabled\n");
201           $_ =~ s/^$sep//;
202       }
203       print ICWRITE "$_\n";
204     }
205     close(ICREAD);
206     close(ICWRITE) || die "Error closing new inetd.conf: $!\n";
207
208     rename("$inetdcf.new","$inetdcf") ||
209         die "Error installing new $inetdcf: $!\n";
210     chmod(0644, "$inetdcf");
211
212     &wakeup_inetd;
213     return(1);
214 }
215
216 sub wakeup_inetd {
217     my($pid);
218     if (open(P,"/var/run/inetd.pid")) {
219         $pid=<P>;
220         if (open(C,sprintf("/proc/%d/stat",$pid))) {
221             $_=<C>;
222             if (m/^\d+ \(inetd\)/) { kill(1,$pid); }
223             close(C);
224         }
225         close(P);
226     }
227     return(1);
228 }
229
230 sub scan_entries {
231     my ($service, $pattern) = @_;
232     my $counter = 0;
233
234     open(ICREAD, "$inetdcf");
235     SLOOP: while (<ICREAD>) {
236         $counter++ if (/^$service\b/ and /$pattern/);
237     }
238     close(ICREAD);
239     return($counter);
240 }
241
242 sub printv {
243     print @_ if (defined($verbose));
244 }
245
246 1;
247