[x-posted to list] 

       How to get REBOL to tell you how big the messages are
       with the pop:// protocol. 

> Bo wrote:  
> Well, it's kind  of a hack, but   you can do this with  the
> standard REBOL:
> 
>      echo  %popread.txt  trace/net     on mbx:   open/direct
>      pop://user:[EMAIL PROTECTED] echo none
> ... 

  Whoah. That was inspiring.  :-) Below is a slightly modified
  version of the pop:// protocol which will store the message
  numbers and sizes together in a block within the port/locals
  sub-object.  For instamce:

    pop-port: open pop://user:pass@server
    probe pop-port/locals 

  ;- and you'll see a field called total size and sizes which 
  ;  contains the total size of your mail, and the sizes block
  ;  contains the message number followed by the size of that
  ;  message. 

  We'll go ahead and add this to the next version, but until
  then here it is:

  ----------------------------------------------------------

REBOL [
    Title: "A slightly modified version of pop"
]


make Root-Protocol [
    {Communicate with POP.  This protocol is block oriented not
    string oriented.}
    
    port-flags: system/standard/port-flags/pass-thru

    open-check:  [  ; port is bound to confirm frame
        none "+OK"
        ["USER" port/user] "+OK"
        ["PASS" port/pass] "+OK"
    ]
    close-check: ["QUIT" "+OK"]
    write-check: [none   "+OK"]
    stat-check:  ["STAT" "+OK"]
    list-check:  ["LIST" "+OK"]

    open: func [port /total][
        open-proto port
        port/state/tail: second total: load net-utils/confirm port/sub-port stat-check
        port/locals: make object! [
                total-size: third total
            net-utils/confirm port/sub-port list-check 
            sizes: load read-til-dot port make string! 100 
            msg-nums: make block! port/state/tail
            repeat n port/state/tail [append msg-nums n] ; lookaside index
        ]
        port/state/index: 0   ; a zero based index
    ]

    read-til-dot: func [port buf][
        while [(line: system/words/pick port/sub-port 1) <> "."] [
            insert tail buf line
            insert tail buf newline
        ]
        buf
    ]
    read-message: func [
        "Read a message from the POP server"
        port 
        n [integer!]
        /local buf line
    ][
        insert port/sub-port reform [
            "RETR" system/words/pick port/locals/msg-nums port/state/index + n]
        net-utils/confirm port/sub-port write-check
        read-til-dot port buf: make string! 1024  ; guess at size
    ]
    
    pick: func [
        "Read the Nth message from the POP port"
        port
    ][
        read-message port 1
    ]

    copy: func [
        "Copy a set of messages into a block"
        port
        /local msgs n
    ][
        msgs: make block! port/state/num
        repeat n port/state/num [
            append msgs read-message port n
        ]
        msgs
    ]

    remove: func [
        "Remove the current message"
        port
    ][
        while [ port/state/num > 0 ][
            insert port/sub-port reform [
                "DELE" system/words/pick port/locals/msg-nums port/state/index + 1]
            net-utils/confirm port/sub-port write-check
            system/words/remove at port/locals/msg-nums port/state/index + 1
            port/state/tail: port/state/tail - 1
            port/state/num: port/state/num - 1
        ]
        port
    ]

    net-utils/net-install POP self 110
]


Reply via email to