File: find-fossil-cgis.tcl

package info (click to toggle)
fossil 1%3A2.26-2
  • links: PTS
  • area: main
  • in suites: sid, trixie
  • size: 28,572 kB
  • sloc: ansic: 332,171; tcl: 14,144; javascript: 10,171; sh: 6,791; makefile: 4,276; pascal: 1,139; cpp: 1,001; cs: 879; sql: 376; asm: 281; perl: 166; xml: 95
file content (141 lines) | stat: -rwxr-xr-x 3,810 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/tclsh
#
# This script scans a directory hierarchy looking for Fossil CGI files -
# the files that are used to launch Fossil as a CGI program.  For each
# such file found, in prints the name of the file and also the file
# content, indented, if the --print option is used.
#
#     tclsh find-fossil-cgis.tcl [OPTIONS] DIRECTORY
#
# The argument is the directory from which to begin the search.
#
# OPTIONS can be zero or more of the following:
#
#    --has REGEXP               Only show the CGI if the body matches REGEXP.
#                               May be repeated multiple times, in which case
#                               all must match.
#
#    --hasnot REGEXP            Only show the CGI if it does NOT match the
#                               REGEXP.
#
#    --print                    Show the content of the CGI, indented by
#                               three spaces
#
#    --symlink                  Process DIRECTORY arguments that are symlinks.
#                               Normally symlinks are silently ignored.
#
#    -v                         Show progress information for debugging
#
# EXAMPLE USE CASES:
#
# Find all CGIs that do not have the "errorlog:" property set
#
#    find-fossil-cgis.tcl *.website --has '\nrepository:' \
#           --hasnot '\nerrorlog:'
#
# Add the errorlog: property to any CGI that does not have it:
#
#    find-fossil-cgis.tcl *.website --has '\nrepository:' \
#           --hasnot '\nerrorlog:' | while read x
#    do
#      echo 'errorlog: /logs/errors.txt' >>$x
#    done
#
# Find and print all CGIs that do redirects
#
#    find-fossil-cgis.tcl *.website --has '\nredirect:' --print
#


# Find the CGIs in directory $dir.  Invoke recursively to
# scan subdirectories.
#
proc find_in_one_dir {dir} {
  global HAS HASNOT PRINT V
  if {$V>0} {
    puts "# $dir"
  }
  foreach obj [lsort [glob -nocomplain -directory $dir *]] {
    if {[file isdir $obj]} {
      find_in_one_dir $obj
      continue
    }
    if {![file isfile $obj]} continue
    if {[file size $obj]>5000} continue
    if {![file exec $obj]} continue
    if {![file readable $obj]} continue
    set fd [open $obj rb]
    set txt [read $fd]
    close $fd
    if {![string match #!* $txt]} continue
    if {![regexp {fossil} $txt]} continue
    if {![regexp {\nrepository: } $txt] &&
        ![regexp {\ndirectory: } $txt] &&
        ![regexp {\nredirect: } $txt]} continue
    set ok 1
    foreach re $HAS {
      if {![regexp $re $txt]} {set ok 0; break;}
    }
    if {!$ok} continue
    foreach re $HASNOT {
      if {[regexp $re $txt]} {set ok 0; break;}
    }
    if {!$ok} continue
    # 
    # At this point assume we have found a CGI file.
    #
    puts $obj
    if {$PRINT} {
      regsub -all {\n} [string trim $txt] "\n   " out
      puts "   $out"
    }
  }
}
set HAS [list]
set HASNOT [list]
set PRINT 0
set SYMLINK 0
set V 0
set N [llength $argv]
set DIRLIST [list]

# First pass:  Gather all the command-line arguments but do no
# processing.
#
for {set i 0} {$i<$N} {incr i} {
  set dir [lindex $argv $i]
  if {($dir eq "-has" || $dir eq "--has") && $i<[expr {$N-1}]} {
    incr i
    lappend HAS [lindex $argv $i]
    continue
  }
  if {($dir eq "-hasnot" || $dir eq "--hasnot") && $i<[expr {$N-1}]} {
    incr i
    lappend HASNOT [lindex $argv $i]
    continue
  }
  if {$dir eq "-print" || $dir eq "--print"} {
    set PRINT 1
    continue
  }
  if {$dir eq "-symlink" || $dir eq "--symlink"} {
    set SYMLINK 1
    continue
  }
  if {$dir eq "-v"} {
    set V 1
    continue
  }
  if {[file type $dir]=="directory"} {
    lappend DIRLIST $dir
  }
}

# Second pass: Process the non-option arguments.
#
foreach dir $DIRLIST {
  set type [file type $dir]
  if {$type eq "directory" || ($SYMLINK && $type eq "link")} {
    find_in_one_dir $dir
  }
}