]> git.pld-linux.org Git - projects/distfiles.git/blob - specparser.pl
- NoSource protection
[projects/distfiles.git] / specparser.pl
1 #!/usr/bin/perl
2 #
3 # USAGE: specparser.pl file.spec
4 #
5 # Output:
6 #   stdout:
7 #     list of:
8 #       <md5><space><url>\n
9 #     for given specfile.
10 #     except for lines prefixed with: ERROR:
11 #   exit status:
12 #     0 - normal
13 #     2 - cannot open spec file
14 #
15
16 sub next_spec($)
17 {
18   $spec = shift;
19   %macro = ();
20   $err_cnt = 0;
21 }
22
23 sub error($)
24 {
25   $err_cnt++;
26   print "ERROR: $spec: $_[0]\n";
27 }
28
29 sub warning($)
30 {
31   print "ERROR: $spec: $_[0]\n";
32 }
33
34 sub trim_spaces($)
35 {
36   my $v = shift;
37   
38   $v =~ s/\s+$//;
39   $v =~ s/^\s+//;
40   
41   return $v;
42 }
43
44 # expand macros in string
45 sub expand($)
46 {
47   my $v = trim_spaces(shift);
48   my $cnt = 20;
49
50   while ($v =~ /\%\{([^\{]+)\}/) {
51     my $value;
52     if (defined $macro{$1}) {
53       $value = $macro{$1};
54     } else {
55       error("undefined macro $1");
56       $value = "UNDEFINED";
57     }
58     $v =~ s/\%\{([^\{]+)\}/$value/;
59
60     return $v if (length $v > 1000 or $cnt-- <= 0)
61   }
62
63   while ($v =~ s/\%\(\s*echo\s+([^\|]+?)\s*\|\s*tr\s*(-d|)\s+([^\)]+?)\s*\)/\@\@tr-me\@\@/) {
64     my ($what, $d_opt, $how) = ($1, $2, $3);
65     my ($from, $to) = ($how, "");
66     ($from, $to) = ($1, $2) 
67       if $how =~ /^([^\s]+)\s+([^\s]+)$/;
68     if ($d_opt and $to ne "") {
69       error("tr -d with second string)");
70     } elsif (($from . $to) =~ /^[a-zA-Z0-9\+_\-\.]+$/) {
71       if ($d_opt) {
72         eval "\$what =~ tr/$from//d;";
73       } else {
74         eval "\$what =~ tr/$from/$to/;";
75       }
76     } else {
77       error("illegal characters in tr string(s) '$from' '$to'");
78     }
79     $v =~ s/\@\@tr-me\@\@/$what/;
80     
81     return $v if (length $v > 1000 or $cnt-- <= 0)
82   }
83
84   error("unexpanded macros in $v")
85     if ($v =~ /\%[^0-9]/);
86   
87   return $v;
88 }
89
90 # define given macro
91 sub define($$)
92 {
93   my ($n, $v) = @_;
94   $macro{$n} = trim_spaces($v);
95 }
96
97 # sets hash of macros defined with %define or %global
98 # also define %{name}, %{version} and %{source_N}
99 sub parse_defines($)
100 {
101   open(F, "< $_[0]") or die;
102   while (<F>) {
103     chomp;
104     if (/^\s*\%(define|global)\s+([^\s]+)\s+([^\s].*)$/) {
105      define($2, $3);
106     } elsif (/^Version\s*:\s*(.*)/i) {
107       define("version", $1);
108     } elsif (/^Name\s*:\s*(.*)/i) {
109       define("name", $1);
110     } elsif (/^Source(\d+)\s*:\s*(.*)/i) {
111       define("source_$1", expand($2));
112     } elsif (/^Patch(\d+)\s*:\s*(.*)/i) {
113       define("patch_$1", expand($2));
114     }
115   }
116   close(F);
117 }
118
119 sub print_md5($)
120 {
121   open(F, "< $_[0]") or die;
122   while (<F>) {
123     chomp;
124     if (/^\s*#\s*source(\d+)-md5\s*:\s*([a-f0-9]{32})/i) {
125       my $no = $1;
126       my $md5 = $2;
127       if (defined $macro{"source_$1"}) {
128         my $s = $macro{"source_$1"};
129         if ($s =~ /^([a-z0-9A-Z:\=\?\@\+\~\.\-\/_]|\%[0-9])+$/) {
130           if ($s =~ /^(ftp|http):\/\//) {
131             if ($s =~ /\/$/) {
132               error("source $no ($s) is directory");
133             } else {
134               if ($s =~ /:\/\/distfiles\.pld-linux\.org\/src/) {
135                 $s =~ s|.*/||;
136                 print "$md5 no-url-copy://$s\n";
137               } else {
138                 print "$md5 $s\n";
139               }
140             }
141           } else {
142             $s =~ s|.*/||;
143             print "$md5 no-url://$s\n";
144           }
145         } else {
146           error("source $no url $s is ill-formatted");
147         }
148       } else {
149         error("source $no not defined");
150       }
151     }
152   }
153   close(F);
154 }
155
156 next_spec(shift);
157 parse_defines($spec);
158 print_md5($spec);
159
160 exit(0);
This page took 0.039766 seconds and 3 git commands to generate.