1382 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			1382 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| ##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| # outils pour gérer des fichiers .ldif
 | |
| ##@cooked nocomments
 | |
| ##@require base
 | |
| ##@require awk
 | |
| uprovide ldif
 | |
| urequire base awk
 | |
| 
 | |
| function def_match_attr() {
 | |
|     local attr first script
 | |
|     script="function fix_attr(attr) {
 | |
|     gsub(/:+$/, \"\", attr)
 | |
|     return attr \":\"
 | |
| }
 | |
| function norm_attr(attr) {
 | |
|   return tolower(attr)
 | |
| }
 | |
| function match_attr(attr) {
 | |
| attr = tolower(attr)
 | |
| if ("
 | |
|     if [ -n "$*" ]; then
 | |
|         first=1
 | |
|         for attr in "$@"; do
 | |
|             attr="${attr%%:*}"
 | |
|             if [ -n "$first" ]; then
 | |
|                 first=
 | |
|             else
 | |
|                 script="$script || "
 | |
|             fi
 | |
|             script="${script}attr == tolower(\"$attr:\") || attr == tolower(\"$attr::\")"
 | |
|         done
 | |
|     else
 | |
|         script="${script}1"
 | |
|     fi
 | |
|     script="$script) return 1
 | |
| else return 0
 | |
| }"
 | |
|     echo "$script"
 | |
| }
 | |
| 
 | |
| function def_match_value() {
 | |
|     local pattern first script
 | |
|     script="function match_value(line) {
 | |
| sub(/^[^:]+::?[ ]+/, \"\", line)
 | |
| if ("
 | |
|     if [ -n "$*" ]; then
 | |
|         first=1
 | |
|         for pattern in "$@"; do
 | |
|             pattern="${pattern//\\\\/\\\\}"
 | |
|             if [ -n "$first" ]; then
 | |
|                 first=
 | |
|             else
 | |
|                 script="$script || "
 | |
|             fi
 | |
|             script="${script}line ~ /$pattern/"
 | |
|         done
 | |
|     else
 | |
|         script="${script}1"
 | |
|     fi
 | |
|     script="$script) return 1
 | |
| else return 0
 | |
| }"
 | |
|     echo "$script"
 | |
| }
 | |
| 
 | |
| function uncut_lines() {
 | |
|     # reformer les lignes qui sont coupées
 | |
|     awk '
 | |
| BEGIN {
 | |
|   inline = 0
 | |
| }
 | |
| 
 | |
| {
 | |
|   if (!inline) {
 | |
|     line = $0
 | |
|     inline = 1
 | |
|   } else {
 | |
|     if ($0 ~ /^ /) {
 | |
|       line = line substr($0, 2)
 | |
|     } else {
 | |
|       print line
 | |
|       inline = 0
 | |
| 
 | |
|       line = $0
 | |
|       inline = 1
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| END {
 | |
|   if (inline) print line
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function cut_lines() {
 | |
|     # couper les lignes trop longues
 | |
|     awk '
 | |
| {
 | |
|   if (length($0) > 78) {
 | |
|     prefix = ""
 | |
|     maxlen = 78
 | |
|     line = $0
 | |
|     while (length(line) > maxlen) {
 | |
|       print prefix substr(line, 1, maxlen)
 | |
|       line = substr(line, maxlen + 1)
 | |
|       prefix = " "
 | |
|       maxlen = 77
 | |
|     }
 | |
|     if (line != "") print prefix line
 | |
|   } else {
 | |
|     print
 | |
|   }
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function ensure_complete_objects() {
 | |
|     # S'assurer que le ldif ne contient que des objets complets (éliminant ainsi
 | |
|     # les groupes ayant seulement dn:)
 | |
|     awk '
 | |
| function dump_ldif() {
 | |
|   if (attrs) {
 | |
|     print ldif
 | |
|     print ""
 | |
|   }
 | |
|   ldif = ""
 | |
|   attrs = 0
 | |
| }
 | |
| 
 | |
| /^dn:/ {
 | |
|   dump_ldif()
 | |
|   ldif = $0
 | |
|   next
 | |
| }
 | |
| $0 != "" {
 | |
|   ldif = ldif "\n" $0
 | |
|   attrs = 1
 | |
| }
 | |
| 
 | |
| END {
 | |
|   dump_ldif()
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function delete_marked_objects() {
 | |
|     # Supprimer les objets marqués avec --DELETE--:
 | |
|     awk '
 | |
| BEGIN { keep = 0 }
 | |
| function dump_ldif() {
 | |
|   if (keep) {
 | |
|     print ldif
 | |
|     print ""
 | |
|   }
 | |
|   ldif = ""
 | |
|   keep = 1
 | |
| }
 | |
| /^dn:/ {
 | |
|   dump_ldif()
 | |
|   ldif = $0
 | |
|   next
 | |
| }
 | |
| /^--DELETE--:/ { keep = 0 }
 | |
| $0 != "" { ldif = ldif "\n" $0 }
 | |
| END { dump_ldif() }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_addattr() {
 | |
|     awk '
 | |
| /^dn:/ {
 | |
|   lastattr = ""
 | |
|   dn = $0
 | |
|   next
 | |
| }
 | |
| 
 | |
| {
 | |
|   attr = $1
 | |
|   if (attr != "") {
 | |
|     if (dn != "") {
 | |
|       print dn
 | |
|       print "changetype: add"
 | |
|       dn = ""
 | |
|     }
 | |
|     sub(/:+$/, "", attr)
 | |
|   }
 | |
|   print
 | |
|   lastattr = attr
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_modifyattr() {
 | |
|     local modtype="$1"
 | |
|     awkrun modtype="$modtype" '
 | |
| /^dn:/ {
 | |
|   lastattr = ""
 | |
|   dn = $0
 | |
|   next
 | |
| }
 | |
| 
 | |
| {
 | |
|   attr = $1
 | |
|   if (attr == "") {
 | |
|     if (lastattr != "") {
 | |
|       print "-"
 | |
|     }
 | |
|   } else {
 | |
|     if (dn != "") {
 | |
|       print dn
 | |
|       print "changetype: modify"
 | |
|       dn = ""
 | |
|     }
 | |
|     sub(/:+$/, "", attr)
 | |
|     if (lastattr != attr) {
 | |
|       if (lastattr != "") {
 | |
|         print "-"
 | |
|       }
 | |
|       print modtype ": " attr
 | |
|     }
 | |
|   }
 | |
|   print
 | |
|   lastattr = attr
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_deleteattr() {
 | |
|     awk '
 | |
| /^dn:/ {
 | |
|   lastattr = ""
 | |
|   dn = $0
 | |
|   next
 | |
| }
 | |
| 
 | |
| {
 | |
|   attr = $1
 | |
|   if (attr == "") {
 | |
|     if (lastattr != "") {
 | |
|       print "-"
 | |
|       print
 | |
|     }
 | |
|   } else {
 | |
|     if (dn != "") {
 | |
|       print dn
 | |
|       print "changetype: modify"
 | |
|       dn = ""
 | |
|     }
 | |
|     sub(/:+$/, "", attr)
 | |
|     if (lastattr != attr) {
 | |
|       if (lastattr != "") {
 | |
|         print "-"
 | |
|       }
 | |
|       print "delete: " attr
 | |
|     }
 | |
|   }
 | |
|   lastattr = attr
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_deleteentry() {
 | |
|     awk '
 | |
| /^dn:/ {
 | |
|   dn = $0
 | |
|   print dn
 | |
|   print "changetype: delete"
 | |
|   print ""
 | |
|   next
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_touchentry() {
 | |
|     awk '
 | |
| /^dn:/ {
 | |
|   dn = $0
 | |
|   print dn
 | |
|   print "changetype: modify"
 | |
|   print ""
 | |
|   next
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_keepattr() {
 | |
|     local match_attr="$1"
 | |
|     awk "$match_attr"'
 | |
| $0 == "" || match_attr($1) {
 | |
|   print
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_keepval() {
 | |
|     local match_attr="$1" match_value="$2"
 | |
|     awk "$match_attr
 | |
| $match_value"'
 | |
| match_attr($1) {
 | |
|   if (match_value($0)) {
 | |
|     print
 | |
|   }
 | |
|   next
 | |
| }
 | |
| { print }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_excludeattr() {
 | |
|     local match_attr="$1"
 | |
|     awk "$match_attr"'
 | |
| ! match_attr($1) {
 | |
|     print
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_excludeval() {
 | |
|     local match_attr="$1" match_value="$2"
 | |
|     awk "$match_attr
 | |
| $match_value"'
 | |
| match_attr($1) {
 | |
|   if (! match_value($0)) {
 | |
|     print
 | |
|   }
 | |
|   next
 | |
| }
 | |
| { print }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_keepvalentry() {
 | |
|     local match_attr="$1" match_value="$2"
 | |
|     awk "$match_attr
 | |
| $match_value"'
 | |
| function keep_maybe() {
 | |
|   if (! keep) print "--DELETE--: yes"
 | |
|   done = 1
 | |
| }
 | |
| /^dn:/ {
 | |
|   keep = 0
 | |
|   done = 0
 | |
| }
 | |
| match_attr($1) {
 | |
|   if (match_value($0)) keep = 1
 | |
| }
 | |
| $0 == "" { keep_maybe() }
 | |
| { print }
 | |
| END {
 | |
|   if (! done) keep_maybe()
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_excludevalentry() {
 | |
|     local match_attr="$1" match_value="$2"
 | |
|     awk "$match_attr
 | |
| $match_value"'
 | |
| function keep_maybe() {
 | |
|   if (! keep) print "--DELETE--: yes"
 | |
|   done = 1
 | |
| }
 | |
| /^dn:/ {
 | |
|   keep = 1
 | |
|   done = 0
 | |
| }
 | |
| match_attr($1) {
 | |
|   if (match_value($0)) keep = 0
 | |
| }
 | |
| $0 == "" { keep_maybe() }
 | |
| { print }
 | |
| END {
 | |
|   if (! done) keep_maybe()
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_replval() {
 | |
|     local script="$1"; shift
 | |
|     script="$script
 | |
| function print_values() {
 | |
|   for (i = 0; i < count; i++) {
 | |
|     print attr \" \" values[i]
 | |
|   }
 | |
| }
 | |
| BEGIN {
 | |
|   count=$#"
 | |
|     local i value
 | |
|     let i=0
 | |
|     for value in "$@"; do
 | |
|         script="$script
 | |
| values[$i] = $(quoted_awk "$value")"
 | |
|         let i=$i+1
 | |
|     done
 | |
|     script="$script
 | |
| }"'
 | |
| match_attr($1) {
 | |
|   attr = fix_attr($1)
 | |
|   while (match_attr($1)) {
 | |
|     if (getline <= 0) break
 | |
|   }
 | |
|   print_values()
 | |
| }
 | |
| { print }
 | |
| '
 | |
|     awkrun value="$value" "$script"
 | |
| }
 | |
| 
 | |
| function tl_addval() {
 | |
|     local attr="$1"; shift
 | |
|     local script="$(def_match_attr "$attr")
 | |
| function print_values() {
 | |
|   for (i = 0; i < count; i++) {
 | |
|     print attr \" \" values[i]
 | |
|   }
 | |
|   add = 0
 | |
| }
 | |
| BEGIN {
 | |
|   add=0
 | |
|   attr=fix_attr($(quoted_awk "$attr"))
 | |
|   count=$#"
 | |
|     local i value
 | |
|     let i=0
 | |
|     for value in "$@"; do
 | |
|         script="$script
 | |
| values[$i] = $(quoted_awk "$value")"
 | |
|         let i=$i+1
 | |
|     done
 | |
|     script="$script
 | |
| }"'
 | |
| /^dn:/ {
 | |
|     add = 1
 | |
| }
 | |
| add && match_attr($1) {
 | |
|   while (match_attr($1)) {
 | |
|     print
 | |
|     status = getline
 | |
|     if (status == 0) {
 | |
|       # traiter EOF de façon particulière, pour ne pas dupliquer le dernier print
 | |
|       print_values()
 | |
|       next
 | |
|     } else if (status < 0) {
 | |
|       break
 | |
|     }
 | |
|   }
 | |
|   print_values()
 | |
| }
 | |
| add && $0 == "" {
 | |
|   print_values()
 | |
| }
 | |
| { print }
 | |
| END {
 | |
|   if (add) print_values()
 | |
| }
 | |
| '
 | |
|     awk "$script"
 | |
| }
 | |
| 
 | |
| function tl_defval() {
 | |
|     local attr="$1"; shift
 | |
|     local script="$(def_match_attr "$attr")
 | |
| function resetp() {
 | |
|   add = 0
 | |
|   found = 0
 | |
| }
 | |
| function print_values() {
 | |
|   for (i = 0; i < count; i++) {
 | |
|     print attr \" \" values[i]
 | |
|   }
 | |
|   resetp()
 | |
| }
 | |
| BEGIN {
 | |
|   add = 0
 | |
|   found = 0
 | |
|   attr = fix_attr($(quoted_awk "$attr"))
 | |
|   count = $#"
 | |
|     local i value
 | |
|     let i=0
 | |
|     for value in "$@"; do
 | |
|         script="$script
 | |
| values[$i] = $(quoted_awk "$value")"
 | |
|         let i=$i+1
 | |
|     done
 | |
|     script="$script
 | |
| }"'
 | |
| /^dn:/ {
 | |
|   add = 1
 | |
| }
 | |
| add && match_attr($1) {
 | |
|   found = 1
 | |
| }
 | |
| add && $0 == "" {
 | |
|   if (!found) print_values()
 | |
|   resetp()
 | |
| }
 | |
| { print }
 | |
| END {
 | |
|   if (add && !found) print_values()
 | |
| }
 | |
| '
 | |
|     awk "$script"
 | |
| }
 | |
| 
 | |
| function tl_ensureval() {
 | |
|     local attr="$1"; shift
 | |
|     local script="$(def_match_attr "$attr")
 | |
| BEGIN {
 | |
|   resetp()
 | |
|   attr = fix_attr($(quoted_awk "$attr"))
 | |
|   ensure_count = $#"
 | |
|     local i value
 | |
|     let i=0
 | |
|     for value in "$@"; do
 | |
|         script="$script
 | |
|   ensure_values[$i] = $(quoted_awk "$value")"
 | |
|         let i=$i+1
 | |
|     done
 | |
|     script="$script
 | |
|   found_count = 0
 | |
|   found_values[0] = 0
 | |
|   delete found_values
 | |
| }"'
 | |
| function resetp() {
 | |
|   ensure = 0
 | |
|   found = 0
 | |
| }
 | |
| function get_attrvalue(line) {
 | |
|   sub(/^[^:]+::?[ ]+/, "", line)
 | |
|   return line
 | |
| }
 | |
| function add_to_found_values(value) {
 | |
|   found_values[found_count] = value
 | |
|   found_count++
 | |
| }
 | |
| function in_found_values(value,             i, found_value) {
 | |
|   if (value ~ /^{}/) {
 | |
|     sub(/^{}/, "", value)
 | |
|     for (i = 0; i < found_count; i++) {
 | |
|       found_value = found_values[i]
 | |
|       sub(/^{[0-9]+}/, "", found_value)
 | |
|       if (found_value == value) {
 | |
|         return 1
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     for (i = 0; i < found_count; i++) {
 | |
|       if (found_values[i] == value) {
 | |
|         return 1
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return 0
 | |
| }
 | |
| function print_ensure_values() {
 | |
|   for (i = 0; i < ensure_count; i++) {
 | |
|     value = ensure_values[i]
 | |
|     sub(/^{}/, "", value)
 | |
|     print attr " " value
 | |
|   }
 | |
|   resetp()
 | |
| }
 | |
| function print_missing_values(              value) {
 | |
|   for (i = 0; i < ensure_count; i++) {
 | |
|     value = ensure_values[i]
 | |
|     if (!in_found_values(value)) {
 | |
|       sub(/^{}/, "", value)
 | |
|       print attr " " value
 | |
|     }
 | |
|   }
 | |
|   resetp()
 | |
| }
 | |
| /^dn:/ {
 | |
|   ensure = 1
 | |
| }
 | |
| ensure && match_attr($1) {
 | |
|   found = 1
 | |
|   value = get_attrvalue($0)
 | |
|   add_to_found_values(value)
 | |
|   next
 | |
| }
 | |
| ensure && $0 == "" {
 | |
|   if (found) print_missing_values()
 | |
|   else print_ensure_values()
 | |
| }
 | |
| { print }
 | |
| END {
 | |
|   if (ensure) {
 | |
|     if (found) print_missing_values()
 | |
|     else print_ensure_values()
 | |
|   }
 | |
| }
 | |
| '
 | |
|     awk "$script"
 | |
| }
 | |
| 
 | |
| function tl_decode() {
 | |
|     local match_attr="$1"
 | |
|     awkrun -f "$match_attr"'
 | |
| function split_base64(text,   result) {
 | |
|   result = ""
 | |
|   while (text != "") {
 | |
|     if (result != "") result = result "\n"
 | |
|     result = result substr(text, 1, 64)
 | |
|     text = substr(text, 65)
 | |
|   }
 | |
|   return result
 | |
| }
 | |
| 
 | |
| /^[^:]+:: / && match_attr($1) {
 | |
|   name = $0; sub(/::.*$/, "", name)
 | |
|   value = $0; sub(/^[^:]+:: /, "", value)
 | |
| 
 | |
|   decoded_value = b64decode(value)
 | |
|   #cmd = "echo '\''" split_base64(value) "'\'' | openssl base64 -d"
 | |
|   #decoded_value = ""
 | |
|   #while ((cmd | getline line) > 0) {
 | |
|   #    decoded_value = decoded_value line
 | |
|   #}
 | |
|   #close(cmd)
 | |
|   print name ": " decoded_value
 | |
|   next
 | |
| }
 | |
| { print }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_encode() {
 | |
|     local match_attr="$1"
 | |
|     awkrun "$match_attr"'
 | |
| function quote(text) {
 | |
|   # remplacer les quotes par le caractere echappement approprie
 | |
|   gsub('"/'/, \"'\\\\''\""', text)
 | |
|   return text
 | |
| }
 | |
| 
 | |
| /^[^:]+: / && match_attr($1) {
 | |
|   name = $0; sub(/:.*$/, "", name)
 | |
|   value = $0; sub(/^[^:]+: /, "", value)
 | |
| 
 | |
|   cmd = "echo '\''" quote(value) "'\'' | openssl base64"
 | |
|   coded_value = ""
 | |
|   while ((cmd | getline line) > 0) {
 | |
|     coded_value = coded_value line
 | |
|   }
 | |
|   close(cmd)
 | |
|   print name ":: " coded_value
 | |
|   next
 | |
| }
 | |
| { print }
 | |
| '
 | |
| }
 | |
| 
 | |
| __AWK_VSEP_FUNCTIONS='
 | |
| function quote_vsep(value, vsep,    hvsep) {
 | |
|   gsub(/\\/, "\\5c", value)
 | |
|   if (vsep != "\\") {
 | |
|     hvsep = "\\" hex(ord(vsep))
 | |
|     gsub(quote_regexp(vsep), hvsep, value)
 | |
|   }
 | |
|   return value
 | |
| }
 | |
| function unquote_vsep(value, vsep,    hvsep) {
 | |
|   if (vsep != "\\") {
 | |
|     hvsep = "\\" hex(ord(vsep))
 | |
|     gsub(quote_regexp(hvsep), vsep, value)
 | |
|   }
 | |
|   gsub(quote_regexp("\\5c"), "\\", value)
 | |
|   return value
 | |
| }
 | |
| '
 | |
| 
 | |
| function tl_format() {
 | |
|     local args show_headers asep vsep qsep qempty escape shell cmd begincmd endcmd localvars
 | |
|     show_headers=
 | |
|     asep=$'\t'
 | |
|     vsep=';'
 | |
|     qsep=
 | |
|     if parse_opts \
 | |
|         -h,--show-headers show_headers \
 | |
|         -F: asep= \
 | |
|         -R: vsep= \
 | |
|         --quote: qsep= \
 | |
|         --quote-empty qempty=::EMPTY:: \
 | |
|         --empty-value: qempty= \
 | |
|         --escape: escape \
 | |
|         -e shell \
 | |
|         -c: cmd= \
 | |
|         --bc: begincmd= \
 | |
|         --ec: endcmd= \
 | |
|         -l,--local localvars=1 \
 | |
|         @ args -- "$@"; then
 | |
|         set -- "${args[@]}"
 | |
|     else
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     fi
 | |
|     [ -n "$shell" ] && show_headers=1
 | |
| 
 | |
|     local -a attrs mapattrs
 | |
|     local attr mapattr
 | |
|     for attr in "$@"; do
 | |
|         splitpair "$attr" mapattr attr
 | |
|         [ -n "$attr" ] || attr="$mapattr"
 | |
|         attr="${attr//:/}"; array_add attrs "$attr"
 | |
|         mapattr="${mapattr//:/}"; array_add mapattrs "$mapattr"
 | |
|     done
 | |
|     local match_attr="$(def_match_attr "${attrs[@]}")"
 | |
| 
 | |
|     awkrun -f show_headers:int="$show_headers" asep="$asep" vsep="$vsep" qsep="$qsep" qempty="$qempty" escape="$escape" \
 | |
|         shell:int="$shell" cmd="$cmd" begincmd="$begincmd" endcmd="$endcmd" localvars:int="$localvars" \
 | |
|         attrs[@] mapattrs[@] "$__AWK_VSEP_FUNCTIONS"'
 | |
| function reset_values() {
 | |
|   for (i = 1; i <= attrs_count; i++) {
 | |
|     attr = norm_attr(attrs[i])
 | |
|     values[attr] = ""
 | |
|   }
 | |
|   has_values = 0
 | |
| }
 | |
| function quote_shell(value) {
 | |
|   gsub(/'\''/, "'\'\\\\\''", value)
 | |
|   return "'\''" value "'\''"
 | |
| }
 | |
| function dump_headers() {
 | |
|   line = ""
 | |
|   if (shell) {
 | |
|     if (localvars) {
 | |
|       print "local attributes index"
 | |
|       for (i = 1; i <= attrs_count; i++) {
 | |
|         attr = norm_attr(mapattrs[i])
 | |
|         print "local " attr
 | |
|       }
 | |
|     }
 | |
|     line = line "attributes=("
 | |
|     for (i = 1; i <= attrs_count; i++) {
 | |
|       attr = norm_attr(mapattrs[i])
 | |
|       if (i > 1) line = line " "
 | |
|       line = line quote_shell(attr)
 | |
|     }
 | |
|     line = line ")"
 | |
|   } else {
 | |
|     for (i = 1; i <= attrs_count; i++) {
 | |
|       attr = mapattrs[i]
 | |
|       if (i > 1) line = line asep
 | |
|       line = line attr
 | |
|     }
 | |
|   }
 | |
|   if (line != "") print line
 | |
| }
 | |
| function dump_cmd(atbegin, atend) {
 | |
|   if (atbegin && begincmd != "") print begincmd
 | |
|   if (atend && endcmd != "") print endcmd
 | |
| }
 | |
| function __should_quote(s) {
 | |
|   if (s ~ /^[[:blank:][:cntrl:][:space:]]/) return 1
 | |
|   if (s ~ /[[:blank:][:cntrl:][:space:]]$/) return 1
 | |
|   return 0
 | |
| }
 | |
| function dump_values(atbegin,            value) {
 | |
|   if (shell) {
 | |
|     print "index=" nr
 | |
|     for (i = 1; i <= attrs_count; i++) {
 | |
|       attr = norm_attr(attrs[i])
 | |
|       mapattr = norm_attr(mapattrs[i])
 | |
|       print mapattr "=" values[attr]
 | |
|     }
 | |
|     if (!atbegin && cmd != "") print cmd
 | |
|   } else {
 | |
|     line = ""
 | |
|     for (i = 1; i <= attrs_count; i++) {
 | |
|       attr = norm_attr(attrs[i])
 | |
|       if (i > 1) line = line asep
 | |
|       value = values[attr]
 | |
|       if (qsep != "" && index(value, qsep) != 0) {
 | |
|         if (escape) gsub(qsep, quote_subrepl(escape) "&", value);
 | |
|         else gsub(qsep, "&&", value);
 | |
|       }
 | |
|       if (qsep != "" && (index(value, qsep) != 0 || index(value, asep) != 0 || __should_quote(value))) {
 | |
|         line = line qsep value qsep
 | |
|       } else {
 | |
|         line = line value
 | |
|       }
 | |
|     }
 | |
|     if (line != "") print line
 | |
|   }
 | |
|   nr = nr + 1
 | |
| }
 | |
| 
 | |
| function parse_attr(line) {
 | |
|   sub(/::?.*$/, "", line)
 | |
|   return line
 | |
| }
 | |
| function parse_value(line) {
 | |
|   sub(/^[^:]+::? */, "", line)
 | |
|   return line
 | |
| }
 | |
| 
 | |
| '"$match_attr"'
 | |
| BEGIN {
 | |
|   if (show_headers) dump_headers()
 | |
|   reset_values()
 | |
|   nr = -1
 | |
|   if (shell) dump_values(1)
 | |
|   dump_cmd(1, 0)
 | |
| }
 | |
| $0 != "" && match_attr($1) {
 | |
|   has_values = 1
 | |
|   attr = norm_attr(parse_attr($0))
 | |
|   value = parse_value($0)
 | |
|   if (shell) {
 | |
|     if (values[attr] == "") {
 | |
|       values[attr] = quote_shell(value)
 | |
|     } else {
 | |
|       tmp = values[attr]
 | |
|       if (substr(tmp, 1, 1) == "(") tmp = substr(tmp, 2, length(tmp) - 2)
 | |
|       tmp = tmp " " quote_shell(value)
 | |
|       values[attr] = "(" tmp ")"
 | |
|     }
 | |
|   } else {
 | |
|     if (value == "") value = qempty
 | |
|     value = quote_vsep(value, vsep)
 | |
|     if (values[attr] == "") {
 | |
|       values[attr] = value
 | |
|     } else {
 | |
|       values[attr] = values[attr] vsep value
 | |
|     }
 | |
|   }
 | |
| }
 | |
| $0 == "" {
 | |
|   if (has_values) dump_values()
 | |
|   reset_values()
 | |
| }
 | |
| END {
 | |
|   if (has_values) dump_values()
 | |
|   if (shell) dump_cmd(0, 1)
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_formatcsv() {
 | |
|     local args show_headers vsep qsep escape
 | |
|     show_headers=1
 | |
|     vsep=';'
 | |
|     qsep='"'
 | |
|     qempty=1
 | |
|     escape=
 | |
|     if parse_opts \
 | |
|         -h,--show-headers show_headers=1 \
 | |
|         -n,--no-headers show_headers= \
 | |
|         -R: vsep= \
 | |
|         --quote: qsep= \
 | |
|         --quote-empty qempty=1 \
 | |
|         --no-quote-empty qempty= \
 | |
|         --escape: escape \
 | |
|         @ args -- "$@"; then
 | |
|         set -- "${args[@]}"
 | |
|     else
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     tl_format ${show_headers:+--show-headers} -F , -R "$vsep" --quote "$qsep" ${qempty:+--quote-empty} --escape "$escape" "$@"
 | |
| }
 | |
| 
 | |
| function tl_parsecsv() {
 | |
|     local -a args headers
 | |
|     local basedn= rdnattr= skip_lines=0 parse_headers= vsep=';' qempty=::EMPTY::
 | |
|     if parse_opts \
 | |
|         -u:,--rdnattr: rdnattr= \
 | |
|         -s:,--skip-lines: skip_lines= \
 | |
|         -h,--parse-headers parse_headers=1 \
 | |
|         -R: vsep= \
 | |
|         --no-parse-empty qempty= \
 | |
|         --parse-empty qempty=::EMPTY:: \
 | |
|         --empty-value: qempty= \
 | |
|         @ args -- "$@"; then
 | |
|         set -- "${args[@]}"
 | |
|     else
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     fi
 | |
|     basedn="$1"; shift
 | |
|     if [ -n "$basedn" ]; then
 | |
|         [ -n "$rdnattr" ] || rdnattr=uid
 | |
|     else
 | |
|         [ -n "$rdnattr" ] || rdnattr=dn
 | |
|     fi
 | |
|     [ -n "$*" ] && headers=("$@")
 | |
|     [ -n "${headers[*]}" ] || parse_headers=1
 | |
| 
 | |
|     awkrun -f \
 | |
|         basedn="$basedn" rdnattr="$rdnattr" \
 | |
|         skip_lines:int="$skip_lines" parse_headers:int="$parse_headers" headers[@] \
 | |
|         vsep="$vsep" qempty="$qempty" "$__AWK_VSEP_FUNCTIONS"'
 | |
| NR <= skip_lines { next }
 | |
| parse_headers {
 | |
|   array_parsecsv(headers, $0)
 | |
|   headers_count = array_len(headers)
 | |
|   parse_headers = 0
 | |
|   next
 | |
| }
 | |
| {
 | |
|   array_parsecsv(attrvalues, $0)
 | |
|   rdnindex = key_index(rdnattr, headers)
 | |
|   rdnvalue = attrvalues[rdnindex]
 | |
|   if (basedn != "") {
 | |
|     print "dn: " rdnattr "=" rdnvalue "," basedn
 | |
|   } else if (rdnattr != "dn") {
 | |
|     print "dn: " rdnattr "=" rdnvalue
 | |
|   } else {
 | |
|     print "dn: " rdnvalue
 | |
|   }
 | |
|   for (i = 1; i <= headers_count; i++) {
 | |
|     attr = headers[i]
 | |
|     if (basedn == "" && rdnattr == "dn" && attr == rdnattr) {
 | |
|       continue # ne pas écrire deux fois le même attribut
 | |
|     }
 | |
|     attrvalue = attrvalues[i]
 | |
|     split(attrvalue, values, vsep)
 | |
|     values_count = array_len(values)
 | |
|     for (j = 1; j <= values_count; j++) {
 | |
|       value = unquote_vsep(values[j], vsep)
 | |
|       if (value == qempty) value = ""
 | |
|       print attr ": " value
 | |
|     }
 | |
|   }
 | |
|   print ""
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| function tl_parsecsvmod() {
 | |
|     local -a args headers
 | |
|     local basedn= rdnattr= skip_lines=0 parse_headers= vsep=';' qempty=::EMPTY::
 | |
|     if parse_opts \
 | |
|         -u:,--rdnattr: rdnattr= \
 | |
|         -s:,--skip-lines: skip_lines= \
 | |
|         -h,--parse-headers parse_headers=1 \
 | |
|         -R: vsep= \
 | |
|         --no-parse-empty qempty= \
 | |
|         --parse-empty qempty=::EMPTY:: \
 | |
|         --empty-value: qempty= \
 | |
|         @ args -- "$@"; then
 | |
|         set -- "${args[@]}"
 | |
|     else
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     fi
 | |
|     basedn="$1"; shift
 | |
|     if [ -n "$basedn" ]; then
 | |
|         [ -n "$rdnattr" ] || rdnattr=uid
 | |
|     else
 | |
|         [ -n "$rdnattr" ] || rdnattr=dn
 | |
|     fi
 | |
|     [ -n "$*" ] && headers=("$@")
 | |
|     [ -n "${headers[*]}" ] || parse_headers=1
 | |
| 
 | |
|     awkrun -f \
 | |
|         basedn="$basedn" rdnattr="$rdnattr" \
 | |
|         skip_lines:int="$skip_lines" parse_headers:int="$parse_headers" headers[@] \
 | |
|         vsep="$vsep" qempty="$qempty" "$__AWK_VSEP_FUNCTIONS"'
 | |
| NR <= skip_lines { next }
 | |
| parse_headers {
 | |
|   array_parsecsv(headers, $0)
 | |
|   headers_count = array_len(headers)
 | |
|   parse_headers = 0
 | |
|   next
 | |
| }
 | |
| {
 | |
|   array_parsecsv(attrvalues, $0)
 | |
|   rdnindex = key_index(rdnattr, headers)
 | |
|   rdnvalue = attrvalues[rdnindex]
 | |
|   # déterminer d"abord s"il faut écrire l"objet
 | |
|   printobj = 0
 | |
|   for (i = 1; i <= headers_count; i++) {
 | |
|     attr = headers[i]
 | |
|     if (attr == rdnattr) continue
 | |
|     attrvalue = attrvalues[i]
 | |
|     if (attrvalue == "") continue
 | |
|     # ok on doit ecrire le dn
 | |
|     if (basedn != "") {
 | |
|       print "dn: " rdnattr "=" rdnvalue "," basedn
 | |
|     } else {
 | |
|       print "dn: " rdnvalue
 | |
|     }
 | |
|     print "changetype: modify"
 | |
|     printobj = 1
 | |
|     break
 | |
|   }
 | |
|   # maintenant, écrire l"objet le cas échéant
 | |
|   if (printobj) {
 | |
|     for (i = 1; i <= headers_count; i++) {
 | |
|       attr = headers[i]
 | |
|       if (attr == rdnattr) continue
 | |
|       attrvalue = attrvalues[i]
 | |
|       if (attrvalue == "") {
 | |
|         continue
 | |
|       } else if (attrvalue ~ /^(replace|add|delete):/) {
 | |
|         changetype = attrvalue
 | |
|         sub(/:.*/, "", changetype)
 | |
|         attrvalue = substr(attrvalue, length(changetype) + 2)
 | |
|       } else {
 | |
|         changetype = "replace"
 | |
|       }
 | |
|       print changetype ": " attr
 | |
|       split(attrvalue, values, vsep)
 | |
|       values_count = array_len(values)
 | |
|       for (j = 1; j <= values_count; j++) {
 | |
|         value = unquote_vsep(values[j], vsep)
 | |
|         if (value == qempty) value = ""
 | |
|         print attr ": " value
 | |
|       }
 | |
|       print "-"
 | |
|     }
 | |
|     print ""
 | |
|   }
 | |
| }
 | |
| '
 | |
| }
 | |
| 
 | |
| TRANSFORM_CMD_HELP="\
 | |
| Il est possible de spécifier plusieurs commandes séparées par //
 | |
| Les expressions régulières sont celles reconnues par awk.
 | |
| 
 | |
| u, uncut
 | |
|     Fusionner les lignes coupées. Cette action est en principe effectuée
 | |
|     automatiquement au début, sauf avec l'option --nu
 | |
| c, cut
 | |
|     Couper les lignes trop longues. Il n'est pas conseillé d'appliquer des
 | |
|     méthodes de transformation après avoir utilisé cette action.
 | |
| dec, decode [ATTRS...]
 | |
|     Décoder les valeurs des attributs mentionnés si nécessaire (c'est à dire
 | |
|     s'ils sont encodés en base64)
 | |
| enc, encode [ATTRS...]
 | |
|     Encoder en base64 les valeurs des attributs mentionnés.
 | |
| xe, xempty, excludeempty
 | |
|     Supprimer les objets sans attributs, qui ont uniquement une ligne dn:
 | |
| k, keepattr [--no-xempty] ATTRS...
 | |
|     Garder uniquement les attributs mentionnés, puis supprimer les objets sans
 | |
|     attributs avec xempty, sauf si l'option --no-xempty est spécifiée (en
 | |
|     d'autres termes, keepattr sans argument supprime *tout* le flux)
 | |
| kv, keepval [--no-xempty] ATTR PATTERNS...
 | |
|     Pour l'attribut attr, garder uniquement les lignes pour lesquelles les
 | |
|     valeurs correspondent aux expressions régulières. Les autres attributs ne
 | |
|     sont pas modifiés. Ensuite, supprimer les objets sans attributs avec xempty,
 | |
|     sauf si l'option --no-xempty est spécifiée
 | |
| x, excludeattr [--no-xempty] ATTRS...
 | |
|     Supprimer les lignes des attributs mentionnés. Ensuite, supprimer les objets
 | |
|     sans attributs avec xempty, sauf si l'option --no-xempty est spécifiée
 | |
| xv, excludeval [--no-xempty] ATTR PATTERNS...
 | |
|     Pour l'attribut attr, supprimer les lignes pour lesquelles les valeurs
 | |
|     correspondent aux expressions régulières. Les autres attributs ne sont pas
 | |
|     modifiés. Ensuite, supprimer les objets sans attributs avec xempty, sauf si
 | |
|     l'option --no-xempty est spécifiée.
 | |
| kve, keepvalentry ATTR PATTERNS...
 | |
|     Pour l'attribut attr, vérifier si *au moins une* valeur correspond à l'une
 | |
|     des expressions régulières. Si c'est le cas, garder toute l'entrée, sinon
 | |
|     supprimer toute l'entrée.
 | |
| xve, excludevalentry ATTR PATTERNS...
 | |
|     Pour l'attribut attr, vérifier si *aucune* des valeurs ne correspond à l'une
 | |
|     des expressions régulières. Si c'est le cas, garder toute l'entrée, sinon
 | |
|     supprimer toute l'entrée.
 | |
| rv, replval ATTR VALUES...
 | |
|     Remplacer toutes les valeurs de l'attribut attr par les valeurs spécifiées.
 | |
| av, addval ATTR VALUES...
 | |
|     Ajouter un nouvel attribut avec les valeurs spécifiées. Si l'attribut existe
 | |
|     déjà, les nouvelles valeurs sont ajoutées à la fin.
 | |
| fv, defval ATTR VALUES...
 | |
|     Ajouter un nouvel attribut avec les valeurs spécifiées, s'il n'existe pas
 | |
|     déjà. Si l'attribut existe déjà, cette opération est un NOP.
 | |
| ev, ensureval ATTR VALUES...
 | |
|     A utiliser avec modaddval, ne garder que les valeurs que l'attribut n'a pas
 | |
|     déjà. Par exemple, pour s'assurer que l'attribut ATTR a les valeurs V0 et
 | |
|     V1, on ferait:
 | |
|         ensureval ATTR V0 V1 // modaddval
 | |
|     Certains attributs sont ordonnés. Leurs valeurs sont étiquettées avec leur
 | |
|     index, e.g {2}value. Si l'on ne veut pas faire de correspondance exacte,
 | |
|     c'est à dire tester uniquement la présence d'une valeur indépendamment de
 | |
|     son index, il faut utiliser la syntaxe {}value, e.g:
 | |
|         ensureval ATTR {}value // modaddval
 | |
|     S'il faut ajouter les valeurs, elle sont mentionnées sans le préfixe {}
 | |
| sed ARGS
 | |
| awk ARGS
 | |
| grep ARGS
 | |
| sort [ARGS]
 | |
| awkrun [ARGS]
 | |
|     Traiter le flux avec respectivement les commandes sed, awk, grep, sort et
 | |
|     awkrun. awkrun est la version 'améliorée' de awk offerte par nutools.
 | |
|     Note: ces commandes ne tiennent pas compte de la locale: elles sont lancées
 | |
|     avec la variable LANG=C
 | |
|     Note: aucun argument n'est filtré, mais il ne faudrait pas utiliser les
 | |
|     options qui provoquent la modification en place d'un fichier, comme par
 | |
|     exemple l'option -i de sed
 | |
| format [OPTIONS] ATTRS...
 | |
|     Formater le flux au format ldif en données tabulaires.
 | |
|     Chaque attribut peut être de la forme newname:oldname pour avoir des
 | |
|     en-têtes avec un nom différent des noms des attributs. L'effet est le même
 | |
|     qu'avec awkcsv -m
 | |
|     -h, --show-headers
 | |
|         Afficher les en-têtes. Par défaut, les en-têtes ne sont pas affichés.
 | |
|     -F ASEP
 | |
|         Spécifier le séparateur pour les attributs. Par défaut, il s'agit du
 | |
|         caractère de tabulation.
 | |
|     -R VSEP
 | |
|         Spécifier le séparateur pour les valeurs des attributs. Par défaut, il
 | |
|         s'agit du point-virgule ';'
 | |
|     --quote QUOTE
 | |
|         Spécifier le caractère à employer pour encadrer une valeur si elle
 | |
|         contient l'un des caractères ASEP ou QSEP. Par défaut, les valeurs ne
 | |
|         sont pas encadrées.
 | |
|     --escape ESCAPE
 | |
|         Indiquer que le caractère QUOTE dans une chaine doit être mis en
 | |
|         échappement avec le caractère ESCAPE. Si ESCAPE est une valeur vide,
 | |
|         doubler le caractère QUOTE.
 | |
|         e.g. si QUOTE='\"' et ESCAPE='\\', la valeur abc\"def est écrite ainsi:
 | |
|             \"abc\\\"def\"
 | |
|         Par contre, si ESCAPE='', alors la valeur est écrite ainsi:
 | |
|             \"abc\"\"def\"
 | |
|     -e
 | |
|         Retourner les valeurs comme des variables shell. Les options -F et -R
 | |
|         sont ignorées. Les attributs multivalués sont écrits sous forme de
 | |
|         tableaux. Par exemple:
 | |
|             attributes=('mail' 'givenName')
 | |
|             index=0
 | |
|             mail='user@domain.fr'
 | |
|             givenName=('peter' 'gabriel')
 | |
|     -l, --local
 | |
|         Ajouter une définition pour rendre locales les variables utilisées,
 | |
|         e.g. avec l'exemple précédent:
 | |
|             local attributes index
 | |
|             local mail
 | |
|             local givenName
 | |
|             attributes=('mail' 'givenName')
 | |
|             index=0
 | |
|             mail='user@domain.fr'
 | |
|             givenName=('peter' 'gabriel')
 | |
|     --bc
 | |
|         Dans le mode -e, spécifier une commande à insérer avant le premier
 | |
|         enregistrement. Quand cette commande est lancée, index==-1
 | |
|     -c
 | |
|         Dans le mode -e, spécifier une commande à insérer après chaque
 | |
|         enregistrement
 | |
|     --ec
 | |
|         Dans le mode -e, spécifier une commande à insérer après le dernier
 | |
|         enregistrement
 | |
| formatcsv [OPTIONS] ATTRS...
 | |
|     Equivalent à 'format -F , --show-headers --quote \\\"'
 | |
|     -n, --no-headers
 | |
|         Ne pas afficher les en-têtes. Par défaut, les en-têtes sont affichés.
 | |
|     -R VSEP
 | |
|     --quote QUOTE
 | |
|     --escape ESCAPE
 | |
|         Ces options ont la même signification que pour format
 | |
| parsecsv [OPTIONS] BASEDN [ATTRS...]
 | |
|     Analyser le flux au format CSV (qui a par exemple été générée avec la
 | |
|     commande formatcsv), et reconstruire les objets LDAP associés.
 | |
| 
 | |
|     En principe, BASEDN n'est pas vide, et l'option -u détermine l'attribut dont
 | |
|     la valeur est utilisée pour nommer les objets. Le cas particulier BASEDN==''
 | |
|     est aussi supporté, auquel cas la valeur par défaut de rdnattr n'est plus
 | |
|     'uid' mais 'dn'
 | |
| 
 | |
|     BASEDN
 | |
|         DN de base des objets à construire
 | |
|     -u, --rdnattr rdnattr[=uid]
 | |
|         Nommer les objets avec la valeur de l'attribut spécifié
 | |
|     -s, --skip-lines nblines
 | |
|         Sauter nblines au début du flux
 | |
|     -h, --parse-headers
 | |
|         Lire la liste des attributs à partir de la première ligne non ignorée du
 | |
|         flux. Si la liste des attributs est vide, cette option est implicitement
 | |
|         activée.
 | |
|     -R VSEP
 | |
|         Spécifier le séparateur pour les valeurs des attributs. Par défaut, il
 | |
|         s'agit du point-virgule ';'
 | |
| parsecsvmod [OPTIONS] BASEDN [ATTRS...]
 | |
|     Analyser le flux au format CSV qui contient des ordres de modification des
 | |
|     objets LDAP, et construire les modifications au format LDIF.
 | |
|     L'attribut rdnattr (spécifié avec l'option -u) est le seul dont la valeur
 | |
|     doit être au format standard.  Les valeurs des autres attributs doivent être
 | |
|     de la forme [CHANGETYPE:]value où CHANGETYPE peut valoir replace, add, ou
 | |
|     delete. CHANGETYPE vaut replace par défaut. Si une valeur est vide, elle est
 | |
|     ignorée
 | |
|     En principe, BASEDN n'est pas vide, et l'option -u détermine l'attribut dont
 | |
|     la valeur est utilisée pour nommer les objets. Le cas particulier basedn==''
 | |
|     est aussi supporté, auquel cas la valeur par défaut de rdnattr n'est plus
 | |
|     'uid' mais 'dn'
 | |
| 
 | |
|     BASEDN
 | |
|         DN de base des objets à construire
 | |
|     -u, --rdnattr rdnattr[=uid]
 | |
|         Nommer les objets avec la valeur de l'attribut spécifié
 | |
|     -s, --skip-lines nblines
 | |
|         Sauter nblines au début du flux
 | |
|     -h, --parse-headers
 | |
|         Lire la liste des attributs à partir de la première ligne non ignorée du
 | |
|         flux. Si la liste des attributs est vide, cette option est implicitement
 | |
|         activée.
 | |
|     -R VSEP
 | |
|         Spécifier le séparateur pour les valeurs des attributs. Par défaut, il
 | |
|         s'agit du point-virgule ';'
 | |
| awkcsv [OPTIONS] [ATTRS...]
 | |
| $(sed 's/^/    /g' <<<"$__AWKCSV_HELP")
 | |
| mergecsv [OPTIONS] LEFT RIGHT -k FIELD
 | |
| $(sed 's/^/    /g' <<<"$__MERGECSV_HELP")
 | |
| sortcsv [OPTIONS] INPUT -k FIELD
 | |
| $(sed 's/^/    /g' <<<"$__SORTCSV_HELP")
 | |
| 
 | |
| lsed ARGS
 | |
| lawk ARGS
 | |
| lgrep ARGS
 | |
| lsort [ARGS]
 | |
| lawkrun [ARGS]
 | |
| lawkcsv [OPTIONS] [ATTRS...]
 | |
| lmergecsv [OPTIONS] LEFT RIGHT -k FIELD
 | |
| lsortcsv [OPTIONS] INPUT -k FIELD
 | |
|     Ces commandes sont comme les commandes sans le préfixe 'l', mais elles sont
 | |
|     lancées sans LANG=C, ce qui fait qu'elle tiennent compte de la locale.
 | |
|     En effet, les outils de coreutils utilisent les règles de la locale pour le
 | |
|     tri et la comparaison des chaines, et par exemple, avec LANG=fr_FR.UTF-8, la
 | |
|     locale indique que les ponctuations doivent être ignorées pour le tri, ce
 | |
|     qui peut poser problème.
 | |
| csed ARGS
 | |
| cawk ARGS
 | |
| cgrep ARGS
 | |
| csort [ARGS]
 | |
| cawkrun [ARGS]
 | |
| cawkcsv [OPTIONS] [ATTRS...]
 | |
| cmergecsv [OPTIONS] LEFT RIGHT -k FIELD
 | |
| csortcsv [OPTIONS] INPUT -k FIELD
 | |
|     Ces commandes existent pour compatibilité. Ces commandes sont des aliases
 | |
|     des commandes sans le préfixe 'c', et existent pour insister sur le fait
 | |
|     qu'elles sont lancées avec LANG=C.
 | |
| 
 | |
| Les directives suivantes transforment le flux au format ldif en une suite de
 | |
| commandes de modifications pour ldapmodify:
 | |
| 
 | |
| A, modaddattr
 | |
|     Créer un objet de toutes pièces avec les attributs donnés et leurs valeurs
 | |
| a, modaddval
 | |
|     Ajouter les valeurs spécifiée à l'attribut
 | |
| r, modreplval
 | |
|     Remplacer les valeurs de l'attribut par celles spécifiées
 | |
| d, moddelval
 | |
|     Supprimer les valeurs spécifiées de l'attribut
 | |
| D, moddelattr
 | |
|     Supprimer l'attribut
 | |
| delentry
 | |
|     Supprimer l'objet
 | |
| touchentry
 | |
|     Forcer la réplication de l'objet en simulant une modification"
 | |
| 
 | |
| function get_transform_cmd() {
 | |
|     # Créer une liste de commandes bash à évaluer en fonction des arguments: une
 | |
|     # suite de commandes séparées par //
 | |
|     # Les variables suivantes peuvent être définies en entrée:
 | |
|     # _T_inputfile:
 | |
|     #     Si cette variable est non vide, lire à partir du fichier $_T_inputfile
 | |
|     #     au lieu de stdin
 | |
|     # _T_uncut_before:
 | |
|     #     faut-il fusionner automatiquement les lignes *avant* de lancer les
 | |
|     #     commandes.
 | |
|     # _T_cut_after:
 | |
|     #     faut-il découper automatiquement les lignes *après* avoir lancé les
 | |
|     #     commandes.
 | |
|     local -a cmds cmdparts
 | |
|     local cmd dest first=1 xempty xdel
 | |
|     local auto_uncut="$_T_uncut_before"
 | |
|     local auto_cut="$_T_cut_after" last_is_cut
 | |
|     [ -n "$_T_inputfile" ] && dest='cat "$_T_inputfile"'
 | |
|     if [ -n "$*" ]; then
 | |
|         cmd=
 | |
|         while [ "$#" -gt 0 ]; do # parce qu'on peut avoir un argument vide!
 | |
|             if [ "$1" == // ]; then
 | |
|                 [ -n "$cmd" ] && cmds=("${cmds[@]}" "$cmd")
 | |
|                 cmd=
 | |
|                 shift
 | |
|                 continue
 | |
|             fi
 | |
|             cmd="${cmd:+"$cmd "}$(quoted_arg "$1")"
 | |
|             shift
 | |
|         done
 | |
|         [ -n "$cmd" ] && cmds=("${cmds[@]}" "$cmd")
 | |
|         cmd=
 | |
|     fi
 | |
|     for cmd in "${cmds[@]}"; do
 | |
|         eval "set -- $cmd"
 | |
|         cmd="$1"; shift
 | |
|         xempty=
 | |
|         xdel=
 | |
|         last_is_cut=
 | |
|         case "$cmd" in
 | |
|         u|uncut)
 | |
|             if [ -n "$first" -a -n "$auto_uncut" ]; then
 | |
|                 # l'uncut automatique est demandé, et la première commande est
 | |
|                 # uncut: pas besoin de faire l'uncut automatique
 | |
|                 auto_uncut=
 | |
|             fi
 | |
|             cmdparts=(uncut_lines)
 | |
|             ;;
 | |
|         c|cut)
 | |
|             cmdparts=(cut_lines)
 | |
|             last_is_cut=1
 | |
|             ;;
 | |
|         dec|decode) cmdparts=(tl_decode "$(def_match_attr "$@")");;
 | |
|         enc|encode) cmdparts=(tl_encode "$(def_match_attr "$@")");;
 | |
|         xe|xempty|excludeempty) cmdparts=(ensure_complete_objects);;
 | |
|         k|keep|keepattr)
 | |
|             [ "$1" == --no-xempty ] && shift || xempty=1
 | |
|             cmdparts=(tl_keepattr "$(def_match_attr dn "$@")")
 | |
|             ;;
 | |
|         K|kv|keepval)
 | |
|             [ "$1" == --no-xempty ] && shift || xempty=1
 | |
|             local match_attr="$(def_match_attr "$1")"; shift
 | |
|             cmdparts=(tl_keepval "$match_attr" "$(def_match_value "$@")")
 | |
|             ;;
 | |
|         x|exclude|excludeattr)
 | |
|             [ "$1" == --no-xempty ] && shift || xempty=1
 | |
|             cmdparts=(tl_excludeattr "$(def_match_attr "$@")")
 | |
|             ;;
 | |
|         dv|delval|X|xv|excludeval)
 | |
|             [ "$1" == --no-xempty ] && shift || xempty=1
 | |
|             local match_attr="$(def_match_attr "$1")"; shift
 | |
|             cmdparts=(tl_excludeval "$match_attr" "$(def_match_value "$@")")
 | |
|             ;;
 | |
|         xve|excludevalentry)
 | |
|             local match_attr="$(def_match_attr "$1")"; shift
 | |
|             cmdparts=(tl_excludevalentry "$match_attr" "$(def_match_value "$@")")
 | |
|             xdel=1
 | |
|             ;;
 | |
|         kve|keepvalentry)
 | |
|             local match_attr="$(def_match_attr "$1")"; shift
 | |
|             cmdparts=(tl_keepvalentry "$match_attr" "$(def_match_value "$@")")
 | |
|             xdel=1
 | |
|             ;;
 | |
|         sv|setval|rv|replval)
 | |
|             local match_attr="$(def_match_attr "$1")"; shift
 | |
|             cmdparts=(tl_replval "$match_attr" "$@")
 | |
|             ;;
 | |
|         av|addval) cmdparts=(tl_addval "$@");;
 | |
|         fv|defval) cmdparts=(tl_defval "$@");;
 | |
|         ev|ensureval) cmdparts=(tl_ensureval "$@");;
 | |
|         sed|awk|grep|sort) cmdparts=(LANG=C "$cmd" "$@");;
 | |
|         csed|cawk|cgrep|csort) cmdparts=(LANG=C "${cmd#c}" "$@");;
 | |
|         lsed|lawk|lgrep|lsort) cmdparts=("${cmd#l}" "$@");;
 | |
|         awkrun|cawkrun) cmdparts=(cawkrun "$@");;
 | |
|         lawkrun) cmdparts=(lawkrun "$@");;
 | |
|         awkcsv|csvawk|cawkcsv) cmdparts=(cawkcsv "$@");;
 | |
|         lawkcsv) cmdparts=(lawkcsv "$@");;
 | |
|         mergecsv|cmergecsv) cmdparts=(cmergecsv "$@");;
 | |
|         lmergecsv) cmdparts=(lmergecsv "$@");;
 | |
|         sortcsv|csortcsv) cmdparts=(csortcsv "$@");;
 | |
|         lsortcsv) cmdparts=(lsortcsv "$@");;
 | |
|         f|format) cmdparts=(tl_format "$@");;
 | |
|         fcsv|formatcsv|format_csv|csv) cmdparts=(tl_formatcsv "$@");;
 | |
|         pcsv|parsecsv|parse_csv) cmdparts=(tl_parsecsv "$@");;
 | |
|         pcsvmod|parsecsvmod|parse_csvmod) cmdparts=(tl_parsecsvmod "$@");;
 | |
|         A|modaddattr) cmdparts=(tl_addattr);;
 | |
|         a|ma|modadd|modaddval) cmdparts=(tl_modifyattr add);;
 | |
|         r|mr|modrepl|modreplval) cmdparts=(tl_modifyattr replace);;
 | |
|         d|md|moddel|moddelval) cmdparts=(tl_modifyattr delete);;
 | |
|         D|moddelattr) cmdparts=(tl_deleteattr);;
 | |
|         delentry|moddelentry) cmdparts=(tl_deleteentry);;
 | |
|         touch|touchentry|modtouchentry) cmdparts=(tl_touchentry);;
 | |
|         litteral) cmdpars=("$@");;
 | |
|         *)
 | |
|             eerror "$cmd: commande inconnue. elle sera ignorée"
 | |
|             continue
 | |
|             ;;
 | |
|         esac
 | |
|         [ -n "$auto_uncut" ] && dest="${dest:+"$dest | "}"'uncut_lines'
 | |
|         dest="${dest:+"$dest | "}$(quoted_args "${cmdparts[@]}")"
 | |
|         [ -n "$xempty" ] && dest="${dest:+"$dest | "}"'ensure_complete_objects'
 | |
|         [ -n "$xdel" ] && dest="${dest:+"$dest | "}"'delete_marked_objects'
 | |
|         first=
 | |
|         auto_uncut=
 | |
|     done
 | |
|     [ -n "$auto_cut" -a -z "$last_is_cut" ] && dest="${dest:+"$dest | "}"'cut_lines'
 | |
|     echo "$dest"
 | |
| }
 | |
| function transform() { eval "$(get_transform_cmd "$@")"; }
 |