diff --git a/exec/imapservice.js b/exec/imapservice.js index 8735a267313de440757bafcce2e686956f2b3c46..f6498273bb797b7e578d7fc00fbbec421a8fa278 100644 --- a/exec/imapservice.js +++ b/exec/imapservice.js @@ -83,7 +83,7 @@ function encode_string(str) function get_from(hdr) { // From - if(!hdr.from_net_type || !hdr.from_net_addr) /* local message */ + if(!hdr.from_net_type || hdr.from_net_addr.length==0) /* local message */ return(hdr.from + " <" + hdr.from.replace(/ /g,".").toLowerCase() + "@" + system.inetaddr + ">"); else if(!hdr.from_net_addr.length) return(hdr.from); @@ -108,7 +108,7 @@ function send_fetch_response(msgnum, fmat, uid) var seen_changed=false; var envelope; - idx=base.get_msg_index(msgnum); + idx=index.idx[msgnum]; function get_header() { if(hdr == undefined) { @@ -139,6 +139,10 @@ function send_fetch_response(msgnum, fmat, uid) rfc822.header += "Newsgroups: "+hdr.newsgroups+"\r\n"; if(hdr.replyto != undefined) rfc822.header += "Reply-To: "+hdr.replyto+"\r\n"; + else { + if(base.subnum != -1) + rfc822.header += "Reply-To: "+hdr.from+" <sub:"+base.cfg.code+"@"+system.inet_addr+">\r\n"; + } if(hdr.reply_id != undefined) rfc822.header += "In-Reply-To: "+hdr.reply_id+"\r\n"; if(hdr.references != undefined) @@ -201,16 +205,20 @@ function send_fetch_response(msgnum, fmat, uid) function set_seen_flag() { if(readonly) return; - if(base.subnum==65535) { + if(base.subnum==-1) { get_header(); if(!(hdr.attr & MSG_READ)) { hdr.attr |= MSG_READ; base.put_msg_header(msgnum); + index=read_index(base); hdr=base.get_msg_header(msgnum); if(hdr.attr & MSG_READ) seen_changed=true; } } + else { + idx.attr |= MSG_READ; + } } function get_envelope() { @@ -229,8 +237,14 @@ function send_fetch_response(msgnum, fmat, uid) if((m2=m[1].match(/^\s*(.*)\s+<([^@]*)@(.*)>\s*$/))!=null) { return '(('+[encode_string(m2[1]), "NIL", encode_string(m2[2]), encode_string(m2[3])].join(" ")+'))'; } - else if((m2=m[1].match(/^\s*(.*)\s+<([^@]i)>\s*$/))!=null) { - return '(('+[encode_string(m2[1]), "NIL", encode_string(m2[2]), NIL].join(" ")+'))'; + else if((m2=m[1].match(/^\s*(.*)\s+<([^@]*)>\s*$/))!=null) { + return '(('+[encode_string(m2[1]), "NIL", encode_string(m2[2]), "NIL"].join(" ")+'))'; + } + else if((m2=m[1].match(/^\s*<([^@]*)@(.*)>\s*$/))!=null) { + return '(('+["NIL", "NIL", encode_string(m2[1]), encode_string(m2[2])].join(" ")+'))'; + } + else if((m2=m[1].match(/^\s*([^@]*)@(.*)\s*$/))!=null) { + return '(('+["NIL", "NIL", encode_string(m2[1]), encode_string(m2[2])].join(" ")+'))'; } else return '(('+[encode_string(m[1]), "NIL", "NIL", "NIL"].join(" ")+'))'; @@ -259,10 +273,7 @@ function send_fetch_response(msgnum, fmat, uid) } } - if(base.subnum==65535) - resp=inbox_map.offset[msgnum]; - else - resp=idx.offset+1; + resp=idx.offset; resp += " FETCH ("; // Moves flags to the end... @@ -365,7 +376,7 @@ function send_fetch_response(msgnum, fmat, uid) switch(fmat[i].toUpperCase()) { case 'FLAGS': get_header(); - resp += "FLAGS ("+calc_msgflags(hdr.attr, hdr.netattr, base.subnum==65535, base.cfg==undefined?null:base.cfg.code, msgnum, readonly)+") "; + resp += "FLAGS ("+calc_msgflags(idx.attr, hdr.netattr, base.subnum, msgnum, readonly)+") "; sent_flags=true; break; case 'UID': @@ -405,11 +416,11 @@ function send_fetch_response(msgnum, fmat, uid) } if(seen_changed && !sent_flags) { get_header(); - resp += "FLAGS ("+calc_msgflags(hdr.attr, hdr.netattr, base.subnum==65535, base.cfg==undefined?null:base.cfg.code, msgnum, readonly)+") "; + resp += "FLAGS ("+calc_msgflags(idx.attr, hdr.netattr, base.subnum, msgnum, readonly)+") "; } if(uid && !sent_uid) resp += "UID "+idx.number+" "; - resp=resp.replace(/\s*$/,''); + resp=resp.replace(/ $/,''); resp += ")"; untagged(resp); } @@ -448,15 +459,12 @@ function parse_seq_set(set, uid) { var i; var max; var idx; + var msgnum; if(uid) max=base.last_msg; - else { - if(base.subnum==65535) - max=inbox_map.uid.length; - else - max=base.total_msgs; - } + else + max=index.offsets.length-1; for(chunk in chunks) { range=chunks[chunk].split(/:/); if(range.length == 1) @@ -473,16 +481,12 @@ function parse_seq_set(set, uid) { range[1]=i; } for(i=range[0]; i<=range[1]; i++) { - if(base.subnum==65535) { - idx=base.get_msg_index(uid?parseInt(i,10):inbox_map.uid[parseInt(i,10)-1]); - if(idx==null || idx.to != user.number) - continue; - } - else - idx=base.get_msg_index(uid?false:true, parseInt(i,10)-(uid?0:1)); - if(idx!=null) { - response.push(idx.number); - } + msgnum=parseInt(i, 10); + if(!uid) + msgnum=index.offsets[msgnum-1]; + if(msgnum==undefined || index.idx[msgnum]==undefined) + continue; + response.push(msgnum); } } response=response.sort(compNumbers); @@ -616,7 +620,7 @@ const Authenticated=1; const Selected=2; var state=UnAuthenticated; var base; -var inbox_map; +var index={offsets:[],idx:{}}; // Command handling functions any_state_command_handlers = { @@ -641,7 +645,7 @@ any_state_command_handlers = { arguments:0, handler:function(args) { var tag=args[0]; - + untagged("BYE I'll go now"); tagged(tag, "OK", "Thanks for stopping by."); client.socket.close(); @@ -676,6 +680,7 @@ unauthenticated_command_handlers = { return; } tagged(tag, "OK", "Howdy."); + read_cfg(); state=Authenticated; } else @@ -694,6 +699,7 @@ unauthenticated_command_handlers = { return; } tagged(tag, "OK", "Sure, come on in."); + read_cfg(); state=Authenticated; }, } @@ -704,14 +710,8 @@ function sendflags(perm) var flags=""; var pflags=""; - if(base.subnum==65535) { - flags=calc_msgflags(0xffff, 0xffff, true, null, null, true); - pflags=calc_msgflags(0xffff, 0xffff, true, null, null, true); - } - else { - flags=calc_msgflags(0xffff, 0xffff, false, null, null, true); - pflags=calc_msgflags(0xffff, 0xffff, false, null, null, true); - } + flags=calc_msgflags(0xffff, 0xffff, base.subnum, base.last_msg, readonly); + pflags=calc_msgflags(0xffff, 0xffff, base.subnum, base.last_msg, readonly); if(perm) untagged("OK [PERMANENTFLAGS ("+pflags+")] Overkill!"); else @@ -726,7 +726,6 @@ function parse_flags(inflags) for(i in inflags) { switch(inflags[i].toUpperCase()) { case '\\SEEN': - case 'READ': flags.attr |= MSG_READ; break; case '\\ANSWERED': @@ -829,18 +828,14 @@ function check_msgflags(attr, netattr, ismail, touser, fromuser, isoperator) return(flags); } -function calc_msgflags(attr, netattr, ismail, code, msg, readonly) +function calc_msgflags(attr, netattr, num, msg, readonly) { var flags=''; if(attr & MSG_PRIVATE) flags += "PRIVATE "; - if(attr & MSG_READ) { - if(base.subnum==65535) - flags += "\\Seen "; - else - flags += "READ "; - } + if(attr & MSG_READ) + flags += "\\Seen "; if(attr & MSG_PERMANENT) flags += "PERMANENT "; if(attr & MSG_LOCKED) @@ -856,7 +851,7 @@ function calc_msgflags(attr, netattr, ismail, code, msg, readonly) if(attr & MSG_VALIDATED) flags += "\\Flagged "; if(attr & MSG_REPLIED) { - if(base.subnum==65535) + if(num==-1) flags += "\\Answered "; else flags += "REPLIED "; @@ -893,13 +888,15 @@ function calc_msgflags(attr, netattr, ismail, code, msg, readonly) if(netattr & MSG_TYPENET) flags += "TYPENET "; - if(msg==null || msg_ptrs[code] < msg) { + if(attr==0xffff || orig_ptrs[num] < msg) { flags += '\\Recent '; } if(!readonly) { - if(msg > msg_ptrs[code]) - msg_ptrs[code]=msg; + if(msg > msg_ptrs[num]) + msg_ptrs[num]=msg; + if(base != undefined && base.is_open) + scan_ptr=msg; } if(flags.length) @@ -946,7 +943,7 @@ function sublist(group, match, subscribed) for(sub in msg_area.grp_list[grp].sub_list) { if(re.test(msg_area.grp_list[grp].description+sepchar+msg_area.grp_list[grp].sub_list[sub].description)) { - if((!subscribed) || msg_area.grp_list[grp].sub_list[sub].scan_cfg&SCAN_CFG_NEW) + if((!subscribed) || (msg_area.grp_list[grp].sub_list[sub].scan_cfg&SCAN_CFG_NEW && (!(msg_area.grp_list[grp].sub_list[sub].scan_cfg&SCAN_CFG_YONLY)))) ret.push(msg_area.grp_list[grp].description+sepchar+msg_area.grp_list[grp].sub_list[sub].description); } } @@ -974,71 +971,57 @@ function getsub(longname) { return("NONE!!!"); } -function generate_inbox_map(base) +function count_unseen(index) { var i; - var idx; var count=0; - var unseen=0; - var uid=[]; - var offset={}; + var idx; - for(i=base.first_msg; i<=base.last_msg; i++) { - idx=base.get_msg_index(i); - if(idx != null) { - if(idx.to != user.number) - continue; - uid.push(idx.number); - offset[idx.number]=uid.length; - } + for(i in index.offsets) { + idx=index.idx[index.offsets[i]]; + if((idx.attr & MSG_READ)==0) + count++; } - return({uid:uid,unseen:unseen,offset:offset}); + return(count); } -function count_recent(base) +function count_recent(index, scan_ptr) { var i; var count=0; var idx; - if(base.cfg==undefined) - return 0; - for(i=base.first_msg; i<= base.last_msg; i++) { - idx=base.get_msg_index(i); - if(idx==null) - continue; - if(base.subnum==65535 && idx.to != user.number) - continue; - if(i > msg_area.sub[base.cfg.code].scan_ptr) - count++; + for(i in index.offsets) { + idx=index.idx[index.offsets[i]]; + if(idx.number > scan_ptr) + count++; } return(count); } function update_status() { + var i; + var idx; + if(base==undefined || !base.is_open) { - curr_status={exists:-1,recent:-1,unseen:-1,uidnext:-1,uidvalidity:-1}; + curr_status.exists=-1; + curr_status.recent=-1; + curr_status.unseen=-1; + curr_status.uidnext=-1; + curr_status.uidvalidity=-1; return; } - if(base.subnum==65535) { - inbox_map=generate_inbox_map(base); - curr_status.exists=inbox_map.uid.length; - curr_status.recent=count_recent(base); - curr_status.unseen=inbox_map.unseen; - if(inbox_map.uid.length > 0) - curr_status.uidnext=inbox_map.uid[inbox_map.uid.length-1]+1; - else - curr_status.uidnext=1; - curr_status.uidvalidity=0; - } - else { - curr_status.exists=base.total_msgs; - curr_status.recent=count_recent(base); - curr_status.unseen=base.total_msgs; - curr_status.uidnext=base.last_msg+1; - curr_status.uidvalidity=0; - } + if(base.subnum != index.subnum || base.last_msg != index.last) + index=read_index(base); + curr_status.exists=index.offsets.length; + curr_status.recent=count_recent(index, orig_ptrs[base.subnum]); + curr_status.unseen=count_unseen(index); + if(index.offsets.length == 0) + curr_status.uidnext=1; + else + curr_status.uidnext=index.idx[index.offsets[index.offsets.length-1]].number+1; + curr_status.uidvalidity=0; } function send_updates() @@ -1061,23 +1044,93 @@ function send_updates() } } -function open_sub(sub) +function read_index(base) { - if(base != undefined && base.is_open && base.cfg != undefined) { - if(msg_ptrs[base.cfg.code]!=orig_ptrs[base.cfg.code]) - msg_base.sub[base.cfg.code]=msg_ptrs[base.cfg.code]; + var i; + var idx; + var index; + + index={offsets:[],idx:{}}; + index.first=base.first_msg; + index.last=base.last_msg; + index.subnum=base.subnum; + index.total=base.total_msgs; + + if(base.cfg != undefined) + index.code=base.cfg.code; + for(i=0; i<index.total; i++) { + idx=base.get_msg_index(true,i); + if(idx==null) + continue; + if(base.subnum==-1) { + if(idx.to != user.number) + continue; + } + else { + // Fake \Seen + idx.attr &= ~MSG_READ; + if(idx.number <= msg_area.sub[base.cfg.code].scan_ptr) + idx.attr |= MSG_READ; + } + index.idx[idx.number]=idx; + index.offsets.push(idx.number); + idx.offset=index.offsets.length; + } + return(index); +} + +function exit_func() +{ + close_sub(); + save_cfg(); +} + +function save_cfg() +{ + var cfg; + + if(user.number > 0) { + cfg=new File(format(system.data_dir+"user/%04d.imap", user.number)); + if(cfg.open()) { + cfg.iniSetObject("inbox",saved_config.inbox); + cfg.close(); + } + } +} + +function close_sub() +{ + if(base != undefined && base.is_open) { + msg_ptrs[base.subnum]=scan_ptr; + if(msg_ptrs[base.subnum]!=orig_ptrs[base.subnum]) { + if(base.subnum==-1) { + saved_config.inbox.scan_ptr=scan_ptr; + } + else + msg_area.sub[base.cfg.code].scan_ptr=scan_ptr; + } base.close(); - update_status(); } +} + +function open_sub(sub) +{ + var i; + var idx; + + close_sub(); base=new MsgBase(sub); - if(base == undefined || (!base.open())) + if(base == undefined || sub=="NONE!!!" || (!base.open())) { + update_status(); return false; + } if(base.cfg != undefined) { - if(orig_ptrs[base.cfg.code]==undefined) { - orig_ptrs[base.cfg.code]=msg_area.sub[base.cfg.code]; - msg_ptrs[base.cfg.code]=msg_area.sub[base.cfg.code]; + if(orig_ptrs[base.subnum]==undefined) { + orig_ptrs[base.subnum]=msg_area.sub[base.cfg.code].scan_ptr; + msg_ptrs[base.subnum]=msg_area.sub[base.cfg.code].scan_ptr; } } + scan_ptr=orig_ptrs[base.subnum]; update_status(); sendflags(false); untagged(curr_status.exists+" EXISTS"); @@ -1123,12 +1176,13 @@ authenticated_command_handlers = { var tag=args[0]; var sub=getsub(args[1]); + readonly=false; if(!open_sub(sub)) { tagged(tag, "NO", "Can't find "+args[1]+" ("+sub+")"); + state=Authenticated; return; } tagged(tag, "OK", "[READ-WRITE] Mailbox "+sub+" has been selected"); - readonly=false; state=Selected; }, }, @@ -1138,12 +1192,13 @@ authenticated_command_handlers = { var tag=args[0]; var sub=getsub(args[1]); + readonly=true; if(!open_sub(sub)) { tagged(tag, "NO", "Can't find "+args[1]+" ("+sub+")"); + state=Authenticated; return; } tagged(tag, "OK", "[READ-ONLY] Mailbox "+sub+" has been examined"); - readonly=true; state=Selected; }, }, @@ -1239,7 +1294,7 @@ authenticated_command_handlers = { var response=[]; var base; var mademap=false; - var inbox_map; + var index; if(typeof(items)!="object") items=[items]; @@ -1248,29 +1303,23 @@ authenticated_command_handlers = { tagged(tag, "NO", "Can't find your mailbox"); return; } - if(base.cfg != undefined && orig_ptrs[base.cfg.code]==undefined) { - orig_ptrs[base.cfg.code]=msg_area.sub[base.cfg.code]; - msg_ptrs[base.cfg.code]=msg_area.sub[base.cfg.code]; - } + if(base.cfg != undefined && orig_ptrs[base.subnum]==undefined) + orig_ptrs[base.subnum]=msg_area.sub[base.cfg.code].scan_ptr; + index=read_index(base); + base.close(); for(i in items) { switch(items[i].toUpperCase()) { case 'MESSAGES': response.push("MESSAGES"); - if(base.subnum==65535) { - if(!mademap) - inbox_map=generate_inbox_map(base); - response.push(inbox_map.length); - } - else - response.push(base.total_msgs); + response.push(index.offsets.length); break; case 'RECENT': response.push("RECENT"); - response.push(count_recent(base)); + response.push(count_recent(index, orig_ptrs[base.subnum])); break; case 'UIDNEXT': response.push("UIDNEXT"); - response.push(base.last_msg+1); + response.push(index.idx[index.offsets[index.offsets.length-1]].number+1); break; case 'UIDVALIDITY': response.push("UIDVALIDITY"); @@ -1278,18 +1327,10 @@ authenticated_command_handlers = { break; case 'UNSEEN': response.push("UNSEEN"); - if(base.subnum==65535) { - if(!mademap) - inbox_map=generate_inbox_map(base); - response.push(inbox_map.unseen); - } - else - response.push(base.total_msgs+1); + response.push(count_unseen(index)); break; } } - base.close(); - update_status(); untagged("STATUS "+encode_string(args[1])+" ("+response.join(" ")+")"); tagged(tag, "OK", "And that's the way it is."); }, @@ -1336,12 +1377,14 @@ function do_store(seq, uid, item, data) chflags={attr:hdr.attr^(hdr.attr&~flags.attr), netattr:hdr.netattr^(hdr.netattr&~flags.netattr)}; break } - chflags=check_msgflags(chflags.attr, chflags.netattr, base.subnum==65535, hdr.to_net_type==NET_NONE?hdr.to==user.number:false, hdr.from_net_type==NET_NONE?hdr.from==user.number:false,base.is_operator); + chflags=check_msgflags(chflags.attr, chflags.netattr, base.subnum==-1, hdr.to_net_type==NET_NONE?hdr.to==user.number:false, hdr.from_net_type==NET_NONE?hdr.from==user.number:false,base.is_operator); if(chflags.attr || chflags.netattr) { hdr.attr ^= chflags.attr; hdr.netattr ^= chflags.netattr; - if(!readonly) + if(!readonly) { base.put_msg_header(seq[i], hdr); + index=read_index(base); + } hdr=base.get_msg_header(seq[i]); } if(!silent) @@ -1398,7 +1441,7 @@ function do_search(args, uid) search_set.idx.push(function(idx) { return true; }); break; case 'ANSWERED': - search_set.idx.push(function(idx) { if(base.subnum==65535 && (idx.attr & MSG_REPLIED)) return true; return false; }); + search_set.idx.push(function(idx) { if(base.subnum==-1 && (idx.attr & MSG_REPLIED)) return true; return false; }); break; case 'BODY': search_set.body.push(eval("function(body) { return(body.indexOf("+args.shift().toUpperCase().toSource()+")!=-1) }")); @@ -1419,20 +1462,16 @@ function do_search(args, uid) search_set.hdr.push(eval("function(hdr) { var flags="+parse_flags([args.shift()]).toSource()+"; if((hdr.attr & flags.attr)==flags.attr && (hdr.netattr & flags.netattr)==flags.netattr) return true; return false;}")); break; case 'NEW': - // TODO: We don't do \Recent in INBOX and don't do \Seen in subs - search_set.idx.push(eval("function(idx) { if(base.cfg==undefined) return false; if(msg_ptrs[base.cfg.code] < idx.number) return true; return false; }")); + search_set.idx.push(eval("function(idx) { if((idx.number > orig_ptrs[base.subnum]) && (idx.attr & MSG_READ)==0) return true; return false; }")); break; case 'OLD': - // TODO: We don't do \Recent in INBOX and don't do \Seen in subs - search_set.idx.push(eval("function(idx) { if(base.cfg==undefined) return true; if(msg_ptrs[base.cfg.code] < idx.number) return false; return true; }")); + search_set.idx.push(eval("function(idx) { if(idx.number <= orig_ptrs[base.subnum]) return true; return false; }")); break; case 'RECENT': - // TODO: We don't do \Recent in INBOX - search_set.idx.push(eval("function(idx) { if(base.cfg==undefined) return false; if(msg_ptrs[base.cfg.code] < idx.number) return true; return false; }")); + search_set.idx.push(eval("function(idx) { if(idx.number > orig_ptrs[base.subnum]) return true; return false; }")); break; case 'SEEN': - // We don't do \Seen in subs - search_set.idx.push(function(idx) { if(base.subnum != 65535) return false; if(idx.attr & MSG_READ) return true; return false }); + search_set.idx.push(function(idx) { if(idx.attr & MSG_READ) return true; return false }); break; case 'SUBJECT': search_set.hdr.push(eval("function(hdr) { return(hdr.subject.toUpperCase().indexOf("+args.shift().toUpperCase().toSource()+")!=-1) }")); @@ -1444,7 +1483,7 @@ function do_search(args, uid) search_set.idx.push(eval("function(idx) { var good_uids="+parse_seq_set(args.shift(), true).toSource()+"; var i; for(i in good_uids) { if(good_uids[i]==idx.number) return true; } return false; }")); break; case 'UNANSWERED': - search_set.idx.push(function(idx) { if(base.subnum==65535 && (idx.attr & MSG_REPLIED)) return false; return true; }); + search_set.idx.push(function(idx) { if(base.subnum==-1 && (idx.attr & MSG_REPLIED)) return false; return true; }); break; case 'UNDELETED': search_set.idx.push(function(idx) { if(idx.attr & MSG_DELETE) return false; return true; }); @@ -1496,15 +1535,9 @@ function do_search(args, uid) } } - for(i=base.first_msg; i<=base.last_msg; i++) { + for(i in index.offsets) { failed=false; - idx=base.get_msg_index(i); - if(idx==null) - continue; - if(base.subnum==65535) { - if(idx.to != user.number) - continue; - } + idx=index.idx[index.offsets[i]]; if(search_set.idx.length > 0) { for(j in search_set.idx) { if(search_set.idx[j](idx)==false) @@ -1514,7 +1547,7 @@ function do_search(args, uid) continue; } if(search_set.hdr.length > 0) { - hdr=base.get_msg_header(i); + hdr=base.get_msg_header(idx.number); for(j in search_set.hdr) { if(search_set.hdr[j](hdr)==false) failed=true; @@ -1522,9 +1555,8 @@ function do_search(args, uid) if(failed) continue; } - body=base.get_msg_index(i); if(search_set.body.length > 0) { - body=base.get_msg_body(i,true,true,true).toUpperCase(); + body=base.get_msg_body(idx.number,true,true,true).toUpperCase(); for(j in search_set.body) { if(search_set.body[j](body)==false) failed=true; @@ -1533,7 +1565,7 @@ function do_search(args, uid) continue; } if(!failed) - result.push(uid?idx.number:(base.subnum==65535?inbox_map.offset[i]:idx.offset+1)); + result.push(uid?idx.number:idx.offset); } untagged("SEARCH "+result.join(" ")); @@ -1553,11 +1585,7 @@ selected_command_handlers = { handler:function(args) { var tag=args[0]; - if(base.cfg != undefined) { - if(msg_ptrs[base.cfg.code]!=orig_ptrs[base.cfg.code]) - msg_base.sub[base.cfg.code]=msg_ptrs[base.cfg.code]; - } - base.close(); + close_sub(); update_status(); tagged(tag, "OK", "Closed."); state=Authenticated; @@ -1677,11 +1705,29 @@ selected_command_handlers = { } }; +function read_cfg() +{ + var cfg=new File(format(system.data_dir+"user/%04d.imap",user.number)); + + if(cfg.open("r+")) { + saved_config.inbox=cfg.iniGetObject("inbox"); + cfg.close(); + } + else + saved_config={inbox:{scan_ptr:0}}; + msg_ptrs[-1]=saved_config.inbox.scan_ptr; + orig_ptrs[-1]=saved_config.inbox.scan_ptr; +} + var line; var readonly=true; var orig_ptrs={}; var msg_ptrs={}; var curr_status={exists:0,recent:0,unseen:0,uidnext:0,uidvalidity:0}; +var saved_config={inbox:{scan_ptr:0}}; +var scan_ptr; + +js.on_exit("exit_func()"); client.socket.send("* OK Give 'er\r\n"); while(1) { line=client.socket.recvline(10240, 300);