1# edit-tree-randomly:
2#
3################################################################
4# Copyright (C) 2003 Robert Anderson and Tom Lord
5#
6# See the file "COPYING" for further information about
7# the copyright and warranty status of this work.
8#
9
10limit_size=yes
11
12# ADD="$TLA add"
13# DEL="$TLA delete"
14# MV="$TLA move"
15
16max_files=15
17max_dirs=10
18max_symlinks=8
19num_edits_bound=100
20
21echo '################################'
22echo '#'
23echo '# baseline configuration'
24echo '#'
25echo '################################'
26
27
28file_add_chances=72
29file_delete_chances=36
30file_rename_chances=72
31
32dir_add_chances=72
33dir_delete_chances=24
34dir_rename_chances=144
35
36symlink_add_chances=72
37symlink_delete_chances=36
38symlink_rename_chances=72
39
40file_patch_chances=72
41symlink_retarget_chances=72
42chmod_chances=0
43
44move_file_to_symlink_chances=72
45move_symlink_to_file_chances=72
46
47
48# echo '################################'
49# echo '#'
50# echo '# tree-delta configuration'
51# echo '#'
52# echo '################################'
53#
54#
55# file_add_chances=72
56# file_delete_chances=12
57# file_rename_chances=72
58#
59# dir_add_chances=72
60# dir_delete_chances=12
61# dir_rename_chances=144
62#
63# symlink_add_chances=72
64# symlink_delete_chances=12
65# symlink_rename_chances=72
66#
67# file_patch_chances=72
68# symlink_retarget_chances=72
69# chmod_chances=0
70#
71# move_file_to_symlink_chances=72
72# move_symlink_to_file_chances=72
73
74
75
76
77random_range=$((  $file_add_chances \
78                + $file_delete_chances \
79                + $file_rename_chances \
80                \
81                + $dir_add_chances \
82                + $dir_delete_chances \
83                + $dir_rename_chances \
84                \
85                + $symlink_add_chances \
86                + $symlink_delete_chances \
87                + $symlink_rename_chances \
88                \
89                + $file_patch_chances \
90                + $symlink_retarget_chances \
91                + $chmod_chances \
92                \
93                + $move_file_to_symlink_chances \
94                + $move_symlink_to_file_chances ))
95
96random_name ()
97{
98    echo "${RANDOM}${RANDOM}x" | sed -e 's/01/\*/g' -e 's/02/\?/g'\
99    	-e 's/03/\+/g' -e 's/04/\[/g' -e 's/05/\]/g' -e "s/06/\"/g"\
100    	-e 's/07/	/g' -e 's/08/\\/g' -e 's/0/ /g'
101}
102
103file_add ()
104{
105  echo -n "file add: "
106
107  n_files=$(count file)
108  if [ ! -z $limit_size -a "(" $n_files -gt $max_files ")" ] ; then
109    echo "too many files already"
110    continue
111  else
112    newparent="$(choose dir)"
113    newfile="$newparent/file$(random_name)"
114    check_exists file "$newfile"
115
116    echo $RANDOM > "$newfile"
117
118    # 1 in 2 files are binary, in the GNU diff sense of the word
119    #
120    type=$(random_upto 2)
121    if [ $type -eq 1 ]; then
122      echo -e "$RANDOM\000" > "$newfile"
123      echo -n "(binary)"
124    fi
125
126    $ADD "$newfile"
127    echo "($newfile)"
128  fi
129}
130
131
132dir_add ()
133{
134  echo -n "dir add: "
135
136  n_dirs=$(count dir)
137
138  if [ ! -z $limit_size -a "(" $n_dirs -gt $max_dirs ")" ] ; then
139    echo "too many dirs already"
140    continue
141  else
142    parent="$(choose dir)"
143    newdir="dir$(random_name)"
144    check_exists dir "$newdir"
145
146    mkdir "$parent/$newdir"
147    if [ $? -ne 0 ]; then exit 0; fi # might not have permission
148    $ADD "$parent/$newdir"
149    echo "($parent/$newdir)"
150  fi
151}
152
153symlink_add ()
154{
155  echo -n "symlink add: "
156
157  n_symlinks=$(count link)
158
159  if [ ! -z $limit_size -a "(" $n_symlinks -gt $max_symlinks ")" ] ; then
160    echo "too many symlinks already"
161    continue
162  else
163
164    parent="$(choose dir)"
165    newlink="$parent/link$(random_name)"
166    check_exists link "$newlink"
167
168    ntarget_objs=4
169    target_type=$(random_upto $ntarget_objs)
170    case $target_type in
171      1)
172        target="target$(random_name)"
173        ;;
174      2)
175        abort_if_none file
176        target="$(choose file)"
177        ;;
178      3)
179        target="$(choose dir)"
180        ;;
181      4)
182        abort_if_none link
183        target="$(choose link)"
184        ;;
185    esac
186
187    ln -s "$target" "$newlink"
188    $ADD "$newlink"
189    echo "$newlink -> $target"
190  fi
191}
192
193file_delete ()
194{
195  abort_if_none file
196
197  echo -n "file delete: "
198  delfile="$(choose file)"
199  $DEL "$delfile"
200  rm -f "$delfile"
201  echo "($delfile)"
202}
203
204dir_delete ()
205{
206  echo -n "dir delete: "
207  deldir="$(choose dir)"
208  if [ "$deldir" == "." ]; then
209    echo "(skipping - can't delete .)"
210    continue
211  fi
212  rm -rf "$deldir"
213
214  echo "($deldir)"
215}
216
217symlink_delete ()
218{
219  abort_if_none link
220
221  echo -n "delete symlink: "
222  dellink="$(choose link)"
223  echo -n "($dellink)"
224  $DEL "$dellink"
225  rm -f "$dellink"
226  echo
227}
228
229file_patch ()
230{
231  abort_if_none file
232
233  echo -n "file patch: "
234  filename="$(choose file)"
235  set +e
236  echo "$RANDOM" > "$filename"
237  set -e
238  echo "($filename)"
239}
240
241file_rename ()
242{
243  abort_if_none file
244
245  echo -n "file rename: "
246  oldname="$(choose file)"
247  newparent="$(choose dir)"
248  newname="$newparent/file$(random_name)"
249  check_exists file "$newname"
250
251  $MV "$oldname" "$newname"
252  mv "$oldname" "$newname"
253  echo "($oldname -> $newname)"
254}
255
256move_file_to_symlink ()
257{
258  abort_if_none file
259
260  echo -n "move file to symlink: "
261
262  delfile="$(choose file)"
263  rm -f "$delfile"
264
265  # add symlink
266  parent="$(choose dir)"
267  newlink="$parent/link$(random_name)"
268  target="target$(random_name)"
269  ln -s "$target" "$newlink"
270
271  $MV "$delfile" "$newlink"
272
273  echo "($delfile -> $newlink)"
274}
275
276move_symlink_to_file ()
277{
278  abort_if_none link
279
280  echo -n "move symlink to file: "
281
282  newparent="$(choose dir)"
283  newfile="$newparent/file$(random_name)"
284  check_exists file "$newfile"
285
286  dellink="$(choose link)"
287  rm -f "$dellink"
288
289  echo $RANDOM > "$newfile"
290
291  # 1 in 2 files are binary
292  type=$(random_upto 2)
293  if [ $type -eq 1 ]; then
294    echo -e "$RANDOM\000" > "$newfile"
295    echo -n "(binary)"
296  fi
297
298  $MV "$dellink" "$newfile"
299
300  echo "($delfile -> $newlink)"
301}
302
303symlink_rename ()
304{
305  abort_if_none link
306
307  echo -n "link rename: "
308  oldname="$(choose link)"
309  newparent="$(choose dir)"
310  newname="$newparent/link$(random_name)"
311  check_exists link "$newname"
312
313  mv "$oldname" "$newname"
314  $MV "$oldname" "$newname"
315  echo "($oldname -> $newname)"
316}
317
318dir_rename ()
319{
320  # Can't move .
321  oldname="$(choose dir)"
322  if [ "$oldname" == "." ]; then continue; fi
323
324  echo -n "dir rename: "
325
326  newparent="$(choose dir)"
327  newname="$newparent/dir$(random_name)"
328  check_exists dir "$newname"
329
330  # This can fail if the new dir is a subdir of itself
331  set +e
332  mv "$oldname" "$newname" 2> /dev/null
333  if [ $? -ne 0 ]; then
334    echo "(randomly generated dir rename is illegal ... skipping)"
335    continue;
336  fi
337  set -e
338
339  echo "($oldname -> $newname)"
340}
341
342symlink_retarget ()
343{
344  abort_if_none link
345
346  echo -n "link retarget: "
347  oldlink="$(choose link)"
348  target="target$(random_name)"
349  rm -f "$oldlink"
350  ln -s "$target" "$oldlink"
351  echo "($oldlink -> $target)"
352}
353
354# count a particular type of file
355#
356count ()
357{
358  obj=$1
359  case $obj in
360
361    file)
362      findtype=f
363      ;;
364    link)
365      findtype=l
366      ;;
367    dir)
368      findtype=d
369      ;;
370  esac
371
372  rm -rf ,,list
373  find . \
374    -name "{arch}" -prune -o \
375    -name ".arch-ids" -prune -o \
376    -name ",,*" -prune -o \
377    -name "++*" -prune -o \
378    -type $findtype -print >> ,,list
379
380  n=$(wc -l ,,list | awk '{print $1}')
381
382  echo -n "$n"
383}
384
385
386# Get a random item from the file, dir, or link lists
387#
388choose ()
389{
390  obj=$1
391  case $obj in
392
393    file)
394      findtype=f
395      ;;
396    link)
397      findtype=l
398      ;;
399    dir)
400      findtype=d
401      ;;
402  esac
403
404  rm -rf ,,list
405  find . \
406    -name "{arch}" -prune -o \
407    -name ".arch-ids" -prune -o \
408    -name ",,*" -prune -o \
409    -name "++*" -prune -o \
410    -type $findtype -print >> ,,list
411
412  n=$(wc -l ,,list | awk '{print $1}')
413
414  num=$(random_upto $n)
415
416  name="$(head -n $num ,,list | tail -n 1)"
417
418  echo -n "$name"
419}
420
421abort_if_none ()
422{
423  obj=$1
424  case $obj in
425
426    file)
427      findtype=f
428      ;;
429    link)
430      findtype=l
431      ;;
432    dir)
433      findtype=d
434      ;;
435  esac
436
437  rm -rf ,,list
438  find . \
439    -name "{arch}" -prune -o \
440    -name ".arch-ids" -prune -o \
441    -name ",,*" -prune -o \
442    -name "++*" -prune -o \
443    -type $findtype -print >> ,,list
444
445  num=$(wc -l ,,list | awk '{print $1}')
446  if [ $num -eq 0 ]; then continue; fi
447}
448
449check_exists ()
450{
451  obj="$1"
452  name="$2"
453  case $obj in
454
455    file)
456      findtype=-f
457      ;;
458    link)
459      findtype=-h
460      ;;
461    dir)
462      findtype=-d
463      ;;
464  esac
465
466  if [ $findtype "$name" ]; then
467    echo "(skipping: $name already exists)"
468    continue
469  fi
470}
471
472random_upto ()
473{
474  range=$1
475  num=$(( $RANDOM % $range + 1 ))
476  echo -n "$num"
477}
478
479edit_tree_randomly ()
480{
481
482  edit_num=1
483  num_edits=$(random_upto $num_edits_bound)
484
485  while [ $edit_num -lt $num_edits ]; do
486
487    edit_kind=$(random_upto $random_range)
488
489    if [ $edit_kind -le $file_add_chances ] ; then
490      file_add
491      edit_num=$(( $edit_num + 1))
492      continue
493    else
494      edit_kind=$(( $edit_kind - $file_add_chances ))
495    fi
496
497    if [ $edit_kind -le $file_delete_chances ] ; then
498      file_delete
499      edit_num=$(( $edit_num + 1))
500      continue
501    else
502      edit_kind=$(( $edit_kind - $file_delete_chances ))
503    fi
504
505    if [ $edit_kind -le $file_rename_chances ] ; then
506      file_rename
507      edit_num=$(( $edit_num + 1))
508      continue
509    else
510      edit_kind=$(( $edit_kind - $file_rename_chances ))
511    fi
512
513
514    if [ $edit_kind -le $dir_add_chances ] ; then
515      dir_add
516      edit_num=$(( $edit_num + 1))
517      continue
518    else
519      edit_kind=$(( $edit_kind - $dir_add_chances ))
520    fi
521
522    if [ $edit_kind -le $dir_delete_chances ] ; then
523      dir_delete
524      edit_num=$(( $edit_num + 1))
525      continue
526    else
527      edit_kind=$(( $edit_kind - $dir_delete_chances ))
528    fi
529
530    if [ $edit_kind -le $dir_rename_chances ] ; then
531      dir_rename
532      edit_num=$(( $edit_num + 1))
533      continue
534    else
535      edit_kind=$(( $edit_kind - $dir_rename_chances ))
536    fi
537
538
539
540    if [ $edit_kind -le $symlink_add_chances ] ; then
541      symlink_add
542      edit_num=$(( $edit_num + 1))
543      continue
544    else
545      edit_kind=$(( $edit_kind - $symlink_add_chances ))
546    fi
547
548    if [ $edit_kind -le $symlink_delete_chances ] ; then
549      symlink_delete
550      edit_num=$(( $edit_num + 1))
551      continue
552    else
553      edit_kind=$(( $edit_kind - $symlink_delete_chances ))
554    fi
555
556    if [ $edit_kind -le $symlink_rename_chances ] ; then
557      symlink_rename
558      edit_num=$(( $edit_num + 1))
559      continue
560    else
561      edit_kind=$(( $edit_kind - $symlink_rename_chances ))
562    fi
563
564
565    if [ $edit_kind -le $file_patch_chances ] ; then
566      file_patch
567      edit_num=$(( $edit_num + 1))
568      continue
569    else
570      edit_kind=$(( $edit_kind - $file_patch_chances ))
571    fi
572
573    if [ $edit_kind -le $symlink_retarget_chances ] ; then
574      symlink_retarget
575      edit_num=$(( $edit_num + 1))
576      continue
577    else
578      edit_kind=$(( $edit_kind - $symlink_retarget_chances ))
579    fi
580
581    if [ $edit_kind -le $chmod_chances ] ; then
582      chmod
583      edit_num=$(( $edit_num + 1))
584      continue
585    else
586      edit_kind=$(( $edit_kind - $chmod_chances ))
587    fi
588
589
590    if [ $edit_kind -le $move_file_to_symlink_chances ] ; then
591      move_file_to_symlink
592      edit_num=$(( $edit_num + 1))
593      continue
594    else
595      edit_kind=$(( $edit_kind - $move_file_to_symlink_chances ))
596    fi
597
598    if [ $edit_kind -le $move_symlink_to_file_chances ] ; then
599      move_symlink_to_file
600      edit_num=$(( $edit_num + 1))
601      continue
602    else
603      edit_kind=$(( $edit_kind - $move_symlink_to_file_chances ))
604    fi
605
606  done
607  echo "done editing."
608}
609
610###  Local Variables:
611###  mode: shell-script
612###  End:
613
614# tag: Robert Anderson, Christian Thaeter Sat Feb  7 08:50:42 CET 2004 (edit-tree-randomly-with-spaces)
615
616