|
Packit Service |
0ef63b |
/* run-threaded.c - Helper to put GPGME under multithread load.
|
|
Packit Service |
0ef63b |
* Copyright (C) 2018 by Bundesamt für Sicherheit in der Informationstechnik
|
|
Packit Service |
0ef63b |
* Software engineering by Intevation GmbH
|
|
Packit Service |
0ef63b |
*
|
|
Packit Service |
0ef63b |
* This file is part of GPGME.
|
|
Packit Service |
0ef63b |
*
|
|
Packit Service |
0ef63b |
* GPGME is free software; you can redistribute it and/or modify it
|
|
Packit Service |
0ef63b |
* under the terms of the GNU Lesser General Public License as
|
|
Packit Service |
0ef63b |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
0ef63b |
* the License, or (at your option) any later version.
|
|
Packit Service |
0ef63b |
*
|
|
Packit Service |
0ef63b |
* GPGME is distributed in the hope that it will be useful, but
|
|
Packit Service |
0ef63b |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
0ef63b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
0ef63b |
* Lesser General Public License for more details.
|
|
Packit Service |
0ef63b |
*
|
|
Packit Service |
0ef63b |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
0ef63b |
* License along with this program; if not, see <https://gnu.org/licenses/>.
|
|
Packit Service |
0ef63b |
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
Packit Service |
0ef63b |
*/
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
/* The idea of this test is not to be run as unit test but as part
|
|
Packit Service |
0ef63b |
* of development to find threading issues and resource leaks. */
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
0ef63b |
# include <config.h>
|
|
Packit Service |
0ef63b |
#endif
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#include <gpgme.h>
|
|
Packit Service |
0ef63b |
#include <gpg-error.h>
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#include <stdlib.h>
|
|
Packit Service |
0ef63b |
#include <stdio.h>
|
|
Packit Service |
0ef63b |
#include <string.h>
|
|
Packit Service |
0ef63b |
#include <sys/stat.h>
|
|
Packit Service |
0ef63b |
#include <sys/types.h>
|
|
Packit Service |
0ef63b |
#include <fcntl.h>
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#include <unistd.h>
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#define PGM "run-threaded"
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#include "run-support.h"
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static volatile int stop;
|
|
Packit Service |
0ef63b |
static volatile int thread_cnt;
|
|
Packit Service |
0ef63b |
static volatile int running_threads;
|
|
Packit Service |
0ef63b |
static int verbose;
|
|
Packit Service |
0ef63b |
static int data_type;
|
|
Packit Service |
0ef63b |
static int mem_only;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#ifdef HAVE_W32_SYSTEM
|
|
Packit Service |
0ef63b |
# include <windows.h>
|
|
Packit Service |
0ef63b |
# define THREAD_RET DWORD CALLBACK
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static void
|
|
Packit Service |
0ef63b |
create_thread (THREAD_RET (*func) (void *), void *arg)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
HANDLE hd = CreateThread (NULL, 0, func, arg, 0, NULL);
|
|
Packit Service |
0ef63b |
if (hd == INVALID_HANDLE_VALUE)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Failed to create thread!\n");
|
|
Packit Service |
0ef63b |
exit (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
running_threads++;
|
|
Packit Service |
0ef63b |
CloseHandle (hd);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#else
|
|
Packit Service |
0ef63b |
# include <pthread.h>
|
|
Packit Service |
0ef63b |
# define THREAD_RET void *
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static void
|
|
Packit Service |
0ef63b |
create_thread (THREAD_RET (func) (void *), void *arg)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
pthread_t handle;
|
|
Packit Service |
0ef63b |
running_threads++;
|
|
Packit Service |
0ef63b |
if (pthread_create (&handle, NULL, func, arg))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Failed to create thread!\n");
|
|
Packit Service |
0ef63b |
exit (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
#endif
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#include <gpg-error.h>
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
GPGRT_LOCK_DEFINE (out_lock);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#define out(format, ...) \
|
|
Packit Service |
0ef63b |
{ \
|
|
Packit Service |
0ef63b |
gpgrt_lock_lock (&out_lock); \
|
|
Packit Service |
0ef63b |
printf (format "\n", ##__VA_ARGS__); \
|
|
Packit Service |
0ef63b |
gpgrt_lock_unlock (&out_lock); \
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#define errpoint \
|
|
Packit Service |
0ef63b |
{ \
|
|
Packit Service |
0ef63b |
out ("Error on %i", __LINE__); \
|
|
Packit Service |
0ef63b |
exit (1); \
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
#define log(format, ...) \
|
|
Packit Service |
0ef63b |
if (verbose) \
|
|
Packit Service |
0ef63b |
{ \
|
|
Packit Service |
0ef63b |
gpgrt_lock_lock (&out_lock); \
|
|
Packit Service |
0ef63b |
printf (format "\n", ##__VA_ARGS__); \
|
|
Packit Service |
0ef63b |
gpgrt_lock_unlock (&out_lock); \
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
/* Lazy mans signal */
|
|
Packit Service |
0ef63b |
GPGRT_LOCK_DEFINE (threads_lock);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void del_thread (void)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
if (--running_threads == 0)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgrt_lock_unlock (&threads_lock);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static int
|
|
Packit Service |
0ef63b |
show_usage (int ex)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fputs ("usage: " PGM " [options] [messages]\n\n"
|
|
Packit Service |
0ef63b |
"Options:\n"
|
|
Packit Service |
0ef63b |
" --verbose run in verbose mode\n"
|
|
Packit Service |
0ef63b |
" --no-list do not do keylistings\n"
|
|
Packit Service |
0ef63b |
" --allow-del allow to delete keys after import\n"
|
|
Packit Service |
0ef63b |
" --data-type mem function to use one of:\n"
|
|
Packit Service |
0ef63b |
" 1: fstream\n"
|
|
Packit Service |
0ef63b |
" 2: posix fd\n"
|
|
Packit Service |
0ef63b |
" 3: memory\n"
|
|
Packit Service |
0ef63b |
" 4: gpgrt_stream\n"
|
|
Packit Service |
0ef63b |
" default: random\n"
|
|
Packit Service |
0ef63b |
/* " --mem-cache read data only once and then work on memory\n"
|
|
Packit Service |
0ef63b |
" exlusive with data-type option\n" */
|
|
Packit Service |
0ef63b |
" --threads N use 4+N threads (4 are used for keylisting"
|
|
Packit Service |
0ef63b |
" default 1)\n"
|
|
Packit Service |
0ef63b |
" --repeat N do N repeats on the messages (default 1)\n\n"
|
|
Packit Service |
0ef63b |
"Note: The test does keylistings of both S/MIME and OpenPGP\n"
|
|
Packit Service |
0ef63b |
" in the background while running operations on the\n"
|
|
Packit Service |
0ef63b |
" messages, depending on their type.\n"
|
|
Packit Service |
0ef63b |
" (Currently decrypt / verify).\n\n"
|
|
Packit Service |
0ef63b |
" Without messages only keylistings will be done.\n"
|
|
Packit Service |
0ef63b |
, stderr);
|
|
Packit Service |
0ef63b |
exit (ex);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
struct msg_list_s
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
const char *file_name;
|
|
Packit Service |
0ef63b |
struct msg_list_s *next;
|
|
Packit Service |
0ef63b |
};
|
|
Packit Service |
0ef63b |
typedef struct msg_list_s *msg_list_t;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
struct data_s
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
int fd;
|
|
Packit Service |
0ef63b |
FILE *file;
|
|
Packit Service |
0ef63b |
gpgrt_stream_t stream;
|
|
Packit Service |
0ef63b |
unsigned char *mem;
|
|
Packit Service |
0ef63b |
gpgme_data_t dh;
|
|
Packit Service |
0ef63b |
};
|
|
Packit Service |
0ef63b |
typedef struct data_s *data_t;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
struct keylist_args_s
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_protocol_t proto;
|
|
Packit Service |
0ef63b |
int secret;
|
|
Packit Service |
0ef63b |
};
|
|
Packit Service |
0ef63b |
typedef struct keylist_args_s *keylist_args_t;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static volatile int keylists;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static int allow_del;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static THREAD_RET
|
|
Packit Service |
0ef63b |
do_keylist (void *keylist_args)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_error_t err;
|
|
Packit Service |
0ef63b |
gpgme_ctx_t ctx;
|
|
Packit Service |
0ef63b |
gpgme_key_t key;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
keylist_args_t args = (keylist_args_t) keylist_args;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
log ("Keylist %i, Protocol: %s, Secret %i",
|
|
Packit Service |
0ef63b |
keylists++,
|
|
Packit Service |
0ef63b |
args->proto == GPGME_PROTOCOL_CMS ? "CMS" : "OpenPGP",
|
|
Packit Service |
0ef63b |
args->secret);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_new (&ctx;;
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_set_protocol (ctx, args->proto);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_op_keylist_start (ctx, NULL, args->secret);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_key_unref (key);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (gpgme_err_code (err) != GPG_ERR_EOF)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_release (ctx);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (!stop)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
create_thread (do_keylist, keylist_args);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
del_thread ();
|
|
Packit Service |
0ef63b |
return 0;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static unsigned char *
|
|
Packit Service |
0ef63b |
get_file (const char *fname, size_t *r_size)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpg_error_t err;
|
|
Packit Service |
0ef63b |
gpgrt_stream_t fp;
|
|
Packit Service |
0ef63b |
struct stat st;
|
|
Packit Service |
0ef63b |
unsigned char *buf;
|
|
Packit Service |
0ef63b |
size_t buflen;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
fp = gpgrt_fopen (fname, "r");
|
|
Packit Service |
0ef63b |
if (!fp)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
err = gpg_error_from_syserror ();
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Error: can't open '%s': %s\n", fname,
|
|
Packit Service |
0ef63b |
gpg_strerror (err));
|
|
Packit Service |
0ef63b |
return NULL;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (fstat (gpgrt_fileno(fp), &st))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
err = gpg_error_from_syserror ();
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Error: can't stat '%s': %s\n", fname,
|
|
Packit Service |
0ef63b |
gpg_strerror (err));
|
|
Packit Service |
0ef63b |
gpgrt_fclose (fp);
|
|
Packit Service |
0ef63b |
return NULL;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
buflen = st.st_size;
|
|
Packit Service |
0ef63b |
buf = malloc (buflen+1);
|
|
Packit Service |
0ef63b |
if (!buf)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Error: no mem\n");
|
|
Packit Service |
0ef63b |
gpgrt_fclose (fp);
|
|
Packit Service |
0ef63b |
return NULL;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (gpgrt_fread (buf, buflen, 1, fp) != 1)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
err = gpg_error_from_syserror ();
|
|
Packit Service |
0ef63b |
fprintf (stderr, "error reading '%s': %s\n", fname,
|
|
Packit Service |
0ef63b |
gpg_strerror (err));
|
|
Packit Service |
0ef63b |
gpgrt_fclose (fp);
|
|
Packit Service |
0ef63b |
free (buf);
|
|
Packit Service |
0ef63b |
return NULL;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
buf[buflen] = 0;
|
|
Packit Service |
0ef63b |
gpgrt_fclose (fp);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (r_size)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
*r_size = buflen;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
return buf;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
/** Lets use random data. This should also introduce a bit
|
|
Packit Service |
0ef63b |
of randomness into the system by changing the runtimes
|
|
Packit Service |
0ef63b |
of various data functions. Esp. Mem against the file ops. */
|
|
Packit Service |
0ef63b |
data_t
|
|
Packit Service |
0ef63b |
random_data_new (const char *fname)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
data_t ret = calloc (1, sizeof (struct data_s));
|
|
Packit Service |
0ef63b |
int data_rand;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
ret->fd = -1;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (data_type)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
data_rand = data_type;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
data_rand = rand () % 3;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (data_rand == 0) /* stream */
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
FILE *f_stream = fopen (fname, "rb");
|
|
Packit Service |
0ef63b |
if (!f_stream)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
fail_if_err (gpgme_data_new_from_stream (&(ret->dh), f_stream));
|
|
Packit Service |
0ef63b |
ret->file = f_stream;
|
|
Packit Service |
0ef63b |
return ret;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
if (data_rand == 1) /* fd */
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
int fd = open (fname, O_RDONLY);
|
|
Packit Service |
0ef63b |
gpgme_data_t dh;
|
|
Packit Service |
0ef63b |
if (fd == -1)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
fail_if_err (gpgme_data_new_from_fd (&dh, fd));
|
|
Packit Service |
0ef63b |
ret->fd = fd;
|
|
Packit Service |
0ef63b |
ret->dh = dh;
|
|
Packit Service |
0ef63b |
return ret;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
if (data_rand == 2) /* mem */
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
unsigned char *mem;
|
|
Packit Service |
0ef63b |
size_t size;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
mem = get_file (fname, &size);
|
|
Packit Service |
0ef63b |
if (!mem)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
fail_if_err (gpgme_data_new_from_mem (&(ret->dh),
|
|
Packit Service |
0ef63b |
(const char *)mem,
|
|
Packit Service |
0ef63b |
size, 0));
|
|
Packit Service |
0ef63b |
ret->mem = mem;
|
|
Packit Service |
0ef63b |
return ret;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
if (data_rand == 3) /* estream */
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgrt_stream_t stream = gpgrt_fopen (fname, "rb");
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (!stream)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
fail_if_err (gpgme_data_new_from_estream (&(ret->dh), stream));
|
|
Packit Service |
0ef63b |
ret->stream = stream;
|
|
Packit Service |
0ef63b |
return ret;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
/* notreached */
|
|
Packit Service |
0ef63b |
return ret;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
random_data_close (data_t data)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
if (data->dh)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_data_release (data->dh);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (data->fd != -1)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
close (data->fd);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (data->file)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fclose (data->file);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (data->stream)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgrt_fclose (data->stream);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (data->mem)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
free (data->mem);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
free (data);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
verify (const char *fname, gpgme_protocol_t proto)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_ctx_t ctx;
|
|
Packit Service |
0ef63b |
gpgme_error_t err;
|
|
Packit Service |
0ef63b |
gpgme_data_t output;
|
|
Packit Service |
0ef63b |
char *msg;
|
|
Packit Service |
0ef63b |
size_t msg_len;
|
|
Packit Service |
0ef63b |
data_t data = random_data_new (fname);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
log ("Starting verify on: %s with protocol %s", fname,
|
|
Packit Service |
0ef63b |
proto == GPGME_PROTOCOL_CMS ? "CMS" : "OpenPGP");
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_data_new (&output);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_new (&ctx;;
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_set_protocol (ctx, proto);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_op_verify (ctx, data->dh, NULL, output);
|
|
Packit Service |
0ef63b |
out ("Data: %p, %i %p %p %p", data->dh,
|
|
Packit Service |
0ef63b |
data->fd, data->file, data->stream,
|
|
Packit Service |
0ef63b |
data->mem);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
msg = gpgme_data_release_and_get_mem (output, &msg_len);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (msg_len)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
log ("Verify result \n'%.*s'", (int)msg_len, msg);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_release (ctx);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
random_data_close (data);
|
|
Packit Service |
0ef63b |
free (msg);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
/* We randomize data access to put in a bit additional
|
|
Packit Service |
0ef63b |
entropy in this test and also to check if maybe
|
|
Packit Service |
0ef63b |
some data functions might not be properly thread
|
|
Packit Service |
0ef63b |
safe. */
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
decrypt (const char *fname, gpgme_protocol_t proto)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_ctx_t ctx;
|
|
Packit Service |
0ef63b |
gpgme_error_t err;
|
|
Packit Service |
0ef63b |
gpgme_data_t output;
|
|
Packit Service |
0ef63b |
char *msg;
|
|
Packit Service |
0ef63b |
size_t msg_len;
|
|
Packit Service |
0ef63b |
data_t data = random_data_new (fname);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
log ("Starting decrypt on: %s", fname);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_data_new (&output);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_new (&ctx;;
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_set_protocol (ctx, proto);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_op_decrypt (ctx, data->dh, output);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_release (ctx);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
msg = gpgme_data_release_and_get_mem (output, &msg_len);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (msg_len)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
log ("Decrypt result \n'%.*s'", (int)msg_len, msg);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
random_data_close (data);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
delete_key (gpgme_key_t key)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_ctx_t ctx;
|
|
Packit Service |
0ef63b |
gpgme_error_t err;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_new (&ctx;;
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_set_protocol (ctx, key->protocol);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_op_delete (ctx, key, 0);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_release (ctx);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
/* Get the key for the fpr in protocol and call delete_key
|
|
Packit Service |
0ef63b |
on it. */
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
delete_fpr (const char *fpr, gpgme_protocol_t proto)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_ctx_t ctx;
|
|
Packit Service |
0ef63b |
gpgme_error_t err;
|
|
Packit Service |
0ef63b |
gpgme_key_t key = NULL;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_new (&ctx;;
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_set_protocol (ctx, proto);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_get_key (ctx, fpr, &key, 0);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (!key)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
delete_key (key);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
log ("deleted key %s", fpr);
|
|
Packit Service |
0ef63b |
gpgme_key_unref (key);
|
|
Packit Service |
0ef63b |
gpgme_release (ctx);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
delete_impres (gpgme_import_result_t r, gpgme_protocol_t proto)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_import_status_t st;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (!r)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
for (st=r->imports; st; st = st->next)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
delete_fpr (st->fpr, proto);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
import (const char *fname, gpgme_protocol_t proto)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_ctx_t ctx;
|
|
Packit Service |
0ef63b |
gpgme_error_t err;
|
|
Packit Service |
0ef63b |
data_t data = random_data_new (fname);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
log ("Starting import on: %s", fname);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_new (&ctx;;
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_set_protocol (ctx, proto);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_set_offline (ctx, 1);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
err = gpgme_op_import (ctx, data->dh);
|
|
Packit Service |
0ef63b |
fail_if_err (err);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (allow_del)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
delete_impres (gpgme_op_import_result (ctx), proto);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgme_release (ctx);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
log ("Import completed.");
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
random_data_close (data);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
static THREAD_RET
|
|
Packit Service |
0ef63b |
do_data_op (void *file_name)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
gpgme_data_t data;
|
|
Packit Service |
0ef63b |
const char *fname = (const char *) file_name;
|
|
Packit Service |
0ef63b |
FILE *f = fopen (fname, "rb");
|
|
Packit Service |
0ef63b |
gpgme_data_type_t type;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (!f)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Failed to open '%s'\n", fname);
|
|
Packit Service |
0ef63b |
exit (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
fail_if_err (gpgme_data_new_from_stream (&data, f));
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
type = gpgme_data_identify (data, 0);
|
|
Packit Service |
0ef63b |
gpgme_data_release (data);
|
|
Packit Service |
0ef63b |
fclose (f);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
switch (type)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_INVALID:
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_UNKNOWN:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
fprintf (stderr, "Failed to identify '%s'", fname);
|
|
Packit Service |
0ef63b |
exit(1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_PGP_SIGNED:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
verify (fname, GPGME_PROTOCOL_OpenPGP);
|
|
Packit Service |
0ef63b |
break;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_CMS_SIGNED:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
verify (fname, GPGME_PROTOCOL_CMS);
|
|
Packit Service |
0ef63b |
break;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_PGP_ENCRYPTED:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
decrypt (fname, GPGME_PROTOCOL_OpenPGP);
|
|
Packit Service |
0ef63b |
break;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_CMS_ENCRYPTED:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
decrypt (fname, GPGME_PROTOCOL_CMS);
|
|
Packit Service |
0ef63b |
break;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_PGP_KEY:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
import (fname, GPGME_PROTOCOL_OpenPGP);
|
|
Packit Service |
0ef63b |
break;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
case GPGME_DATA_TYPE_X509_CERT:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
import (fname, GPGME_PROTOCOL_CMS);
|
|
Packit Service |
0ef63b |
break;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
default:
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
out ("Unhandled data type 0x%x for '%s'\n", type, fname);
|
|
Packit Service |
0ef63b |
errpoint;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
del_thread ();
|
|
Packit Service |
0ef63b |
return 0;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
void
|
|
Packit Service |
0ef63b |
start_keylistings (void)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
static struct keylist_args_s args[4];
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
args[0].proto = GPGME_PROTOCOL_OpenPGP;
|
|
Packit Service |
0ef63b |
args[0].secret = 0;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
args[1].proto = GPGME_PROTOCOL_OpenPGP;
|
|
Packit Service |
0ef63b |
args[1].secret = 1;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
args[2].proto = GPGME_PROTOCOL_CMS;
|
|
Packit Service |
0ef63b |
args[2].secret = 0;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
args[3].proto = GPGME_PROTOCOL_CMS;
|
|
Packit Service |
0ef63b |
args[3].secret = 1;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
for (int i = 0; i < 4; i++)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
thread_cnt--;
|
|
Packit Service |
0ef63b |
create_thread (do_keylist, &args[i]);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
int
|
|
Packit Service |
0ef63b |
main (int argc, char **argv)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
int last_argc = -1;
|
|
Packit Service |
0ef63b |
int repeats = 1;
|
|
Packit Service |
0ef63b |
int threads = 0;
|
|
Packit Service |
0ef63b |
int no_list = 0;
|
|
Packit Service |
0ef63b |
msg_list_t msgs = NULL;
|
|
Packit Service |
0ef63b |
msg_list_t msg_it = NULL;
|
|
Packit Service |
0ef63b |
stop = 0;
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
srand (1 /* Somewhat deterministic results */);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (argc)
|
|
Packit Service |
0ef63b |
{ argc--; argv++; }
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
while (argc && last_argc != argc )
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
last_argc = argc;
|
|
Packit Service |
0ef63b |
if (!strcmp (*argv, "--help"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (0);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--verbose"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
verbose = 1;
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--no-list"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
no_list = 1;
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--allow-del"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
allow_del = 1;
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--mem-only"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
if (data_type)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
mem_only = 1;
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--threads"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
if (!argc)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
threads = atoi (*argv);
|
|
Packit Service |
0ef63b |
if (!threads)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--data-type"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
if (!argc || mem_only)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
data_type = atoi (*argv);
|
|
Packit Service |
0ef63b |
if (data_type > 4)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else if (!strcmp (*argv, "--repeat"))
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
if (!argc)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
repeats = atoi (*argv);
|
|
Packit Service |
0ef63b |
if (!repeats)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
show_usage (1);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
init_gpgme_basic ();
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (threads < argc)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
/* Make sure we run once on each arg */
|
|
Packit Service |
0ef63b |
threads += argc;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
while (argc)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
if (!msgs)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
msgs = calloc (1, sizeof *msgs);
|
|
Packit Service |
0ef63b |
msg_it = msgs;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
msg_it->next = calloc (1, sizeof *msgs);
|
|
Packit Service |
0ef63b |
msg_it = msg_it->next;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
msg_it->file_name = *argv;
|
|
Packit Service |
0ef63b |
argc--; argv++;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
gpgrt_lock_lock (&threads_lock);
|
|
Packit Service |
0ef63b |
do
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
stop = 0;
|
|
Packit Service |
0ef63b |
thread_cnt = threads + 4;
|
|
Packit Service |
0ef63b |
out ("Repeats left: %i", repeats);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
if (!no_list)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
start_keylistings ();
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
else
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
thread_cnt -= 4;
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
while (thread_cnt)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
log ("Thread %i", thread_cnt);
|
|
Packit Service |
0ef63b |
for (msg_it = msgs; msg_it && thread_cnt; msg_it = msg_it->next)
|
|
Packit Service |
0ef63b |
{
|
|
Packit Service |
0ef63b |
thread_cnt--;
|
|
Packit Service |
0ef63b |
create_thread (do_data_op, (void *)msg_it->file_name);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
stop = 1;
|
|
Packit Service |
0ef63b |
gpgrt_lock_lock (&threads_lock);
|
|
Packit Service |
0ef63b |
}
|
|
Packit Service |
0ef63b |
while (--repeats != 0);
|
|
Packit Service |
0ef63b |
|
|
Packit Service |
0ef63b |
return 0;
|
|
Packit Service |
0ef63b |
}
|