class MyOptions
def self.parse(args)
opts = OpenStruct.new
- opts.mailboxes = Array.new
+ opts.mailboxes = Array.new
# Fill in $opts values
parser = OptionParser.new do |myparser|
myparser.on("--username USERNAME", "-u",
"Email account to fetch. (example: \
RareCactus@gmail.com)") do |u|
- opts.username = u
+ opts.username = u
end
myparser.on("--list-folders", "-l",
"List the IMAP folders that are present.") do |a|
- raise "can only specify one action" if (opts.action)
- opts.action = :list
+ raise "can only specify one action" if (opts.action)
+ opts.action = :list
end
myparser.on("--snarf", "-S",
- "Copy mail to the current directory.") do |a|
- raise "can only specify one action" if (opts.action)
- opts.action = :snarf
- end
+ "Copy mail to the current directory.") do |a|
+ raise "can only specify one action" if (opts.action)
+ opts.action = :snarf
+ end
myparser.on("--box [MAILBOX]", "-b",
"Act on a given mailbox. You may specify -b more than once for \
multiple mailboxes.") do |a|
- opts.mailboxes << a
+ opts.mailboxes << a
end
myparser.on("--server [SERVER]", "-s",
- "Email server to use") do |u|
- opts.server = u
- end
+ "Email server to use") do |u|
+ opts.server = u
+ end
end
parser.parse!(args)
# Get a password from STDIN without echoing it.
# This is kind of ugly, but it does work.
def get_password(prompt)
- shell_cmds = 'stty -echo && read password && echo ${password}'
- printf "#{prompt}"
- STDOUT.flush
- pass = ""
- pipe = IO.popen(shell_cmds, "r") do |pipe|
- pass = pipe.read
- end
- echo_status = $?.exitstatus
- system("stty sane")
- puts
- if (echo_status != 0) then
- raise "get_password: error executing: #{shell_cmds}"
- end
- return pass.chomp
+ shell_cmds = 'stty -echo && read password && echo ${password}'
+ printf "#{prompt}"
+ STDOUT.flush
+ pass = ""
+ pipe = IO.popen(shell_cmds, "r") do |pipe|
+ pass = pipe.read
+ end
+ echo_status = $?.exitstatus
+ system("stty sane")
+ puts
+ if (echo_status != 0) then
+ raise "get_password: error executing: #{shell_cmds}"
+ end
+ return pass.chomp
end
def format_uid(uid)
- # We don't know how to deal with non-numeric UIDs. Best just to leave them
- # alone.
- return uid if (uid =~ /[^0123456789]/)
+ # We don't know how to deal with non-numeric UIDs. Best just to leave them
+ # alone.
+ return uid if (uid =~ /[^0123456789]/)
- # Pad numeric uids out to 6 digits
- return sprintf("%006d", uid)
+ # Pad numeric uids out to 6 digits
+ return sprintf("%006d", uid)
end
def snarf_mailbox(imap, mailbox)
- imap.select(mailbox)
- count = 0
+ imap.select(mailbox)
+ count = 0
total_count = 0
- imap.search(["NOT", "DELETED"]).each do |message_id|
- data = imap.fetch(message_id, [ "UID", "RFC822.HEADER", "RFC822.TEXT" ])
- a = data[0].attr
- filename = "#{mailbox}#{format_uid(a["UID"])}"
- fp = File.open(filename, 'w')
- fp.write(a["RFC822.HEADER"])
- fp.write(a["RFC822.TEXT"])
- fp.close
- count = count + 1
+ imap.search(["NOT", "DELETED"]).each do |message_id|
+ data = imap.fetch(message_id, [ "UID", "RFC822.HEADER", "RFC822.TEXT" ])
+ a = data[0].attr
+ filename = "#{mailbox}#{format_uid(a["UID"])}"
+ fp = File.open(filename, 'w')
+ fp.write(a["RFC822.HEADER"])
+ fp.write(a["RFC822.TEXT"])
+ fp.close
+ count = count + 1
total_count = total_count + 1
- if (count > 10) then
- count = 0
- printf(".")
- STDOUT.flush()
- end
- end
- puts "fetched #{total_count} messages from #{mailbox}"
+ if (count > 10) then
+ count = 0
+ printf(".")
+ STDOUT.flush()
+ end
+ end
+ puts "fetched #{total_count} messages from #{mailbox}"
end
# MAIN
imap.login($opts.username, password)
case ($opts.action)
when :list
- imap.list("", "*").each do |mbl|
- puts "#{mbl.name}"
- end
+ imap.list("", "*").each do |mbl|
+ puts "#{mbl.name}"
+ end
when :snarf
- $opts.mailboxes.each do |mailbox|
- snarf_mailbox(imap, mailbox)
- end
+ $opts.mailboxes.each do |mailbox|
+ snarf_mailbox(imap, mailbox)
+ end
else
- raise "unknown action #{$opts.action}"
+ raise "unknown action #{$opts.action}"
end
imap.logout()
imap.disconnect()