예제 #1
0
파일: read.py 프로젝트: askovpen/PyFTN
def forward(srcid, dstid, msgid, header, body, tosrc=False, newsubj=None):

      origdom, origtext = ftnconfig.get_addr(db, srcid)
      origdom = db.FTN_backdomains[origdom]
      destdom, desttext = ftnconfig.get_addr(db, dstid)
      destdom = db.FTN_backdomains[destdom]

      tpl = ["From: " + repr(ftnconfig.SYSOP) + "\n"]
      if tosrc:
        tpl.append("To: "+repr(header.find("sendername").text)+"\n")
      else:
        tpl.append("To: ''\n")

      if newsubj:
        tpl.append("Subject: " + repr(newsubj) + "\n")
      else:
        tpl.append("Subject: " + repr(header.find("subject").text) + "\n")

      tpl.append("ReplyTo: " + repr(None) + "\n")

      if tosrc:
        tpl.append("Destination: (%s, %s)\n"%(repr(origdom), repr(origtext)))
      else:
        tpl.append("Destination: ('', '')\n")

      tpl.append("Attr: []\n")
      tpl.append("\n")
      if tosrc:
        tpl.append("Hello "+(header.find("sendername").text or "Sysop")+",\n")
      else:
        tpl.append("Hello ,\n")
      tpl.append("\n")
      tpl.append(" *** Forwarded message:\n")
      tpl.append("="*79+"\n")
      tpl.append("From: %s, %s %s\n"%(header.find("sendername").text or '', origdom, origtext))
      tpl.append("To  : %s, %s %s\n"%(header.find("recipientname").text or '', destdom, desttext))
      tpl.append("Subj: %s\n"%(header.find("subject").text or ''))
      tpl.append("Date: %s\n"%(header.find("date").text or ''))
      tpl.append("-"*79+"\n")
      tpl.extend(map(inval, body.splitlines(True)))
      tpl.append("="*79+"\n")
      tpl.append("\n")
      tpl.append("... vim\n")

      newmsg = "".join(tpl)
      (fh, fname) = tempfile.mkstemp()
      fo = os.fdopen(fh, "w")
      fo.write(newmsg)
      fo.close()
      os.system ("vi " + fname)
      editedmsg = open(fname).read()
      if newmsg == editedmsg:
        print("no changes")
        r = False
      else:
        submit(editedmsg)
        r = True
      os.unlink(fname)
      return r
예제 #2
0
def reply(srcid, dstid, msgid, header, body):

    nameparts = RE_s.split(header.find("sendername").text.strip())
    senderfirstname = nameparts[0]
    if senderfirstname:
        qname = senderfirstname[0]
    else:
        qname = ''
    if len(nameparts) > 1:
        qname += nameparts[-1][0]

    origdom, origtext = ftnconfig.get_addr(db, srcid)
    origdom = db.FTN_backdomains[origdom]
    destdom, desttext = ftnconfig.get_addr(db, dstid)
    destdom = db.FTN_backdomains[destdom]

    tpl = ["From: " + repr(ftnconfig.SYSOP) + "\n"]
    tpl.append("To: " + repr(header.find("sendername").text) + "\n")
    tpl.append("Subject: " + repr(header.find("subject").text) + "\n")
    tpl.append("ReplyTo: " + repr(msgid) + "\n")

    if destdom == 'echo':
        tpl.append("Destination: " + repr((destdom, desttext)) + "\n")
        tpl.append("#Destination: " + repr((origdom, origtext)) + "\n")
    else:
        tpl.append("Destination: " + repr((origdom, origtext)) + "\n")
    tpl.append("Attr: []\n")

    tpl.append("\n")
    tpl.append(" ".join(("Hello", senderfirstname)) + ",\n")
    tpl.append("\n")
    tpl.append("orig.message to %s %s on " % (destdom, desttext) +
               header.find("date").text.strip() + "\n")

    tpl.extend(quote(qname, body.splitlines()))

    tpl.append("\n")
    tpl.append("Sergey\n")
    tpl.append("\n")
    tpl.append("... vim\n")

    newmsg = "".join(tpl)
    (fh, fname) = tempfile.mkstemp()
    fo = os.fdopen(fh, "w")
    fo.write(newmsg)
    fo.close()
    os.system("vi " + fname)
    editedmsg = open(fname).read()
    if newmsg == editedmsg:
        print("no changes")
        r = False
    else:
        submit(editedmsg)
        r = True
    os.unlink(fname)
    return r
예제 #3
0
파일: read.py 프로젝트: askovpen/PyFTN
def reply(srcid, dstid, msgid, header, body):

      nameparts = RE_s.split(header.find("sendername").text.strip())
      senderfirstname = nameparts[0]
      if senderfirstname:
        qname = senderfirstname[0]
      else:
        qname = ''
      if len(nameparts)>1:
        qname += nameparts[-1][0]

      origdom, origtext = ftnconfig.get_addr(db, srcid)
      origdom = db.FTN_backdomains[origdom]
      destdom, desttext = ftnconfig.get_addr(db, dstid)
      destdom = db.FTN_backdomains[destdom]

      tpl = ["From: " + repr(ftnconfig.SYSOP) + "\n"]
      tpl.append("To: " + repr(header.find("sendername").text) + "\n")
      tpl.append("Subject: " + repr(header.find("subject").text) + "\n")
      tpl.append("ReplyTo: " + repr(msgid) + "\n")

      if destdom == 'echo':
        tpl.append("Destination: " + repr((destdom, desttext)) + "\n")
        tpl.append("#Destination: " + repr((origdom, origtext)) + "\n")
      else:
        tpl.append("Destination: " + repr((origdom, origtext)) + "\n")
      tpl.append("Attr: []\n")

      tpl.append("\n")
      tpl.append(" ".join(("Hello", senderfirstname))+",\n")
      tpl.append("\n")
      tpl.append("orig.message to %s %s on "%(destdom, desttext) + header.find("date").text.strip() + "\n")

      tpl.extend(quote(qname, body.splitlines()))

      tpl.append("\n")
      tpl.append("Sergey\n")
      tpl.append("\n")
      tpl.append("... vim\n")

      newmsg = "".join(tpl)
      (fh, fname) = tempfile.mkstemp()
      fo = os.fdopen(fh, "w")
      fo.write(newmsg)
      fo.close()
      os.system ("vi " + fname)
      editedmsg = open(fname).read()
      if newmsg == editedmsg:
        print("no changes")
        r = False
      else:
        submit(editedmsg)
        r = True
      os.unlink(fname)
      return r
예제 #4
0
파일: read.py 프로젝트: askovpen/PyFTN
def view(mid, srcid, dstid, header, body):
    print ("="*10 + " %20d "%mid + "="*47)
    print ("From: %-36s, %s"%(header.find("sendername").text, str(ftnconfig.get_addr(db, srcid))))
    print ("To  : %-36s, %s"%(header.find("recipientname").text, str(ftnconfig.get_addr(db, dstid))))
    print ("Subj: %s"%header.find("subject").text)
    print ("Date: %s"%header.find("date").text)
    print ("-"*79)
    ftn=header.find("FTN")
    for kl in ftn.findall("KLUDGE"):
      print ("@"+kl.get("name"), kl.get("value"))
    print (body)
    print ("="*79)
예제 #5
0
def view(mid, srcid, dstid, header, body):
    print("=" * 10 + " %20d " % mid + "=" * 47)
    print("From: %-36s, %s" %
          (header.find("sendername").text, str(ftnconfig.get_addr(db, srcid))))
    print("To  : %-36s, %s" % (header.find("recipientname").text,
                               str(ftnconfig.get_addr(db, dstid))))
    print("Subj: %s" % header.find("subject").text)
    print("Date: %s" % header.find("date").text)
    print("-" * 79)
    ftn = header.find("FTN")
    for kl in ftn.findall("KLUDGE"):
        print("@" + kl.get("name"), kl.get("value"))
    print(body)
    print("=" * 79)
예제 #6
0
파일: ftnexport.py 프로젝트: fidoman/PyFTN
  def output():

   if withheader:
    header = msgdata["header"]
    ftnheader=header.find("FTN")

    tzutc = None
    reply = None
    for kludge in ftnheader.findall("KLUDGE"):
      if kludge.get("name")=="TZUTC:":
        tzutc = kludge.get("value")
      elif kludge.get("name")=="REPLY:":
        reply = kludge.get("value")
    # ..References:

    msgdate=header.find("date").text
    if msgdate is not None:
      date3339 = date_to_RFC3339(msgdate, tzutc)
      msgdate=time.strftime("%a, %d %b %Y %H:%M:%S", time.strptime(date3339[:-7], "%Y-%m-%d %H:%M:%S")) + \
        " " + date3339[-6:-3]+date3339[-2:]
    else:
      msgdate=msgdata["receivedtimestamp"].strftime("%a, %d %b %Y %H:%M:%S %z")
    yield "Date: "+msgdate
    srcdom, srcname = get_addr(db, msgdata["source"])
    if srcdom != db.FTN_domains["node"]:
      srcname = "Not-a-valid-source-{%d}"%msgdata["source"]
    yield "From: "+(header.find("sendername").text or '')+" <"+srcname+">"
    yield "Message-ID: "+nntp_make_messageid(msgdata["msgid"])
    if reply is not None:
      yield "In-Reply-To: "+nntp_make_messageid(reply)
    destdom, destname = get_addr(db, msgdata["destination"])
    if destdom != db.FTN_domains["echo"]:
      destname = "Not-a-valid-newsgroup-{%d}"%msgdata["destination"]
    yield "Newsgroups: "+destname
    yield "Path: "+HOSTNAME
    yield "Subject: "+(header.find("subject").text or '')

   if withheader and withbody:
    yield ""

   if withbody:
    for l in msgdata["body"].split("\n")[:-1]:
      yield l
예제 #7
0
파일: ftnpoll.py 프로젝트: fidoman/PyFTN
    def do(self):
        to_poll = set()
        for d in self.dests:
            to_poll.update(
                map(lambda x: x[0], ftnexport.get_subscribers(self.db, d)))
        self.dests = set()
        myzone = ftn.addr.str2addr(ftnconfig.ADDRESS)[0]
        #print (myzone)
        for a in to_poll:
            #print("poll", a)
            a = ftnconfig.get_addr(self.db, a)[1]
            #print (a)
            link_id = ftnconfig.find_link(self.db, a)
            if ftnconfig.get_link_polling(self.db, link_id):
                print("poll", a)
            else:
                #print ("not needed")
                continue
            addr = ftn.addr.str2addr(a)
            if addr[0] == myzone:
                zonepath = ftnconfig.BINKLEYSTYLE
            else:
                zonepath = ftnconfig.BINKLEYSTYLE + ".%d" % addr[0]
            if addr[3] == 0:
                pollfilename = "%04x%04x.dlo" % (addr[1], addr[2])
                basepath = zonepath
            else:
                pollfilename = "0000%04x.dlo" % addr[3]
                basepath = os.path.join(zonepath,
                                        "%04x%04x.pnt" % (addr[1], addr[2]))

            try:
                os.makedirs(basepath, exist_ok=True)
            except FileExistsError:
                pass
            except:
                print("could not create outbound directory")
                return
            try:
                touch = open(os.path.join(basepath, pollfilename), "a")
                touch.close()
            except:
                print("could not poll", a)
                traceback.print_exc()
예제 #8
0
파일: ftnpoll.py 프로젝트: fidoman/PyFTN
  def do(self):
    to_poll = set()
    for d in self.dests:
      to_poll.update(map(lambda x: x[0], ftnexport.get_subscribers(self.db,d)))
    self.dests=set()
    myzone=ftn.addr.str2addr(ftnconfig.ADDRESS)[0]
    #print (myzone)
    for a in to_poll:
      #print("poll", a)
      a=ftnconfig.get_addr(self.db, a)[1]
      #print (a)
      link_id=ftnconfig.find_link(self.db, a)
      if ftnconfig.get_link_polling(self.db, link_id):
         print ("poll",a)
      else:
        #print ("not needed")
        continue
      addr=ftn.addr.str2addr(a)
      if addr[0]==myzone:
        zonepath=ftnconfig.BINKLEYSTYLE
      else:
        zonepath=ftnconfig.BINKLEYSTYLE+".%d"%addr[0]
      if addr[3]==0:
        pollfilename="%04x%04x.dlo"%(addr[1], addr[2])
        basepath=zonepath
      else:
        pollfilename="0000%04x.dlo"%addr[3]
        basepath=os.path.join(zonepath, "%04x%04x.pnt"%(addr[1], addr[2]))

      try:
        os.makedirs(basepath, exist_ok=True)
      except FileExistsError:
        pass
      except:
        print ("could not create outbound directory")
        return
      try:
        touch=open(os.path.join(basepath,pollfilename),"a")
        touch.close()
      except:
        print ("could not poll", a)
        traceback.print_exc()
예제 #9
0
파일: util_purge.py 프로젝트: fidoman/PyFTN
    if domain == "fileecho":
        print(area, os.listdir("/tank/home/fido/fareas/" + area.lower()))
    elif domain == "echo":
        count = db.prepare(
            "select count(*) from messages where destination=$1").first(aid)
        print(area, count)
        if count:
            continue

    else:
        1 / 0
    # 2. send message to subscribers
    # 3. remove subscriptions and address
    with ftnimport.session(db) as sess:
        for node in [
                ftnconfig.get_addr(db, x[0])[1]
                for x in ftnexport.get_subscribers(db, aid)
        ]:
            print(node)

        input("enter to purge, Ctrl-C to abort")
        for node in [
                ftnconfig.get_addr(db, x[0])[1]
                for x in ftnexport.get_subscribers(db, aid)
        ]:
            print(node)
            sess.send_message(
                ftnconfig.SYSOP, ("node", node), "Sysop", None,
                "Area Expunging notification", """Dear Sysop,

%s %s is about to be deleted from node %s.
예제 #10
0
def forward(srcid, dstid, msgid, header, body, tosrc=False, newsubj=None):

    origdom, origtext = ftnconfig.get_addr(db, srcid)
    origdom = db.FTN_backdomains[origdom]
    destdom, desttext = ftnconfig.get_addr(db, dstid)
    destdom = db.FTN_backdomains[destdom]

    tpl = ["From: " + repr(ftnconfig.SYSOP) + "\n"]
    if tosrc:
        tpl.append("To: " + repr(header.find("sendername").text) + "\n")
    else:
        tpl.append("To: ''\n")

    if newsubj:
        tpl.append("Subject: " + repr(newsubj) + "\n")
    else:
        tpl.append("Subject: " + repr(header.find("subject").text) + "\n")

    tpl.append("ReplyTo: " + repr(None) + "\n")

    if tosrc:
        tpl.append("Destination: (%s, %s)\n" % (repr(origdom), repr(origtext)))
    else:
        tpl.append("Destination: ('', '')\n")

    tpl.append("Attr: []\n")
    tpl.append("\n")
    if tosrc:
        tpl.append("Hello " + (header.find("sendername").text or "Sysop") +
                   ",\n")
    else:
        tpl.append("Hello ,\n")
    tpl.append("\n")
    tpl.append(" *** Forwarded message:\n")
    tpl.append("=" * 79 + "\n")
    tpl.append("From: %s, %s %s\n" %
               (header.find("sendername").text or '', origdom, origtext))
    tpl.append("To  : %s, %s %s\n" %
               (header.find("recipientname").text or '', destdom, desttext))
    tpl.append("Subj: %s\n" % (header.find("subject").text or ''))
    tpl.append("Date: %s\n" % (header.find("date").text or ''))
    tpl.append("-" * 79 + "\n")
    tpl.extend(map(inval, body.splitlines(True)))
    tpl.append("=" * 79 + "\n")
    tpl.append("\n")
    tpl.append("... vim\n")

    newmsg = "".join(tpl)
    (fh, fname) = tempfile.mkstemp()
    fo = os.fdopen(fh, "w")
    fo.write(newmsg)
    fo.close()
    os.system("vi " + fname)
    editedmsg = open(fname).read()
    if newmsg == editedmsg:
        print("no changes")
        r = False
    else:
        submit(editedmsg)
        r = True
    os.unlink(fname)
    return r
예제 #11
0
파일: util_purge.py 프로젝트: fidoman/PyFTN
  # 1. verify that there is nothing there
  if domain == "fileecho":
    print (area, os.listdir("/tank/home/fido/fareas/"+area.lower()))
  elif domain == "echo":
    count = db.prepare("select count(*) from messages where destination=$1").first(aid)
    print (area, count)
    if count:
      continue

  else:
    1/0
  # 2. send message to subscribers
  # 3. remove subscriptions and address
  with ftnimport.session(db) as sess:
    for node in [ftnconfig.get_addr(db, x[0])[1] for x in ftnexport.get_subscribers(db, aid)]:
      print (node)

    input("enter to purge, Ctrl-C to abort")
    for node in [ftnconfig.get_addr(db, x[0])[1] for x in ftnexport.get_subscribers(db, aid)]:
      print (node)
      sess.send_message(ftnconfig.SYSOP, ("node", node),
                            "Sysop", None, "Area Expunging notification", """Dear Sysop,

%s %s is about to be deleted from node %s.
Please find new uplink for the area or 
expunge it too.
"""%(domain, area, ftnconfig.ADDRESS))

      sess.remove_subscription(domain, area, node)
예제 #12
0
import ftnconfig
import ftnexport
import ftnimport

db = ftnconfig.connectdb()

bydomain = {}

for domain in ["echo", "fileecho"]:
    #print ("domain", domain)
    for t in ftnexport.get_all_targets(db, domain):
        tid = ftnconfig.get_addr_id(db, db.FTN_domains[domain], t)
        ulist = []
        for x in ftnexport.get_subscribers(db, tid, True):
            ulist.append("%d|%s" % ftnconfig.get_addr(db, x[0]) + "!%d" % x[2])
        #print
        ulist.sort()
        bydomain.setdefault(domain, {}).setdefault(", ".join(ulist),
                                                   []).append(t)

with ftnimport.session(db) as sess:
    for d, byuplink in bydomain.items():
        outp = []
        for u, targets in byuplink.items():
            outp.append("  uplink = [" + u + "]\n")
            targets.sort()
            for t in targets:
                outp.append("    " + t + "\n")
            outp.append("\n")
예제 #13
0
  elif cmd == "query": # send areafix request
    sess.send_message(my_addr, ftnconfig.SYSOP, ("node", subscriber), robot, None, pw, "%QUERY", sendmode="direct")

  elif cmd == "list": # send areafix request
    sess.send_message(my_addr, ftnconfig.SYSOP, ("node", subscriber), robot, None, pw, "%LIST", sendmode="direct")

  elif cmd == "show": # show subscribed areas
    if area==".": # show for link
      for x in ftnexport.get_node_subscriptions(db, subscriber, domain):
        print (x)
    else: # show from area
      tid =  ftnconfig.get_addr_id(db, db.FTN_domains[domain], area)
      print (tid)
      for aid, vital, level in ftnexport.get_subscribers(db, tid):
        print (ftnconfig.get_addr(db, aid))

  elif cmd == "showuplink": # show areas subsribed as vital
    if area==".": # show for link
      for x in ftnexport.get_node_subscriptions(db, subscriber, domain, asuplink=True):
        print (x)
    else: # show from area
      tid =  ftnconfig.get_addr_id(db, db.FTN_domains[domain], area)
      print (tid)
      for x in ftnexport.get_subscribers(db, tid, True):
        print (x)      

  elif cmd == "verifyuplink":
    a_uplink = set(ftnexport.get_node_subscriptions(db, subscriber, domain, asuplink=True))
    a_all = set(ftnexport.get_node_subscriptions(db, subscriber, domain))
    print ("linked not as uplink to:")
예제 #14
0
파일: ftnftp.py 프로젝트: askovpen/PyFTN
  def __init__(self, b):
    self.b = b

  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: 
          ftpc.cwd(path)
예제 #15
0
import ftnconfig
import ftnexport
import ftnimport

db = ftnconfig.connectdb()

bydomain = {}

for domain in ["echo", "fileecho"]:
  #print ("domain", domain)
  for t in ftnexport.get_all_targets(db, domain):
    tid = ftnconfig.get_addr_id(db, db.FTN_domains[domain], t)
    ulist = []
    for x in ftnexport.get_subscribers(db, tid, True):
        ulist.append("%d|%s"%ftnconfig.get_addr(db, x[0])+"!%d"%x[2])
    #print 
    ulist.sort()
    bydomain.setdefault(domain, {}).setdefault(", ".join(ulist), []).append(t)


with ftnimport.session(db) as sess:
  for d, byuplink in bydomain.items():
    outp=[]
    for u, targets in byuplink.items():
      outp.append("  uplink = ["+u+"]\n")
      targets.sort()
      for t in targets:
        outp.append("    "+t+"\n")
      outp.append("\n")
      
예제 #16
0
    def __init__(self, b):
        self.b = b

    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")
예제 #17
0
파일: ftnexport.py 프로젝트: fidoman/PyFTN
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))

  link_id, addr_id, myaddr_id = ftnaccess.check_link(db, address, password, False)

  if myaddr_id is None:
    raise FTNWrongPassword()

  print("password is correct" if link_id else "unprotected session", "local address", myaddr_id)

  # WARNING!
  # unprotected sessions never must do queries as it may result in leaking netmail
  # if address of some hub is spoofed

  myaddr_text = get_addr(db, myaddr_id)[1]
  link_pkt_format, link_bundler = get_link_packing(db, link_id)
  link_my_id, link_pw = ftnaccess.link_password(db, link_id, False)

  if link_id 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, myaddr_text, address, link_pw or '', lambda: get_pkt_n(db, link_id), 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
    p = pktpacker(link_pkt_format, myaddr_text, address, link_pw 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 link_id 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, myaddr_text, address, link_pw or '', lambda: get_pkt_n(db, link_id), lambda: echomailcommitter(),
            bundlepacker(link_bundler, address, lambda: get_bundle_n(db, link_id), lambda: echomailcommitter()))
        else:
          p = pktpacker(link_pkt_format, myaddr_text, address, link_pw or '', lambda: get_pkt_n(db, link_id), 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"]):

          # ??? "my" addr in subscription - is it used here

          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 - NOT TESTED
          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 link_id 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 link_id and ("fileecho" in what):
    explock = postgresql.alock.ExclusiveLock(db, ((EXPORTLOCK["fileecho"], addr_id)))
    if explock.acquire(False):
      try:
        print ("exporting fileechoes for", address)
        subscache = {}
        tic_password = password
        t = ticpacker(lambda: get_tic_n(db, link_id), lambda: ticcommitter(db))
        latest_post = db.prepare("select max(post_time) from file_post").first()
        fruitful = False
        for fp_id, fp_filename, fp_destination, fp_recv_from, fp_recv_as, fp_post_time, fp_filedata, \
                fp_origin, fp_other, withsubscr, file_length, file_content, file_lo in \
            db.prepare("select fp.id, fp.filename, fp.destination, fp.recv_from, fp.recv_as, fp.post_time, "
              "fp.filedata, fp.origin, fp.other, s.id, f.length, f.content, f.lo "
            "from file_post fp, subscriptions s, files f "
            "where exists(select * from subscriptions ss where ss.target=fp.destination and ss.subscriber=$1) and s.subscriber=$1 and "
            "fp.post_time>(select lastsent from lastsent where subscriber=$1) and fp.destination=s.target and f.id=fp.filedata "
            "order by fp.post_time")(addr_id):
          print (fp_id, fp_filename, fp_destination)

          will_export = True # do we really must send message or just update last_sent pointer

          if fp_recv_from == addr_id:
            #print ("Message from this link, will not export")
            will_export = False

          other = json.loads(fp_other)
          del fp_other
          seenby = set(other.get("SEENBY", []))

          if address in seenby:
            print ("already in seenby list, not sending")
            will_export = False
          # dupe (own address) in path should be checked at import

          # check commuter - NOT TESTED
          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 fp_destination in subscache:
            subscribers = subscache[fp_destination]
          else:
            subscribers = db.prepare("select a.domain, a.text from subscriptions s, addresses a where s.target=$1 and s.subscriber=a.id")(fp_destination)

            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[fp_destination] = [x[1] for x in subscribers]

          dsta = get_addr(db, fp_destination)

          # modify path and seen-by
          # seen-by's - get list of all subscribers of this target; add subscribers list

          if will_export:
            fruitful = True # something was exported

            #print("add seen-by", subscribers, " add path", myaddr_text)

            other.setdefault("PATH", []).append(myaddr_text+" "+str(fp_post_time)+" "+time.asctime(time.gmtime(fp_post_time))+" PyFTN")
            seenby.update(subscribers)
            other["SEENBY"]=list(seenby)

            if "CRC" in other:
              file_crc32 = other.pop("CRC")[0]
              print ("filename %s length %d crc %s"%(fp_filename, file_length, file_crc32))
            else:
              if file_content:
                file_crc32 = ftntic.sz_crc32s(file_content)[1]
              else:
                file_crc32 = ftntic.sz_crc32fd(lo.LOIOReader(db, file_lo))[1]

            #if fp_origin is None:
            #  print("substitute empty origin with source")
            #  fp_origin = fp_recv_from
            tic = ftntic.make_tic(myaddr_text, address, tic_password, dsta[1], get_addr(db, fp_origin)[1] if fp_origin else None,
                fp_filename, file_length, file_crc32, other)

          # code was migrated from echo export, so it cares about blocked exports to update 
          # per-subscription last-sents
          for x in t.add_item(((tic, (fp_filename, file_length, file_content or (db, file_lo))) if will_export else None), (addr_id, fp_post_time)): # ordering by post_time
            yield x

        if not fruitful:
          print("empty export, must update per-subscriber lastsent up to", latest_post)

        for x in t.flush():
          yield x

      finally:
        explock.release()
    else:
      print ("cannot acquire fileecho lock for", addr_id)

  return
예제 #18
0
#!/usr/bin/python3

import ftnconfig
import ftntic
import json

files="""litg1336.rar
tropoi14.rar
tropoi18.rar
vert0001.rar
vert0104.rar
vert0203.rar
vert0204.rar
vert0301.rar
vert0303.rar""".split("\n")

db=ftnconfig.connectdb()

for f in files:
  print (f)
  for (fp,fp_origin,fp_destination,fp_filename, fp_other, f_size) in db.prepare("select fp.id, fp.origin, fp.destination, fp.filename, fp.other, f.length from file_post fp, files f where filename ilike $1 and fp.filedata=f.id")(f):
    print (fp)
    other= json.loads(fp_other)
    crc = other.pop("CRC", "00000000")[0]

    tic = ftntic.make_tic("2:5020/12000", "2:5059/37", "*", ftnconfig.get_addr(db, fp_destination)[1], ftnconfig.get_addr(db, fp_origin)[1] if fp_origin else None,
                fp_filename, f_size, crc, other)

    open("%d.tic"%fp, "wb").write(tic)
예제 #19
0
                          ftnconfig.SYSOP, ("node", subscriber),
                          robot,
                          None,
                          pw,
                          "%LIST",
                          sendmode="direct")

    elif cmd == "show":  # show subscribed areas
        if area == ".":  # show for link
            for x in ftnexport.get_node_subscriptions(db, subscriber, domain):
                print(x)
        else:  # show from area
            tid = ftnconfig.get_addr_id(db, db.FTN_domains[domain], area)
            print(tid)
            for aid, vital, level in ftnexport.get_subscribers(db, tid):
                print(ftnconfig.get_addr(db, aid))

    elif cmd == "showuplink":  # show areas subsribed as vital
        if area == ".":  # show for link
            for x in ftnexport.get_node_subscriptions(db,
                                                      subscriber,
                                                      domain,
                                                      asuplink=True):
                print(x)
        else:  # show from area
            tid = ftnconfig.get_addr_id(db, db.FTN_domains[domain], area)
            print(tid)
            for x in ftnexport.get_subscribers(db, tid, True):
                print(x)

    elif cmd == "verifyuplink":