
?]Mc        7   @   s  d  Z  d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k	 Z	 d d k
 Z
 d d k l Z d d k l Z d d k l Z d d k Td d k Z d d k l Z l Z l Z d d k l Z d d	 k l Z d d
 k l Z d d k l Z d d k l Z d d k l Z d d k l  Z  d d k! l" Z" d d k# l$ Z$ d d k% l& Z& d d k' l( Z( d d k) l* Z* d d k+ l, Z, d d k- l. Z. d d k/ l0 Z0 d d k1 l2 Z2 d d k l3 Z3 d d k l4 Z4 d d k l5 Z5 d d k6 l7 Z7 d d k l8 Z8 d d k l9 Z9 d d k l: Z: d d k; l< Z< e: i= Z= d  Z> y e? e@ f Wn eA j
 o d! Z? d" Z@ n Xd# e, e& e. e  e( e0 e$ e* e" e2 e3 i3 f d$     YZB d S(%   sU   The class representing a Mailman mailing list.

Mixes in many task-specific classes.
iN(   t   StringIO(   t   UserDict(   t   urlparse(   t   *(   t   getaddressest
   formataddrt	   parseaddr(   t   Header(   t   mm_cfg(   t   Utils(   t   Errors(   t   LockFile(   t   UserDesc(   t   Archiver(   t   Autoresponder(   t   Bouncer(   t	   Deliverer(   t   Digester(   t   GatewayManager(   t   HTMLFormatter(   t	   ListAdmin(   t   SecurityManager(   t   TopicMgr(   t   Pending(   t   Gui(   t   MemberAdaptor(   t   OldStyleMemberships(   t   Message(   t   Site(   t   i18n(   t   syslogt    i   i    t   MailListc           B   s  e  Z d3 d  d  Z d   Z d   Z d d  Z d   Z d   Z d   Z	 d	   Z
 d3 d
  Z d   Z d   Z d d  Z d   Z d   Z d   Z d   Z d   Z d d  Z d d d  Z d   Z d3 d d d  Z d   Z d   Z d3 d  Z d3 d3 d  Z d   Z d   Z d   Z e d  Z  d    Z! d!   Z" d"   Z# d d#  Z$ d3 d$  Z% d3 d3 d d d%  Z& d3 d3 e d&  Z' d3 d3 d3 d'  Z( d(   Z) d)   Z* d*   Z+ d3 d+  Z, d3 d3 d,  Z- d-   Z. d.   Z/ d/   Z0 d3 d0  Z1 d1   Z2 d2   Z3 RS(4   i   c         C   s  x5 |  i  i D]' } t | d  o | i |   q q W|  i |  t |   |  _ | d  j o d  St i	 i
 |  i   d  } h  } y t | |  Wn< t j
 o0 } | i t i j o q t d d |  n& X| i d  } | o | |   n | o |  i   n |  i   d  S(   Nt   __init__s	   extend.pyt   errors"   IOError reading list extension: %st   extend(   t	   __class__t	   __bases__t   hasattrR!   t   InitTempVarsR   t   _memberadaptort   Nonet   ost   patht   joint   fullpatht   execfilet   IOErrort   errnot   ENOENTR   t   gett   Lockt   Load(   t   selft   namet   lockt	   baseclasst   filenamet   dictt   et   func(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR!   ^   s,     c         C   sr   y t  |  i |  SWnW t j
 oK xF |  i D]- } y t  | |  SWq/ t j
 o q/ Xq/ Wt |  n Xd  S(   N(   t   getattrR(   t   AttributeErrort   _gui(   R5   R6   t   guicomponent(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   __getattr__   s    
 	c         C   s:   |  i    o
 d } n d } d |  i   | t |   f S(   Ns   (locked)s
   (unlocked)s   <mailing list "%s" %s at %x>(   t   Lockedt   internal_namet   id(   R5   t   status(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   __repr__   s
    
i    c         C   sE   |  i  i |  y |  i   Wn  t j
 o |  i     n Xd  S(   N(   t   _MailList__lockR7   R4   t	   Exceptiont   Unlock(   R5   t   timeout(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR3      s    
c         C   s   |  i  i d d  d  S(   Nt   unconditionallyi   (   RG   t   unlock(   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyRI      s    c         C   s   |  i  i   S(   N(   RG   t   locked(   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyRB      s    c         C   s   |  i  S(   N(   t   _internal_name(   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyRC      s    c         C   s   |  i  S(   N(   t
   _full_path(   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR-      s    c         C   s?   | d  j o d |  i   |  i f Sd |  i   | |  i f S(   Ns   %s@%ss   %s-%s@%s(   R)   RC   t	   host_name(   R5   t   extra(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   getListAddress   s    c         C   s   |  i  d  S(   Nt   bounces(   RR   (   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetBouncesEmail   s    c         C   s   |  i  d  S(   Nt   owner(   RR   (   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetOwnerEmail   s    R   c         C   s0   t  i o | o |  i |  S|  i d  Sd  S(   Nt   request(   R   t   VERP_CONFIRMATIONSt   GetConfirmEmailRR   (   R5   t   cookie(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetRequestEmail   s    c         C   s.   t  i h d |  i   d 6| d 6d |  i S(   Ns
   %s-confirmt   addrRZ   t   @(   R   t   VERP_CONFIRM_FORMATRC   RP   (   R5   RZ   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyRY      s    c         C   sb   t  i oL | oE t i   i   p t i |  i  } t t	 d  | d d } | Sd | Sd  S(   NsC   Your confirmation is required to join the %(listname)s mailing listt   header_namet   subjects   confirm (
   R   RX   R   t   get_translationt   charsetR	   t
   GetCharSett   preferred_languageR   t   _(   R5   t   listnameRZ   t   csett   subj(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetConfirmJoinSubject   s    	c         C   sb   t  i oL | oE t i   i   p t i |  i  } t t	 d  | d d } | Sd | Sd  S(   NsD   Your confirmation is required to leave the %(listname)s mailing listR_   R`   s   confirm (
   R   RX   R   Ra   Rb   R	   Rc   Rd   R   Re   (   R5   Rf   RZ   Rg   Rh   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetConfirmLeaveSubject   s    	c         C   s
   |  i    S(   N(   RR   (   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetListEmail   s    c         C   sB   |  i  p | St | i d   \ } } d | |  i | f Sd S(   s  Usually the member addr, but modified for umbrella lists.

        Umbrella lists have other mailing lists as members, and so admin stuff
        like confirmation requests and passwords must not be sent to the
        member addresses - the sublists - but rather to the administrators of
        the sublists.  This routine picks the right address, considering
        regular member address to be their own administrative addresses.

        R]   s   %s%s@%sN(   t   umbrella_listt   tuplet   splitt   umbrella_member_suffix(   R5   t   membert   acctt   host(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetMemberAdminEmail   s    

c         C   s$   t  i | |  i |  d |  i   S(   Nt   /(   R	   t	   ScriptURLt   web_page_urlRC   (   R5   t
   scriptnamet   absolute(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetScriptURL   s    c         C   sI   |  i  d |  } | o t i |  } n d | t i | i    f S(   Nt   optionss   %s/%s(   Ry   R	   t   ObscureEmailt   urllibt   quotet   lower(   R5   t   usert   obscureRx   t   url(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetOptionsURL   s    c         C   s  d |  _  t i t i i t i | p d  d d t i d t i |  _	 | |  _
 | o t i |  |  _ n
 d |  _ x5 |  i i D]' } t | d  o | i |   q q Wg  |  _ xG t t  D]9 } | i d  o q n |  i i t t |     q Wd	 S(
   s6   Set transient variables of this and inherited classes.i    s   <site>s   .lockt   lifetimet   withloggingR   R'   Re   N(   t   _MailList__timestampR   R*   R+   R,   R   t   LOCK_DIRt   LIST_LOCK_LIFETIMEt   LIST_LOCK_DEBUGGINGRG   RN   R   t   get_listpathRO   R$   R%   R&   R'   R?   t   dirR   t
   startswitht   appendR=   (   R5   R6   R8   t	   component(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR'   
  s&    	#			 	 c         C   s"  | o | |  _  n t i   |  _ d |  _ h  |  _ t i |  _ d |  _ d |  _	 h  |  _
 h  |  _ h  |  _ h  |  _ t i |  _ d |  _ t i |  _ t i |  _ t i |  _ t i p t i |  _ t i p t i t i |  _ | g |  _ g  |  _ t i  |  _! d |  _" t i# |  _$ t i% |  _& t i' |  _( t i) |  _* t i+ |  _, t i- |  _. t i/ |  _0 t i1 |  _2 t i3 |  _4 t i5 |  _6 t i7 |  _8 t i9 |  _: t i; |  _< g  |  _= t i> |  _? |  i@   } | d iA   | d |  _B d |  _C d |  _D d |  _E d |  _F t iG |  _H t iI |  _J t iK |  _L t iM |  _N t iO |  _P t iQ |  _R t iS |  _T g  |  _U d |  _V d |  _W t iX |  _Y t iZ |  _[ t i\ |  _] t i^ |  __ t i` |  _a t ib |  _c t id |  _e t if |  _g t ih |  _i d |  _j t ik |  _l d |  _m d |  _n d |  _o g  |  _p g  |  _q g  |  _r g  |  _s t it |  _u t iv |  _w d |  _x g  |  _y | |  _z h  |  _{ x5 |  i| i} D]' } t~ | d  o | i |   qqWt i |  i |  _ t i |  _ t i |  _ t i |  iT  d j o d |  _ n
 d |  _ t i |  _ t i |  _ d S(	   s?   Assign default values - some will be overriden by stored state.i   i    g      ?R   t   InitVarss   us-asciii   N(   RN   t   timet
   created_att   volumet   membersR   t   DATA_FILE_VERSIONt   data_versiont   last_post_timet   post_idt   user_optionst   languaget	   usernamest	   passwordst   DEFAULT_NEW_MEMBER_OPTIONSt   new_member_optionst   respond_to_post_requestst   DEFAULT_LIST_ADVERTISEDt
   advertisedt   DEFAULT_MAX_NUM_RECIPIENTSt   max_num_recipientst   DEFAULT_MAX_MESSAGE_SIZEt   max_message_sizet   DEFAULT_HOST_NAMEt   DEFAULT_EMAIL_HOSTRP   t   DEFAULT_URLt   DEFAULT_URL_PATTERNt   DEFAULT_URL_HOSTRv   RU   t	   moderatort   DEFAULT_REPLY_GOES_TO_LISTt   reply_goes_to_listt   reply_to_addresst   DEFAULT_FIRST_STRIP_REPLY_TOt   first_strip_reply_tot   DEFAULT_ADMIN_IMMED_NOTIFYt   admin_immed_notifyt   DEFAULT_ADMIN_NOTIFY_MCHANGESt   admin_notify_mchangest$   DEFAULT_REQUIRE_EXPLICIT_DESTINATIONt   require_explicit_destinationt   DEFAULT_ACCEPTABLE_ALIASESt   acceptable_aliasest   DEFAULT_UMBRELLA_LISTRl   t$   DEFAULT_UMBRELLA_MEMBER_ADMIN_SUFFIXRo   t   DEFAULT_REGULAR_EXCLUDE_LISTSt   regular_exclude_listst   DEFAULT_REGULAR_INCLUDE_LISTSt   regular_include_listst   DEFAULT_SEND_REMINDERSt   send_reminderst   DEFAULT_SEND_WELCOME_MSGt   send_welcome_msgt   DEFAULT_SEND_GOODBYE_MSGt   send_goodbye_msgt   DEFAULT_BOUNCE_MATCHING_HEADERSt   bounce_matching_headerst   header_filter_rulest   DEFAULT_ANONYMOUS_LISTt   anonymous_listRC   t   uppert	   real_namet   descriptiont   infot   welcome_msgt   goodbye_msgt   DEFAULT_SUBSCRIBE_POLICYt   subscribe_policyt   DEFAULT_UNSUBSCRIBE_POLICYt   unsubscribe_policyt   DEFAULT_PRIVATE_ROSTERt   private_rostert   DEFAULT_OBSCURE_ADDRESSESt   obscure_addressest   DEFAULT_ADMIN_MEMBER_CHUNKSIZEt   admin_member_chunksizet   DEFAULT_ADMINISTRIVIAt   administriviat   DEFAULT_SERVER_LANGUAGERd   t   available_languagest   include_rfc2369_headerst   include_list_post_headert   DEFAULT_FILTER_MIME_TYPESt   filter_mime_typest   DEFAULT_PASS_MIME_TYPESt   pass_mime_typest"   DEFAULT_FILTER_FILENAME_EXTENSIONSt   filter_filename_extensionst    DEFAULT_PASS_FILENAME_EXTENSIONSt   pass_filename_extensionst   DEFAULT_FILTER_CONTENTt   filter_contentt   DEFAULT_COLLAPSE_ALTERNATIVESt   collapse_alternativest!   DEFAULT_CONVERT_HTML_TO_PLAINTEXTt   convert_html_to_plaintextt   DEFAULT_FILTER_ACTIONt   filter_actiont   DEFAULT_NONDIGESTABLEt   nondigestablet   personalizet!   DEFAULT_DEFAULT_MEMBER_MODERATIONt   default_member_moderationt	   emergencyt   member_moderation_actiont   member_moderation_noticet   accept_these_nonmemberst   hold_these_nonmemberst   reject_these_nonmemberst   discard_these_nonmemberst   DEFAULT_FORWARD_AUTO_DISCARDSt   forward_auto_discardst    DEFAULT_GENERIC_NONMEMBER_ACTIONt   generic_nonmember_actiont   nonmember_rejection_noticet   ban_listt   passwordt   hold_and_cmd_autoresponsesR$   R%   R&   R   t   DEFAULT_SUBJECT_PREFIXt   __dict__t   subject_prefixt   DEFAULT_MSG_HEADERt
   msg_headert   DEFAULT_MSG_FOOTERt
   msg_footerR	   Rc   t   encode_ascii_prefixest   DEFAULT_SCRUB_NONDIGESTt   scrub_nondigestt   DEFAULT_MAX_DAYS_TO_HOLDt   max_days_to_hold(   R5   R6   t   admint   crypted_passwordt   internalnameR8   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR   %  s    									
																						 	c         C   sY   d t  f d     Y} |   } x3 |  i D]( } | i   \ } } | | f | | <q) W| S(   Nt   CategoryDictc           B   s,   e  Z d    Z d   Z d   Z d   Z RS(   c         S   s   t  i |   t i |  _ d  S(   N(   R   R!   R   t   ADMIN_CATEGORIESt   keysinorder(   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR!     s    c         S   s   |  i  S(   N(   R  (   R5   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   keys  s    c         S   s8   g  } x+ t  i D]  } | i | |  i | f  q W| S(   N(   R   R  R   t   data(   R5   t   itemst   k(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    s
    
 c         S   s2   g  } x% t  i D] } | i |  i |  q W| S(   N(   R   R  R   R  (   R5   t   valuesR  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    s
    
 (   t   __name__t
   __module__R!   R  R  R  (    (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    s   			(   R   R?   t   GetConfigCategory(   R5   R  t
   categoriest   guiR  t   v(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetConfigCategories  s    	
 c         C   sM   xF |  i  D]; } t | d  o% | i |  } | d  j	 o | Sq
 q
 Wd  S(   Nt   GetConfigSubCategories(   R?   R&   R   R)   (   R5   t   categoryR  t   subcat(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR     s    
 c         C   sM   xF |  i  D]; } t | d  o% | i |  | |  } | o | Sq
 q
 Wd  S(   Nt   GetConfigInfo(   R?   R&   R#  (   R5   R!  R"  R  t   value(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR#    s    
 c         C   sW  | | i    j p
 t d  t i |  o t i |  n t t i t	 i
 d |   d j o t i |  n | d  j o t	 i } n d | | f } y t i |  Wn" t i j
 o t i |  n Xt i |  | |  _ t i | d d |  _ |  i i   |  i | | |  |  i   | d  j o |  i g |  _ n
 | |  _ d  S(   Ns!   List name must be all lower case.R   i    s   %s@%st   createi   (   R~   t   AssertionErrorR	   t   list_existsR
   t   MMListAlreadyExistsErrort   lent   ret   subR   t   ACCEPTABLE_LISTNAME_CHARACTERSt   BadListNameErrorR)   R   t   ValidateEmailt   EmailAddressErrorRN   R   R   RO   RG   R7   R   t   CheckValuesRd   R   (   R5   R6   R  R  t   langst	   emailhostt   postingaddr(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   Create  s*    %	
c         C   s  t  i i |  i   d  } | d t i   t  i   f } | d } d  } y[ t | d  } t	 i
 | | d  | i   t i o t  i | i    n | i   WnF t j
 o: } t d d |  | d  j	 o t  i |  n   n Xy t  i |  Wn/ t j
 o# } | i t i j o   q2n Xy t  i | |  Wn/ t j
 o# } | i t i j o   qxn Xt  i | |  t  i i |  |  _ d  S(   Ns
   config.pcks
   .tmp.%s.%ds   .lastt   wi   R"   s0   Failed config.pck write, retaining old state.
%s(   R*   R+   R,   R-   t   sockett   gethostnamet   getpidR)   t   opent   cPicklet   dumpt   flushR   t   SYNC_AFTER_WRITEt   fsynct   filenot   closeR/   R   t   unlinkt   OSErrorR0   R1   t   linkt   renamet   getmtimeR   (   R5   R:   t   fnamet	   fname_tmpt
   fname_lastt   fpR;   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   __save  s:     



  c         C   s   |  i  i   h  } xR |  i i   D]A \ } } | d d j p t |  t j o q# n | | | <q# Wt i d  } z |  i |  Wd  t i |  |  i	   X|  i
   d  S(   Ni    Re   i   (   RG   t   refreshR  R  t   typet
   MethodTypeR*   t   umaskt   _MailList__savet   SaveRequestsDbt   CheckHTMLArchiveDir(   R5   R:   t   keyR$  t   omask(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   Save*  s     $c         C   s_  | i  d  p | i  d  o t i } n? | i  d  p | i  d  o t i } n d p
 t d  y7 t i i |  } | |  i j o d St
 |  } Wn6 t j
 o* } | i t i j o   n d  | f SXzc y( | |  } t |  t j o d	 SWn4 t t t t t i t i f j
 o } d  | f SXWd  | i   X| |  _ | d  f S(
   Ns   .dbs   .db.lasts   .pcks	   .pck.lasti    s   Bad database file names&   Load() expected to return a dictionary(   NN(   Ns&   Load() expected to return a dictionary(   t   endswitht   marshalt   loadR:  R&  R*   R+   RE  R   R)   R9  t   EnvironmentErrorR0   R1   RL  t   DictTypet   EOFErrort
   ValueErrort	   TypeErrort   MemoryErrort   PicklingErrort   UnpicklingErrorR@  (   R5   t   dbfilet   loadfunct   mtimeRI  R;   R:   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   __load@  s2       		c   
      C   s  t  i |  i    p t i  n t i i |  i   d  } | d } t i i |  i   d  } | d } x | | | | f D]U } |  i	 |  \ } } | d  j o, | d  j	 o t d d | |  q d  Sq Pq Wt d d |  i    t i |  | | j p | | j o t d d |  t }	 zM y |  i i   Wn t i j
 o t }	 n X|  i | | | | |  Wd  |	 o |  i i   n Xn |  i i |  | o |  i |  |  i   n d  S(   Ns
   config.pcks   .lasts	   config.dbR"   s   couldn't load config file %s
%ss(   All %s fallbacks were corrupt, giving ups%   fixing corrupt config file, using: %s(   R	   R'  RC   R
   t   MMUnknownListErrorR*   R+   R,   R-   t   _MailList__loadR)   R   t   MMCorruptListDatabaseErrort   TrueRG   R7   R   t   AlreadyLockedErrort   Falset   _MailList__fix_corrupt_pckfileRL   R  t   updatet   CheckVersionR0  (
   R5   t   check_versiont   pfilet   plastt   dfilet   dlastt   fileR:   R;   RL   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR4   o  sB    

 		c      
   C   s  | | j o y t  i | | d  Wn/ t j
 o# } | i t i j o   qW n Xy t  i | d  Wn/ t j
 o# } | i t i j o   q n Xt i | |  t i | | d  n | | j o y t  i | | d  Wn/ t j
 o# } | i t i j o   qn Xy t  i | d  Wn/ t j
 o# } | i t i j o   qdn Xt i | |  t i | | d  n d  S(   Ns   .corrupts   .safety(   R*   RD  RB  R0   R1   t   removet   shutilt   copy(   R5   Rr  Rn  Ro  Rp  Rq  R;   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   __fix_corrupt_pckfile  s4        c         C   s   |  i  t i j o d S|  i   d |  _ |  i d d  |  i   } | p |  i   n z7 d d k l	 } | |  |  t i |  _  |  i
   Wd | p |  i   n Xd S(   s    Auto-update schema if necessary.Ni    Rm  i(   t   Update(   R   R   R   R   R   R4   RB   R3   t   versionsRw  RT  RI   (   R5   t   stored_statet	   waslockedRw  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyRl    s    
	c         C   s{  d t  |  i  d  j o! t i p t i t i |  _ n |  i o( |  i d d j o |  i d |  _ n y2 |  i i   o |  i o t	 i
 |  i  n WnD t i j
 o5 t d d |  i |  i    d |  _ d |  _ n Xg  } x |  i D]t \ } } } } y t i |  Wn5 t i t f j
 o  t d d | |  i    q X| i | | | | f  q W| |  _ d	 S(
   s+   Normalize selected values to known formats.R   i   iRt   R"   s.   Bad reply_to_address "%s" cleared for list: %si    s#   Bad topic pattern "%s" for list: %sN(   R   Rv   R   R   R   R   R   t   stripR   R	   R.  R
   R/  R   RC   t   topicsR*  t   compileR"   R\  R   (   R5   t
   goodtopicsR6   t   patternt   desct	   emptyflag(    (    s$   /usr/lib/mailman/Mailman/MailList.pyR0    s.    
		
 	c         C   sQ  | i  } t i |  |  i |  } | o t i |  n |  i   | _ |  i t	 i
 |  } |  i d  } d |  i d d d | f } |  i } | t i d h | d 6| d 6|  i d	 6| d
 6| d 6| d 6|  i   d 6d |  7} |  i |  }	 t i | |	 d | d |  i }
 |  i | |  } |
 d =| |
 d <|
 i |   d S(   s   Invite a new member to the list.

        This is done by creating a subscription pending for the user, and then
        crafting a message to the member informing them of the invitation.
        RW   s   %s/%st   confirmRx   i   s
   invite.txtt   emailRf   t   hostnamet
   confirmurlt   requestaddrRZ   t	   listownert   mlistt   textt   langR`   t   SubjectN(   t   addressR	   R.  t   GetBannedPatternR
   t   MembershipIsBannedRC   t
   invitationt   pend_newR   t   SUBSCRIPTIONRR   Ry   R   t   maketextRP   RV   R[   R   t   UserNotificationRd   Ri   t   send(   R5   t   userdescR  t   inviteeR  RZ   R  R  Rf   t   sendert   msgRh   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   InviteNewMember  s:    	
		


	
c         C   s  |  i    p t  t i | i  } t | d d  } t | d |  i  } t | d d$  } t | d t i    } | d$ j o |  i	 o
 d } q d } n t i
 |  |  i |  o t i |  n | i   |  i   i   j o t i  n |  i } |  i |  }	 |	 o& t d d	 | | |	  t i |	  n | o |  i o t i  n! | o |  i	 o t i  n | | _ | | _ | | _ | | _ | | _ |  i d j o |  i | d
 | p d n|  i d j p |  i d j o~|  i t i  |  }
 | d$ j o d } } n d | } t! d  } |  i" |  } d |  i# d d d |
 f } t i$ d h | d 6|  i   d 6| d 6|
 d 6|  i% d  d 6| d 6|  i&   d 6| d 6d | d |  } t' i( | |  i) |
  d | d | } | d =|  i* | |
  | d <|  i) |
  | d  <| i+ |   t, | | f  } t d! d" |  i-   | |  t i.  n, |  i/ | | | | |  t i0 t! d#   d$ S(%   s  Front end to member subscription.

        This method enforces subscription policy, validates values, sends
        notifications, and any other grunt work involved in subscribing a
        user.  It eventually calls ApprovedAddMember() to do the actual work
        of subscribing the user.

        userdesc is an instance with the following public attributes:

            address  -- the unvalidated email address of the member
            fullname -- the member's full name (i.e. John Smith)
            digest   -- a flag indicating whether the user wants digests or not
            language -- the requested default language for the user
            password -- the user's password

        Other attributes may be defined later.  Only address is required; the
        others all have defaults (fullname='', digests=0, language=list's
        preferred language, password=generated).

        remote is a string which describes where this add request came from.
        t   fullnameR   R   t   digestR   i    i   t   vettes(   %s banned subscription: %s (matched: %s)t   whencei   t    s    from %(remote)ss   %s/%sR  Rx   s
   verify.txtR  t   listaddrRf   RZ   RW   R  t   remotet	   listadminR  R  R  R  R`   R  s   Reply-Tot	   subscribes   %s: pending %s %ss8   subscriptions to %(realname)s require moderator approvalN(1   RB   R&  R	   t   LCDomainR  R=   Rd   R)   t   MakeRandomPasswordR   R.  t   isMemberR
   t   MMAlreadyAMemberR~   Rk   t   MMBadEmailErrorR   R  R   R  t
   digestablet   MMCantDigestErrort   MMMustDigestErrorR  R  R   R   R   t   ApprovedAddMemberR  R   R  Re   Rs   Ry   R  RR   RV   R   R  R[   Ri   R  R   RC   t   MMSubscribeNeedsConfirmationt   HoldSubscriptiont   MMNeedApproval(   R5   R  R  R  R6   R  R  R   t   realnameR  RZ   t   byt	   recipientR  R  R  t   who(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt	   AddMember-  s    


							 



		c      
   C   s  |  i    p t  | d j o |  i } n | d j o |  i } n t i | i  } t | d d  } t | d |  i	  } t | d d  }	 t | d t i
    }
 |	 d j o |  i o
 d }	 q d }	 n t i |  |  i |  o t i |  n |  i |  } | o t i |  n |  i | d | d |	 d |
 d | |  i | t i d |  i  |  i | t i |  i  |	 o
 d	 } n d } t d
 d |  i   | t | | f  |  | o# |  i | |  i |  |	 |  n | o |  i	 } t i   } t i  |  z |  i! } t" d  } Wd t i# |  Xt$ | t%  o | i& t i' |  d  } n t i( d h | d 6t | | f  d 6d |  } t) i* |  | |  } | i+ |   n d S(   s  Add a member right now.

        The member's subscription must be approved by what ever policy the
        list enforces.

        userdesc is as above in AddMember().

        ack is a flag that specifies whether the user should get an
        acknowledgement of their being subscribed.  Default is to use the
        list's default flag value.

        admin_notif is a flag that specifies whether the list owner should get
        an acknowledgement of this subscription.  Default is to use the list's
        default flag value.
        R  R   R   R  R   i    i   R  s	    (digest)R  s   %s: new%s %s, %ss&   %(realname)s subscription notificationNt   replaces   adminsubscribeack.txtRf   Rp   R  (,   RB   R&  R)   R   R   R	   R  R  R=   Rd   R  R   R.  R  R
   R  R  R  t   addNewMembert   setMemberOptionR   t   DisableMimet   mime_is_default_digestt   ModerateR   R   RC   R   t   SendSubscribeAckt   getMemberPasswordR   Ra   t   set_languageR   Re   t   set_translationt
   isinstancet   UnicodeTypet   encodeRc   R  R   t   OwnerNotificationR  (   R5   R  t   ackt   admin_notifR  R  R  R6   R  R  R   R  t   kindt   otransR  R`   R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    sf    




		
	c         C   s_   t  |  \ } } |  i d j o |  i | | | |  n  |  i |  t i t d   d  S(   Ni    s*   unsubscriptions require moderator approval(   R   R   t   ApprovedDeleteMembert   HoldUnsubscriptionR
   R  Re   (   R5   R6   R  R  t   userackR  R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   DeleteMember  s    	c         C   s#  | d  j o |  i } n | d  j o |  i } n t |  \ } } |  i |  } |  i |  | o |  i | |  n | od |  i } t d  }	 t	 i
 d h | d 6|  i d 6d |  }
 t i |  |	 |
  } | i |   n | o d | } n d } t d d	 |  i   | |  d  S(
   Ns%   %(realname)s unsubscribe notifications   adminunsubscribeack.txtRp   Rf   R  s   ; %sR   R  s   %s: deleted %s%s(   R)   R   R   R   t   getMemberLanguaget   removeMembert   SendUnsubscribeAckR   Re   R	   R  R   R  R  R   RC   (   R5   R6   R  R  R  R  t	   emailaddrt   userlangR  R`   R  R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    s0    	
		c         C   s   |  i  | |  | p d  Sx t i   D] } | |  i   j o q) n t | d d } | i |  i j o q) n | i |  p q) n | i   z | i  | |  | i   Wd  | i	   Xq) Wd  S(   NR7   i    (
   t   setMemberNameR	   t
   list_namesRC   R    RP   R  R3   RT  RI   (   R5   R\   R6   t   globallyRf   R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   ChangeMemberName  s"     
c         C   s  t  i |  } t  i |  | o3 |  i |  o# | |  i |  j o t i  n | |  i   i   j o t i	  n |  i
 } |  i |  } | o) t d d | | | |  t i |  n |  i t i | | |  } d |  i d d d | f } |  i |  } t  i d h | d 6|  i   d	 6| d
 6| d 6|  i d  d 6d d 6|  i   d 6| d 6d | d |  }	 t i | |  i |  d |	 d | }
 |
 d =|  i | |  |
 d <|  i |  |
 d <|
 i |   d  S(   NR  s0   %s banned address change: %s -> %s (matched: %s)s   %s/%sR  Rx   i   s
   verify.txtR  R  Rf   RZ   RW   R  R   R  R  R  R  R  R  R`   R  s   Reply-To(   R	   R  R.  R  t   getMemberCPAddressR
   R  Rk   R~   R  R   R  R   R  R  R   t   CHANGE_OF_ADDRESSRy   R  R  RR   RV   R   R  R[   Ri   R  (   R5   t   oldaddrt   newaddrR  R  R  RZ   R  R  R  R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   ChangeMemberAddress)  sJ    	


c         C   s  |  i  |  } | o t i |  n |  i |  oA |  i |  | j o+ |  i |  | j o |  i |  q n |  i | |  | p d  Sxt i   D]} | |  i	   j o q n t
 | d d } | i |  i j o q n | i |  p q n | i  |  o q n | i   zo | i |  oA | i |  | j o+ | i |  | j o | i |  qn | i | |  | i   Wd  | i   Xq Wd  S(   NR7   i    (   R  R
   R  R  R  R  t   changeMemberAddressR	   R  RC   R    RP   R3   RT  RI   (   R5   R  R  R  R  Rf   R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   ApprovedChangeMemberAddressc  s<    	
 
c         C   s  |  i  |  } | d  j o t i d |  n y | d } | d } Wn& t j
 o t i d | f  n X| t i j oJd } y_ | d } t | t  o | | 7} d } n | i	 } | i
 }	 | i }
 | i } | i } Wn& t j
 o t i d | f  n Xt | d t  } | o4 | |  i   j o |  i | |  t i  qnI |  i d j o8 |  i | |	 |
 | |  |  i } t i t d   n |  i | d | | | |
 | | f S| t i j oK | d } t | t i  o
 d } n d } |  i | d | | | f S| t i j o0 | \ } } } |  i | | |  | | | f S| t i j o| d } d  } t | t i  o+| i d | i d   } | py& t  t! i" i# | d d   d } Wn t$ j
 o d  } n X| o t% | i&    } x t' o | i(   } | p Pn | i)   p qn | i* d  } | d j oJ | |  i+   d j p | |  i+   d j o | | d i)   } qn PqWqqn | d  j	 oR |  i, t- i. t- i/ g |  t- i0 j o t- i1 } q,|  i2 | |  t i3  n
 t- i4 } y |  i5 | |  Wn# t6 j
 o t7 d d |  n X| f S| t i8 j o( | d } |  i9 | t: i;  | | f Sd p t< d |  d  S(   Ns   No cookie record for %si    i   s   op-less data %ss   via email confirmations   via web confirmations   bad subscr data %sR  i   i   s8   subscriptions to %(name)s require administrator approvalR  s   email confirmations   web confirmationt   Approvedt   ApproveR  t   plaint   :t   approvet   approvedR"   s"   Could not process HELD_MESSAGE: %ss
   Bad op: %s(   i   i   (=   t   pend_confirmR)   R
   t   MMBadConfirmationR[  R   R  R  R   R  R  R   R  R   R=   Ri  RC   t   SendHostileSubscriptionNoticet   HostileSubscriptionErrorR   R  R   R  Re   R  t   UNSUBSCRIPTIONR   R  R  R  t   HELD_MESSAGER2   t   listR  t	   Iteratorst   typed_subpart_iteratort
   IndexErrorR    t   get_payloadRg  t   readlineR{  t   findR~   t   AuthenticateR   t   AuthListAdmint   AuthListModeratort   UnAuthorizedt   APPROVEt   pend_rependt   MMBadPasswordErrort   DISCARDt   HandleRequestt   KeyErrorR   t	   RE_ENABLEt   setDeliveryStatusR   t   ENABLEDR&  (   R5   RZ   t   contextt   rect   opR  R  R  R\   R  R   R  R  R  R6   R  R  R  RD   R  t   subpartt   st   linet   it   actionRp   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   ProcessConfirmation  s    



						


 		
c   
      C   sc  | d  j o |  i |  } n |  i t i |  } d |  i d d d | f } |  i } | d  j	 o d | } t d  } n d } d } t i	 d h | d	 6|  i
   d
 6| d 6| d 6|  i d  d 6| d 6|  i   d 6| d 6d | d |  } t i | |  i |  d | d | }	 |	 d =|  i | |  |	 d <|  i |  |	 d <|	 i |   d  S(   Ns   %s/%sR  Rx   i   R  s    from %(remote)sR   s	   unsub.txtR  R  Rf   RZ   RW   R  R  R  R  R  R  R  R`   R  s   Reply-To(   R)   R  R  R   R  Ry   R   Re   R	   R  Rk   RR   RV   R   R  R[   Rj   R  (
   R5   R\   R  R  RZ   R  R  R  R  R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   ConfirmUnsubscription  s:    
	


c      	   C   sl  d |  i    |  i f } g  } g  } x- d	 D]% } | i t | i | g     q, Wx | D]w \ } } | d
 j o q\ n | i   } | i d  d } | |  i    j p | | j o t S| i	 | | f  q\ Wd   }	 |  i
 i   }
 xv | D]n \ } } x_ |
 D]W } | i   } | p q	n d | j o |	 | |  o t S|	 | |  o t Sq	Wq Wt S(   st   True if list name or any acceptable_alias is included among the
        addresses in the recipient headers.
        s   %s@%st   tot   ccs	   resent-tos	   resent-ccR]   i    c         S   sf   y" t  i |  | t  i  o t SWn= t  i j
 o. t  i t  i |   | t  i  o t Sn Xt S(   N(   R*  t   matcht
   IGNORECASERg  R"   t   escapeRi  (   R  R\   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   domatchU  s    	"
(   s   toR  s	   resent-tos	   resent-ccN(   RC   RP   R#   R   t   get_allR)   R~   Rn   Rg  R   R   t
   splitlinesR{  Ri  (   R5   R  t   listfullnamet   recipsR  t   headerR  R\   t	   localpartR	  t   aliasest   aliast   stripped(    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   HasExplicitDest;  s<     # 	  c      
   C   s
  g  } x |  i  i d  D] } | i   } | p | d d j o q n | i d  } | d j  o t d d |  i |  q | |  } | | d i   } y t i | t i	  } Wn1 t i
 j
 o" } t d d |  i | |  q X| i | | | f  q W| S(	   s:   Return a list of triples [(field name, regex, line), ...].s   
i    t   #R  t   configs&   bad bounce_matching_header line: %s
%si   s=   bad regexp in bounce_matching_header line: %s

%s (cause: %s)(   R   Rn   R{  R  R   R   t   lstripR*  R}  R  R"   R   (   R5   t   allR  R   R  R$  t   creR;   (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   parse_matching_header_optt  s&     	
c         C   sV   xO |  i    D]A \ } } } x/ | i | g   D] } | i |  o | Sq/ Wq Wd S(   s   Return true if named header field matches a regexp in the
        bounce_matching_header list variable.

        Returns constraint line which matches or empty string for no
        matches.
        i    (   R  R
  t   search(   R5   R  R  R  R  R$  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   hasMatchingHeader  s      c   	      C   s  | d j o |  i } n t i |  t i d j o d St i   d  } |  i i	 |  } | d j p | d | j o | d f |  i | <d S| \ } } | d j  o t
 d d |  d S| t i j o t
 d d |  | d f |  i | <t i d h | d	 6d
 |  i |  i f d 6| d 6|  i   d 6d | } t i | |  i   t d  | d | } | i |   d S| | d f |  i | <d S(   s  Return true if Mailman should auto-respond to this sender.

        This is only consulted for messages sent to the -request address, or
        for posting hold notifications, and serves only as a safety value for
        mail loops with email 'bots.
        i    i   i   R  s,   -request/hold autoresponse discarded for: %ss,   -request/hold autoresponse limit hit for: %sis   nomoretoday.txtR  s   %s@%sRf   t   numt
   owneremailR  s(   Last autoresponse notification for todayN(   R)   Rd   R   R  R   t   MAX_AUTORESPONSES_PER_DAYR   t	   localtimeR  R2   R   R	   R  R   RP   RV   R   R  Re   R  (	   R5   R  R  t   todayR   t   datet   countR  R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   autorespondToSender  sD    		
		c         C   s   t  } x |  i D] } | i d  oE y( t i | | t i  o t } Pn Wq t i j
 o q Xq | i   | i   j o t } Pq q W| o | Sd Sd S(   s\   Returns matched entry in ban_list if email matches.
        Otherwise returns None.
        t   ^N(
   Ri  R   R   R*  R  R  Rg  R"   R~   R)   (   R5   R  t   banR  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    s     
 			c         C   sc   |  i  } t i | j o | i t i  n g  } | D]$ } t i i |  o | | q8 q8 ~ S(   N(   R   R   R   R   t   LC_DESCRIPTIONSt   has_key(   R5   R1  t   _[1]R  (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   GetAvailableLanguages  s    	N(4   R  R  R)   R!   RA   RF   R3   RI   RB   RC   R-   RR   RT   RV   R[   RY   Ri   Rj   Rk   Rs   Ry   R   R'   R   R  R   R#  R4  RO  RT  Re  Rg  R4   Rj  Rl  R0  R  R  R  R  R  R  R  R  R  R  R  R  R  R#  R  R)  (    (    (    s$   /usr/lib/mailman/Mailman/MailList.pyR    W   sd   &		
											
				(	(		/6	"		%*p	N			:	7|%	9	 	1	(C   t   __doc__t   sysR*   R   RV  R0   R*  Rt  R6  R|   R:  t	   cStringIOR    R   R   t   typest   email.IteratorsR  t   email.UtilsR   R   R   t   email.HeaderR   t   MailmanR   R	   R
   R   t   Mailman.UserDescR   t   Mailman.ArchiverR   t   Mailman.AutoresponderR   t   Mailman.BouncerR   t   Mailman.DelivererR   t   Mailman.DigesterR   t   Mailman.GatewayManagerR   t   Mailman.HTMLFormatterR   t   Mailman.ListAdminR   t   Mailman.SecurityManagerR   t   Mailman.TopicMgrR   R   R   R   t   Mailman.OldStyleMembershipsR   R   R   R   t   Mailman.Logging.SyslogR   Re   t   EMPTYSTRINGRg  Ri  t	   NameErrorR    (    (    (    s$   /usr/lib/mailman/Mailman/MailList.pyt   <module>   sd   
	
