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