xref: /aoo41x/main/extensions/workben/testpgp.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include <sal/types.h>
31 #include <rtl/memory.h>
32 #ifndef _RTL_WSTRING_
33 #include <rtl/wstring>
34 #endif
35 #include <vos/macros.hxx>
36 
37 #ifndef _USR_SMARTSERVICES_HXX_
38 #include <usr/smartservices.hxx>
39 #endif
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/io/XInputStream.hpp>
42 #include <com/sun/star/io/XOutputStream.hpp>
43 #include <com/sun/star/pgp/RecipientsEvent.hpp>
44 #include <com/sun/star/pgp/SignatureEvent.hpp>
45 #include <com/sun/star/pgp/XPGPDecoder.hpp>
46 #include <com/sun/star/pgp/XPGPDecoderListener.hpp>
47 #include <com/sun/star/pgp/XPGPEncoder.hpp>
48 #include <com/sun/star/pgp/XPGPPreferences.hpp>
49 #include <com/sun/star/uno/XInterface.hpp>
50 #include <com/sun/star/uno/Any.h>
51 #include <com/sun/star/uno/Reference.h>
52 #include <com/sun/star/uno/Sequence.hxx>
53 #include <cppuhelper/weak.hxx>
54 
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 
59 #include <fcntl.h>
60 #include <io.h>
61 
62 using namespace com::sun::star::lang;
63 using namespace com::sun::star::io;
64 using namespace com::sun::star::pgp;
65 using namespace com::sun::star::uno;
66 
67 /*========================================================================
68  *
69  * DataSource_Impl interface.
70  *
71  *======================================================================*/
72 class DataSource_Impl :
73 	public OWeakObject,
74 	public XInputStream
75 {
76 	Sequence<sal_Int8> m_buffer;
77 	sal_Int32          m_position;
78 	int                m_fd;
79 
80 public:
81 	DataSource_Impl (int fd = 0);
82 	virtual ~DataSource_Impl (void);
83 
84 	void setBuffer (const Sequence<sal_Int8> &rBuffer);
85 
86 	/** XInterface.
87 	 */
88 	virtual sal_Bool SAL_CALL queryInterface (
89 		const Uik &rUik, Any &rIfc) throw(RuntimeException);
90 
91 	virtual void SAL_CALL acquire (void) throw(RuntimeException);
92 
93 	virtual void SAL_CALL release (void) throw(RuntimeException);
94 
95 	/** XInputStream.
96 	 */
97 	virtual sal_Int32 SAL_CALL readBytes (
98 		Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead)
99 		throw (NotConnectedException,
100 			   BufferSizeExceededException,
101 			   IOException);
102 
103 	virtual sal_Int32 SAL_CALL readSomeBytes (
104 		Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead)
105 		throw (NotConnectedException,
106 			   BufferSizeExceededException,
107 			   IOException);
108 
109 	virtual void SAL_CALL skipBytes (sal_Int32 nBytesToSkip)
110 		throw (NotConnectedException,
111 			   BufferSizeExceededException,
112 			   IOException);
113 
114 	virtual sal_Int32 SAL_CALL available (void)
115 		throw (NotConnectedException, IOException);
116 
117 	virtual void SAL_CALL closeInput (void)
118 		throw (NotConnectedException, IOException);
119 };
120 
121 /*========================================================================
122  *
123  * DataSink_Impl interface.
124  *
125  *======================================================================*/
126 class DataSink_Impl :
127 	public OWeakObject,
128 	public XOutputStream
129 {
130 	Sequence<sal_Int8> m_buffer;
131 
132 public:
133 	DataSink_Impl (void);
134 	virtual ~DataSink_Impl (void);
135 
136 	const Sequence<sal_Int8>& getBuffer (void) const { return m_buffer; }
137 
138 	/** XInterface.
139 	 */
140 	virtual sal_Bool SAL_CALL queryInterface (
141 		const Uik &rUik, Any &rIfc) throw(RuntimeException);
142 
143 	virtual void SAL_CALL acquire (void) throw(RuntimeException);
144 	virtual void SAL_CALL release (void) throw(RuntimeException);
145 
146 	/** XOutputStream.
147 	 */
148 	virtual void SAL_CALL writeBytes (
149 		const Sequence<sal_Int8> &rBuffer)
150 		throw (NotConnectedException,
151 			   BufferSizeExceededException,
152 			   IOException);
153 
154 	virtual void SAL_CALL flush (void)
155 		throw (NotConnectedException,
156 			   BufferSizeExceededException,
157 			   IOException);
158 
159 	virtual void SAL_CALL closeOutput (void)
160 		throw (NotConnectedException,
161 			   BufferSizeExceededException,
162 			   IOException);
163 };
164 
165 /*========================================================================
166  *
167  * DecoderListener_Impl interface.
168  *
169  *======================================================================*/
170 class DecoderListener_Impl :
171 	public OWeakObject,
172 	public XPGPDecoderListener
173 {
174 public:
175 	DecoderListener_Impl (void);
176 	virtual ~DecoderListener_Impl (void);
177 
178 	/** XInterface.
179 	 */
180 	virtual sal_Bool SAL_CALL queryInterface (
181 		const Uik &rUik, Any &rIfc) throw(RuntimeException);
182 
183 	virtual void SAL_CALL acquire (void) throw(RuntimeException);
184 
185 	virtual void SAL_CALL release (void) throw(RuntimeException);
186 
187 	/** XEventListener.
188 	 */
189 	virtual void SAL_CALL disposing (const EventObject &rSource);
190 
191 	/** XPGPDecoderListener.
192 	 */
193 	virtual void SAL_CALL decrypted (const RecipientsEvent &rEvent);
194 	virtual void SAL_CALL verified  (const SignatureEvent &rEvent);
195 };
196 
197 /*========================================================================
198  *
199  * DataSource_Impl implementation.
200  *
201  *======================================================================*/
202 /*
203  * DataSource_Impl.
204  */
205 DataSource_Impl::DataSource_Impl (int fd)
206 	: m_fd (fd), m_position (0)
207 {
208 }
209 
210 /*
211  * ~DataSource_Impl.
212  */
213 DataSource_Impl::~DataSource_Impl (void)
214 {
215 }
216 
217 /*
218  * DataSource_Impl: setBuffer.
219  */
220 void DataSource_Impl::setBuffer (const Sequence<sal_Int8> &rBuffer)
221 {
222 	m_buffer = rBuffer;
223 	if (!m_buffer.getLength())
224 	{
225 		// Fill buffer from file descriptor.
226 		char buffer[1024];
227 		rtl_zeroMemory (buffer, sizeof(buffer));
228 
229 		int k = read (m_fd, buffer, sizeof(buffer));
230 		while (k > 0)
231 		{
232 			sal_Int32 n = m_buffer.getLength();
233 			m_buffer.realloc (n + k);
234 
235 			rtl_copyMemory (m_buffer.getArray() + n, buffer, k);
236 			n += k;
237 
238 			rtl_zeroMemory (buffer, k);
239 			k = read (m_fd, buffer, sizeof(buffer));
240 		}
241 	}
242 	m_position = 0;
243 }
244 
245 /*
246  * XInterface: queryInterface.
247  */
248 sal_Bool SAL_CALL DataSource_Impl::queryInterface (
249 	const Uik &rUik, Any &rIfc) throw(RuntimeException)
250 {
251 	if (com::sun::star::uno::queryInterface (
252 		rUik, rIfc,
253 		SAL_STATIC_CAST (XInputStream*, this)))
254 		return sal_True;
255 	else
256 		return OWeakObject::queryInterface (rUik, rIfc);
257 }
258 
259 /*
260  * XInterface: acquire.
261  */
262 void SAL_CALL DataSource_Impl::acquire (void) throw(RuntimeException)
263 {
264 	OWeakObject::acquire();
265 }
266 
267 /*
268  * XInterface: release.
269  */
270 void SAL_CALL DataSource_Impl::release (void) throw(RuntimeException)
271 {
272 	OWeakObject::release();
273 }
274 
275 /*
276  * XInputStream: readBytes.
277  */
278 sal_Int32 SAL_CALL DataSource_Impl::readBytes (
279 	Sequence<sal_Int8> &rData, sal_Int32 nBytesToRead)
280 	throw (NotConnectedException, BufferSizeExceededException, IOException)
281 {
282 	if (nBytesToRead < 0)
283 		throw IOException();
284 
285 	sal_Int32 k = m_buffer.getLength() - m_position;
286 	k = VOS_BOUND(k, 0, nBytesToRead);
287 	if (k > 0)
288 	{
289 		rData.realloc(k);
290 		rtl_copyMemory (
291 			rData.getArray(), m_buffer.getConstArray() + m_position, k);
292 		m_position += k;
293 	}
294 	return k;
295 }
296 
297 /*
298  * XInputStream: readSomeBytes.
299  */
300 sal_Int32 SAL_CALL DataSource_Impl::readSomeBytes (
301 	Sequence<sal_Int8> &rData, sal_Int32 nMaxBytesToRead)
302 	throw (NotConnectedException, BufferSizeExceededException, IOException)
303 {
304 	return readBytes (rData, nMaxBytesToRead);
305 }
306 
307 /*
308  * XInputStream: skipBytes.
309  */
310 void SAL_CALL DataSource_Impl::skipBytes (sal_Int32 nBytesToSkip)
311 	throw (NotConnectedException, BufferSizeExceededException, IOException)
312 {
313 	if (nBytesToSkip < 0)
314 		throw IOException();
315 
316 	m_position += nBytesToSkip;
317 }
318 
319 /*
320  * XInputStream: available.
321  */
322 sal_Int32 SAL_CALL DataSource_Impl::available (void)
323 	throw (NotConnectedException, IOException)
324 {
325 	sal_Int32 k = m_buffer.getLength() - m_position;
326 	return ((k > 0) ? k : 0);
327 }
328 
329 /*
330  * XInputStream: closeInput.
331  */
332 void SAL_CALL DataSource_Impl::closeInput (void)
333 	throw (NotConnectedException, IOException)
334 {
335 }
336 
337 /*========================================================================
338  *
339  * DataSink_Impl implementation.
340  *
341  *======================================================================*/
342 /*
343  * DataSink_Impl.
344  */
345 DataSink_Impl::DataSink_Impl (void)
346 {
347 }
348 
349 /*
350  * ~DataSink_Impl.
351  */
352 DataSink_Impl::~DataSink_Impl (void)
353 {
354 }
355 
356 /*
357  * XInterface: queryInterface.
358  */
359 sal_Bool SAL_CALL DataSink_Impl::queryInterface (
360 	const Uik &rUik, Any &rIfc) throw(RuntimeException)
361 {
362 	if (com::sun::star::uno::queryInterface (
363 		rUik, rIfc,
364 		SAL_STATIC_CAST (XOutputStream*, this)))
365 		return sal_True;
366 	else
367 		return OWeakObject::queryInterface (rUik, rIfc);
368 }
369 
370 /*
371  * XInterface: acquire.
372  */
373 void SAL_CALL DataSink_Impl::acquire (void) throw(RuntimeException)
374 {
375 	OWeakObject::acquire();
376 }
377 
378 /*
379  * XInterface: release.
380  */
381 void SAL_CALL DataSink_Impl::release (void) throw(RuntimeException)
382 {
383 	OWeakObject::release();
384 }
385 
386 /*
387  * XOutputStream: writeBytes.
388  */
389 void SAL_CALL DataSink_Impl::writeBytes (const Sequence<sal_Int8> &rBuffer)
390 	throw (NotConnectedException, BufferSizeExceededException, IOException)
391 {
392 	if (rBuffer.getLength())
393 	{
394 		sal_Int32 n = m_buffer.getLength();
395 		m_buffer.realloc (n + rBuffer.getLength());
396 
397 		rtl_copyMemory (
398 			m_buffer.getArray() + n,
399 			rBuffer.getConstArray(),
400 			rBuffer.getLength());
401 	}
402 }
403 
404 /*
405  * XOutputStream: flush.
406  */
407 void SAL_CALL DataSink_Impl::flush (void)
408 	throw (NotConnectedException, BufferSizeExceededException, IOException)
409 {
410 	if (m_buffer.getLength())
411 	{
412 		// Write data to stdout.
413 		const sal_Int8 *pData = m_buffer.getConstArray();
414 		sal_Int32       nData = m_buffer.getLength();
415 
416 		int prev = ::setmode (1, O_BINARY);
417 		if (!(prev < 0))
418 		{
419 			int k = ::write (1, pData, nData);
420 			if (k > 0)
421 				::write (1, "\n", 1);
422 			::setmode (1, prev);
423 		}
424 	}
425 }
426 
427 /*
428  * XOutputStream: closeOutput.
429  */
430 void SAL_CALL DataSink_Impl::closeOutput (void)
431 	throw (NotConnectedException, BufferSizeExceededException, IOException)
432 {
433 	flush();
434 }
435 
436 /*========================================================================
437  *
438  * DecoderListener_Impl implementation.
439  *
440  *======================================================================*/
441 /*
442  * DecoderListener_Impl.
443  */
444 DecoderListener_Impl::DecoderListener_Impl (void)
445 {
446 }
447 
448 /*
449  * ~DecoderListener_Impl.
450  */
451 DecoderListener_Impl::~DecoderListener_Impl (void)
452 {
453 }
454 
455 /*
456  * XInterface: queryInterface.
457  */
458 sal_Bool SAL_CALL DecoderListener_Impl::queryInterface (
459 	const Uik &rUik, Any &rIfc) throw(RuntimeException)
460 {
461 	if (com::sun::star::uno::queryInterface (
462 		rUik, rIfc,
463 		SAL_STATIC_CAST (XEventListener*, this),
464 		SAL_STATIC_CAST (XPGPDecoderListener*, this)))
465 		return sal_True;
466 	else
467 		return OWeakObject::queryInterface (rUik, rIfc);
468 }
469 
470 /*
471  * XInterface: acquire.
472  */
473 void SAL_CALL DecoderListener_Impl::acquire (void) throw(RuntimeException)
474 {
475 	OWeakObject::acquire();
476 }
477 
478 /*
479  * XInterface: release.
480  */
481 void SAL_CALL DecoderListener_Impl::release (void) throw(RuntimeException)
482 {
483 	OWeakObject::release();
484 }
485 
486 /*
487  * XEventListener: disposing.
488  */
489 void SAL_CALL DecoderListener_Impl::disposing (const EventObject &rSource)
490 {
491 }
492 
493 /*
494  * XPGPDecoderListener: decrypted.
495  */
496 void SAL_CALL DecoderListener_Impl::decrypted (const RecipientsEvent &rEvent)
497 {
498 }
499 
500 /*
501  * XPGPDecoderListener: verified.
502  */
503 void SAL_CALL DecoderListener_Impl::verified (const SignatureEvent &rEvent)
504 {
505 }
506 
507 /*========================================================================
508  *
509  * Main.
510  *
511  *======================================================================*/
512 inline rtl::OWString S2U (const sal_Char *ascii)
513 {
514 	return rtl::OWString::createFromAscii (ascii);
515 }
516 
517 #if 0  /* OLD */
518 
519 /*
520  * queryModuleActivator.
521  */
522 BOOL queryModuleActivator (
523 	const XServiceManagerRef &rxManager,
524 	XServiceActivatorRef     &rxActivator)
525 {
526 	XServiceProviderRef xProv;
527 	XInterfaceRef       xProvInst;
528 
529 	xProv = rxManager->queryServiceProvider (
530 		L"stardiv.uno.ServiceActivator.module");
531 	if (!xProv.is())
532 	{
533 		printf ("Error: no ServiceActivator service.\n");
534 		return FALSE;
535 	}
536 
537 	xProvInst = xProv->createInstance();
538 	if (!xProvInst.is())
539 	{
540 		printf ("Error: no ServiceActivator instance.\n");
541 		return FALSE;
542 	}
543 
544 	return xProvInst->queryInterface (
545 		XServiceActivator::getSmartUik(), rxActivator);
546 }
547 
548 /*
549  * install.
550  */
551 BOOL install (
552 	const XServiceActivatorRef &rxActivator,
553 	const char                 *prefix)
554 {
555 	String aModule ("module://");
556 	char   pBuffer[1024];
557 
558 	vos::ORealDynamicLoader::computeModuleName (
559 		prefix, pBuffer, sizeof(pBuffer));
560 	aModule += pBuffer;
561 
562 	return rxActivator->install (
563 		StringToUString (aModule, CHARSET_SYSTEM));
564 }
565 
566 /*
567  * uninstall.
568  */
569 BOOL uninstall (
570 	const XServiceActivatorRef &rxActivator,
571 	const char                 *prefix)
572 {
573 	String aModule ("module://");
574 	char   pBuffer[1024];
575 
576 	vos::ORealDynamicLoader::computeModuleName (
577 		prefix, pBuffer, sizeof(pBuffer));
578 	aModule += pBuffer;
579 
580 	return rxActivator->deinstall (
581 		StringToUString (aModule, CHARSET_SYSTEM));
582 }
583 
584 #endif /* OLD */
585 
586 /*
587  * main.
588  */
589 int SAL_CALL main (int argc, char **argv)
590 {
591 	enum Option
592 	{
593 		OPTION_INSTALL   = 0x01,
594 		OPTION_UNINSTALL = 0x02,
595 
596 		OPTION_DECRYPT   = 0x04,
597 		OPTION_ENCRYPT   = 0x08,
598 		OPTION_SIGN      = 0x10,
599 
600 		OPTION_FILE      = 0x20,
601 		OPTION_HELP      = 0x40
602 	};
603 
604 	int fd = 0;
605 	unsigned long nOptions = 0;
606 
607 	for (int i = 1; i < argc; i++)
608 	{
609 		const char *opt = argv[i];
610 		if (opt[0] == '-')
611 		{
612 			switch (opt[1])
613 			{
614 				case 'i':
615 					nOptions |= OPTION_INSTALL;
616 					break;
617 
618 				case 'u':
619 					nOptions |= OPTION_UNINSTALL;
620 					break;
621 
622 				case 'd':
623 					nOptions |= OPTION_DECRYPT;
624 					break;
625 
626 				case 'e':
627 					nOptions |= OPTION_ENCRYPT;
628 					break;
629 
630 				case 's':
631 					nOptions |= OPTION_SIGN;
632 					break;
633 
634 				case 'f':
635 					nOptions |= OPTION_FILE;
636 					break;
637 
638 				case 'h':
639 				default:
640 					nOptions |= OPTION_HELP;
641 					break;
642 			}
643 		}
644 		else
645 		{
646 			if (nOptions & OPTION_FILE)
647 			{
648 				if ((fd = open (argv[i], O_RDONLY | O_BINARY)) < 0)
649 				{
650 					printf ("Error: can't open file: %s\n", argv[i]);
651 					exit (0);
652 				}
653 			}
654 		}
655 	}
656 
657 	if ((nOptions == 0) || (nOptions & OPTION_HELP))
658 	{
659 		printf ("Options:\n");
660 		printf ("-i\tinstall module\n");
661 		printf ("-u\tuninstall module\n");
662 		printf ("-d\tdecrypt and verify\n");
663 		printf ("-e\tencrypt test pattern\n");
664 		printf ("-s\tsign test pattern\n");
665 		printf ("-h\thelp\n");
666 		exit (0);
667 	}
668 
669 	Reference<XMultiServiceFactory> xManager (
670 		usr::createDefaultSmartRegistryServiceFactory());
671 	if (!xManager.is())
672 	{
673 		printf ("Error: no ProcessServiceManager.\n");
674 		exit (1);
675 	}
676 	usr::setProcessServiceFactory (xManager);
677 
678 	if (nOptions & OPTION_INSTALL)
679 	{
680 #if 0  /* OLD */
681 		XServiceActivatorRef xActivator;
682 		if (queryModuleActivator (xManager, xActivator))
683 		{
684 			if (install (xActivator, "pgp"))
685 				printf ("Module PGP installed.\n");
686 			else
687 				printf ("Error: module PGP not installed.\n");
688 		}
689 		nOptions &= ~OPTION_INSTALL;
690 #endif /* OLD */
691 	}
692 
693 	if (nOptions & (OPTION_DECRYPT | OPTION_ENCRYPT | OPTION_SIGN))
694 	{
695 		Reference<XMultiServiceFactory> xProv (
696 			xManager->createInstance (
697 				S2U("com.sun.star.pgp.PGPFactory")),
698 			UNO_QUERY);
699 		if (!xProv.is())
700 		{
701 			printf ("Error: no PGPFactory service.\n");
702 			exit (1);
703 		}
704 
705 		Reference<XInterface> xProvInst (
706 			xProv->createInstance (
707 				S2U("com.sun.star.pgp.SimplePGPMailer")));
708 		if (!xProvInst.is())
709 		{
710 			printf ("Error: no SimplePGPMailer service.\n");
711 			exit (2);
712 		}
713 
714 		Reference<XPGPPreferences> xPrefs (xProvInst, UNO_QUERY);
715 		if (xPrefs.is())
716 		{
717 			unsigned long nDefaults = 0;
718 
719 			if (xPrefs->getEncryptByDefault())
720 				nDefaults |= OPTION_ENCRYPT;
721 			if (xPrefs->getSignByDefault())
722 				nDefaults |= OPTION_SIGN;
723 			if (xPrefs->getAutoDecrypt())
724 				nDefaults |= OPTION_DECRYPT;
725 
726 			if (nDefaults)
727 			{
728 			}
729 		}
730 
731 		static const sal_Int8 pData[] = "" /* "Hello PGP World." */;
732 		Sequence<sal_Int8> buffer (pData, sizeof (pData) - 1);
733 
734 		if (nOptions & (OPTION_ENCRYPT | OPTION_SIGN))
735 		{
736 			Reference<XPGPEncoder> xEncoder (xProvInst, UNO_QUERY);
737 			if (!xEncoder.is())
738 			{
739 				printf ("Error: no PGPEncoder interface.\n");
740 				exit (4);
741 			}
742 
743 			DataSource_Impl *source = new DataSource_Impl (fd);
744 			source->setBuffer (buffer);
745 
746 			DataSink_Impl *sink = new DataSink_Impl;
747 
748 			Reference<XInputStream>  xPlainText  (source);
749 			Reference<XOutputStream> xCipherText (sink);
750 
751 			if (nOptions & OPTION_ENCRYPT)
752 			{
753 				rtl::OWString aRecipients[] =
754 				{
755 					S2U("er@stardiv.de"),
756 					// L"mhu@stardivision.de",
757 					S2U("mhu@rabbit")
758 				};
759 
760 				sal_Int32 nRecipients =
761 					sizeof(aRecipients) / sizeof(aRecipients[0]);
762 
763 				if (nOptions & OPTION_SIGN)
764 				{
765 					xEncoder->encryptAndSign (
766 						Sequence<rtl::OWString>(aRecipients, nRecipients),
767 						xPlainText,
768 						xCipherText);
769 					nOptions &= ~OPTION_SIGN;
770 				}
771 				else
772 				{
773 					xEncoder->encrypt (
774 						Sequence<rtl::OWString>(aRecipients, nRecipients),
775 						xPlainText,
776 						xCipherText);
777 				}
778 				nOptions &= ~OPTION_ENCRYPT;
779 			}
780 
781 			if (nOptions & OPTION_SIGN)
782 			{
783 				sal_Bool bDataIsAscii = (fd == 0); // stdin.
784 
785 				xEncoder->sign (
786 					bDataIsAscii,
787 					xPlainText,
788 					xCipherText);
789 				nOptions &= ~OPTION_SIGN;
790 			}
791 
792 			buffer = sink->getBuffer();
793 		}
794 
795 		if (nOptions & OPTION_DECRYPT)
796 		{
797 			Reference<XPGPDecoder> xDecoder (xProvInst, UNO_QUERY);
798 			if (!xDecoder.is())
799 			{
800 				printf ("Error: no PGPDecoder interface.\n");
801 				exit (5);
802 			}
803 
804 			DataSource_Impl *source = new DataSource_Impl;
805 			source->setBuffer (buffer);
806 
807 			DataSink_Impl *sink = new DataSink_Impl;
808 
809 			Reference<XInputStream>  xCipherText (source);
810 			Reference<XOutputStream> xPlainText  (sink);
811 
812 			Reference<XPGPDecoderListener> xListener (
813 				new DecoderListener_Impl);
814 			xDecoder->addDecoderListener (xListener);
815 
816 			xDecoder->decryptAndVerify (
817 				xCipherText,
818 				xPlainText);
819 			nOptions &= ~OPTION_DECRYPT;
820 
821 			xDecoder->removeDecoderListener (xListener);
822 
823 			buffer = sink->getBuffer();
824 		}
825 	}
826 
827 	if (nOptions & OPTION_UNINSTALL)
828 	{
829 #if 0  /* OLD */
830 		XServiceActivatorRef xActivator;
831 		if (queryModuleActivator (xManager, xActivator))
832 		{
833 			if (uninstall (xActivator, "pgp"))
834 				printf ("Module PGP uninstalled.\n");
835 			else
836 				printf ("Error: module PGP not uninstalled.\n");
837 		}
838 		nOptions &= ~OPTION_UNINSTALL;
839 #endif /* OLD */
840 	}
841 
842 	return 0;
843 }
844 
845