def _create_tmp(self): global PEER logging.critical("PEER in queue: %s", PEER) now = time.time() uniq = "%s.M%sP%sQ%s-%s-%s-%s" % ( int(now), int(now % 1 * 1e6), os.getpid(), mailbox.Maildir._count, PEER[0], sensorName, USER, ) path = os.path.join(self._path, 'tmp', uniq) try: os.stat(path) except OSError as e: if e.errno == errno.ENOENT: mailbox.Maildir._count += 1 try: return mailbox._create_carefully(path) except OSError as e: if e.errno != errno.EEXIST: raise else: raise # Fall through to here if stat succeeded or open raised EEXIST. raise mailbox.ExternalClashError( 'Name clash prevented file creation: %s' % path)
def _create_tmp(self): now = time.time() rand = binascii.hexlify(os.urandom(4)).decode() uniq = f"{now:.8f}.{rand}.eml" path = os.path.join(self._path, "tmp", uniq) try: os.stat(path) except FileNotFoundError: try: return mailbox._create_carefully(path) except FileExistsError: pass raise mailbox.ExternalClashError( f"name clash prevented file creation: {path}")
def add(self, message): """Add message and return assigned key.""" key = self._encryption_key_func() es = None try: tmpdir = os.path.join(self._path, 'tmp') if not os.path.exists(tmpdir): os.mkdir(tmpdir, 0o700) if key: es = EncryptingStreamer(key, dir=tmpdir, name='WERVD', delimited=False) else: es = ChecksummingStreamer(dir=tmpdir, name='WERVD') self._dump_message(message, es) es.finish() # We are using the MAC to detect file system corruption, not in a # security context - so using as little as 40 bits should be fine. saved = False key = None outer_mac = es.outer_mac_sha256() for l in range(10, len(outer_mac)): key = outer_mac[:l] fn = os.path.join(self._path, 'new', key) if not os.path.exists(fn): es.save(fn) saved = self._toc[key] = os.path.join('new', key) break if not saved: raise mailbox.ExternalClashError( _('Could not find a filename ' 'for the message.')) # FIXME: Copies # for fn in self._copy_paths('new', key, copies): # with mailbox._create_carefully(fn) as ofd: # es.save_copy(ofd) return key finally: if es is not None: es.close()
def _create_tmp(self): now = time.time() uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(), mailbox.Maildir._count, HASHED_HOSTNAME) path = os.path.join(self._path, 'tmp', uniq) try: os.stat(path) except OSError as e: if e.errno == errno.ENOENT: mailbox.Maildir._count += 1 try: return mailbox._create_carefully(path) except OSError as e: if e.errno != errno.EEXIST: raise else: raise # Fall through to here if stat succeeded or open raised EEXIST. raise mailbox.ExternalClashError('Name clash prevented file creation: %s' % path)
def add(self, message, copies=1): """Add message and return assigned key.""" key = self._encryption_key_func() try: if key: es = EncryptingStreamer(key, dir=os.path.join(self._path, 'tmp'), name='WERVD', delimited=False) else: es = ChecksummingStreamer(dir=os.path.join(self._path, 'tmp'), name='WERVD') self._dump_message(message, es) es.finish() # We are using the MD5 to detect file system corruption, not in a # security context - so using as little as 40 bits should be fine. saved = False key = None for l in range(10, len(es.outer_md5sum)): key = es.outer_md5sum[:l] fn = os.path.join(self._path, 'new', key) if not os.path.exists(fn): es.save(fn) saved = self._toc[key] = os.path.join('new', key) break if not saved: raise mailbox.ExternalClashError(_('Could not find a filename ' 'for the message.')) for cpn in range(1, copies): fn = os.path.join(self._path, 'new', '%s.%s' % (key, cpn)) with mailbox._create_carefully(fn) as ofd: es.save_copy(ofd) return key finally: es.close()
path = os.path.join(self._path, 'tmp', uniq) try: os.stat(path) except OSError, e: if e.errno == errno.ENOENT: mailbox.Maildir._count += 1 try: return mailbox._create_carefully(path) except OSError, e: if e.errno != errno.EEXIST: raise else: raise # Fall through to here if stat succeeded or open raised EEXIST. raise mailbox.ExternalClashError( 'Name clash prevented file creation: %s' % path) class QueueError(Exception): def __init__(self, msg, data): Exception.__init__(self, msg) self._message = msg self.data = data class Queue(object): """ Provides a simplified API for dealing with 'queues' in Artemis. It currently just supports maildir queues since those are the most robust, but could implement others later. """
def flush(self): """Write any pending changes to disk. This is called on mailbox close and is usually not called explicitly. .. note:: This deletes messages via truncation. Interruptions may corrupt your mailbox. """ # Appending and basic assertions are the same as in mailbox.mbox.flush. if not self._pending: if self._pending_sync: # Messages have only been added, so syncing the file # is enough. mailbox._sync_flush(self._file) self._pending_sync = False return # In order to be writing anything out at all, self._toc must # already have been generated (and presumably has been modified # by adding or deleting an item). assert self._toc is not None # Check length of self._file; if it's changed, some other process # has modified the mailbox since we scanned it. self._file.seek(0, 2) cur_len = self._file.tell() if cur_len != self._file_length: raise mailbox.ExternalClashError('Size of mailbox file changed ' '(expected %i, found %i)' % (self._file_length, cur_len)) self._file.seek(0) # Truncation logic begins here. Mostly the same except we # can use tempfile because we're not doing rename(2). with tempfile.TemporaryFile() as new_file: new_toc = {} self._pre_mailbox_hook(new_file) for key in sorted(self._toc.keys()): start, stop = self._toc[key] self._file.seek(start) self._pre_message_hook(new_file) new_start = new_file.tell() while True: buffer = self._file.read(min(4096, stop - self._file.tell())) if buffer == '': break new_file.write(buffer) new_toc[key] = (new_start, new_file.tell()) self._post_message_hook(new_file) self._file_length = new_file.tell() self._file.seek(0) new_file.seek(0) # Copy back our messages if self._file_length <= self.maxmem: self._file.write(new_file.read()) else: while True: buffer = new_file.read(4096) if not buffer: break self._file.write(buffer) # Delete the rest. self._file.truncate() # Same wrap up. self._toc = new_toc self._pending = False self._pending_sync = False if self._locked: mailbox._lock_file(self._file, dotlock=False)