<s> from __future__ import unicode_literals , print_function <EOL> from contextlib import contextmanager <EOL> import errno <EOL> import os <EOL> import subprocess <EOL> import sys <EOL> import tempfile <EOL> @ contextmanager <EOL> def nested ( cm1 , cm2 ) : <EOL> with cm1 : <EOL> with cm2 : <EOL> yield <EOL> def close_fds ( * args ) : <EOL> for fds in args : <EOL> for fd in fds : <EOL> try : <EOL> os . close ( fd ) <EOL> except OSError as exc : <EOL> if exc . errno != errno . EBADF : <EOL> raise <EOL> class GnuPG ( object ) : <EOL> '''<STR_LIT>''' <EOL> default_args = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self , args = [ ] ) : <EOL> self . args = args <EOL> self . handles = { } <EOL> def run ( self , args = [ ] , create_fhs = [ ] , attach_fhs = { } ) : <EOL> if self . handles : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> standard_handles = { <EOL> '<STR_LIT>' : ( sys . stdin , '<STR_LIT:wb>' ) , <EOL> '<STR_LIT>' : ( sys . stdout , '<STR_LIT:rb>' ) , <EOL> '<STR_LIT>' : ( sys . stderr , '<STR_LIT:rb>' ) , <EOL> } <EOL> gpg_handles = { <EOL> '<STR_LIT>' : '<STR_LIT:wb>' , <EOL> } <EOL> self . handles = { } <EOL> self . parent_fds = [ ] <EOL> child_fds = [ ] <EOL> fd_args = [ ] <EOL> std_fds = { } <EOL> for name , value in standard_handles . items ( ) : <EOL> if name not in create_fhs and name not in attach_fhs : <EOL> fobj , mode = value <EOL> attach_fhs [ name ] = fobj <EOL> for name in create_fhs : <EOL> if name in standard_handles : <EOL> _ , mode = standard_handles [ name ] <EOL> elif name in gpg_handles : <EOL> mode = gpg_handles [ name ] <EOL> else : <EOL> close_fds ( self . parent_fds , child_fds ) <EOL> raise ValueError ( '<STR_LIT>' % name ) <EOL> pipe_r , pipe_w = os . pipe ( ) <EOL> if mode == '<STR_LIT:wb>' : <EOL> for_parent = pipe_w <EOL> for_child = pipe_r <EOL> elif mode == '<STR_LIT:rb>' : <EOL> for_parent = pipe_r <EOL> for_child = pipe_w <EOL> else : <EOL> assert <NUM_LIT:0> <EOL> if name in standard_handles : <EOL> std_fds [ name ] = for_child <EOL> else : <EOL> fd_args += [ '<STR_LIT>' % name , str ( for_child ) ] <EOL> self . handles [ name ] = os . fdopen ( for_parent , mode ) <EOL> self . parent_fds . append ( for_parent ) <EOL> child_fds . append ( for_child ) <EOL> for name , fobj in attach_fhs . items ( ) : <EOL> if name in standard_handles : <EOL> _ , mode = standard_handles [ name ] <EOL> target_fd = fobj . fileno ( ) <EOL> elif name in gpg_handles : <EOL> mode = gpg_handles [ name ] <EOL> target_fd = None <EOL> else : <EOL> close_fds ( self . parent_fds , child_fds ) <EOL> raise ValueError ( '<STR_LIT>' % name ) <EOL> if hasattr ( fobj , '<STR_LIT>' ) and callable ( fobj . fileno ) : <EOL> source_fd = fobj . fileno ( ) <EOL> self . handles [ name ] = fobj <EOL> elif isinstance ( fobj , int ) : <EOL> source_fd = fobj <EOL> self . handles [ name ] = os . fdopen ( source_fd , mode ) <EOL> else : <EOL> close_fds ( self . parent_fds , child_fds ) <EOL> raise ValueError ( '<STR_LIT>' % name ) <EOL> if name in standard_handles : <EOL> std_fds [ name ] = target_fd <EOL> else : <EOL> fd_args += [ '<STR_LIT>' % name , str ( source_fd ) ] <EOL> def preexec ( ) : <EOL> close_fds ( self . parent_fds ) <EOL> cmdline = [ '<STR_LIT>' ] + fd_args + self . default_args + self . args + args <EOL> self . p = subprocess . Popen ( cmdline , preexec_fn = preexec , <EOL> close_fds = False , ** std_fds ) <EOL> close_fds ( child_fds ) <EOL> def wait ( self ) : <EOL> self . handles = { } <EOL> close_fds ( self . parent_fds ) <EOL> return self . p . wait ( ) <EOL> def gpg_encrypt ( config , filename , passphrase , content ) : <EOL> stderr = tempfile . TemporaryFile ( ) <EOL> target = open ( filename + '<STR_LIT>' , '<STR_LIT:w>' ) <EOL> with nested ( stderr , target ) : <EOL> gnupg = GnuPG ( [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , config . get ( '<STR_LIT>' ) , <EOL> ] ) <EOL> gnupg . run ( <EOL> [ '<STR_LIT>' ] , <EOL> create_fhs = [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> attach_fhs = { <EOL> '<STR_LIT>' : target , <EOL> '<STR_LIT>' : stderr , <EOL> } ) <EOL> gnupg . handles [ '<STR_LIT>' ] . write ( passphrase ) <EOL> gnupg . handles [ '<STR_LIT>' ] . close ( ) <EOL> gnupg . handles [ '<STR_LIT>' ] . write ( content ) <EOL> gnupg . handles [ '<STR_LIT>' ] . close ( ) <EOL> try : <EOL> gnupg . wait ( ) <EOL> except IOError as exc : <EOL> print ( exc , file = sys . stderr ) <EOL> os . remove ( filename + '<STR_LIT>' ) <EOL> else : <EOL> os . rename ( filename + '<STR_LIT>' , filename ) <EOL> def gpg_decrypt ( filename , passphrase ) : <EOL> stderr = tempfile . TemporaryFile ( ) <EOL> source = open ( filename ) <EOL> with nested ( stderr , source ) : <EOL> gnupg = GnuPG ( [ '<STR_LIT>' ] ) <EOL> gnupg . run ( <EOL> [ '<STR_LIT>' ] , <EOL> create_fhs = [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> attach_fhs = { <EOL> '<STR_LIT>' : source , <EOL> '<STR_LIT>' : stderr , <EOL> } ) <EOL> gnupg . handles [ '<STR_LIT>' ] . write ( passphrase ) <EOL> gnupg . handles [ '<STR_LIT>' ] . close ( ) <EOL> content = gnupg . handles [ '<STR_LIT>' ] . read ( ) <EOL> try : <EOL> gnupg . wait ( ) <EOL> except IOError : <EOL> return b'<STR_LIT>' <EOL> else : <EOL> return content </s>
