Avoid creating // sequences in jailed_file return value
[girocco.git] / Girocco / Util.pm
blob7efbf87b821cea830732e222620c0c260f9c8aee
1 package Girocco::Util;
3 use strict;
4 use warnings;
6 use Girocco::Config;
8 BEGIN {
9 use base qw(Exporter);
10 our @EXPORT = qw(scrypt jailed_file
11 lock_file unlock_file
12 filedb_atomic_append filedb_atomic_edit
13 valid_email valid_email_multi
14 valid_repo_url valid_web_url);
18 sub scrypt {
19 my ($pwd) = @_;
20 crypt($pwd, join ('', ('.', '/', 2..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]));
23 sub jailed_file {
24 my ($filename) = @_;
25 $filename =~ s,^/,,;
26 $Girocco::Config::chroot."/$filename";
29 sub lock_file {
30 my ($path) = @_;
32 $path .= '.lock';
34 use Errno qw(EEXIST);
35 use Fcntl qw(O_WRONLY O_CREAT O_EXCL);
36 use IO::Handle;
37 my $handle = new IO::Handle;
39 unless (sysopen($handle, $path, O_WRONLY|O_CREAT|O_EXCL)) {
40 my $cnt = 0;
41 while (not sysopen($handle, $path, O_WRONLY|O_CREAT|O_EXCL)) {
42 ($! == EEXIST) or die "$path open failed: $!";
43 ($cnt++ < 16) or die "$path open failed: cannot open lockfile";
44 sleep(1);
47 # XXX: filedb-specific
48 chmod 0664, $path or die "$path g+w failed: $!";
50 $handle;
53 sub unlock_file {
54 my ($path) = @_;
56 rename "$path.lock", $path or die "$path unlock failed: $!";
59 sub filedb_atomic_append {
60 my ($file, $line) = @_;
61 my $id = 65536;
63 open my $src, $file or die "$file open for reading failed: $!";
64 my $dst = lock_file($file);
66 while (<$src>) {
67 my $aid = (split /:/)[2];
68 $id = $aid + 1 if ($aid >= $id);
70 print $dst $_ or die "$file(l) write failed: $!";
73 $line =~ s/\\i/$id/g;
74 print $dst "$line\n" or die "$file(l) write failed: $!";
76 close $dst or die "$file(l) close failed: $!";
77 close $src;
79 unlock_file($file);
81 $id;
84 sub filedb_atomic_edit {
85 my ($file, $fn) = @_;
87 open my $src, $file or die "$file open for reading failed: $!";
88 my $dst = lock_file($file);
90 while (<$src>) {
91 print $dst $fn->($_) or die "$file(l) write failed: $!";
94 close $dst or die "$file(l) close failed: $!";
95 close $src;
97 unlock_file($file);
100 sub valid_email {
101 $_ = $_[0];
102 /^[a-zA-Z0-9+._-]+@[a-zA-Z0-9-.]+$/;
104 sub valid_email_multi {
105 $_ = $_[0];
106 # More relaxed, we just want to avoid too dangerous characters.
107 /^[a-zA-Z0-9+._, @-]+$/;
109 sub valid_web_url {
110 $_ = $_[0];
111 /^https?:\/\/[a-zA-Z0-9-.:]+(\/[_\%a-zA-Z0-9.\/~:?&=;-]*)?(#[a-zA-Z0-9._-]+)?$/;
113 sub valid_repo_url {
114 $_ = $_[0];
115 /^(https?|git|svn(\+http)?|svn(\+https)?|darcs|bzr):\/\/[a-zA-Z0-9-.:]+(\/[_\%a-zA-Z0-9.\/~-]*)?$/;