
    h*Q                     <   d dl mZmZ d dlZd dlZd dlZd dlZd dlZddlm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZ erddlmZ  e ed	      s
 e!ed	d
        e ed      s
 e!edd        e ed      s
 e!edd        G d de"      Z#y)    )print_functionunicode_literalsN   )ANYWINPY2TYPE_CHECKINGunicode)gencert)QrCode)E_ACCESSE_ADDR_IN_USEE_ADDR_NOT_AVAIL	E_UNREACH	HAVE_IPV6IP6ALL
VF_CAREFULNetdevatomic_movemin_exsunpacktermsize)SvcHubAF_UNIXiIPPROTO_IPV6)   IP_FREEBIND   c                   Z    e Zd ZdZd ZddZd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zy)TcpSrvzk
    tcplistener which forwards clients to Hub
    which then uses the least busy HttpSrv to handle it
    c                    || _         |j                  | _        |j                  | _        t        j                  d       d| _        g | _        g | _        i | _        d| _	        d| _
        d| _        d}i }| j                  j                  D ]  }|dk(  rt        j                  rddg}d}ndg}d}n|g}d}|D ]  }g ||<   	 | j                  j                  D ]8  }d}		 |D ].  }	 | j                  ||       ||   j!                  |       |	dz  }	0 :  | j                  s!| j                  j*                  st'        d      |r| j                  dd       dt-        dddd      i}t.        rt-        dddd      |d<   | j                  j                  D cg c])  }||D cg c]  }|j1                  d      d    c}vs(|+ }}}|r	 | j3                  | j                  j                        | _        |j5                  | j                  j7                         D ci c]  \  }}|j1                  d      d   | c}}       |s |D ]  }t-        |ddd      ||<    ni | _        t9               }| j                  j7                         D ]  \  }}|j;                  d      sd}| j                  j7                         D ]$  \  }}||k(  sd	|v s|j;                  d      r#d}& |s| j                  j<                  st|j?                  |j1                  d      d           g }tA        |j7                               D ]+  \  }}tA        |      D ]  }|j!                  |d|        - i }i }g }g }i }| j                  jB                  j1                  d      D cg c]  }|j;                  d      s|dd   }}d}
tA        |j7                         d       D ]  \  }}|j;                  d      r||vrtA        | j                  j                        D ]  }||jE                  |g       vr)||jE                  dg       vr||jE                  dg       vrA|d|}||vr|j!                  |       d} | j                  jF                  rn| j                  jH                  s|dk(  rd} d	|v rdj#                  |      n|}!|j!                  |
j#                  | |!||             dtK        |      v }"|"r|n|}#	 |#|   j!                  |       | j                  jB                  s|d v r|}$nd!j#                  ||      }$g }%d"|v r|"r|%j!                  d"|$f       d"|v sd#|v r|%j!                  d#|$f       |D ]<  }&|&j;                  d$      s|$j;                  |&dd        s*|%j!                  |&|$f       > |%D ]  \  }'}(	 d||'   |(<      |r|D ]  }
| j                  d|
        | j                  jB                  r| jM                  |       ntO        d%d&       | j                  jP                  |f| j                  jR                  |ffD ]L  \  })}*|)s	tU        |)d'      5 }+|+jW                  d%jY                  |*      j[                  d(             d d d        N | j                  j                  s| j                  j\                  r| j_                  ||      | _        y y #  |r:d	|v r6d
}
| j                  d|
j#                  ||d   t%                     d       d}Y >|	rY C xY w# t&        $ rb}| j                  j(                  s| j                  j*                  r*d}
| j                  d|
j#                  |||      d       d}n Y d }~d }~ww xY wc c}w c c}}w #  d}
| j                  d|
t%               z   d       i | _        Y xY wc c}}w c c}w #  |g|#|<   Y xY w#  |(di||'<   Y ?xY w# 1 sw Y   xY w))Nx   F r   ::0.0.0.0Tr   :z0listen on IPv6 [{}] failed; trying IPv4 {}...
{}tcpsrv   zcould not listen on {}:{}: {})cz/could not listen on any of the given interfaces	127.0.0.1z
local only::1/z'failed to discover server IP addresses
externalfe80 $z&available @ {}://{}:{}/  ([33m{}[0m)c                     | d   S )Nr    )xs    E/jellyfin/media/venv/lib/python3.12/site-packages/copyparty/tcpsrv.py<lambda>z!TcpSrv.__init__.<locals>.<lambda>   s
    !A$     )keyz http  https[{}])P   r7   z{}:{}puballzip-
)endwbutf-8)0hubargslogsocketsetdefaulttimeoutstoppingsrvboundnetdevsnetlistnsrvqrihas_ipv6p_listenappendformatr   	Exception	ign_ebindign_ebind_allr   r   splitdetect_interfacesupdateitemsset
startswithlladdsortedwintitleget	http_only
https_onlyr	   _set_wintitleprintwr_h_epswr_h_aonopenwritejoinencodeqrs_qr),selfrA   padokipipsdualipaportsuccessful_bindstexepsr2   k	nonlocalsvll_okndjust_llip2nd2listening_onportsqr1qr2msgsaccessible_on	title_tab
title_varsdesczsprotohipis_extqrtephitsvartktvfnlsfs,                                               r3   __init__zTcpSrv.__init__/   s   HH	77 	  %
	))++ +	BTz??+CD$+C Dd 3 		 #$ " "" LLd3sGNN40,1,	"+	Z xx		 7 7MNNHHXr" QLA
 q"l;CJ $		W1qRU8VQa8V/VQW	W"#55diikkB JJt||7I7I7KLtq!Q*LM" :A#Aq"j9CF: DL ll((* 
	,FB==(G LL..0 $S9CNN64J#G$ $)),,		"((3-*+
	, 
+ 	:IBu :##r4$89:	: 	%)YY%7%7%=%=c%BXallSVFWaeX
X:syy{? 7	0HB}}V$5tyy{{+ 30r2.BFF4$44BFF9b$99 "D)]*!((,99&&YY))TS[#E+."9fmmB'"AHHUCt<=#wt}4#c%GNN4( yy))9$B D1BJ&6KK,J&%:*=KK,% /C~~e,s12w1GS"I./ # 0FB0,-	"b)0_30	7	0r  &1%& 99y)$B YY.YY/
 	=FB "d^ =qGGTYYr]227;<= =	= 99<<499==hhsC(DG )m"#s
$W $188CQ3RTU V&* (  0 (!  yy**dii.E.E;188Bb+AQG" 	( 9WW">1vx<3!L> Y>%#fCG00)+Q	" = =s   \%"+[\%
^^9^>^*^ _
_1_5_:_&0_5;\"	\%\"	\%!\"	"\%%	^.A^^^)_
_#&	_2	5_?	c                 *    | j                  d||       y )Nr&   )rC   )rm   msgr(   s      r3   nlogzTcpSrv.nlog   s    3"r5   c                 f	   dx}}d }d}d|v rat         j                  }|j                  d      }|d   }t        |      dkD  rt	        |d   d      }t        |      dkD  r	 t	        |d         }n{d
|v rN|dd  }
t        j                   t	        |
            }|j                  t         j                  k(  }|j                  }n)d|v rd}t         j                  }nd}t         j                  }|xs$ t        j                   |t         j                        }t        r| j                  j                   r/|j#                  t         j$                  t         j&                  d       |r/|j#                  t         j                  t         j(                  d       |j+                  d        	 |j#                  t         j,                  t         j.                  d       t1        | j                  dd      r/|j#                  t         j2                  t         j4                  d       |r| j6                  j9                  |       y 	 |r|j;                  ||f       nt        s| j                  j<                  rFt>        j@                  jC                  |      rt?        jD                  |       |j;                  |       nd|t?        jF                         fz  }t>        j@                  jC                  |      rt?        jD                  |       |j;                  |       |dk7  rt?        jH                  |d|       |dk7  rt?        jJ                  ||       tM        | jN                  ||tP               |r|jS                         d   n|}||k7  rtU        tV        d	   d      | j6                  j9                  |       y #  d	d l}	|	j                  |d         j                  }Y xY w#  Y 	xY w# tT        t         jX                  f$ r}	 |j[                          n#  Y nxY wd}|j\                  tV        v r&dj_                  ||      }|s5dj_                  |      }n#|j\                  t`        v rdj_                  |      }|s|sd}| jc                  d|d        |s| j                  j<                  s|dz  }te        |      d }~ww xY w)NFunix:r%      r      r'   r   fd:)filenoTfreebindz%s.%dr"   z*[1;31mport {} is busy on interface {}[0mz![1;31munix-socket {} is busy[0mz&[1;31minterface {} does not exist[0mzD


  NOTE: this crash may be due to a unix-socket bug; try --rm-sck
r&   z#; maybe this is a bug? try --rm-sck)3rD   r   rV   lenintgrpgetgrnamgr_gidr   IPPROTO_TCPfamilyAF_INET6AF_INETSOCK_STREAMr   rB   	reuseaddr
setsockopt
SOL_SOCKETSO_REUSEADDRTCP_NODELAY
settimeoutr   IPV6_V6ONLYgetattrSOL_IPr   rG   rQ   bindrm_sckospathexistsunlinkgetpidchownchmodr   r   r   getsocknameOSErrorr   errorcloseerrnorR   r   rC   rS   )rm   rp   rt   uds_permuds_gidrH   tcpipvudsr   fdrG   tfsportrw   erv   s                    r3   rP   zTcpSrv._listen   s   7b=..C((3-CRB3x!|s1vq>3x!|:!#a&kG
 b[ABBMMR1E++!3!33C,,CBYC//CC..C=v}}S&*<*<=,,NN6,,f.A.A1ENN6--v/A/A1Et	NN6..0B0BEJ 499j%0NN6==&*<*<a@HHOOC 0	"d$TYY--ww~~b)		"HHRL B		#44Bww~~b)		"HHRL"}R12~X.		2r:>,/COO%a(TEu} mA.33HHOOC :!ll3q6299G4	D & 			Axx=(FMMdTVWAHHLA--BII"MbAHHXq!,tyy//::A,/	sD   N( /O 3E4O ($OOR04PR+P	B$R++R0c           	         | j                   D cg c]  }|j                         d d  }}g }g }| j                   D ]  }|j                  t        j                  k(  r*d}t        j                  dd|j                               }d}nd}|j                         d d \  }}|t        k(  rd}	 |j                  | j                  j                         	 |j                  t        j                  t        j                        }	|	s(t        d	j                  |j                                     	 |j%                  ||f       |j%                  |       |j'                         }|r>d|v rdj                  |      n|}dj                  |||t)        j*                               }n%dj                  ||t)        j*                               }| j#                  d|       | j                  j,                  rt/        |       | j0                  j2                  j5                  d|        || _         || _        t9        |      | _        | j=                          y c c}w #  d}	Y [xY w#  |d
k(  rd|f|v r|j!                          Y A|dk(  rd
|f|v r|j!                          Y _d}
| j#                  d|
j                  ||      d        xY w)Nr   Fz	\.[0-9]+$r"   r   Tr#   r   zfailed to listen on {}r$   z

ERROR: could not open listening socket, probably because one of the server ports ({}) is busy on one of the requested interfaces ({}); avoid this issue by specifying a different port (-p 3939) and/or a specific interface to listen on (-i 192.168.56.1)
r&   r%   r9   zlistening @ {}:{}  f{} p{}zlistening @ {}  f{} p{}zhttpsrv.listen)rG   r   r   rD   r   resubr   listenrB   nc
getsockoptr   SO_ACCEPTCONNrS   rR   r   rC   rQ   r   r   r   qrd   rA   brokersayrH   r   rK   _distribute_netdevs)rm   r2   all_epsrH   srvsrG   r   rp   rt   ro   rv   fnor   r   s                 r3   runz
TcpSrv.runZ  sU   04911==?2A&9988 2	7CzzV^^+VVL"coo.?@??,Ra0DV|

499<<((9(96;O;OPB #$<$C$CCOODU$VWW $ LL"d$KK**,C+."9fmmB'"299#tS"))+V/66r3		LHHXs#yy{{c
HHOO 0#6e2	7h 
I	  "u :&B
?d|u'<IIK:9d"3w">IIK X188D"#5q9s5   I*%I.I>*IIIK <K &K c                 V   | j                   j                  j                  d| j                         | j                   j	                          t        | j                  | j                  | j                         | j                   j                          | j                   j                          y )Nzhttpsrv.set_netdevs)
rA   r   r   rI   start_zeroconfr
   rC   rB   restart_ftpdrestart_tftpd)rm   s    r3   r   zTcpSrv._distribute_netdevs  sg    14<<@!$))T\\2 r5   c                     d| _         	 | j                  D ]  }|j                           	 | j                  dd       y #  Y xY w)NTr&   zok bye)rF   rG   r   rC   )rm   rG   s     r3   shutdownzTcpSrv.shutdown  sD    	xx 		
 	8$	s	   !> Ac                 |   | j                   s/t        j                  | j                  j                         | j                  | j                  j                        }|s^g }g }|j                         D ]+  \  }}|| j                  vs|j                  d|d|       - | j                  j                         D ]!  \  }}||vs|j                  d|d|       # d}| j                  d|dj                  |      dj                  |      fz  d       || _        | j                          | j                   s.y y )Nz
[32m  added z = z
[33mremoved znetwork change detected:%s%sr&   r"   r'   )rF   timesleeprB   z_chkrW   rM   rY   rI   rQ   rC   ri   r   )rm   rI   r]   remry   r{   rv   s          r3   netmonzTcpSrv.netmon  s   --JJtyy',,TYY[[9GCC E1DLL(JJaCDE **, E1G#JJaCDE /AHHXqBGGCL"''#,#??C"DL$$&% --r5   c           	         ddl m} |D cg c]  }|j                  d      r| }} |d      }i }|D ]  }|j                  D ]  }dt	        |j
                        v r|j
                  d   n|j
                  }dj                  ||j                        }	t        |	|j                  xs d|j                  d      }
|
||	<   	 t        j                  |
j                        }|rE||
j                  k7  r6d	}| j                  d
|j                  |
j                  |      d       ||
_          t	        t!        |j#                                     }|| j$                  k(  r| j&                  ri S || _        d|vr>d|vr:|j#                         D ci c]  \  }}|j)                  d      d   |v s||! }}}	 t+        | j-                               }|j#                         D cg c]  \  }}|j                  |v s| }}}|D cg c]  }|j)                  d      d    }}|s
t/               	 |D ]e  }|r	|ddg|z   vrd}|dv r|n|g}|D ]G  t3        fd|D        d      sd|   j4                  vs-|   xj4                  d|z   z  c_        I g |S c c}w #  Y ^xY wc c}}w c c}}w c c}w #  | j1                         }|r|gng }Y xY w)Nr   )get_adapters)r   r   Tr%   r   z{}/{}r"   z)netdev idx mismatch; ifaddr={} cpython={}r&   r'   r$   r#   r+   z[32mexternal)r$   r#   c              3   L   K   | ]  }|j                  d z         s|  yw)r+   N)r[   ).0r2   rp   s     r3   	<genexpr>z+TcpSrv.detect_interfaces.<locals>.<genexpr>  s      DQ\\"s(-C1Ds   $$r,   , )stolen.ifaddrr   r[   rq   strrp   rR   network_prefixr   index	nice_namerD   if_nametoindexnameidxrC   r^   rY   rJ   rI   rV   list_extdevs_nixrS   	_defroutenextr   )rm   
listen_ipsr   r2   nicsrx   nicniprs   sipr}   r   rv   rJ   ry   r{   ext_devsext_ipsrtlipr   rq   rp   s                         @r3   rW   zTcpSrv.detect_interfaces  s   /!+RA1<<@P3QaR
RD! 	Cww #&#cff+#5cffQi366nnS#*<*<=CaCC //8Csbff}G188BFFC+@!D!$	 fSYY[)*dll"t||IJ&4z+A$'IIKQDAq1773<?j3P1a4QCQ	)D--/0H%(YY[GTQAFFh4FqGGG0781qwws|A8G8k!   		0Cc)T):W)DD%D $55'C5C 0DcDbI*CGLL8GLLD4K/L0		0 
c S  R H8	)!B rdbGsS   JJA&JJ%+J%4,J6  J+7J+;J6 J1J6 J"+J6 6Kc              #     K   t        dd      5 }t        |       |D ]R  }|j                  d      j                         j	                         }|d   dk(  s9t        |d   d      dz  sL|d	    T 	 d d d        y # 1 sw Y   y xY ww)
Nz/proc/net/routerbr@   r   00000000r'      r   r   )rg   r   decodestriprV   r   )rm   r   lnrs       r3   r   zTcpSrv._extdevs_nix  s     #T* 	aG IIg&,,.446Q47?s1Q4}q'8A$J	 	 	s)   BAA<A<)	A<3	B<BBc                    d}t        j                   t         j                  t         j                        }dD ]*  }	 |j                  |df       |j	                         d   } n |j                          |S # t
        t         j                  f$ r{}|j                  t        v r"| j                  ddj                  |             n=|j                  t        vr+| j                  ddj                  |j                               Y d }~d }~ww xY w)Nr"   )z10.254.39.23z172.31.39.23z192.168.39.23z239.254.39.23z169.254.39.23r   r   r&   zeaccess {} (trying next)zroute lookup failed; err {})rD   r   
SOCK_DGRAMconnectr   r   r   r   r   rC   rR   r   r   )rm   retsrp   rw   s        r3   r   zTcpSrv._defroute  s    MM&..&*;*;<
 	WBW		2q'"mmoa(	W& 	
	
 V\\* W88x'HHX'A'H'H'LMXXY.HHX'D'K'KBHH'UV	Ws   &A66D
A1DD
c           
         |j                  dddi      |d<   |j                  d|d         |d<   i }|j                         D ]  \  }}|D ci c]
  }d|vs|d }}t        |      }t        |      D ]1  }|j	                  d      d   }||vs|j                  |       d||<   3 |D 	cg c]  }	|	j                  d      s|	 }
}	t        |      dkD  r|
r|
D ]  }|j                  |        |||<    d	}|}| j                  j                  j	                  d
      D ]  }|j                  d      r^t        t        |j                  |dd  ddi      j                                     }dj                  |d d       }t        |      dkD  r|dz  }|dj                  |      z  } t        dj                  |      t         j"                  d	       t         j"                  j%                          y c c}w c c}	w )Nr<   z
Local-Onlyr   r;   r%   r   z127.r'   r"   r.   r/   z(None)r   z, ...z{} z	]0;{}\
)filer>   )r`   rY   rZ   r^   rV   r]   r[   r   poprB   r_   r   keysri   rR   rd   sysstderrflush)rm   vsvs2ry   rx   r   filthaverp   r2   lotitlerO   sepss                 r3   rc   zTcpSrv._set_wintitle  s   FF5<"345	FF5"U),5	hhj 	FAs$'9b3b=BE9D9t9DSk !XXc]1%T>HHRL DH	! ":Q\\&%9!:B:4y1} !BHHRL! CF	  ##))#. 	%A||C F266!AB%(A#?#D#D#FGHIId2Ah't9q=LAU\\!_$E	% 	!((/cjjbI

7 : ;s   	G2G2+G7G7c                    |j                         D ci c]  \  }}|dv s|| }}}|j                         D ci c]  \  }}d|v s||vs|| }}}|j                         D ci c]  \  }}||vs||vs|| }}}|j                  |       |j                  |       d }t        |      t        |      z   }| j                  j                  }	| j                  j
                  rJ|	sH|rF| j                  j                  dz   }
t        d |xs |j                         D              ||
<   |
g|z   }|D ]  }|j                  |	      s|	dk(  r nd} |s|	}|syd|v rd|dn|}| j                  j                  rd}n3| j                  j                  rd	}n| j                  j                  rd	nd}|j                  ||j                  |g             }|rd
nd}||v s|sdndj                  |d         }dj                  |||| j                  j                        }|j!                  d      }t"        rt%        dt'        |      z  |      }| j                  j(                  | j                  j*                  | j                  j,                  }| j                  j.                  }t1        j2                  |      }|dk(  r6	 t5               \  }}t7        |dz  |      }|j8                  |dz  z   |k\  rdnd}|j;                  ||      }| j                  j<                  rdj                  ||      S dsdfd}|dkD  rt?        j@                  d||      }|jC                  dd      dz   }rdnd}|dz   }|j                  |      }tD        r|jC                  dd      }||z   S c c}}w c c}}w c c}}w #  d}Y xY w)N)r)   r*   r%   z.localc              3       K   | ]  }|  y w)Nr1   )r   r{   s     r3   r   zTcpSrv._qr.<locals>.<genexpr>C  s     ;!A;s   .r"   []r  r7   r:   z:{}r   zhttp{}://{}{}/{}r@      Br   r   z{}
{}z[40;48;5;{0}m{1}[47;48;5;{2}mz[0;40m{1}[0;47mc           	      `    j                  dt        | j                  d            z        S )Nr.   r   )rR   r   group)mbgfghalfcs    r3   ansifyzTcpSrv._qr.<locals>.ansifyy  s'    <<C#aggaj/$92>>r5   u   (█+)r=   z[K
z[Kz [0;38;5;{0};47;48;5;{1}mz [0;30;47mz
{2}[999G[0m[Jz`
`)#rY   rX   r   rB   qrizmr   r   valuesr[   ra   rb   rk   r`   rR   qrlrj   r   r   r   qr_fgqr_bgqrpqrzr   encode_binaryr   minsizerenderno_ansir   r   replacer   )rm   t1t2r   zlit2ct2brp   rq   r+  r   r   r8   r   dportrt   txtbtxtrn   zoomqrctwthtszrL   r*  ccrv   r'  r(  r)  s                               @@@r3   rl   z
TcpSrv._qr7  sc   &(hhjO72sB:N4Nr3wOO&(hhjP72sC2I"C-r3wPP%'XXZS'"c2S=Rs]b#gSS
		#
		#2hb!iimm99<<99>>H,D;b'8'8':;;BtH&3,C 	B}}S!SCZB	
 B #r	nr99EYY!!E99==CbEr266"b>*"e^5rell586L ''sD$))--Hzz'"4#d)+T2DYY__YY__iimmyy}}""4(19!B"'2&HHsQw.#5q1 ZZc"99??3++7-E	? !8&"-BZZj)H402,8H..HHRR 		$'AQw_ PPShs9   N-N-N3N3N3,N99N9>N95N? ?ON)r   )__name__
__module____qualname____doc__r   r   rP   r   r   r   r   rW   r   r   rc   rl   r1   r5   r3   r   r   )   sK    
)B#eN;#z!%'*4l2!FPr5   r   )$
__future__r   r   r   r   rD   r  r   r   r   r   r   r	   certr
   stolen.qrcodegenr   utilr   r   r   r   r   r   r   r   r   r   r   r   svchubr   hasattrsetattrobjectr   r1   r5   r3   <module>rS     s    7 	 	  
  9 9  $    vy!FIu%v~&FNB'v}%FM2&^	V ^	r5   