ó Ë Rc@s¬dZddlZddlZddlZddljZd„Zd„Zde e d„Z e d„Z d„Z d„Zd „Zd „Zd „Zd „Zd „ZdS(s¤ Generic interfaces for manipulating files in an alternate root. There routines guarantee that if you perform operations on a specified path, and that path is contained within "root", then those operations will not affect any files living outside of "root". These routines mainly protect us when accessing paths which could contain symbolic links which might otherwise redirect us to an unexpected file system object. iÿÿÿÿNcCs]d}xPtrXtjj|ƒ\}}|s1Pn|rOtjj||ƒ}q |}q W|S(s8Strip the leading '/' from a path using os.path.split().N(tNonetTruetostpathtsplittjoin(Rtpath_newttail((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt__path_abs_to_relative2s  cCs#dtjƒ|f}tj|ƒS(sÝGiven a file descriptor return the path to that file descriptor. The readlink() call below can return ENOENT due to 6964121. Normally images live on zfs filesystems so this isn't a problem, but the pkg(5) test suite runs all its tests on tmpfs filesystems, so this function always fails in that case. Either 6964121 should be fixed before fcs, or we should come up with a different safe way to open files in an alternate root.s/proc/%d/path/%d(Rtgetpidtreadlink(tfdR((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt __fd_to_path@s cCsitjj|ƒst‚|tjtjB@dks9t‚| sS|tj@sSt‚| sl|dkslt‚tdƒi|d6|d6}tjj|ƒr«t|ƒ}ntj |tjƒ}yt |ƒ}Wn;t k r }|j t j krtj|ƒ|‚qnXtj|ƒd} y+tjj||ƒ} tj | |ƒ} Wn5t k rƒ}|j t j ksw| r„|‚q„nX| s–|s–t‚| s‹tjj|ƒ} tjj|ƒ} yt|| tjƒ} Wn@t k r}|j t jkr|‚nt t j|ƒ‚nXy*tj| | |tjBtjB|ƒ} Wn&t k rn}tj| ƒ|‚nX| s{t‚tj| ƒnyt | ƒ}WnPt k rí}|j t j krÕtj| ƒ|‚ntjj||ƒ}nX|j|ƒstj| ƒt t j|ƒ‚n|reytj| dƒWqet k ra}tj| ƒ|‚qeXn| S(sÚA function similar to os.open() that ensures that the path we're accessing resides within a specified directory subtree. 'root' is a directory that path must reside in. 'path' is a path that is interpreted relative to 'root'. i.e., 'root' is prepended to path. 'path' can not contain any symbolic links that would cause an access to be redirected outside of 'root'. If this happens we'll raise an OSError exception with errno set to EREMOTE 'mode' optional permissions mask used if we create 'path' 'create' optional flag indicating if we should create 'path' 'truncate' optional flag indicating if we should truncate 'path' after opening it.is9Path outside alternate root: root=%(root)s, path=%(path)strootRN(RRtisabstAssertionErrortO_WRONLYtO_RDONLYRt_RtopenR tOSErrorterrnotENOENTtcloseRtdirnametbasenametar_opentEREMOTEtsattopenattO_CREATtO_EXCLt startswitht ftruncate(R Rtflagstmodetcreatettruncateteremotetroot_fdtetpath_fdtpath_tmptpath_dirt path_filet path_dir_fd((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyRPst!               cCstjj|ƒst‚tjj|ƒr9t|ƒ}ntjj|ƒ}tjj|ƒ}yt||tjƒ}Wn5t k r­}|r¤|j t j kr¤dS|‚nXyt j ||dƒWnBt k r }tj|ƒ|r|j t j krdS|‚nXtj|ƒdS(sVA function similar to os.unlink() that ensures that the path we're accessing resides within a specified directory subtree. 'noent_ok' optional flag indicating if it's ok for 'path' to be missing. For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.Ni(RRRRRRRRRRRRRtunlinkatR(R Rtnoent_okR+R,R-R(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt ar_unlinkÆs(     c Csgtjj|ƒst‚tjj|ƒr9t|ƒ}ntjj|ƒrZt|ƒ}ntjj|ƒ}tjj|ƒ}tjj|ƒ}tjj|ƒ}t||tjƒ}yt||tjƒ}Wn&t k rø} tj |ƒ| ‚nXyt j ||||ƒWn3t k rH} tj |ƒtj |ƒ| ‚nXtj |ƒtj |ƒdS(sJA function similar to os.rename() that ensures that the path we're accessing resides within a specified directory subtree. 'src' and 'dst' are paths that are interpreted relative to 'root'. i.e., 'root' is prepended to both. 'src' and 'dst' can not contain any symbolic links that would cause an access to be redirected outside of 'root'. If this happens we'll raise an OSError exception with errno set to EREMOTE For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.N( RRRRRRRRRRRRtrenameat( R tsrctdsttsrc_dirtsrc_filetdst_dirtdst_filet src_dir_fdt dst_dir_fdR(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt ar_renameìs0       cCsÃtjj|ƒst‚tjj|ƒr9t|ƒ}ntjj|ƒ}tjj|ƒ}t||tjƒ}yt j |||ƒWn&t k r±}tj |ƒ|‚nXtj |ƒdS(sùA function similar to os.mkdir() that ensures that the path we're opening resides within a specified directory subtree. For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.N( RRRRRRRRRRtmkdiratRR(R RR#R+R,R-R(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pytar_mkdirs   cCsUyt||tjƒ}Wntk r4}|‚nXtj|ƒ}tj|ƒ|S(súA function similar to os.stat() that ensures that the path we're accessing resides within a specified directory subtree. For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.(RRRRtfstatR(R RR R(tsi((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pytar_stat4s  cCs_yt||ƒ}Wn/tk rD}|jtjkr;tS|‚nXtj|jƒr[tStS(sA function similar to os.path.isdir() that ensures that the path we're accessing resides within a specified directory subtree. For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.( R?RRRtFalsetstattS_ISDIRtst_modeR(R RR>R(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pytar_isdirCs cCs\yt||tjƒ}Wn/tk rJ}|jtjkrAtS|‚nXtj|ƒtS(sA function similar to os.path.exists() that ensures that the path we're accessing resides within a specified directory subtree. For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.( RRRRRRR@RR(R RR R(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt ar_existsUs  c Cs+d}}t}yµt||tjƒ}t||tjƒ}x„trÃtj|dƒ}tj|dƒ}t|ƒdkr’t|ƒdkr’Pnt|ƒt|ƒks¶||kr@t}Pq@q@WWnEtk r }|rítj |ƒn|rtj |ƒn|‚nXtj |ƒtj |ƒ|S(sþA function similar to filecmp.cmp() that ensures that the path we're accessing resides within a specified directory subtree. For all other parameters, refer to the 'ar_open' function for an explanation of their usage and effects.iiN( RR@RRRRtreadtlenRR( R tpath1tpath2tfd1tfd2tdifftb1tb2R(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pytar_diffes,  $$    cCs‚ddljj}t}t}t||jƒr9t}nt||jƒrTt}n|rd|rddS|rq|jS|r~|jSdS(sçA function that attempts to determine if a user or root pkg(5) managed image can be found at 'root'. If 'root' does point to a pkg(5) image, then we return the relative path to the image metadata directory.iÿÿÿÿN( tpkg.client.imagetclienttimageR@RDtimg_user_prefixRtimg_root_prefixR(R RRtuser_imgtroot_img((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt ar_img_prefix‡s   (t__doc__RRRAt pkg.syscallatt syscallatRRR RR@RR0R:R<R?RDRERORW(((s1/usr/lib/python2.7/vendor-packages/pkg/altroot.pyt"s     u & -     "