def __getitem__(self, name): item = self.hdr[name] if isinstance(item, bytes): item = sstr(item) elif isinstance(item, list): item = [sstr(i) if isinstance(i, bytes) else i for i in item] return item
def __init__(self, screen, tui): self.screen = screen self.tui = tui size = snack._snack.size() toplevel = snack.GridForm(self.screen, sstr(WHY_REGISTER_WINDOW), 1, 2) why_register_text = WHY_REGISTER_TEXT + "\n\n" + \ WHY_REGISTER_SEC + "\n" + \ WHY_REGISTER_SEC_TXT + "\n\n" + \ WHY_REGISTER_DLD + "\n" + \ WHY_REGISTER_DLD_TXT + "\n\n" + \ WHY_REGISTER_SUPP + "\n" + \ WHY_REGISTER_SUPP_TXT + "\n\n" + \ WHY_REGISTER_COMP + "\n" + \ WHY_REGISTER_COMP_TXT + "\n\n" + \ WHY_REGISTER_TIP tb = snack.Textbox(size[0] - 10, size[1] - 14, sstr(why_register_text), 1, 1) toplevel.add(tb, 0, 0, padding=(0, 0, 0, 1)) self.bb = snack.ButtonBar(self.screen, [(sstr(BACK_REGISTER), "back")]) toplevel.add(self.bb, 0, 1, growx=1) self.g = toplevel
def validateFields(self): if self.userNameEntry.value() == "": snack.ButtonChoiceWindow(self.screen, sstr(ERROR), sstr(USER_REQUIRED), buttons=[sstr(OK)]) self.g.setCurrent(self.userNameEntry) return 0 if self.passwordEntry.value() == "": snack.ButtonChoiceWindow(self.screen, sstr(ERROR), sstr(PASSWORD_REQUIRED), buttons=[sstr(OK)]) self.g.setCurrent(self.passwordEntry) return 0 try: self.tui.alreadyRegistered = rhnreg.reserveUser( self.userNameEntry.value(), self.passwordEntry.value()) except up2dateErrors.ValidationError: e = sys.exc_info()[1] snack.ButtonChoiceWindow( self.screen, sstr(_("Error")), sstr(_("The server indicated an error:\n")) + sstr(e.errmsg), buttons=[sstr(_("OK"))]) self.g.setCurrent(self.userNameEntry) return 0 except up2dateErrors.CommunicationError: e = sys.exc_info()[1] FatalErrorWindow( self.screen, _("There was an error communicating with the registration server:\n" ) + e.errmsg) return 1
def drawFrame(self): self.welcomeText = COPYRIGHT_TEXT self.screen.drawRootText(0, 0, sstr(self.welcomeText)) self.screen.pushHelpLine( sstr( _(" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" )))
def __init__(self, screen, tui): if not rhnreg.registered() or tui.test: raise WindowSkipException() self.screen = screen self.tui = tui size = snack._snack.size() systemIdXml = rpclib.xmlrpclib.loads(up2dateAuth.getSystemId()) oldUsername = systemIdXml[0][0]['username'] oldsystemId = systemIdXml[0][0]['system_id'] toplevel = snack.GridForm(self.screen, sstr(SYSTEM_ALREADY_SETUP), 1, 2) self.bb = snack.ButtonBar(self.screen, [(sstr(YES_CONT), "next"), (sstr(NO_CANCEL), "exit")]) toplevel.add(self.bb, 0, 1, growx=1) tb = snack.Textbox( size[0] - 30, size[1] - 20, sstr(SYSTEM_ALREADY_REGISTERED + "\n\n" + _("Spacewalk Location:") + " " + convert_url_from_puny(self.tui.serverURL) + "\n" + _("Login:"******" " + oldUsername + "\n" + _("System ID:") + " " + oldsystemId + "\n\n" + SYSTEM_ALREADY_REGISTERED_CONT + "\n"), 1, 1) toplevel.add(tb, 0, 0, padding=(0, 0, 0, 1)) self.g = toplevel
def exceptionHandler(type, value, tb): log = up2dateLog.initLog() sys.stderr.write(sstr(_("An error has occurred:") + "\n")) if hasattr(value, "errmsg"): sys.stderr.write(sstr(value.errmsg) + "\n") log.log_exception(type, value, tb) else: sys.stderr.write(sstr(str(type) + "\n")) log.log_exception(type, value, tb) sys.stderr.write( sstr(_("See /var/log/up2date for more information") + "\n"))
def __init__(self, screen, tui): self.screen = screen self.tui = tui self.tui.alreadyRegistered = 0 self.server = convert_url_from_puny(self.tui.serverURL) fixed_server_url = rhnreg.makeNiceServerUrl(self.server) #Save the config only if the url is different if fixed_server_url != self.server: self.server = fixed_server_url config.setServerURL(self.server) cfg.save() size = snack._snack.size() toplevel = snack.GridForm(screen, sstr(SATELLITE_URL_WINDOW), 1, 4) prompt_text = SATELLITE_URL_TEXT url_label = SATELLITE_URL_PROMPT ssl_label = SATELLITE_URL_PROMPT2 label = snack.Textbox(size[0] - 10, 3, sstr(prompt_text), scroll=0, wrap=1) toplevel.add(label, 0, 0, anchorLeft=1) # spacer label = snack.Label(sstr("")) toplevel.add(label, 0, 1) grid = snack.Grid(2, 3) label = snack.Label(sstr(url_label)) grid.setField(label, 0, 0, padding=(0, 0, 1, 0), anchorRight=1) self.urlEntry = snack.Entry(40) self.urlEntry.set(self.server) grid.setField(self.urlEntry, 1, 0, anchorLeft=1) label = snack.Label(sstr(ssl_label)) grid.setField(label, 0, 1, padding=(0, 0, 1, 0), anchorRight=1) self.sslEntry = snack.Entry(40) self.sslEntry.set(tui.sslCACert) grid.setField(self.sslEntry, 1, 1, anchorLeft=1) toplevel.add(grid, 0, 2) # BUTTON BAR self.bb = snack.ButtonBar(screen, [(sstr(NEXT), "next"), (sstr(BACK), "back"), (sstr(CANCEL), "cancel")]) toplevel.add(self.bb, 0, 3, padding=(0, 1, 0, 0), growx=1) self.g = toplevel
def __init__(self, screen, tui): self.screen = screen self.tui = tui self.tui.alreadyRegistered = 0 self.server = self.tui.serverURL size = snack._snack.size() toplevel = snack.GridForm(screen, sstr(REGISTER_WINDOW), 1, 4) decoded_server = convert_url_from_puny(self.server) url = self.server if decoded_server != self.server: url += " (%s)" % decoded_server login_prompt = LOGIN_PROMPT % url login_label = LOGIN login_tip = LOGIN_TIP label = snack.Textbox(size[0] - 10, 3, sstr(login_prompt), scroll=0, wrap=1) toplevel.add(label, 0, 0, anchorLeft=1) grid = snack.Grid(2, 3) label = snack.Label(sstr(login_label)) grid.setField(label, 0, 0, padding=(0, 0, 1, 0), anchorRight=1) self.userNameEntry = snack.Entry(20) self.userNameEntry.set(tui.userName) grid.setField(self.userNameEntry, 1, 0, anchorLeft=1) label = snack.Label(sstr(PASSWORD)) grid.setField(label, 0, 1, padding=(0, 0, 1, 0), anchorRight=1) try: self.passwordEntry = snack.Entry(20, password=1) except TypeError: self.passwordEntry = snack.Entry(20, hidden=1) self.passwordEntry.set(tui.password) grid.setField(self.passwordEntry, 1, 1, anchorLeft=1) toplevel.add(grid, 0, 1) label = snack.TextboxReflowed(size[0] - 10, sstr(login_tip)) toplevel.add(label, 0, 2, anchorLeft=1) # BUTTON BAR self.bb = snack.ButtonBar(screen, [(sstr(NEXT), "next"), (sstr(BACK), "back"), (sstr(CANCEL), "cancel")]) toplevel.add(self.bb, 0, 3, padding=(0, 1, 0, 0), growx=1) self.g = toplevel
def __init__(self, screen, tui): self.screen = screen self.tui = tui size = snack._snack.size() toplevel = snack.GridForm(screen, sstr(FINISH_WINDOW), 1, 2) text = snack.TextboxReflowed(size[0] - 11, sstr(FINISH_WINDOW_TEXT_TUI)) toplevel.add(text, 0, 0) # BUTTON BAR self.bb = snack.ButtonBar(screen, [(sstr(_("Finish")), "next")]) toplevel.add(self.bb, 0, 1, padding=(0, 1, 0, 0), growx=1) self.g = toplevel
def _strip_characters(self, *args): """ Strip characters, which are not allowed according: http://www.w3.org/TR/2006/REC-xml-20060816/#charsets From spec: Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */ """ regexp = r'[\x00-\x09]|[\x0b-\x0c]|[\x0e-\x1f]' result = [] for item in args: item_type = type(item) if item_type == StringType or item_type == UnicodeType: item = re.sub(regexp, '', sstr(item)) elif item_type == TupleType: item = tuple(self._strip_characters(i) for i in item) elif item_type == ListType: item = [self._strip_characters(i) for i in item] elif item_type == DictType or item_type == DictionaryType: item = dict([(self._strip_characters(name, val)) for name, val in item.items()]) # else: some object - should take care of himself # numbers - are safe result.append(item) if len(result) == 1: return result[0] else: return tuple(result)
def _add_proxy_headers(self): if not self.__username: return # Authenticated proxy userpass = "******" % (self.__username, self.__password) enc_userpass = base64.encodestring(bstr(userpass)).replace( bstr("\n"), bstr("")) self.putheader("Proxy-Authorization", "Basic %s" % sstr(enc_userpass))
def write_log(self, s): log_name = self.cfg["logFile"] or "/var/log/up2date" log_file = open(log_name, 'a') msg = u"%s %s\n" % (ustr(self.log_info), ustr(s)) log_file.write(sstr(msg)) log_file.flush() log_file.close()
def __init__(self, screen, tui): self.screen = screen self.tui = tui size = snack._snack.size() toplevel = snack.GridForm(screen, sstr(SEND_WINDOW), 1, 2) text = snack.TextboxReflowed(size[0] - 15, sstr(SEND_WINDOW_DESC)) toplevel.add(text, 0, 0) # BUTTON BAR self.bb = snack.ButtonBar(screen, [(sstr(NEXT), "next"), (sstr(BACK), "back"), (sstr(CANCEL), "cancel")]) toplevel.add(self.bb, 0, 1, padding=(0, 1, 0, 0), growx=1) self.g = toplevel
def validateFields(self): msgbox = "ok" later_release = False if self.limited_updates_button.selected(): later_release = self.channelList.current() != \ self.available_channels['default_channel'] title = sstr(CONFIRM_OS_RELEASE_SELECTION) if later_release: msgbox = snack.ButtonChoiceWindow(self.screen, title, sstr(CONFIRM_OS_WARNING) % self.channelList.current(), buttons=[sstr(OK), sstr(CANCEL)]) return msgbox if self.all_updates_button.selected() or later_release: msgbox = snack.ButtonChoiceWindow(self.screen, title, sstr(CONFIRM_OS_ALL), buttons=[sstr(OK), sstr(CANCEL)]) return msgbox return msgbox
def __init__(self, screen, tui): self.screen = screen self.tui = tui size = snack._snack.size() self.pwin = snack.GridForm(screen, sstr(SENDING_WINDOW), 1, 1) self.scale = snack.Scale(40, 100) self.pwin.add(self.scale, 0, 0)
def systemExit(code, msgs=None): "Exit with a code and optional message(s). Saved a few lines of code." if msgs is not None: if type(msgs) not in [type([]), type(())]: msgs = (msgs, ) for msg in msgs: if hasattr(msg, 'value'): msg = msg.value sys.stderr.write(sstr(msg) + "\n") sys.exit(code)
def __check_instance_lock(): lock = None try: lock = rhnLockfile.Lockfile('/var/run/rhn_check.pid') except rhnLockfile.LockfileLockedException: sys.stderr.write( sstr( _("Attempting to run more than one instance of mgr_check. Exiting.\n" ))) sys.exit(0)
def _run_oscap(arguments): dev_null = open('/dev/null', mode="ab+") c = _popen(['/usr/bin/oscap'] + arguments, stdout=dev_null.fileno()) ret = c.wait() dev_null.close() errors = sstr(c.stderr.read()) if ret != 0: errors += 'xccdf_eval: oscap tool returned %i\n' % ret log.log_debug('The oscap tool completed\n%s' % errors) return errors
def process(self, data): # Assume straight text/xml self.data = data # Content-Encoding header if self.encoding == self.ENCODE_GZIP: import gzip encoding_name = self.encodings[self.ENCODE_GZIP][0] self.set_header("Content-Encoding", encoding_name) f = SmartIO(force_mem=1) gz = gzip.GzipFile(mode="wb", compresslevel=COMPRESS_LEVEL, fileobj=f) if sys.version_info[0] == 3: gz.write(bstr(data)) else: gz.write(sstr(data)) gz.close() self.data = f.getvalue() f.close() elif self.encoding == self.ENCODE_ZLIB: import zlib encoding_name = self.encodings[self.ENCODE_ZLIB][0] self.set_header("Content-Encoding", encoding_name) obj = zlib.compressobj(COMPRESS_LEVEL) self.data = obj.compress(data.encode()) + obj.flush() elif self.encoding == self.ENCODE_GPG: # XXX: fix me. raise NotImplementedError(self.transfer, self.encoding) # Content-Transfer-Encoding header if self.transfer == self.TRANSFER_BINARY: transfer_name = self.transfers[self.TRANSFER_BINARY] self.set_header("Content-Transfer-Encoding", transfer_name) self.set_header("Content-Type", "application/binary") elif self.transfer == self.TRANSFER_BASE64: import base64 transfer_name = self.transfers[self.TRANSFER_BASE64] self.set_header("Content-Transfer-Encoding", transfer_name) self.set_header("Content-Type", "text/base64") self.data = base64.encodestring(self.data).decode() self.set_header("Content-Length", len(bstr(self.data))) rpc_version = __version__ if len(__version__.split()) > 1: rpc_version = __version__.split()[1] # other headers self.set_header( "X-Transport-Info", 'Extended Capabilities Transport (C) Red Hat, Inc (version %s)' % rpc_version) self.__processed = 1
def figureSerial(caCertFilename, serialFilename, indexFilename): """ for our purposes we allow the same serial number for server certs BUT WE DO NOT ALLOW server certs and CA certs to share the same serial number. We blow away the index.txt file each time because we are less concerned with matching serials/signatures between server.crt's. """ # what serial # is the ca cert using (we need to increment from that) ret, outstream, errstream = rhn_popen([ '/usr/bin/openssl', 'x509', '-noout', '-serial', '-in', caCertFilename ]) out = sstr(outstream.read()) outstream.close() sslerrmsg = ( "non-zero exitcode.\n" "If you ran configure-proxy.sh, try copying again the certs from the SUSE Manager Server\n" f"exit-code: {ret}\n" f"error: {sstr(errstream.read())}\n") errstream.close() assert not ret, sslerrmsg caSerial = out.strip().split('=') assert len(caSerial) > 1 caSerial = caSerial[1] caSerial = eval('0x' + caSerial) # initialize the serial value (starting at whatever is in # serialFilename or 1) serial = 1 if os.path.exists(serialFilename): serial = open(serialFilename, 'r').read().strip() if serial: serial = eval('0x' + serial) else: serial = 1 # make sure it is at least 1 more than the CA's serial code always # REMEMBER: openssl will incremented the serial number each time # as well. if serial <= caSerial: serial = incSerial(hex(caSerial)) serial = eval('0x' + serial) serial = fixSerial(hex(serial)) # create the serial file if it doesn't exist # write the digits to this file open(serialFilename, 'w').write(serial + '\n') os.chmod(serialFilename, int('0600', 8)) # truncate the index.txt file. Less likely to have unneccessary clashes. open(indexFilename, 'w') os.chmod(indexFilename, int('0600', 8)) return serial
def __init__(self, screen, tui): self.screen = screen self.tui = tui size = snack._snack.size() toplevel = snack.GridForm(self.screen, sstr(START_REGISTER_WINDOW), 1, 2) start_register_text = sstr(START_REGISTER_TEXT) tb = snack.Textbox(size[0] - 10, size[1] - 14, start_register_text, 1, 1) toplevel.add(tb, 0, 0, padding=(0, 0, 0, 1)) self.bb = snack.ButtonBar(self.screen, [(sstr(WHY_REGISTER), "why_register"), (sstr(NEXT), "next"), (sstr(CANCEL), "cancel")]) toplevel.add(self.bb, 0, 1, growx=1) self.g = toplevel
def __init__(self, screen, tui): self.screen = screen self.tui = tui size = snack._snack.size() self.server = convert_url_from_puny(self.tui.serverURL) self.proxy = cfg['httpProxy'] toplevel = snack.GridForm(self.screen, sstr(CONNECT_WINDOW), 1, 1) text = CONNECT_WINDOW_TEXT % self.server + "\n\n" if self.proxy: text += CONNECT_WINDOW_TEXT2 % self.proxy tb = snack.Textbox(size[0] - 30, size[1] - 20, sstr(text), 1, 1) toplevel.add(tb, 0, 0, padding=(0, 0, 0, 1)) self.g = toplevel
def save_unknown_domain_configs(self, domain_uuids): """ This function saves the configuration for any domains whose UUIDs are passed in the domain_uuids list. If the UUID is already known, it is skipped. """ for uuid in domain_uuids: uuid = sstr(uuid) # If we already have a config for this uuid, skip it. Also, don't # try to figure out a config for a host UUID. if not is_host_uuid(uuid) and not self.is_known_config(uuid): # The UUID is a formatted string. Turn it back into a number, # since that's what libvirt wants. dehyphenized_uuid = dehyphenize_uuid(uuid) uuid_as_num = binascii.unhexlify(dehyphenized_uuid) # Lookup the domain by its uuid. try: domain = self.conn.lookupByUUID(uuid_as_num) except libvirt.libvirtError: lve = sys.exc_info()[1] raise VirtualizationException( "Failed to obtain handle to domain %s: %s" % (uuid, repr(lve))) # Now grab the XML description of the configuration. xml = domain.XMLDesc(0) # Write the xml out to a file so that we can load it into our # abstract DomainConfig object and manipulate it easily. cfg_file_path = self.__write_xml_file(uuid, xml) new_config = DomainConfig(self.__path, uuid) # Don't record the config this time if the domain is # installing; we don't want to restart the domain later and # make it re-install itself. if not new_config.isInstallerConfig(): # Now we'll reformat the configuration object so that it's # valid the next time this domain runs.. self.__fixup_config_for_restart(new_config) # The config is now prepared. Save it and move on to the # next uuid. new_config.save() else: # Remove the config file we just wrote. os.unlink(cfg_file_path)
def read_to_file(self, file): """Copies the contents of this File object into another file object""" fd = self._get_file() while 1: buf = fd.read(self.bufferSize) if not buf: break if sys.version_info[0] == 3: file.write(bstr(buf)) else: file.write(sstr(buf)) return file
def __init__(self, screen, tui): if not rhnreg.rhsm_registered() or tui.test: raise WindowSkipException() self.screen = screen self.tui = tui size = snack._snack.size() toplevel = snack.GridForm(self.screen, sstr(SYSTEM_ALREADY_SETUP), 1, 2) self.bb = snack.ButtonBar(self.screen, [(sstr(YES_CONT), "next"), (sstr(NO_CANCEL), "exit")]) toplevel.add(self.bb, 0, 1, growx=1) tb = snack.Textbox( size[0] - 30, size[1] - 20, sstr(WARNING + "\n\n" + RHSM_SYSTEM_ALREADY_REGISTERED + "\n\n" + SYSTEM_ALREADY_REGISTERED_CONT + "\n"), 1, 1) toplevel.add(tb, 0, 0, padding=(0, 0, 0, 1)) self.g = toplevel
def f_content(path, name, is_binary): statinfo = None if os.access(path, os.R_OK): f = open(path, ('r' if int(sys.version[0]) == 3 else 'U') + ('b' if is_binary else '')) content = [sstr(i) for i in f.readlines()] f.close() statinfo = os.stat(path) f_time = time.ctime(statinfo.st_mtime) if not is_binary and content and content[ -1] and content[-1][-1] != "\n": content[-1] += "\n" else: content = [] f_time = time.ctime(0) if not name: name = path if is_binary: return (str(content), name, f_time, statinfo) return (content, name, f_time, statinfo)
def _xccdf_resume(results_file, temp_dir=None): xslt = '/usr/share/openscap/xsl/xccdf-resume.xslt' dev_null = open('/dev/null', mode="ab+") resume_file = tempfile.NamedTemporaryFile(dir=temp_dir) c = _popen([ '/usr/bin/xsltproc', '--output', resume_file.name, xslt, results_file ], stdout=dev_null.fileno()) ret = c.wait() dev_null.close() errors = sstr(c.stderr.read()) if ret != 0: errors += 'xccdf_eval: xsltproc tool returned %i\n' % ret log.log_debug('The xsltproc tool completed:\n%s' % errors) resume = resume_file.read() del (resume_file) return ret, resume, errors
def _write_secure_file(secure_file, file_contents): """ Write a file to disk that is not readable by other users. """ dir_name = os.path.dirname(secure_file) if not os.access(dir_name, os.W_OK): return False if os.access(secure_file, os.F_OK): # already have file there; let's back it up try: os.rename(secure_file, secure_file + '.save') except: return False fd = os.open(secure_file, os.O_WRONLY | os.O_CREAT, int('0600', 8)) fd_file = os.fdopen(fd, 'w') try: fd_file.write(sstr(file_contents)) finally: fd_file.close() return True
def validateFields(self): if self.urlEntry.value() == "": snack.ButtonChoiceWindow(self.screen, sstr(ERROR), sstr(SATELLITE_REQUIRED), buttons=[sstr(OK)]) self.g.setCurrent(self.urlEntry) return 0 if (self.urlEntry.value()[:5] == 'https' and self.sslEntry.value() == ""): snack.ButtonChoiceWindow(self.screen, sstr(ERROR), sstr(SSL_REQUIRED), buttons=[sstr(OK)]) self.g.setCurrent(self.sslEntry) return 0 return 1
def _getOSVersionAndRelease(): osVersionRelease = None ts = transaction.initReadOnlyTransaction() for h in ts.dbMatch('Providename', "oraclelinux-release"): SYSRELVER = 'system-release(releasever)' version = sstr(h['version']) release = sstr(h['release']) if SYSRELVER in (sstr(provide) for provide in h['providename']): provides = dict((sstr(n), sstr(v)) for n,v in zip(h['providename'], h['provideversion'])) release = '%s-%s' % (version, release) version = provides[SYSRELVER] osVersionRelease = (sstr(h['name']), version, release) return osVersionRelease else: for h in ts.dbMatch('Providename', "redhat-release"): SYSRELVER = 'system-release(releasever)' version = sstr(h['version']) release = sstr(h['release']) if SYSRELVER in (sstr(provide) for provide in h['providename']): provides = dict((sstr(n), sstr(v)) for n,v in zip(h['providename'], h['provideversion'])) release = '%s-%s' % (version, release) version = provides[SYSRELVER] osVersionRelease = (sstr(h['name']), version, release) return osVersionRelease else: # new SUSE always has a baseproduct link which point to the # product file of the first installed product (the OS) # all rpms containing a product must provide "product()" # search now for the package providing the base product baseproduct = '/etc/products.d/baseproduct' if os.path.exists(baseproduct): bp = os.path.abspath(os.path.join(os.path.dirname(baseproduct), os.readlink(baseproduct))) for h in ts.dbMatch('Providename', "product()"): if bstr(bp) in h['filenames']: osVersionRelease = (sstr(h['name']), sstr(h['version']), sstr(h['release'])) # zypper requires a exclusive lock on the rpmdb. So we need # to close it here. ts.ts.closeDB() return osVersionRelease else: # for older SUSE versions we need to search for distribution-release # package which also has /etc/SuSE-release file for h in ts.dbMatch('Providename', "distribution-release"): osVersionRelease = (sstr(h['name']), sstr(h['version']), sstr(h['release'])) if bstr('/etc/SuSE-release') in h['filenames']: # zypper requires a exclusive lock on the rpmdb. So we need # to close it here. ts.ts.closeDB() return osVersionRelease log = up2dateLog.initLog() log.log_me("Error: Could not determine what version of Linux you are running. "\ "Check if the product is installed correctly. Aborting.") raise up2dateErrors.RpmError( "Could not determine what version of Linux you "\ "are running.\nIf you get this error, try running \n\n"\ "\t\trpm --rebuilddb\n\n")