ó
ýGpNc           @   s  d  Z  d d l Z d d l Z d d l Z d d l Z y  d d l m Z m Z m Z Wn- e	 k
 r… d d l m Z m Z m Z n Xd d l
 m Z d d l m Z e j j d d ƒ a d a d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d d „ Z d „  Z  d e! d „ Z" d e" _# d d l$ Z$ d d l% Z% d d l Z d d l& Z& d d l' Z' d d l( Z( y d d l) m* Z* Wn! e	 k
 rÐd d l+ m* Z* n Xd e$ j, f d „  ƒ  YZ- e. d k re$ j/ ƒ  n  d S(   s0   Functions to manage apport problem report files.iÿÿÿÿN(   t   ConfigParsert   NoOptionErrort   NoSectionError(   t   ProblemReport(   t   implt   APPORT_REPORT_DIRs
   /var/crashs   ~/.config/apport/settingsc         C   sV   |  d k r d Sd } x9 t j |  ƒ D]( } | j d ƒ r& | rE d S| } q& q& W| S(   s›   Return a package's .desktop file.

    If given package is installed and has a single .desktop file, return the
    path to it, otherwise return None.
    s   .desktopN(   t   Nonet	   packagingt	   get_filest   endswith(   t   packaget   desktopfilet   line(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   find_package_desktopfile   s    c         C   sr   d d d d d d d d g } t  } x' | D] } |  j | ƒ r+ t } Pq+ q+ W| oq |  j d	 ƒ oq |  j d
 ƒ S(   s2  Check whether the given file is likely to belong to a package.

    This is semi-decidable: A return value of False is definitive, a True value
    is only a guess which needs to be checked with find_file_package().
    However, this function is very fast and does not access the package
    database.
    s   /bin/s   /boots   /etc/s   /initrds   /libs   /sbin/s   /usr/s   /vars   /usr/local/s	   /var/lib/(   t   Falset
   startswitht   True(   t   filet   pkg_whitelistt   whitelist_matcht   i(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   likely_packaged0   s    c         C   sq   t  j j |  ƒ \ } } t  j j | ƒ } t  j j | ƒ rT t  j j | | ƒ }  n  t |  ƒ sd d St j	 |  ƒ S(   s_   Return the package that ships the given file.
    
    Return None if no package ships it.
    N(
   t   ost   patht   splitt   realpatht   isdirt   joinR   R   R   t   get_file_package(   R   t   dirt   namet   resolved_dir(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   find_file_packageC   s    c         C   s.   t  j |  ƒ } | j | j k p- | j d k S(   sA   Check whether the report file has already been processed earlier.i    (   R   t   statt   st_atimet   st_mtimet   st_size(   t   reportt   st(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   seen_reportS   s    c         C   sõ   t  j |  ƒ } y$ t  j |  | j | j d f ƒ Wn» t k
 rð d } xˆ | d k rÓ t |  ƒ } | j d ƒ | j ƒ  y t  j |  ƒ } Wn t k
 r¢ d SX| j | j k r¹ Pn  t	 j
 d ƒ | d 8} qL W| d k rñ t |  ƒ qñ n Xd S(   s   Mark given report file as seen.i   i   i    Ngš™™™™™¹?(   R   R!   t   utimeR#   t   OSErrort   opent   readt   closeR"   t   timet   sleept   delete_report(   R%   R&   t   timeoutt   f(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   mark_report_seenY   s&    $
c          C   sˆ   g  }  x{ t  j  t j j t d ƒ ƒ D][ } yA t j j | ƒ d k rk t j | t j ƒ rk |  j | ƒ n  Wq% t	 k
 r q% Xq% W|  S(   sC   Return a list with all report files accessible to the calling user.s   *.crashi    (
   t   globR   R   R   t
   report_dirt   getsizet   accesst   R_OKt   appendR)   (   t   reportst   r(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   get_all_reportsw   s    %-c          C   sR   g  }  xE t  ƒ  D]: } y  t | ƒ s5 |  j | ƒ n  Wq t k
 rI q Xq W|  S(   s   Get new reports for calling user.

    Return a list with all report files which have not yet been processed
    and are accessible to the calling user.
    (   R;   R'   R8   R)   (   R9   R:   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   get_new_reports…   s    c          C   s‹   g  }  x~ t  j  t j j t d ƒ ƒ D]^ } yD t j j | ƒ d k rn t j | ƒ j d k  rn |  j | ƒ n  Wq% t	 k
 r‚ q% Xq% W|  S(   s‹   Get all system reports.

    Return a list with all report files which belong to a system user (i. e.
    uid < 500 according to LSB).
    s   *.crashi    iô  (
   R3   R   R   R   R4   R5   R!   t   st_uidR8   R)   (   R9   R:   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   get_all_system_reports–   s    %0c          C   s&   g  t  ƒ  D] }  t |  ƒ s
 |  ^ q
 S(   s«   Get new system reports.

    Return a list with all report files which have not yet been processed
    and belong to a system user (i. e. uid < 500 according to LSB).
    (   R>   R'   (   R:   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   get_new_system_reports§   s    c         C   s?   y t  j |  ƒ Wn' t k
 r: t |  d ƒ j d ƒ n Xd S(   sÁ   Delete the given report file.

    If unlinking the file fails due to a permission error (if report_dir is not
    writable to normal users), the file will be truncated to 0 bytes instead.
    t   wi    N(   R   t   unlinkR)   R*   t   truncate(   R%   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyR/   ¯   s    c         C   s•   t  ƒ  } | j |  t ƒ y] t | d ƒ } t j t j | d ƒ ƒ } t j t j ƒ  ƒ } | | d k rq d S| SWn t t	 f k
 r d SXd S(   sº   Return the number of recent crashes for the given report file.

    Return the number of recent crashes (currently, crashes which happened more
    than 24 hours ago are discarded).
    t   CrashCountert   Datei   i  i    Ni€Q (
   R   t   loadR   t   intR-   t   mktimet   strptimet	   localtimet
   ValueErrort   KeyError(   R%   t   prt   countt   report_timet   cur_time(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   get_recent_crashesº   s    	c         C   s˜   |  j  d ƒ r( |  d j d d ƒ } n8 |  j  d ƒ rT |  d j d	 d ƒ d } n t d ƒ ‚ | su t j ƒ  } n  t j j t	 d | t
 | ƒ f ƒ S(
   s‚   Construct a canonical pathname for the given report.

    If uid is not given, it defaults to the uid of the current process.
    t   ExecutablePatht   /t   _t   Packagei   i    s7   report has neither ExecutablePath nor Package attributes   %s.%s.crashN(   t   has_keyt   replaceR   R   RJ   R   t   getuidR   R   R4   t   str(   R%   t   uidt   subject(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   make_report_pathÍ   s    c         C   sÇ   t  j j |  ƒ s t ‚ t j d d |  g d t j d t j d t d d d i  ƒ} | j ƒ  d	 } | j	 d	 k rw g  Sg  } xC | j
 ƒ  D]5 } | j d
 ƒ rŠ | j | j d d ƒ d	 ƒ qŠ qŠ W| S(   s”   Check file integrity against md5 sum file.

    sumfile must be md5sum(1) format (relative to /).

    Return a list of files that don't match.
    s   /usr/bin/md5sums   -ct   stdoutt   stderrt	   close_fdst   cwdRR   t   envi    t   FAILEDt   :i   (   R   R   t   existst   AssertionErrort
   subprocesst   Popent   PIPER   t   communicatet
   returncodet
   splitlinesR	   R8   t   rsplit(   t   sumfilet   mt   outt
   mismatchest   l(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   check_files_md5Þ   s    $c         C   sƒ   t  j s4 t ƒ  t  _ t  j j t j j t ƒ ƒ n  y0 | rP t  j j |  | ƒ St  j j	 |  | ƒ SWn t
 t f k
 r~ | SXd S(   sœ   Return a setting from user configuration.

    This is read from ~/.config/apport/settings. If bool is True, the value is
    interpreted as a boolean.
    N(   t
   get_configt   configR    R+   R   R   t
   expandusert   _config_filet
   getbooleant   getR   R   (   t   sectiont   settingt   defaultt   bool(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyRr   ö   s    	(   t   StringIOt   _Tc           B   s‰   e  Z d  „  Z d „  Z e d „ Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z RS(   c         C   s"   t  |  _ t j ƒ  a  t |  _ d  S(   N(   R4   t   orig_report_dirt   tempfilet   mkdtempRu   t   orig_config_file(   t   self(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   setUp  s    	c         C   s,   t  j t ƒ |  j a d  |  _ |  j a d  S(   N(   t   shutilt   rmtreeR4   R~   R   R   Ru   (   R‚   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   tearDown  s    		c         C   sÒ   t  j j t d ƒ } t  j j t d ƒ } t | d ƒ j d ƒ t | d ƒ j d ƒ t  j | d ƒ t  j | d ƒ | rÄ t  j j t d ƒ } t | d ƒ j d ƒ t  j | d	 ƒ | | | g S| | g Sd
 S(   s   Create some test reports.s
   rep1.crashs
   rep2.crashR@   s   report 1s   report 2i€  s   inaccessible.crasht   inaccessiblei    N(   R   R   R   R4   R*   t   writet   chmod(   R‚   t   create_inaccessiblet   r1t   r2t   ri(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   _create_reports$  s    c         C   sÌ  d } t  g  t j | ƒ D] } | j d ƒ r | ^ q ƒ d k sI t ‚ d	 } d	 } xÉ t j d ƒ D]¸ } | j d ƒ s€ qe n  t j t j	 j
 d | ƒ ƒ } t  g  t j | ƒ D] } | j d ƒ r± | ^ q± ƒ } | rñ | d k rñ | } n | r| d k r| } n  | re | re Pqe qe W| rG|  j t | ƒ d	 d | ƒ n  | rm|  j t | ƒ d	 d | ƒ n  | rÈt | ƒ } |  j | d	 d | ƒ |  j t j	 j | ƒ ƒ |  j | j d ƒ ƒ n  d	 S(
   s   find_package_desktopfile().t   bashs   .desktopi    s   /usr/share/applications/i   s   no-desktop package %ss   multi-desktop package %ss   one-desktop package %sN(   t   lenR   R   R	   Rd   R   R   t   listdirR   R   R   t   assertEqualR   t   assertNotEqualt
   assertTrueRc   (   R‚   t	   nodesktopR1   t
   onedesktopt   multidesktopt   dt   pkgt   num(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_find_package_desktopfile6  s6    *		  c         C   sˆ   |  j  t d ƒ t ƒ |  j  t d ƒ t ƒ |  j  t d ƒ t ƒ |  j  t d ƒ t ƒ |  j  t d ƒ t ƒ |  j  t d ƒ t ƒ d S(   s   likely_packaged().s	   /bin/bashs   /usr/bin/foos   /usr/local/bin/foos   /home/test/bin/foos   /tmp/foos   /var/lib/fooN(   R’   R   R   R   (   R‚   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_likely_packagedZ  s    c         C   sF   |  j  t d ƒ d ƒ |  j  t d ƒ d ƒ |  j  t d ƒ d ƒ d S(   s   find_file_package().s	   /bin/bashR   s   /bin/catt	   coreutilss   /nonexistingN(   R’   R    R   (   R‚   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_find_file_packagee  s    c         C   s  |  j  t ƒ  g  ƒ t j ƒ  d k r7 |  j t ƒ } n. g  |  j t ƒ D] } d | k rG | ^ qG } |  j  t t ƒ  ƒ t | ƒ ƒ t | ƒ } xj | D]b } |  j  t | ƒ t ƒ | j	 | ƒ t
 | ƒ |  j  t | ƒ t ƒ |  j  t t ƒ  ƒ | ƒ q— Wd S(   s$   get_new_reports() and seen_report().i    R‡   N(   R’   R<   R   RW   RŽ   R   t   setR'   R   t   removeR2   (   R‚   t   trR:   t   nr(    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt	   test_seenl  s    .
c         C   sÂ   |  j  t ƒ  g  ƒ t j ƒ  d k r7 |  j t ƒ } n. g  |  j t ƒ D] } d | k rG | ^ qG } |  j  t t ƒ  ƒ t | ƒ ƒ x | D] } t | ƒ q‹ W|  j  t t ƒ  ƒ t | ƒ ƒ d S(   s   get_all_reports().i    R‡   N(   R’   R;   R   RW   RŽ   R   RŸ   R2   (   R‚   R¡   R:   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_get_all_reports  s    .c         C   sQ  |  j  t ƒ  g  ƒ |  j  t ƒ  g  ƒ t j ƒ  d k rá |  j t ƒ } |  j  t t ƒ  ƒ t | ƒ ƒ |  j  t t ƒ  ƒ t | ƒ ƒ x | D] } t	 | ƒ qŒ W|  j  t t ƒ  ƒ t | ƒ ƒ |  j  t t ƒ  ƒ t g  ƒ ƒ nl g  |  j t ƒ D] } d | k rñ | ^ qñ } |  j  t t ƒ  ƒ t g  ƒ ƒ |  j  t t ƒ  ƒ t g  ƒ ƒ d S(   s6   get_all_system_reports() and get_new_system_reports().i    R‡   N(
   R’   R;   R>   R   RW   RŽ   R   RŸ   R?   R2   (   R‚   R¡   R:   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_get_system_reports  s    ".c         C   sL   |  j  ƒ  } x9 | rG |  j t t ƒ  ƒ t | ƒ ƒ t | j ƒ  ƒ q Wd S(   s   delete_report().N(   RŽ   R’   RŸ   R;   R/   t   pop(   R‚   R¡   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_delete_report¤  s    	c         C   sî   t  d ƒ } |  j t | ƒ d ƒ t  d ƒ } |  j t | ƒ d ƒ t  d ƒ } |  j t | ƒ d ƒ t  d t j t j t j ƒ  ƒ d
 ƒ ƒ } |  j t | ƒ d ƒ t  d t j t j t j ƒ  ƒ d ƒ ƒ } |  j t | ƒ d ƒ d	 S(   s   get_recent_crashes().s   ProblemType: Crashi    s1   ProblemType: Crash
Date: Wed Aug 01 00:00:01 1990sA   ProblemType: Crash
Date: Wed Aug 01 00:00:01 1990
CrashCounter: 3s+   ProblemType: Crash
Date: %s
CrashCounter: 3i   i  i   Ni_ (   R|   R’   RP   R-   t   ctimeRG   RI   (   R‚   R:   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_get_recent_crashes­  s    		))c         C   st   t  ƒ  } |  j t t | ƒ d | d <|  j t | ƒ j d t ƒ ƒ d | d <|  j t | ƒ j d t ƒ ƒ d S(   s   make_report_path().s   bash 1RT   s   %s/bashs	   /bin/bashRQ   s   %s/_bin_bashN(   R   t   assertRaisesRJ   R[   R”   R   R4   (   R‚   RL   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_make_report_pathÊ  s    	
 
c         C   sM  t  j j t d ƒ } t  j j t d ƒ } t  j j t d ƒ } t | d ƒ j d ƒ t | d ƒ j d ƒ t | d ƒ j d | d | f ƒ |  j t | ƒ g  d	 ƒ t | d ƒ j d
 ƒ |  j t | ƒ | d g d ƒ t | d ƒ j d ƒ |  j t | ƒ | d | g d ƒ t | d ƒ j d ƒ |  j t | ƒ | g d ƒ d S(   s   check_files_md5().s
   test 1.txts
   test:2.txts   sums.txtR@   s
   Some stuffs
   More stuffsJ   2e41290da2fa3f68bd3313174467e3b5  %s
f6423dfbc4faf022e58b4d3f5ff71a70  %s
i   s   correct md5sumss   Some stuff!s   file 1 wrongs   More stuff!s   files 1 and 2 wrongs   file 2 wrongN(   R   R   R   R4   R*   Rˆ   R’   Rq   (   R‚   t   f1t   f2Rl   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_check_files_md5Õ  s     #c         C   s7  d a  |  j t d d ƒ d ƒ |  j t d d d ƒ d ƒ d t _ t j ƒ  } | j a  |  j t d d ƒ d ƒ |  j t d d d ƒ d ƒ d t _ | j d ƒ | j	 ƒ  |  j t d d ƒ d ƒ |  j t d d d ƒ d ƒ |  j t d d ƒ d ƒ |  j t d d d d ƒd ƒ |  j t d d	 ƒ d
 ƒ |  j t d d d t
 ƒt
 ƒ |  j t d d d t
 ƒt ƒ |  j t d d d t
 ƒd ƒ |  j t d d d t d t
 ƒt ƒ |  j t d d ƒ d ƒ |  j t d d	 ƒ d ƒ |  j t d d d ƒ d ƒ |  j t d d d ƒ d ƒ d t _ | j ƒ  d S(   s   get_config().s   /nonexistingt   maint   foot   moos:   [main]
one=1
two = TWO
b1 = 1
b2=False
[spethial]
one= 99
t   onet   1Rz   t   twot   TWOt   b1R{   t   b2t   b3t   spethialt   99t   nopeN(   Ru   R’   Rr   R   Rs   R   t   NamedTemporaryFileR   Rˆ   t   flushR   R   R,   (   R‚   R1   (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   test_get_configê  s4    			
%	(   t   __name__t
   __module__Rƒ   R†   R   RŽ   R›   Rœ   Rž   R£   R¤   R¥   R§   R©   R«   R®   R¾   (    (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyR}     s   			$										t   __main__(0   t   __doc__R   R3   Re   t   os.patht   configparserR    R   R   t   ImportErrort   problem_reportR   t   apport.packaging_implR   R   t   environRw   R4   Ru   R   R   R    R'   R2   R;   R<   R>   R?   R/   RP   R   R[   Rq   R   Rr   Rs   t   unittestR   R„   t   sysR-   t	   cStringIOR|   t   iot   TestCaseR}   R¿   R¯   (    (    (    s4   /usr/lib/python2.7/dist-packages/apport/fileutils.pyt   <module>   s@   0  													Hü