Handle hostnames with upper-case letters
[webmin.git] / software / openbsd-lib.pl
1 # openbsd-lib.pl
2 # Functions for OpenBSD package management
3
4 use POSIX;
5 chop($system_arch = `uname -m`);
6 $package_dir = "/var/db/pkg";
7
8 sub list_package_system_commands
9 {
10 return ("pkg_info", "pkg_add");
11 }
12
13 # list_packages([package]*)
14 # Fills the array %packages with a list of all packages
15 sub list_packages
16 {
17 local $i = 0;
18 local $arg = @_ ? join(" ", map { quotemeta($_) } @_) : "-a";
19 %packages = ( );
20 &open_execute_command(PKGINFO, "pkg_info -I $arg", 1, 1);
21 while(<PKGINFO>) {
22         if (/^(\S+)\s+(.*)/) {
23                 $packages{$i,'name'} = $1;
24                 $packages{$i,'class'} = "";
25                 $packages{$i,'desc'} = $2;
26                 $i++;
27                 }
28         }
29 close(PKGINFO);
30 return $i;
31 }
32
33 # package_info(package)
34 # Returns an array of package information in the order
35 #  name, class, description, arch, version, vendor, installtime
36 sub package_info
37 {
38 local $qm = quotemeta($_[0]);
39 local $out = &backquote_command("pkg_info $_[0] 2>&1", 1);
40 return () if ($?);
41 local @rv = ( $_[0] );
42 push(@rv, "");
43 push(@rv, $out =~ /Description:\n([\0-\177]*\S)/i ? $1 : $text{'bsd_unknown'});
44 push(@rv, $system_arch);
45 push(@rv, $_[0] =~ /-([^\-]+)$/ ? $1 : $text{'bsd_unknown'});
46 push(@rv, "OpenBSD");
47 local @st = stat(&translate_filename("$package_dir/$_[0]"));
48 push(@rv, @st ? ctime($st[9]) : $text{'bsd_unknown'});
49 return @rv;
50 }
51
52 # check_files(package)
53 # Fills in the %files array with information about the files belonging
54 # to some package. Values in %files are  path type user group mode size error
55 sub check_files
56 {
57 local $i = 0;
58 local $file;
59 local $qm = quotemeta($_[0]);
60 &open_execute_command(PKGINFO, "pkg_info -L $qm", 1, 1);
61 while($file = <PKGINFO>) {
62         $file =~ s/\r|\n//g;
63         next if ($file !~ /^\//);
64         local $real = &translate_filename($file);
65         local @st = stat($real);
66         $files{$i,'path'} = $file;
67         $files{$i,'type'} = -l $real ? 3 :
68                             -d $real ? 1 : 0;
69         $files{$i,'user'} = getpwuid($st[4]);
70         $files{$i,'group'} = getgrgid($st[5]);
71         $files{$i,'mode'} = sprintf "%o", $st[2] & 07777;
72         $files{$i,'size'} = $st[7];
73         $files{$i,'link'} = readlink($real);
74         $i++;
75         }
76 return $i;
77 }
78
79 # installed_file(file)
80 # Given a filename, fills %file with details of the given file and returns 1.
81 # If the file is not known to the package system, returns 0
82 # Usable values in %file are  path type user group mode size packages
83 sub installed_file
84 {
85 local (%packages, $file, $i, @pkgin);
86 local $n = &list_packages();
87 for($i=0; $i<$n; $i++) {
88         &open_execute_command(PKGINFO, "pkg_info -L $packages{$i,'name'}", 1,1);
89         while($file = <PKGINFO>) {
90                 $file =~ s/\r|\n//g;
91                 if ($file eq $_[0]) {
92                         # found it
93                         push(@pkgin, $packages{$i,'name'});
94                         }
95                 }
96         close(PKGINFO);
97         }
98 if (@pkgin) {
99         local $real = &translate_filename($_[0]);
100         local @st = stat($real);
101         $file{'path'} = $_[0];
102         $file{'type'} = -l $real ? 3 :
103                         -d $real ? 1 : 0;
104         $file{'user'} = getpwuid($st[4]);
105         $file{'group'} = getgrgid($st[5]);
106         $file{'mode'} = sprintf "%o", $st[2] & 07777;
107         $file{'size'} = $st[7];
108         $file{'link'} = readlink($real);
109         $file{'packages'} = join(" ", @pkgin);
110         return 1;
111         }
112 else {
113         return 0;
114         }
115 }
116
117 # is_package(file)
118 sub is_package
119 {
120 local ($desc, $contents);
121 local $qm = quotemeta($_[0]);
122 &open_execute_command(TAR, "gunzip -c $qm | tar tf -", 1, 1);
123 while(<TAR>) {
124         $desc++ if (/^\+DESC/);
125         $contents++ if (/^\+CONTENTS/);
126         }
127 close(TAR);
128 return $desc && $contents;
129 }
130
131 # file_packages(file)
132 # Returns a list of all packages in the given file, in the form
133 #  package description
134 sub file_packages
135 {
136 local $temp = &transname();
137 &make_dir($temp, 0700);
138 local $qm = quotemeta($_[0]);
139 &execute_command("cd $temp && gunzip -c $qm | tar xf - +CONTENTS +COMMENT");
140 local ($comment, $name);
141 &open_readfile(COMMENT, "$temp/+COMMENT");
142 ($comment = <COMMENT>) =~ s/\r|\n//g;
143 close(COMMENT);
144 &open_readfile(CONTENTS, "$temp/+CONTENTS");
145 while(<CONTENTS>) {
146         $name = $1 if (/^\@name\s+(\S+)/);
147         }
148 close(CONTENTS);
149 &unlink_file($temp);
150 return ( "$name $comment" );
151 }
152
153 # install_options(file, package)
154 # Outputs HTML for choosing install options
155 sub install_options
156 {
157 print &ui_table_row($text{'bsd_scripts'},
158         &ui_radio("scripts", 0, [ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]));
159
160 print &ui_table_row($text{'bsd_force'},
161         &ui_yesno_radio("force", 1));
162 }
163
164 # install_package(file, package)
165 # Installs the package in the given file, with options from %in
166 sub install_package
167 {
168 local $in = $_[2] ? $_[2] : \%in;
169 local $args = ($in->{"scripts"} ? " -I" : "").
170               ($in->{"force"} ? " -f" : "");
171 local $out = &backquote_logged("pkg_add $args $_[0] 2>&1");
172 if ($?) {
173         return "<pre>$out</pre>";
174         }
175 return undef;
176 }
177
178 # delete_package(package)
179 # Totally remove some package
180 sub delete_package
181 {
182 local $out = &backquote_logged("pkg_delete $_[0] 2>&1");
183 if ($?) { return "<pre>$out</pre>"; }
184 return undef;
185 }
186
187 sub package_system
188 {
189 return &text('bsd_manager', "OpenBSD");
190 }
191
192 sub package_help
193 {
194 return "pkg_add pkg_info pkg_delete";
195 }
196
197 1;