def __init__(self, db, address, password, filename, length): print("from",address,"pw",password,"recv",filename,"len",length) # based on length choose to process data in memory (check received data length) # or save to disk # packets # bundles # freqs # tics # files self.db = db self.address = address if password is not None: if password == get_link_password(db, address): self.protected = True else: raise FTNWrongPassword() else: self.protected = False savedir = inbound_dir(address, self.protected, True) if not os.path.exists(savedir): os.makedirs(savedir) mod = 0 while True: try: self.file = os.path.join(savedir, modname(filename, mod)) self.fo = os.fdopen(os.open(self.file, os.O_CREAT | os.O_EXCL | os.O_WRONLY), "wb") # should add | os.O_BINARY break except OSError as e: if e.args[0]!=17: raise e mod += 1
for link_id in ftnconfig.find_link(node): my, pw = ftnaccess.link_password(db, link_id, True) # FIX choose sender address (=my) sess.send_message(ftnconfig.SYSOP, ("node", node), robot, None, pw, "-" + area) sess.forget_address(domain, area) exit() exit() # ??? outp = [] pw = ftnconfig.get_link_password(db, link, True) #print(pw) for echo in db.prepare( "select a.text from subscriptions s, addresses a " "where a.id=s.target and s.subscriber=$1 and a.domain=$2")( lid, db.FTN_domains[domain]): outp.append("+" + echo[0] + "\n") if len(outp) == 0: print("nothing to relink") else: print("".join(outp)) with ftnimport.session(db) as sess:
from socketutil import * try: os.mkdir("test") except: pass if not os.path.isdir("test"): print ("please make dir test") exit() s = socket.socket(socket.AF_INET) import ftnconfig db=ftnconfig.connectdb() password = ftnconfig.get_link_password(db, address) print (address, password) do_send = False s.connect(("127.0.0.1", 24555)) try: print(readline(s)) s.send(b"ADDRESS "+address.encode(encoding)+b"\n") s.send(b"PASSWORD "+password.encode(encoding)+b"\n") if do_send: s.send(b"FILENAME test1.dat\n") s.send(b"BINARY 100\n") s.send(b"*"*100)
#for k, v in hubs.items(): # print ("%-17s: "%k, ", ".join(v)) #print () #exit() downlinks = ftnexport.get_subnodes(db, ADDRESS) #print (downlinks) #exit() selfsubscribers = set() selfsubscribers.add(ADDRESS) selfsubscribers.add(ADDRESS+".999") # filter links that are not password-protected for x in list(links) + downlinks: if not get_link_password(db, x): print ("skip", x) else: selfsubscribers.add(x) #print ("direct links =", ", ".join(selfsubscribers)) # add subscription for self for l in selfsubscribers: hubs.setdefault(l, set()).add(l) #print ("subscriptions") #for k, v in hubs.items(): # print ("subscribe %s to"%k, ", ".join(v)) #print () #exit()
from ftnconfig import connectdb, get_link_password db = connectdb() fareas = {} for a, b in db.prepare( "select t.text, sr.text from subscriptions s, addresses sr, addresses t " "where s.subscriber=sr.id and s.target=t.id and t.domain=3")(): fareas.setdefault(a, set()).add(b) fa = open("fareas.bbs", "w") fa.write("*****\n") for k, v in fareas.items(): fa.write("/tank/home/fido/fareas/" + k.lower() + " " + k + " " + " ".join(v) + "\n") fa.close() pw = open("passwd", "w") for a in db.prepare("select a.text from links l, addresses a " "where l.address=a.id and a.domain=$1 order by a.text")( db.FTN_domains["node"]): #print (a[0]) linkpw = get_link_password(db, a[0]) if linkpw is not None: pw.write("password %-23s %s\n" % (a[0], linkpw)) pw.close()
def feed(self, d): self.b.write(d) print(len(d), "bytes added") db = ftnconfig.connectdb() for lid, addr, conn in db.prepare("select id, address, connection from links"): if conn is not None: ftp = conn.find("FTP") if ftp is not None: #print (addr, ftp.keys(), ftp.get("host")) domain, address = ftnconfig.get_addr(db, addr) link_pkt_format = ftnconfig.get_link_pkt_format(db, address) password = ftnconfig.get_link_password(db, address) print(ftp.get("username"), ftp.get("password"), ftp.get("host"), ftp.get("port", 0)) with ftplib.FTP() as ftpc: ftpc.connect(host=ftp.get("host"), port=int(ftp.get("port", 0))) ftpc.login(user=ftp.get("username"), passwd=ftp.get("password")) #print (ftpc.getwelcome()) ftpc.set_pasv(ast.literal_eval(ftp.get("passive", "False"))) path = ftp.get("getfrom") print(path) if path:
#!/usr/local/bin/python3 link = '2:5020/1042' list = 'lists/GFD.txt' orphans = list #'upl' domain = 'fileecho' oldlink = ['2:5020/758', '2:5020/1200'] robotname = ftnconfig.robotnames[domain] import ftnconfig import ftnimport db = ftnconfig.connectdb() pw = ftnconfig.get_link_password(db, link, forrobots=True) pwold = {} for ol in oldlink: pwold[ol] = ftnconfig.get_link_password(db, ol, forrobots=True) avail = set() for l in open(list): avail.add(l.strip().upper()) orphan = set() for l in open(orphans): orphan.add(l.strip().upper()) print(len(orphan), len(avail), len(orphan.intersection(avail))) with ftnimport.session(db) as sess:
try: cmd = sys.argv[1] domain = sys.argv[2] area = sys.argv[3] subscriber = sys.argv[4] except: print("usage: ./util_subscription.py add|addvital|remove echo|fileecho AREANAME 2:5020/9999") exit() try: robot = ftnconfig.robotnames[domain] except: raise Exception("cannot manage subscriptions in domain", domain) pw = ftnconfig.get_link_password(db, subscriber, forrobots=True) with ftnimport.session(db) as sess: if cmd == "add": try: sess.add_subscription(None, domain, area, subscriber) except FTNAlreadySubscribed: print ("local subscription exists") if subscriber != ftnconfig.ADDRESS: sess.send_message(ftnconfig.SYSOP, ("node", subscriber), robot, None, pw, "+"+area, sendmode="direct") else: print ("local subscription") elif cmd == "remove": sess.remove_subscription(domain, area, subscriber) if subscriber != ftnconfig.ADDRESS:
#!/usr/local/bin/python3 -bb from ftnconfig import connectdb, get_link_password db=connectdb() fareas={} for a, b in db.prepare("select t.text, sr.text from subscriptions s, addresses sr, addresses t " "where s.subscriber=sr.id and s.target=t.id and t.domain=3")(): fareas.setdefault(a, set()).add(b) fa=open("/tank/home/fido/fareas.bbs", "w") fa.write("*****\n") for k, v in fareas.items(): fa.write("/tank/home/fido/fareas/"+k.lower()+" "+k+" "+" ".join(v)+"\n") fa.close() pw=open("/tank/home/fido/passwd", "w") for a in db.prepare("select a.text from links l, addresses a " "where l.address=a.id and a.domain=$1 order by a.text")(db.FTN_domains["node"]): #print (a[0]) linkpw = get_link_password(db, a[0]) if linkpw is not None: pw.write("password %-23s %s\n"%(a[0], linkpw)) pw.close()
link='2:5020/1042' domain = "fileecho" import ftnconfig import ftnimport robot = ftnconfig.robotnames[domain] db=ftnconfig.connectdb() lid = ftnconfig.get_addr_id(db, db.FTN_domains["node"], link) outp=[] pw = ftnconfig.get_link_password(db, link, True) #print(pw) for echo in db.prepare("select a.text from subscriptions s, addresses a " "where a.id=s.target and s.subscriber=$1 and a.domain=$2")(lid, db.FTN_domains[domain]): outp.append("+"+echo[0]+"\n") if len(outp)==0: print ("nothing to relink") else: print ("".join(outp)) with ftnimport.session(db) as sess: sess.send_message("Sergey Dorofeev", ("node", link), robot, None, pw, "".join(outp))
db=ftnconfig.connectdb() domain=sys.argv[1] area=sys.argv[2].upper() print ("pq://*****:*****@host/database") db=ftnconfig.connectdb(input("enter connection string for admin connection: ")) robot = ftnconfig.robotnames[domain] addr_id = ftnconfig.get_addr_id(db, db.FTN_domains[domain], area) print (addr_id) #msg_from = db.prepare("select count (*) from messages where source=$1")(addr_id) #print ("from:", msg_from) #msg_from = db.prepare("select count (*) from messages where destination=$1")(addr_id) #print ("to:", msg_from) assert( input("enter 'yes' to confirm: ")=="yes" ) with ftnimport.session(db) as sess: for (link_addr,subs_id) in db.prepare("select a.text, s.id from addresses a, subscriptions s where a.id=s.subscriber and s.target=$1")(addr_id): print ("unsubscribing",link_addr) db.prepare("delete from subscriptions where id=$1")(subs_id) pw=ftnconfig.get_link_password(db, link_addr, forrobots=True) sess.send_message(ftnconfig.SYSOP, ("node", link_addr), robot, None, pw, "-"+area, sendmode="direct") sess.send_message(ftnconfig.SYSOP, ("echo", "FLUID.LOCAL"), "All", None, "removal", domain+" "+area+" removed from node") db.prepare("delete from addresses where id=$1")(addr_id) exit()
#!/usr/local/bin/python3 link = '2:5020/1042' list = 'lists/GFD.txt' orphans = list #'upl' domain = 'fileecho' oldlink = ['2:5020/758', '2:5020/1200'] robotname = ftnconfig.robotnames[domain] import ftnconfig import ftnimport db=ftnconfig.connectdb() pw = ftnconfig.get_link_password(db, link, forrobots=True) pwold = {} for ol in oldlink: pwold[ol] = ftnconfig.get_link_password(db, ol, forrobots=True) avail = set() for l in open(list): avail.add(l.strip().upper()) orphan = set() for l in open(orphans): orphan.add(l.strip().upper()) print (len(orphan), len(avail), len(orphan.intersection(avail)))
#!/usr/local/bin/python3 -bb import ftnconfig import ftnimport db = ftnconfig.connectdb() area = "FLUID.LOCAL" robot = ftnconfig.robotnames["echo"] with ftnimport.session(db) as sess: for (link_addr, ) in db.prepare( "select a.text from links l, addresses a where a.id=l.address"): print(link_addr) sess.add_subscription(None, "echo", area, link_addr) pw = ftnconfig.get_link_password(db, link_addr, forrobots=True) sess.send_message(ftnconfig.SYSOP, ("node", link_addr), robot, None, pw, "+" + area, sendmode="direct")
def file_export(db, address, password, what): """ This generator fetches messages from database and yields objects, that contain the file information and instructions how to commit to db inforamtion about successful message delivery """ # first netmail # then requested file # then echoes # then filebox # and at last fileechoes print("export to", repr(address), repr(password), repr(what)) if password != (get_link_password(db, address) or ""): raise FTNWrongPassword() print("password is correct" if password else "password is empty") # WARNING! # unprotected sessions never must do queries as it may result in leaking netmail # if address of some hub is spoofed addr_id = get_addr_id(db, db.FTN_domains["node"], address) link_pkt_format = get_link_pkt_format(db, address) link_bundler = get_link_bundler(db, address) if password and ("netmail" in what): explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["netmail"], addr_id))) if explock.acquire(False): try: print ("exporting netmail") # only vital subscriptions is processed # non-vital (CC) should be processed just like echomail # set password in netmail packets p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, get_link_id(db, address)), lambda: netmailcommitter()) #..firstly send pkts in outbound for id_msg, src, dest, msgid, header, body, origcharset, recvfrom in get_subscriber_messages_n(db, addr_id, db.FTN_domains["node"]): print("netmail %d recvfrom %d pack to %s"%(id_msg, recvfrom, repr(address))) # if exporting to utf8z always use UTF-8 if link_pkt_format == "utf8z": origcharset = "utf-8" myvia = "PyFTN " + ADDRESS + " " + time.asctime() srca=db.prepare("select domain, text from addresses where id=$1").first(src) dsta=db.prepare("select domain, text from addresses where id=$1").first(dest) try: msg, msgcharset = denormalize_message( (db.FTN_backdomains[srca[0]], srca[1]), (db.FTN_backdomains[dsta[0]], dsta[1]), msgid, header, body, origcharset, address, addvia = myvia) except: raise Exception("denormalization error on message id=%d"%id_msg+"\n"+traceback.format_exc()) try: print ("export msg attributes", msg.attr) except: traceback.print_exception() if 'AuditRequest' in ftn.attr.binary_to_text(msg.attr): audit_reply = (db.FTN_backdomains[srca[0]], srca[1]), header.find("sendername").text, address, msg, msgcharset else: audit_reply = None for x in p.add_item(msg, (id_msg, audit_reply)): # add ARQ flag yield x for x in p.flush(): yield x del p finally: explock.release() else: print ("could not acquire netmail lock") if "direct" in what: # available for unprotected sessions # export messages with processed==8 and destination==addr_id explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["netmail"], addr_id))) if explock.acquire(False): print ("exporting direct netmail") # only vital subscriptions is processed # non-vital (CC) should be processed just like echomail # set password in netmail packets link_id=get_link_id(db, address, withfailback=True) p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, link_id), lambda: netmailcommitter(newstatus=7)) #..firstly send pkts in outbound for id_msg, src, dest, msgid, header, body, origcharset, recvfrom in get_direct_messages(db, addr_id): print("direct netmail %d recvfrom %d pack to %s"%(id_msg, recvfrom, repr(address))) # if exporting to utf8z always use UTF-8 if link_pkt_format == "utf8z": origcharset = "utf-8" myvia = "PyFTN " + ADDRESS + " DIRECT " + time.asctime() srca=db.prepare("select domain, text from addresses where id=$1").first(src) dsta=db.prepare("select domain, text from addresses where id=$1").first(dest) try: msg, msgcharset = denormalize_message( (db.FTN_backdomains[srca[0]], srca[1]), (db.FTN_backdomains[dsta[0]], dsta[1]), msgid, header, body, origcharset, address, addvia = myvia) except: raise Exception("denormalization error on message id=%d"%id_msg+"\n"+traceback.format_exc()) try: print ("export msg attributes", msg.attr) except: traceback.print_exception() if 'AuditRequest' in ftn.attr.binary_to_text(msg.attr): audit_reply = (db.FTN_backdomains[srca[0]], srca[1]), header.find("sendername").text, address, msg, msgcharset else: audit_reply = None for x in p.add_item(msg, (id_msg, audit_reply)): # add ARQ flag yield x for x in p.flush(): yield x del p explock.release() pass if password and ("echomail" in what): explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["echomail"], addr_id))) if explock.acquire(False): try: print ("exporting echomail") #..firstly send bundles in outbound # if link_bundler: p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, get_link_id(db, address)), lambda: echomailcommitter(), bundlepacker(link_bundler, address, lambda: get_bundle_n(db, get_link_id(db, address)), lambda: echomailcommitter())) else: p = pktpacker(link_pkt_format, ADDRESS, address, get_link_password(db, address) or '', lambda: get_pkt_n(db, get_link_id(db, address)), lambda: echomailcommitter()) subscache = {} for id_msg, xxsrc, dest, msgid, header, body, origcharset, recvfrom, withsubscr, processed in get_subscriber_messages_e(db, addr_id, db.FTN_domains["echo"]): will_export = True # do we really must send message or just update last_sent pointer #print("echomail %d"%id_msg, repr(dest)) #print("dest %d recvfrom %s subscr %s pack to %s"%(dest, repr(recvfrom), repr(withsubscr), address)) # ignore src - for echomail it is just recv_from # if exporting to utf8z always use UTF-8 if link_pkt_format == "utf8z": origcharset = "utf-8" if recvfrom == addr_id: #print ("Message from this link, will not export") will_export = False if processed == 5: #print ("Archived message, will not export") will_export = False # check commuter subscriber_comm = db.FTN_commuter.get(withsubscr) if subscriber_comm is not None: # must check as None==None => no export at all # get subscription through what message was received recvfrom_subscription = db.prepare("select id from subscriptions where target=$1 and subscriber=$2").first(sub_tart, m_recvfrom) recvfrom_comm = db.FTN_commuter.get(recvfrom_subscription) if recvfrom_comm == subscriber_comm: print("commuter %d - %d, will not export"%(withsubscr, recvfrom_subscription)) will_export = False # continue # do not forward between subscriptions in one commuter group (e.g. two uplinks) if dest in subscache: subscribers = subscache[dest] else: subscribers = db.prepare("select a.domain, a.text from subscriptions s, addresses a where s.target=$1 and s.subscriber=a.id")(dest) if not all([x[0]==db.FTN_domains["node"] for x in subscribers]): raise FTNFail("subscribers from wrong domain for "+str(sub_targ)) # print(sub_id, sub_targ, "all subscribers:", [x[1] for x in subscribers]) subscribers = subscache[dest] = [x[1] for x in subscribers] #print("subscribers:", repr(subscribers)) # if withsubscr not in subscribers: # raise Exception("strange: exporting to non-existent subscription", withsubscr) dsta = db.prepare("select domain, text from addresses where id=$1").first(dest) # modify path and seen-by # seen-by's - get list of all subscribers of this target; add subscribers list #... if go to another zone remove path and seen-by's and only add seen-by's of that zone -> ftnexport if will_export: # create MSG else do not bother try: msg, msgcharset = denormalize_message( ("node", ADDRESS), (db.FTN_backdomains[dsta[0]], dsta[1]), msgid, header, body, origcharset, address, addseenby=subscribers, addpath=ADDRESS) except: raise Exception("denormalization error on message id=%d"%id_msg+"\n"+traceback.format_exc()) for x in p.add_item((msg if will_export else None), (withsubscr, id_msg)): yield x for x in p.flush(): yield x finally: explock.release() else: print("could not acquire echomail lock") if password and ("filebox" in what): explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["filebox"], addr_id))) if explock.acquire(False): # ..send freq filebox print ("exporting filebox") dsend = addrdir(DOUTBOUND, address) if os.path.isdir(dsend): print ("exporting daemon outbound") for f in os.listdir(dsend): fname = os.path.join(dsend, f) if os.path.isfile(fname): obj = outfile() obj.data = open(fname, "rb") obj.filename = f obj.length = os.path.getsize(fname) yield obj, filecommitter(fname) explock.release() if password and ("fileecho" in what): explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["fileecho"], addr_id))) if explock.acquire(False): # ..send fileechoes print ("exporting fileechoes (nothing here)") pass #1/0 explock.release() return