10 ###############################################################################
14 ###############################################################################
26 my($mask_inc,$mask_php,$mask_img);
29 my($db_db,$db_host,$db_user,$db_pwd);
35 print $text if ($debug);
38 ###############################################################################
42 ###############################################################################
44 # worker function called by tagextract and tagstrip
46 my($tag1,$tag2,$intag,@lines) = @_;
47 my($line,$pos,@out,$add);
49 while ($line = shift(@lines)) {
51 # we are inside the block
52 if (($pos=index($line, $tag2)) > -1) {
53 $add = substr($line,0,$pos);
54 $line = substr($line,$pos+length($tag2));
62 push @out, "$add\n" if (length($add)>0);
66 # we are outside the block
67 while(($pos = index($line, $tag1)) > -1) {
68 $line = substr($line,$pos+length($tag1));
69 if (($pos=index($line, $tag2)) > -1) {
70 $add = substr($line,0,$pos);
71 $line = substr($line,$pos+length($tag2));
79 push @out, "$add\n" if (length($add)>0);
86 # return only blocks of @lines between tag1 and tag2
88 my($tag1,$tag2,@lines) = @_;
89 return &tagcrunch($tag1,$tag2,0,@lines);
92 # return @lines minus blocks between tag1 and tag2
94 my($tag1,$tag2,@lines) = @_;
95 return &tagcrunch($tag2,$tag1,1,@lines);
98 # for each line, remove whatever is after the comment marker
100 my($tag,@lines) = @_;
103 foreach my $line (@lines) {
106 push @out, "$line\n" if (length($line)>0);
112 ###############################################################################
116 ###############################################################################
119 $dsn = "DBI:mysql:database=$db_db;host=$db_host";
120 $dbh = DBI->connect($dsn,$db_user,$db_pwd);
123 # clear a database table
126 my $sth = $dbh->do("delete from $table");
129 # add a dependency into DB
131 my($pageid,$depid,$did,$type) = @_;
134 $sth = $dbh->prepare("select id from dep where page=$pageid and dep=$depid and dir=$did and type='$type'");
137 $dbh->do("insert into dep set page=$pageid,dep=$depid,dir=$did,type='$type'");
141 # put a directory into DB
145 &dprint("putdir($dir)\n");
146 my $did=&getdirid($dir);
148 $dbh->do("insert into dir set path='$dir'");
149 $did=&getdirid($dir);
156 my($file,$exists,$did) = @_;
159 $exists=0 if (!$exists);
160 &dprint("putfile($file,$exists,$did)\n");
162 $type = "page" if ($file =~ /$mask_php/);
163 $type = "include" if ($file =~ /$mask_inc/);
164 $type = "image" if ($file =~ /$mask_img/);
169 $fid=&getfileid($file);
171 $dbh->do("update file set type='$type' where id=$fid") if ($exists);
173 $dbh->do("insert into file set path='$file',type='$type'");
174 $fid=&getfileid($file);
176 $dbh->do("update file set dir='$did' where id=$fid") if ($did);
180 # return the ID corresponding to a directory name
185 $sth = $dbh->prepare("select id from dir where path='$dir'");
187 if (my $ref = $sth->fetchrow_hashref()) {
194 # return the ID corresponding to a file name
199 $sth = $dbh->prepare("select id from file where path='$file'");
201 if (my $ref = $sth->fetchrow_hashref()) {
209 ###############################################################################
213 ###############################################################################
215 # from a path in the server tree, return the path in the filesystem
219 return $rootdir.$vpath;
222 # given a working directory and a relative path, return full path
223 # ( in the server tree )
225 my($curdir,$relpath) = @_;
226 my(@path,@comps,$ret);
228 # current directory not absolute
229 if ($curdir !~ /^\//) {
230 print "abspath($curdir,$relpath) : $curdir is not an absolute path!\n";
234 # relpath is already absolute
235 return $relpath if ($relpath =~ /^\//);
237 # is there a final slash?
239 $finalslash="/" if ($relpath =~ /\/$/);
241 @path = split /\//,substr($curdir,1);
242 @comps = split /\//,$relpath;
243 foreach my $comp (@comps) {
245 if ($comp =~ /^\.$/) { last SWITCH; }
246 if ($comp =~ /^\.\.$/) { pop @path; last SWITCH; }
250 $ret = "/". join("/",@path) .$finalslash;
263 opendir(DIRHANDLE, &realpath($vdir));
264 my @list = grep /^[^\.]/, readdir(DIRHANDLE);
267 my @incfiles=grep /$mask_inc/,@list;
268 map (&putfile("${vdir}$_", 1, $did), @incfiles);
270 my @imgfiles=grep /$mask_img/,@list;
271 map (&putfile("${vdir}$_", 1, $did), @imgfiles);
273 my @phpfiles=grep /$mask_php/,@list;
274 foreach my $phpfile (@phpfiles) {
275 if (-f realpath("${vdir}${phpfile}")) {
276 $fid=&putfile("${vdir}${phpfile}", 1, $did);
277 &parsefile($fid, $did, "${vdir}${phpfile}", $vdir);
279 &putfile("${vdir}$phpfile", 0, $did)
283 foreach my $entry (@list) {
284 if ((-d realpath("${vdir}${entry}")) && ($entry !~ /^CVS$/)) {
285 &parsedir("${vdir}${entry}/");
292 my($fid,$did,$vfile,$vdir) = @_;
293 my(@lines,@phplines,@includes,$depid,$sth,$ifile,$iexists);
295 &dprint("parsefile($fid,$did,$vfile,$vdir)\n");
297 # we return if we already have dependecies in the same scope
298 $sth = $dbh->prepare("select id from dep where page=$fid and dir=$did");
300 return if (my $ref = $sth->fetchrow_hashref());
302 open(FHANDLE,realpath($vfile));
306 # strip out commented code
307 @lines = &tagstrip("<!--","-->",@lines);
309 # deal with PHP lines
310 @phplines = &tagextract("<?php","?>",@lines);
311 @phplines = &tagstrip("/*","*/",@phplines);
312 @phplines = &commentstrip("\/\/",@phplines);
313 @phplines = &commentstrip("#",@phplines);
314 @includes = grep s/.*(require|include)\s*\({0,1}\"(.*)\"\){0,1}.*\n$/$2/, @phplines;
315 foreach my $include (@includes) {
316 &dprint("REQ:$include\n");
317 if ($include =~ /$mask_php/) {
318 print "Warning : $include gets included by $vfile!\n";
321 if ($include =~ /^[\.\/]/) {
322 # the directory is specified
323 $ifile = &abspath($vdir,$include);
324 $iexists=1 if (-f &realpath($ifile));
326 # directory not specified, go through the include path
327 foreach my $incp (@incpath) {
328 $ifile = &abspath(&abspath($vdir,$incp),$include);
329 &dprint("trying $ifile\n");
330 if (-f &realpath($ifile)) {
335 # did not find file to be included, treat it as if it were
336 # in the first segment of include path
337 $ifile = &abspath(&abspath($vdir,$incpath[0]),$include) if (!$iexists);
339 $depid=&putfile($ifile,$iexists,0);
340 &putdep($fid,$depid,$did,"include");
341 &parsefile($depid,$did,$ifile,$vdir) if ($iexists);
346 ###############################################################################
348 # init and conf file #
350 ###############################################################################
354 $confile="$ENV{'HOME'}/.deptrackrc";
356 if ( not getopts('dhf:', \%opts) or $opts{'h'}) {
360 # check for root directory
367 print "root directory $rootdir not found!\n";
370 print "Using $rootdir as web root directory\n";
375 print "Running in debug mode ...\n";
382 if (-r "$opts{'f'}") {
383 print "Using $opts{'f'} as config file\n";
384 &read_conf("$opts{'f'}");
386 print "$opts{'f'} : not a valid config file\n";
390 print "Using $confile as config file\n";
392 &read_conf("$confile");
394 print "No valid configuration file found, aborting\n";
402 #Read Configuration and init global vars
404 my($default,$value) = @_;
405 if ($value) { return $value; }
406 else { return $default; }
411 $config = new Config::General( -file =>"$file",
412 -AllowMultiOptions =>"yes",
413 -LowerCaseNames =>"yes",);
414 %conf = $config->getall;
416 $db_db = &read_val("deptrack", $conf{'db_db'});
417 $db_host = &read_val("localhost", $conf{'db_host'});
418 $db_pwd = &read_val("", $conf{'db_pwd'});
419 $db_user = &read_val("deptrack", $conf{'db_user'});
421 @incpath = split /:/, &read_val(".", $conf{'include_path'});
422 $mask_img = &read_val("\\.(png|gif|jpg)\$", $conf{'mask_img'});
423 $mask_inc = &read_val("\\.inc(\\.php)?\$", $conf{'mask_inc'});
424 $mask_php = &read_val("(?<!\\.inc)\\.php\$", $conf{'mask_php'});
430 print "deptrack @VERSION@ Copyright (C) Jeremy Lainé and Pierre Habouzit\n\n",
431 " This program comes with ABSOLUTELY NO WARRANTY. This is free software,\n",
432 " you are welcome to distribute it under the terms of the GNU Public\n",
433 " License (GPL) version 2.\n\n";
436 # return program syntax
439 " deptrack [options] root_directory\n\n",
441 " -h - this help message\n",
442 " -f <file> - use <file> as config file\n",
443 " -d - debug mode\n";
448 ###############################################################################
452 ###############################################################################