urVc@skdZddlZddlZddlZddlZddlZddlZddlZddl j j j j jjZddlZddlmZmZddlmZmZmZeddZdZed\ZZZZZ ed \Z!Z"ed \Z#Z$Z%Z&gZ'e'j(e#ee'j(e$ee'j(e%ee'j(e&e gZ)e)j(e#ee)j(e$ee)j(e%ee)j(e&egZ*e*j(e!e'e*j(e"e)d Z+d Z,d Z-dZ.dZ/de1dZ2dZ3dZ4dddZ5dZ6dZ7dZ8dZ9dZ:dZ;dZ<dZ=dS(s Install utility functions iN(t defaultdictt namedtuple(tPopentrunt RadConnectiontmappingssKgroupings services periodic_instances config_props layers labels typess/usr/sbin/svccfgiiicCs|tkrt}nt}|dkr8t|t}nH|dkrUt|t}n+|dkrrt|t}nt|t}|S(s Find next state from space state table. (Private function) Args: curr_state: Current state. One of the state table states listed above curr_char: Current character. Returns: Next state. One of the state table states listed above. Raises: N/A s"s's\(t __QST_ESCt __QST_BSESCt __QST_NONESCt__SPACE_STATE_TABLEt__QST_CHAR_DQTt__QST_CHAR_SQTt __QST_CHAR_BSt__QST_CHAR_CHAR(t curr_statet curr_chartidxt next_state((sutils.pyt__space_next_staters     cCst}d}g}t}t}|j}xZ|D]R}t||}|tkrw|dkrw|dkrw|d7}n|tkr||7}n|tkr|r||7}q}| }|s}t|dkr|j|jd}qq}n|t krP|r||7}q}| }|s}t|dkrM|j|jd}qMq}n-|tkr}t j dd|||fIJn|}q1W|s|rt d|n|tkr|d7}nt|dkr|j|jn|S( s Parse an input string into words, accounting for whitespace inside quoted (or double-quoted) strings. Quotes and double-quotes can be escaped with a \. Unescaped quotes can be used inside double-quotes, and vice versa. Unescaped quotes and double-quotes are removed from the output. Escaped quotes and double-quotes are added to the output but their escaping \ are removed. Args: input_str: string to parse. Returns: list of parsed tokens. Raises: N/A ts"t's\is$space_parse: Shouldn't get here!!!! sChar:%s, state:%d, next:%ds"Unexpected unescaped quote found: ( t __QST_STARTtFalsetstripRRt __QST_CHARt __QST_SQTtlentappendt __QST_DQTtsyststderrt Exception(t input_strtstatetwordtoutlisttsquoteontdquoteontcharR((sutils.pyt space_parsesT                cCsWyt|d}tSWntk r*nXyt|}tSWntk rRnXtS(s Public function: does the (string) argument represent a number Hex, octal, decimal, floating point are all considered. Malformed numbers are considered not numeric. Test cases: 0x123, .123, 0x.1, 0x0x123, 12.2, 12..3, 12., 1.2.3, 1.23, 12z4, abc, 0xabc, 0x1a2b3c4, 0xa2b3c4d, 0xabcdefg, 0xgabcdef, 0x123. Args: String value to evaluate Returns: True: string represents a number. False: string does not represent a numeric value. Raises: None i(tinttTruet ValueErrortfloatR(targtdummy((sutils.pytisnumbers   cCs|dkrd}nM|dkr*d}n8|dkrbttjtjtjddfntj|}t||}|jdS( s Test to see if can access filename with "mode" permissions If the file exists and can be accessed, just return. Otherwise, throw an exception which contains appropriate errno value for proper error message. This method is needed because the chosen XML validator doesn't return an appropriate errno for its exit status, so file access needs to be checked independently. Args: filename: Name of the file to test for access mode: Character string mode, r=read, w=write, rw=read/write Returns: N/A Raises: IOError with the appropriate errno: file doesn't exist or doesn't have the permissions required for the requested access. IOError with errno = EINVAL: mode argument is invalid trwsa+twtatrs: tmodeN(tIOErrorterrnotEINVALtoststrerrortstattopentclose(tfilenameR3R-((sutils.pyt canaccesss      #cCs |dS(s Error handler for find() below. Raises the exception passed to it. Args: raise_me: Exception to raise Returns: None Raises: The exception passed in. N((traise_me((sutils.pyt__find_error_handler@s c Cs-g}d}|dk rC|dkrC|dkrCtddn|rRt}nx|D]}ytj|}Wntk rqYnX|dkrtj|j r|j |qYn4|dkrtj |jrY|j |qYqYnx3tj |t |D]\}}} |dks>|dkrNtj|jrN|j |n|dkr`qn|dkrxP|D]E} |d| } tj| }tj|jss|j | qsqsWnx_| D]W} |d| } |dkrtj| }tj |jsqqn|j | qWqWqYW|S(s Python implementation of the Unix find(1) command. Order of output is similar, but not the same as, find(1) when -depth is not passed to it. A directory is enumerated before the files it contains. Unlike find(1), no errors are returned when given a file or directory to parse which doesn't exist (when raise_errors is False) Args: rootpaths: list of file and/or directory pathnames to parse. path_type: - When set to None, return all found pathnames. - When set to "dir", return all found directories only. This does not include links to directories. - When set to "file", return all found files only. This does not include links to files. raise_errors: - When set to True: raise an OSError when a non-existant file or directory to parse is passed in the rootpaths list. - When set to False, ignore any such errors. tdirtfiles find: "path_type" must be None, s"dir" or "file"t/N( tNoneRR?R7tlstattOSErrorR9tS_ISDIRtst_modeRtS_ISREGtwalkR)( t rootpathst path_typet raise_errorstrlistt error_handlertrootpathtstat_outtpathtsubdirstfilestsubdirtfullnametone_file((sutils.pytfindQsT               cCs@tj|}|jddkr)|jS|jdddSdS(s Get the size of the specified file/dir. If the size of a file/directory is not multiples of 1024, it's size will be rounded up to the next multiples of 1024. This mimics the behavior of ufs especially with directories. This results in a total size that's slightly bigger than if du was called on a ufs directory. The exception that will be raised by os.lstat() is intentionally not caught in this function so it can get passed to the caller and caller can deal with it. Args: filename: name of the file or directory to get the size for Returns: size of the file or directory in bytes. Raises: OSerror as returned from lstat. iiiN(R7RDtst_size(R<R9((sutils.pyt file_sizescCsd}|t|7}|dkr5t|dnxtj|D]n\}}}x\||D]P}|d|}y|t|7}Wq_tk rtjd|IJq_q_Xq_WqEW|S(s Estimates the size of the given directory. This function is similar in functionality to the "du" command, but this function works for both ufs and zfs. On UFS, du(1) reports the size of the data blocks within the file. On ZFS, du(1) reports the actual size of the file as stored on disk. This size includes metadata as well as compression. So, given exactly the same content for a directory, du reports different sizes depending on whether the directory is on UFS or ZFS. This function will traverse all the directories/files under a given directory, and add up the sizes for all the directories and files, and return the value in bytes. Args: rootpath: root of the directory to calculate the size for Returns: Size of the directory contents in bytes. Raises: OSError as returned from file_size Exception: rootpath is not valid is is not validRBs Error getting information about (RYRR7RIRERR(ROtsizetrootRRRSR<t abs_filename((sutils.pytdir_sizes  R[cs|dk rtj||StjdtjffdY}tjd}|j}f|_tj||_ |j }tj|f|_|_ ||}|st d|n|d|}tj||S(s Encrypts the password. If a salt value is given, it will be used. If salt is not given, a salt will be generated for use. Args: plaintext: password string in plaintext salt: salt to be used for the encryption. If none is provided, a salt will be generated. username: name of the user to generate the password for. Default is root. Returns: The encrypted password string Raises: OSError if getpwnam() cannot find username tPasswdc seeZdfdfdejfdejfdfdfdfdfdfg ZRS( tpw_namet pw_passwdtpw_uidtpw_gidtpw_aget pw_commenttpw_gecostpw_dirtpw_shell(t__name__t __module__tCtc_uintt_fields_((tstring(sutils.pyR^*s        s/usr/lib/libc.sosgetpwnam(): name not found: %sN( RCtcryptRjtc_char_pt StructuretCDLLtgetpwnamtargtypestPOINTERtrestypet crypt_gensaltRE(t plaintexttsalttusernameR^t_LIBCRrRvt pwnam_entry((Rmsutils.pytencrypt_passwords         cCst|stdntj|r7tj|St|drVtj|jStj|rutj|jStj|j SdS(sReturns a tuple of (args, varargs, kwargs, defaults) with data on the call signature of any Python callable EXCEPT for builtins s%Not a callable Python function/objecttim_funcN( tcallablet TypeErrortinspectt isfunctiont getargspecthasattrR}tisclasst__init__t__call__(tfunc((sutils.pyt get_argspecPs  cCs|tjd<|tjd service(s) mappings services - list containing the service which participate in sysconfig periodic_instances - list containing all periodic instances config_props - dictionary containing service -> configurable properties mappings layers - dictionary containing service -> layer (admin or site) information labels - dictionary containing label -> property mappings types - dictionary containing property -> SMF type mappings This function is designed to be called only once at the start of sysconfig to minimize activity against the SMF repository. ssysconfig/groups%s:%stperiodic_restarterssysconfig/config_propertiesRCRRs site-profiletsites-sRs-lRRt check_resultitMASKEDs-fiN(&Rt connectionRRtMasterRtlisttdicttservicesRRRRCRt instancestreadPropertiesRRRRRRRtitemstreadPropertyDecorationsRtlayerR)tbundleRRRtANYt returncodeRtbooltMAPPINGSt_make(trad_contmastert groupingsRtperiodic_instancest config_propstlayerstlabelsttypestsvctgroupingRt full_nametinstRtconfig_propertiesRtlabeltvaluetnamet decorationst decorationRR((sutils.pytbuild_mappingss                        #(>t__doc__tctypesRjRnR5RR7R9Rt)rad.bindings.com.oracle.solaris.rad.smf_1tbindingstcomtoracletsolarisRtsmf_1Rt rad.clientt collectionsRRtsolaris_installRRRRRtrangeRRRRRRRR R R R t__QST_NONESC_TBLtinsertt __QST_ESC_TBLR RR'R.R=R?RCRRWRYR]R|RRRRRRRR(((sutils.pyts^            b # * _ & 9A    * )