+
    }rj                         R t ^ RIt^ RIt^ RIt^ RIt^ RIt^RIHt ^RI	H
t
 ]P                  P                  RR4      tRtRtRtRtR	 tR
 tR tR tR tR tR t]3R ltR# )u  sshj.updatecheck — `sshj update-check`: a REAL update check (F4).

The existing `update_needed()` (jsonio) is local-only — it flags from
`SSHJ_UPDATE=1` or the `update.flag` file, and never touches the network.
This module is the one place sshj does reach out: it fetches the published
version, compares it with `VER`, and sets `update.flag` when the remote is
newer. It runs ONLY when invoked (`sshj update-check` / `sshj update-check
--now`) — never on the default path, never from the grid — which is what
keeps F4 inside the anti-goal "no runtime network" (the picker itself stays
a local tool; only this explicit opt-in command has a network surface).

Stdlib only (urllib), bounded (timeout), cached (one check per day per
`SSHJ_STATE_DIR` so a daily `sshj` doesn't hammer the endpoint).
Exit: 0 up-to-date or update-available (the flag is set, the grid shows
"- UPDATE"); 1 the check itself failed (endpoint unreachable, bad version).
N)jsonio)VERSSHJ_UPDATE_URLz;https://raw.githubusercontent.com/serafij/sshj/main/VERSIONg      @zupdate-cache.jsonzupdate.flagc                  "    \         P                  # N)r   	STATE_DIR     src/sshj/updatecheck.py
_state_dirr   (   s     r	   c                  Z    \         P                  P                  \        4       \        4      # r   )ospathjoinr   
CACHE_FILEr   r	   r
   _cache_pathr   .   s    77<<
j11r	   c                  Z    \         P                  P                  \        4       \        4      # r   )r   r   r   r   	FLAG_FILEr   r	   r
   
_flag_pathr   2   s    77<<
i00r	   c                      \        \        4       4      ;_uu_ 4       p \        P                  ! V 4      pR R R 4       \	        X\
        4      '       d   V# / #   + '       g   i     L*; i  \        \        3 d    / u # i ; ir   )openr   jsonload
isinstancedictOSError
ValueError)fds     r
   _read_cacher   6   sb    +-  A		!A !q$''q/R/ !  Z  	s-   A) AA) A) A&	!A) )A?>A?c                 (   \         P                  ! \        4       R R7       RV R\        \        P                  ! 4       4      /p\        \        4       R4      ;_uu_ 4       p\        P                  ! W4       RRR4       R#   + '       g   i     R# ; i)Texist_okremote_version
checked_atwN)	r   makedirsr   inttimer   r   r   dump)r#   r   r   s   &  r
   _write_cacher*   ?   sV    KK
t,	><TYY[9IJA	kmS	!	!Q		! 
"	!	!	!s   B  B	c                   \         P                  P                  V RR\        ,           /R7      p \         P                  P	                  V\
        R7      ;_uu_ 4       pVP                  4       P                  RR4      P                  4       uuRRR4       #   + '       g   i     R# ; i  \         P                  P                  \        \        3 d     R# i ; i)zbFetch the published version string (bounded). Returns the stripped
version or None on any failure.z
User-Agentzsshj/)headers)timeoutzutf-8replaceN)urllibrequestRequestr   urlopenFETCH_TIMEOUTreaddecodestriperrorURLErrorr   r   )urlreqrs   &  r
   _fetchr<   F   s     ..
 
 |Ws].K
 
LC^^##C#??1668??7I6<<> @???LL!!7J7 s/   -B* .B
B* B'	!B* 'B* **CCc                *    R pV! V 4      V! V4      8  # )zuTrue if `remote` > `local` as dotted versions (non-numeric parts
compare lexicographically after the numeric prefix).c                    . p\        V 4      P                  R 4       F`  pRpV F#  pVP                  4       '       d   W4,          pK#   M	  TP                  V'       d   \	        V4      M^ V\        V4      R 34       Kb  	  V# ). N)strsplitisdigitappendr'   len)vpartspnumcs   &    r
   key_newer.<locals>.keyT   sn    Qc"AC99;;HC	 
 LLc#c(q!CHI,?@ # r	   r   )remotelocalrK   s   && r
   _newerrO   Q   s    
 v;U##r	   c           	        RV 9   p\         P                  P                  R\        4      p\	        4       pRpRV9   d6   \
        P
                  ! 4       \        VP                  R^ 4      4      ,
          pV'       gP   VeL   V\        8  dA   VP                  RR4      p\        RVR,          V'       d
   R	V,          MR
3,          4       ^ # V! V4      pVf   \        RV,          4       ^# \        V4       \        V\        4      '       d~   \         P                  ! \        4       RR7       \        \        4       R4      ;_uu_ 4       pVP!                  RV: R\        : R24       RRR4       \        RV: R\        : R24       ^ #  \         P"                  ! \        4       4       \        R\        ,          4       ^ #   + '       g   i     La; i  \$         d     L8i ; i)zDo the check and print the outcome. `args` may contain `--now`
(bypass the cache). `_fetcher` is injectable for tests. Returns the
exit code (0 up-to-date/update-available, 1 the check failed).z--nowr   Nr$   r#   r@   uA   sshj update-check: cached (%.0fh old) — %s (use --now to force)g      @zupdate available: %szno remote versionz^sshj update-check: could not reach %s (no update check performed; the local flag is untouched)Tr!   r%   zupdate available: z
 (current z)
u(   sshj update-check: UPDATE AVAILABLE — z (you are on z ); the grid now shows '- UPDATE'z"sshj update-check: up to date (%s))r   environgetDEFAULT_UPDATE_URLr   r(   floatCHECK_EVERYprintr*   rO   r   r&   r   r   r   writeremover   )args_fetcherforcer9   cacheagerM   r   s   &&      r
   runr^   b   sr    tOE
**..*,>
?CME
CuiikE%))L!"<==S_{):+R0 ,=C069244 	5 c]F~ 8:=> 	?fc
JL40*,$$GGVSIJ %17> 	? 	IIjl# 	2S89 %$  		s   F>G >G	GGiQ )__doc__r   r   r(   urllib.requestr/   urllib.errorr@   r   themer   rQ   rR   rS   rU   r3   r   r   r   r   r   r   r*   r<   rO   r^   r   r	   r
   <module>rc      s      	      ZZ^^AC   
	21$"  #r	   