⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgin.tcl

📁 用于TCL/TK的可视化集成开发环境.(GUI)
💻 TCL
📖 第 1 页 / 共 4 页
字号:
  }  # Append format code for binary result:  append out [binary format S 1]  pgtcl::sendmsg $db F $out  set result {}  set result_size 0  # Fake up a partial result structure for pgtcl::common_message :  set res(error) ""  # FunctionCall response. Also handles common messages (notify, notice).  while {[set c [pgtcl::readmsg $db]] != "Z"} {    if {$c == "V"} {      set result_size [pgtcl::get_int32 $db]      if {$result_size > 0} {        set result [pgtcl::get_bytes $db $result_size]      } else {        set result ""      }    } elseif {![pgtcl::common_message $c $db res]} {      error "Unexpected reply from database: $c"    }  }  set pgtcl::xstate($db) [pgtcl::get_byte $db]  if {$res(error) != ""} {    error $res(error)  }  return $result_size}# === Public prodedures: Function Call ===# Public interface to pgtcl::callfn.proc pg_callfn {db fname result_name arginfo args} {  upvar $result_name result  return [pgtcl::callfn $db [pgtcl::getfnoid $db $fname] result $arginfo $args]}# Public, simplified interface to pgtcl::callfn when an int32 return value is# expected. Returns the backend function return value.proc pg_callfn_int {db fname arginfo args} {  set n [pgtcl::callfn $db [pgtcl::getfnoid $db $fname] result $arginfo $args]  if {$n != 4} {     error "Unexpected response size ($result_size) to pg function call $fname"  }  binary scan $result I val  return $val}# === Internal procedure to support Large Object ===# Convert a LO mode string into the value of the constants used by libpq.# Note: libpgtcl uses a mode like INV_READ|INV_WRITE for lo_creat, but# r, w, or rw for lo_open (which it translates to INV_READ|INV_WRITE).# This seems like a mistake. The code here accepts either form for either.proc pgtcl::lomode {mode} {  set imode 0  if {[string match -nocase *INV_* $mode]} {    if {[string match -nocase *INV_READ* $mode]} {      set imode 0x40000    }    if {[string match -nocase *INV_WRITE* $mode]} {      set imode [expr {$imode + 0x20000}]    }  } else {    if {[string match -nocase *r* $mode]} {      set imode 0x40000    }    if {[string match -nocase *w* $mode]} {      set imode [expr {$imode + 0x20000}]    }  }  if {$imode == 0} {    error "Invalid large object mode $mode"  }  return $imode}# === Public prodedures: Large Object ===# Create large object and return OID.# See note regarding mode above at pgtcl::lomode.proc pg_lo_creat {db mode} {  if {[catch {pg_callfn_int $db lo_creat I [pgtcl::lomode $mode]} result]} {    error "Large Object create failed\n$result"  }  if {$result == -1} {    error "Large Object create failed"  }  return $result}# Open large object and return large object file descriptor.# See note regarding mode above at pgtcl::lomode.proc pg_lo_open {db loid mode} {  if {[catch {pg_callfn_int $db lo_open "I I" $loid [pgtcl::lomode $mode]} \      result]} {    error "Large Object open failed\n$result"  }  if {$result == -1} {    error "Large Object open failed"  }  return $result}# Close large object file descriptor.proc pg_lo_close {db lofd} {  if {[catch {pg_callfn_int $db lo_close I $lofd} result]} {    error "Large Object close failed\n$result"  }  return $result}# Delete large object:proc pg_lo_unlink {db loid} {  if {[catch {pg_callfn_int $db lo_unlink I $loid} result]} {    error "Large Object unlink failed\n$result"  }  return $result}# Read from large object.# Note: The original PostgreSQL documentation says it returns -1 on error,# which is a bad idea since you can't get to the error message. But it's# probably too late to change it, so we remain bug compatible.proc pg_lo_read {db lofd buf_name maxlen} {  upvar $buf_name buf  if {[catch {pg_callfn $db loread buf "I I" $lofd $maxlen} result]} {    return -1  }  return $result}# Write to large object. At most $len bytes are written.# See note above on pg_lo_read error return.proc pg_lo_write {db lofd buf len} {  if {[set buflen [string length $buf]] < $len} {    set len $buflen  }  if {[catch {pg_callfn_int $db lowrite "I $len" $lofd $buf} result]} {    return -1  }  return $result}# Seek to offset inside large object:proc pg_lo_lseek {db lofd offset whence} {  switch $whence {    SEEK_SET { set iwhence 0 }    SEEK_CUR { set iwhence 1 }    SEEK_END { set iwhence 2 }    default { error "'whence' must be SEEK_SET, SEEK_CUR, or SEEK_END" }  }  if {[catch {pg_callfn_int $db lo_lseek "I I I" $lofd $offset $iwhence} \      result]} {    error "Large Object seek failed\n$result"  }  return $result}# Return location of file offset in large object:proc pg_lo_tell {db lofd} {  if {[catch {pg_callfn_int $db lo_tell I $lofd} result]} {    error "Large Object tell offset failed\n$result"  }  return $result}# Import large object. Wrapper for lo_creat, lo_open, lo_write.# Returns Large Object OID, which should be stored in a table somewhere.proc pg_lo_import {db filename} {  if {[catch {open $filename} f]} {    error "Large object import of $filename failed\n$f"  }  fconfigure $f -translation binary  set loid [pg_lo_creat $db INV_READ|INV_WRITE]  set lofd [pg_lo_open $db $loid w]  while {1} {    set buf [read $f 32768]    if {[set len [string length $buf]] == 0} break    if {[pg_lo_write $db $lofd $buf $len] != $len} {      error "Large Object import failed to write $len bytes"    }  }  pg_lo_close $db $lofd  close $f  return $loid}# Export large object. Wrapper for lo_open, lo_read.proc pg_lo_export {db loid filename} {  if {[catch {open $filename w} f]} {    error "Large object export to $filename failed\n$f"  }  fconfigure $f -translation binary  if {[catch {pg_lo_open $db $loid r} lofd]} {    error "Large Object export to $filename failed\n$lofd"  }  while {[set len [pg_lo_read $db $lofd buf 32768]] > 0} {    puts -nonewline $f $buf  }  pg_lo_close $db $lofd  close $f}# === MD5 Checksum procedures for password authentication ===# Coded in Tcl by ljb <lbayuk@mindspring.com>, using these sources:#  RFC1321#  PostgreSQL: src/backend/libpq/md5.c# If you want a better/faster MD5 implementation, see tcllib.namespace eval md5 { }# Round 1 helper, e.g.:#   a = b + ROT_LEFT((a + F(b, c, d) + X[0] + 0xd76aa478), 7)#       p1            p2    p1 p3 p4   p5        p6        p7# Where F(x,y,z) = (x & y) | (~x & z)#proc md5::round1 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p1 & $p3 | ~$p1 & $p4) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Round 2 helper, e.g.:#   a = b + ROT_LEFT((a + G(b, c, d) + X[1] + 0xf61e2562), 5)#       p1            p2    p1 p3 p4   p5        p6        p7# Where G(x,y,z) = (x & z) | (y & ~z)#proc md5::round2 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p1 & $p4 | $p3 & ~$p4) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Round 3 helper, e.g.:#   a = b + ROT_LEFT((a + H(b, c, d) + X[5] + 0xfffa3942), 4)#       p1            p2    p1 p3 p4   p5     p6           p7# Where H(x, y, z) = x ^ y ^ z#proc md5::round3 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p1 ^ $p3 ^ $p4) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Round 4 helper, e.g.:#   a = b + ROT_LEFT((a + I(b, c, d) + X[0] + 0xf4292244), 6)#       p1            p2    p1 p3 p4   p5     p6           p7# Where I(x, y, z) = y ^ (x | ~z)#proc md5::round4 {p1 p2 p3 p4 p5 p6 p7} {  set r [expr {$p2 + ($p3 ^ ($p1 | ~$p4)) + $p5 + $p6}]  return [expr {$p1 + ($r << $p7 | (($r >> (32 - $p7)) & ((1 << $p7) - 1)))}]}# Do one set of rounds. Updates $state(0:3) with results from $x(0:16).proc md5::round {x_name state_name} {  upvar $x_name x $state_name state  set a $state(0)  set b $state(1)  set c $state(2)  set d $state(3)  # Round 1, steps 1-16  set a [round1 $b $a $c $d $x(0)  0xd76aa478  7]  set d [round1 $a $d $b $c $x(1)  0xe8c7b756 12]  set c [round1 $d $c $a $b $x(2)  0x242070db 17]  set b [round1 $c $b $d $a $x(3)  0xc1bdceee 22]  set a [round1 $b $a $c $d $x(4)  0xf57c0faf  7]  set d [round1 $a $d $b $c $x(5)  0x4787c62a 12]  set c [round1 $d $c $a $b $x(6)  0xa8304613 17]  set b [round1 $c $b $d $a $x(7)  0xfd469501 22]  set a [round1 $b $a $c $d $x(8)  0x698098d8  7]  set d [round1 $a $d $b $c $x(9)  0x8b44f7af 12]  set c [round1 $d $c $a $b $x(10) 0xffff5bb1 17]  set b [round1 $c $b $d $a $x(11) 0x895cd7be 22]  set a [round1 $b $a $c $d $x(12) 0x6b901122  7]  set d [round1 $a $d $b $c $x(13) 0xfd987193 12]  set c [round1 $d $c $a $b $x(14) 0xa679438e 17]  set b [round1 $c $b $d $a $x(15) 0x49b40821 22]  # Round 2, steps 17-32  set a [round2 $b $a $c $d $x(1)  0xf61e2562  5]  set d [round2 $a $d $b $c $x(6)  0xc040b340  9]  set c [round2 $d $c $a $b $x(11) 0x265e5a51 14]  set b [round2 $c $b $d $a $x(0)  0xe9b6c7aa 20]  set a [round2 $b $a $c $d $x(5)  0xd62f105d  5]  set d [round2 $a $d $b $c $x(10) 0x02441453  9]  set c [round2 $d $c $a $b $x(15) 0xd8a1e681 14]  set b [round2 $c $b $d $a $x(4)  0xe7d3fbc8 20]  set a [round2 $b $a $c $d $x(9)  0x21e1cde6  5]  set d [round2 $a $d $b $c $x(14) 0xc33707d6  9]  set c [round2 $d $c $a $b $x(3)  0xf4d50d87 14]  set b [round2 $c $b $d $a $x(8)  0x455a14ed 20]  set a [round2 $b $a $c $d $x(13) 0xa9e3e905  5]  set d [round2 $a $d $b $c $x(2)  0xfcefa3f8  9]  set c [round2 $d $c $a $b $x(7)  0x676f02d9 14]  set b [round2 $c $b $d $a $x(12) 0x8d2a4c8a 20]  # Round 3, steps 33-48  set a [round3 $b $a $c $d $x(5)  0xfffa3942  4]  set d [round3 $a $d $b $c $x(8)  0x8771f681 11]  set c [round3 $d $c $a $b $x(11) 0x6d9d6122 16]  set b [round3 $c $b $d $a $x(14) 0xfde5380c 23]  set a [round3 $b $a $c $d $x(1)  0xa4beea44  4]  set d [round3 $a $d $b $c $x(4)  0x4bdecfa9 11]  set c [round3 $d $c $a $b $x(7)  0xf6bb4b60 16]  set b [round3 $c $b $d $a $x(10) 0xbebfbc70 23]  set a [round3 $b $a $c $d $x(13) 0x289b7ec6  4]  set d [round3 $a $d $b $c $x(0)  0xeaa127fa 11]  set c [round3 $d $c $a $b $x(3)  0xd4ef3085 16]  set b [round3 $c $b $d $a $x(6)  0x04881d05 23]  set a [round3 $b $a $c $d $x(9)  0xd9d4d039  4]  set d [round3 $a $d $b $c $x(12) 0xe6db99e5 11]  set c [round3 $d $c $a $b $x(15) 0x1fa27cf8 16]  set b [round3 $c $b $d $a $x(2)  0xc4ac5665 23]  # Round 4, steps 49-64  set a [round4 $b $a $c $d $x(0)  0xf4292244  6]  set d [round4 $a $d $b $c $x(7)  0x432aff97 10]  set c [round4 $d $c $a $b $x(14) 0xab9423a7 15]  set b [round4 $c $b $d $a $x(5)  0xfc93a039 21]  set a [round4 $b $a $c $d $x(12) 0x655b59c3  6]  set d [round4 $a $d $b $c $x(3)  0x8f0ccc92 10]  set c [round4 $d $c $a $b $x(10) 0xffeff47d 15]  set b [round4 $c $b $d $a $x(1)  0x85845dd1 21]  set a [round4 $b $a $c $d $x(8)  0x6fa87e4f  6]  set d [round4 $a $d $b $c $x(15) 0xfe2ce6e0 10]  set c [round4 $d $c $a $b $x(6)  0xa3014314 15]  set b [round4 $c $b $d $a $x(13) 0x4e0811a1 21]  set a [round4 $b $a $c $d $x(4)  0xf7537e82  6]  set d [round4 $a $d $b $c $x(11) 0xbd3af235 10]  set c [round4 $d $c $a $b $x(2)  0x2ad7d2bb 15]  set b [round4 $c $b $d $a $x(9)  0xeb86d391 21]  incr state(0) $a  incr state(1) $b  incr state(2) $c  incr state(3) $d}# Pad out buffer per MD5 spec:proc md5::pad {buf_name} {  upvar $buf_name buf  # Length in bytes:  set len [string length $buf]  # Length in bits as 2 32 bit words:  set len64hi [expr {$len >> 29 & 7}]  set len64lo [expr {$len << 3}]  # Append 1 special byte, then append 0 or more 0 bytes until  # (length in bytes % 64) == 56  set pad [expr {64 - ($len + 8) % 64}]  append buf [binary format a$pad "\x80"]  # Append the length in bits as a 64 bit value, low bytes first.  append buf [binary format i1i1 $len64lo $len64hi]}# Calculate MD5 Digest over a string, return as 32 hex digit string.proc md5::digest {buf} {  # This is 0123456789abcdeffedcba9876543210 in byte-swapped order:  set state(0) 0x67452301  set state(1) 0xEFCDAB89  set state(2) 0x98BADCFE  set state(3) 0x10325476  # Pad buffer per RFC to exact multiple of 64 bytes.  pad buf  # Calculate digest in 64 byte chunks:  set nwords 0  set nbytes 0  set word 0  binary scan $buf c* bytes  # Unclear, but the data seems to get byte swapped here.  foreach c $bytes {    set word [expr {$c << 24 | ($word >> 8 & 0xffffff) }]    if {[incr nbytes] == 4} {      set nbytes 0      set x($nwords) $word      set word 0      if {[incr nwords] == 16} {        round x state        set nwords 0      }    }  }  # Result is state(0:3), but each word is taken low byte first.  set result {}  for {set i 0} {$i <= 3} {incr i} {    set w $state($i)    append result [format %02x%02x%02x%02x \             [expr {$w & 255}] \             [expr {$w >> 8 & 255}] \             [expr {$w >> 16 & 255}] \             [expr {$w >> 24 & 255}]]  }  return $result}package provide pgintcl $pgtcl::version

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -