def validate(self, configuration): val = ConfString.validate(self, configuration) if val is None: return None val = expand_user_vars(val) if not os.path.isfile(val): raise getmailConfigurationError( '%s: specified mbox file "%s" does not exist' % (self.name, val) ) fd = os.open(val, os.O_RDWR) status_old = os.fstat(fd) f = os.fdopen(fd, 'r+') # Check if it _is_ an mbox file. mbox files must start with "From " # in their first line, or are 0-length files. f.seek(0, 0) first_line = f.readline() if first_line and first_line[:5] != 'From ': # Not an mbox file; abort here raise getmailConfigurationError('%s: not an mboxrd file' % val) # Reset atime and mtime try: os.utime(val, (status_old.st_atime, status_old.st_mtime)) except OSError as o: # Not root or owner; readers will not be able to reliably # detect new mail. But you shouldn't be delivering to # other peoples' mboxes unless you're root, anyways. pass return val
def validate(self, configuration): val = ConfString.validate(self, configuration) if val is None: return None val = expand_user_vars(val) if not os.path.isfile(val): raise getmailConfigurationError( '%s: specified mbox file "%s" does not exist' % (self.name, val) ) fd = os.open(val, os.O_RDWR) status_old = os.fstat(fd) f = os.fdopen(fd, 'r+b') lock_file(f) # Check if it _is_ an mbox file. mbox files must start with "From " # in their first line, or are 0-length files. f.seek(0, 0) first_line = f.readline() unlock_file(f) if first_line and first_line[:5] != 'From ': # Not an mbox file; abort here raise getmailConfigurationError( '%s: not an mboxrd file' % val ) # Reset atime and mtime try: os.utime(val, (status_old.st_atime, status_old.st_mtime)) except OSError, o: # Not root or owner; readers will not be able to reliably # detect new mail. But you shouldn't be delivering to # other peoples' mboxes unless you're root, anyways. pass
def validate(self, configuration): val = ConfString.validate(self, configuration) if val is None: return None val = expand_user_vars(val) if not os.path.isfile(val): raise getmailConfigurationError( '%s: specified file "%s" does not exist' % (self.name, val)) return val
def validate(self, configuration): val = ConfString.validate(self, configuration) if val is None: return None val = expand_user_vars(val) if not os.path.isfile(val): raise getmailConfigurationError( '%s: specified file "%s" does not exist' % (self.name, val) ) return val
def main(): try: parser = OptionParser(version='%%prog %s' % __version__) parser.add_option('-g', '--getmaildir', dest='getmaildir', action='store', default=defaults['getmaildir'], help='look in DIR for config/data files', metavar='DIR') parser.add_option( '-r', '--rcfile', dest='rcfile', action='append', default=[], help='load configuration from FILE (may be given multiple times)', metavar='FILE') parser.add_option('--dump', dest='dump_config', action='store_true', default=False, help='dump configuration and exit (debugging)') parser.add_option( '--trace', dest='trace', action='store_true', default=False, help='print extended trace information (extremely verbose)') overrides = OptionGroup( parser, 'Overrides', 'The following options override those specified in any ' 'getmailrc file.') overrides.add_option( '-v', '--verbose', dest='override_verbose', action='count', help='operate more verbosely (may be given multiple times)') overrides.add_option('-q', '--quiet', dest='override_verbose', action='store_const', const=0, help='operate quietly (only report errors)') overrides.add_option( '-d', '--delete', dest='override_delete', action='store_true', help='delete messages from server after retrieving') overrides.add_option( '-l', '--dont-delete', dest='override_delete', action='store_false', help='do not delete messages from server after retrieving') overrides.add_option('-a', '--all', dest='override_read_all', action='store_true', help='retrieve all messages') overrides.add_option('-n', '--new', dest='override_read_all', action='store_false', help='retrieve only unread messages') parser.add_option_group(overrides) (options, args) = parser.parse_args(sys.argv[1:]) if args: raise getmailOperationError('unknown argument(s) %s ; try --help' % args) if options.trace: log.clearhandlers() if not options.rcfile: options.rcfile.append(defaults['rcfile']) s = '' for attr in dir(options): if attr.startswith('_'): continue if s: s += ',' s += '%s="%s"' % (attr, pprint.pformat(getattr(options, attr))) log.debug('parsed options: %s\n' % s) getmaildir_type = 'Default' if options.getmaildir != defaults['getmaildir']: getmaildir_type = 'Specified' getmaildir = expand_user_vars(options.getmaildir) if not os.path.exists(getmaildir): raise getmailOperationError( '%s config/data dir "%s" does not exist - create ' 'or specify alternate directory with --getmaildir option' % (getmaildir_type, getmaildir)) if not os.path.isdir(getmaildir): raise getmailOperationError( '%s config/data dir "%s" is not a directory - fix ' 'or specify alternate directory with --getmaildir option' % (getmaildir_type, getmaildir)) if not os.access(getmaildir, os.W_OK): raise getmailOperationError( '%s config/data dir "%s" is not writable - fix permissions ' 'or specify alternate directory with --getmaildir option' % (getmaildir_type, getmaildir)) configs = [] for filename in options.rcfile: path = os.path.join(os.path.expanduser(options.getmaildir), filename) log.debug('processing rcfile %s\n' % path) if not os.path.exists(path): raise getmailOperationError('configuration file %s does ' 'not exist' % path) elif not os.path.isfile(path): raise getmailOperationError('%s is not a file' % path) f = open(path, 'rb') config = { 'verbose': defaults['verbose'], 'read_all': defaults['read_all'], 'delete': defaults['delete'], 'delete_after': defaults['delete_after'], 'max_message_size': defaults['max_message_size'], 'max_messages_per_session': defaults['max_messages_per_session'], 'max_bytes_per_session': defaults['max_bytes_per_session'], 'delivered_to': defaults['delivered_to'], 'received': defaults['received'], 'logfile': defaults['logfile'], 'message_log': defaults['message_log'], 'message_log_verbose': defaults['message_log_verbose'], 'message_log_syslog': defaults['message_log_syslog'], } # Python's ConfigParser .getboolean() couldn't handle booleans in # the defaults. Submitted a patch; they fixed it a different way. # But for the extant, unfixed versions, an ugly hack.... parserdefaults = config.copy() for (key, value) in parserdefaults.items(): if type(value) == bool: parserdefaults[key] = str(value) try: configparser = ConfigParser.RawConfigParser(parserdefaults) configparser.readfp(f, path) for option in options_bool: log.debug(' looking for option %s ... ' % option) if configparser.has_option('options', option): log.debug('got "%s"' % configparser.get('options', option)) try: config[option] = configparser.getboolean( 'options', option) log.debug('-> %s' % config[option]) except ValueError: raise getmailConfigurationError( 'configuration file %s incorrect (option %s ' 'must be boolean, not %s)' % (path, option, configparser.get('options', option))) else: log.debug('not found') log.debug('\n') for option in options_int: log.debug(' looking for option %s ... ' % option) if configparser.has_option('options', option): log.debug('got "%s"' % configparser.get('options', option)) try: config[option] = configparser.getint( 'options', option) log.debug('-> %s' % config[option]) except ValueError: raise getmailConfigurationError( 'configuration file %s incorrect (option %s ' 'must be integer, not %s)' % (path, option, configparser.get('options', option))) else: log.debug('not found') log.debug('\n') # Message log file for option in options_str: log.debug(' looking for option %s ... ' % option) if configparser.has_option('options', option): log.debug('got "%s"' % configparser.get('options', option)) config[option] = configparser.get('options', option) log.debug('-> %s' % config[option]) else: log.debug('not found') log.debug('\n') if config['message_log']: try: config['logfile'] = logfile(config['message_log']) except IOError, o: raise getmailConfigurationError( 'error opening message_log file %s (%s)' % (config['message_log'], o)) # Clear out the ConfigParser defaults before processing further # sections configparser._defaults = {} # Retriever log.debug(' getting retriever\n') retriever_type = configparser.get('retriever', 'type') log.debug(' type="%s"\n' % retriever_type) retriever_func = getattr(retrievers, retriever_type) if not callable(retriever_func): raise getmailConfigurationError( 'configuration file %s specifies incorrect ' 'retriever type (%s)' % (path, retriever_type)) retriever_args = { 'getmaildir': options.getmaildir, 'configparser': configparser, } for (name, value) in configparser.items('retriever'): if name in ('type', 'configparser'): continue if name == 'password': log.debug(' parameter %s=*\n' % name) else: log.debug(' parameter %s="%s"\n' % (name, value)) retriever_args[name] = value log.debug(' instantiating retriever %s with args %s\n' % (retriever_type, format_params(retriever_args))) try: retriever = retriever_func(**retriever_args) log.debug(' checking retriever configuration for %s\n' % retriever) retriever.checkconf() except getmailOperationError, o: log.error('Error initializing retriever: %s\n' % o) continue # Destination log.debug(' getting destination\n') destination_type = configparser.get('destination', 'type') log.debug(' type="%s"\n' % destination_type) destination_func = getattr(destinations, destination_type) if not callable(destination_func): raise getmailConfigurationError( 'configuration file %s specifies incorrect destination ' 'type (%s)' % (path, destination_type)) destination_args = {'configparser': configparser} for (name, value) in configparser.items('destination'): if name in ('type', 'configparser'): continue if name == 'password': log.debug(' parameter %s=*\n' % name) else: log.debug(' parameter %s="%s"\n' % (name, value)) destination_args[name] = value log.debug(' instantiating destination %s with args %s\n' % (destination_type, format_params(destination_args))) destination = destination_func(**destination_args) # Filters log.debug(' getting filters\n') _filters = [] filtersections = [ section.lower() for section in configparser.sections() if section.lower().startswith('filter') ] filtersections.sort() for section in filtersections: log.debug(' processing filter section %s\n' % section) filter_type = configparser.get(section, 'type') log.debug(' type="%s"\n' % filter_type) filter_func = getattr(filters, filter_type) if not callable(filter_func): raise getmailConfigurationError( 'configuration file %s specifies incorrect filter ' 'type (%s)' % (path, filter_type)) filter_args = {'configparser': configparser} for (name, value) in configparser.items(section): if name in ('type', 'configparser'): continue if name == 'password': log.debug(' parameter %s=*\n' % name) else: log.debug(' parameter %s="%s"\n' % (name, value)) filter_args[name] = value log.debug(' instantiating filter %s with args %s\n' % (filter_type, format_params(filter_args))) mail_filter = filter_func(**filter_args) _filters.append(mail_filter) except ConfigParser.NoSectionError, o: raise getmailConfigurationError( 'configuration file %s missing section (%s)' % (path, o))