mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-31 08:25:22 +00:00
New JNI interface to better support cursor result sets
This commit is contained in:
parent
03536301f8
commit
3a93fee8a5
2
cli.c
2
cli.c
@ -99,6 +99,7 @@ int cli_arg(int argc, const char *const *argv, const struct command_line_option
|
||||
int arglen = strlen(argname);
|
||||
int i;
|
||||
const char *word;
|
||||
*dst = defaultvalue;
|
||||
for(i = 0; (word = o->words[i]); ++i) {
|
||||
int wordlen = strlen(word);
|
||||
/* No need to check that the "<...>" and "[<...>]" are all intact in the command_line_option,
|
||||
@ -118,7 +119,6 @@ int cli_arg(int argc, const char *const *argv, const struct command_line_option
|
||||
never happen, but it can because more than one version of a command line option may exist, one
|
||||
with a given argument and another without, and allowing a default value means we can have a
|
||||
single function handle both in a fairly simple manner. */
|
||||
*dst = defaultvalue;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
300
commandline.c
300
commandline.c
@ -61,8 +61,9 @@ int commandline_usage(int argc, const char *const *argv, const struct command_li
|
||||
JNIEnv *jni_env = NULL;
|
||||
int jni_exception = 0;
|
||||
|
||||
jobject outv_list = NULL;
|
||||
jmethodID listAddMethodId = NULL;
|
||||
jobject jniResults = NULL;
|
||||
jclass IJniResults = NULL;
|
||||
jmethodID startResultSet, setColumnName, putString, putBlob, putLong, putDouble, totalRowCount;
|
||||
|
||||
char *outv_buffer = NULL;
|
||||
char *outv_current = NULL;
|
||||
@ -84,27 +85,43 @@ static int outv_growbuf(size_t needed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int put_blob(jbyte *value, jsize length){
|
||||
jbyteArray arr = NULL;
|
||||
if (value && length>0){
|
||||
arr = (*jni_env)->NewByteArray(jni_env, length);
|
||||
if (arr == NULL || (*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
return WHY("Exception thrown from NewByteArray()");
|
||||
}
|
||||
(*jni_env)->SetByteArrayRegion(jni_env, arr, 0, length, value);
|
||||
if ((*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
return WHYF("Exception thrown from SetByteArrayRegion()");
|
||||
}
|
||||
}
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, putBlob, arr);
|
||||
if ((*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
return WHY("Exception thrown from CallVoidMethod()");
|
||||
}
|
||||
if (arr)
|
||||
(*jni_env)->DeleteLocalRef(jni_env, arr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int outv_end_field()
|
||||
{
|
||||
size_t length = outv_current - outv_buffer;
|
||||
jsize length = outv_current - outv_buffer;
|
||||
outv_current = outv_buffer;
|
||||
jbyteArray arr = (*jni_env)->NewByteArray(jni_env, length);
|
||||
if (arr == NULL) {
|
||||
jni_exception = 1;
|
||||
return WHY("Exception thrown from NewByteArray()");
|
||||
}
|
||||
(*jni_env)->SetByteArrayRegion(jni_env, arr, 0, length, (jbyte*)outv_buffer);
|
||||
if ((*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
return WHY("Exception thrown from SetByteArrayRegion()");
|
||||
}
|
||||
(*jni_env)->CallBooleanMethod(jni_env, outv_list, listAddMethodId, arr);
|
||||
if ((*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
return WHY("Exception thrown from CallBooleanMethod()");
|
||||
}
|
||||
(*jni_env)->DeleteLocalRef(jni_env, arr);
|
||||
return 0;
|
||||
return put_blob((jbyte *)outv_buffer, length);
|
||||
}
|
||||
|
||||
int Throw(JNIEnv *env, const char *class, const char *msg){
|
||||
jclass exceptionClass = NULL;
|
||||
if ((exceptionClass = (*env)->FindClass(env, class)) == NULL)
|
||||
return -1; // exception
|
||||
(*env)->ThrowNew(env, exceptionClass, msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* JNI entry point to command line. See org.servalproject.servald.ServalD class for the Java side.
|
||||
@ -112,70 +129,84 @@ static int outv_end_field()
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_servalproject_servald_ServalD_rawCommand(JNIEnv *env, jobject this, jobject outv, jobjectArray args)
|
||||
{
|
||||
jclass stringClass = NULL;
|
||||
jclass listClass = NULL;
|
||||
unsigned char status = 0; // to match what the shell gets: 0..255
|
||||
// Enforce non re-entrancy.
|
||||
if (jni_env) {
|
||||
jclass exceptionClass = NULL;
|
||||
if ((exceptionClass = (*env)->FindClass(env, "java/lang/IllegalStateException")) == NULL)
|
||||
return -1; // exception
|
||||
(*env)->ThrowNew(env, exceptionClass, "re-entrancy not supported");
|
||||
return -1;
|
||||
if (!IJniResults){
|
||||
IJniResults = (*env)->FindClass(env, "org/servalproject/servald/IJniResults");
|
||||
if (IJniResults==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate class org.servalproject.servald.IJniResults");
|
||||
startResultSet = (*env)->GetMethodID(env, IJniResults, "startResultSet", "(I)V");
|
||||
if (startResultSet==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method startResultSet");
|
||||
setColumnName = (*env)->GetMethodID(env, IJniResults, "setColumnName", "(ILjava/lang/String;)V");
|
||||
if (setColumnName==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method setColumnName");
|
||||
putString = (*env)->GetMethodID(env, IJniResults, "putString", "(Ljava/lang/String;)V");
|
||||
if (putString==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method putString");
|
||||
putBlob = (*env)->GetMethodID(env, IJniResults, "putBlob", "([B)V");
|
||||
if (putBlob==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method putBlob");
|
||||
putLong = (*env)->GetMethodID(env, IJniResults, "putLong", "(J)V");
|
||||
if (putLong==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method putLong");
|
||||
putDouble = (*env)->GetMethodID(env, IJniResults, "putDouble", "(D)V");
|
||||
if (putDouble==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method putDouble");
|
||||
totalRowCount = (*env)->GetMethodID(env, IJniResults, "totalRowCount", "(I)V");
|
||||
if (totalRowCount==NULL)
|
||||
return Throw(env, "java/lang/IllegalStateException", "Unable to locate method totalRowCount");
|
||||
}
|
||||
// Get some handles to some classes and methods that we use later on.
|
||||
if ((stringClass = (*env)->FindClass(env, "java/lang/String")) == NULL)
|
||||
return -1; // exception
|
||||
if ((listClass = (*env)->FindClass(env, "java/util/List")) == NULL)
|
||||
return -1; // exception
|
||||
if ((listAddMethodId = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z")) == NULL)
|
||||
return -1; // exception
|
||||
unsigned char status = 0; // to match what the shell gets: 0..255
|
||||
|
||||
if (jni_env)
|
||||
return Throw(env, "java/lang/IllegalStateException", "re-entrancy not supported");
|
||||
|
||||
// Construct argv, argc from this method's arguments.
|
||||
jsize len = (*env)->GetArrayLength(env, args);
|
||||
const char **argv = malloc(sizeof(char*) * (len + 1));
|
||||
if (argv == NULL) {
|
||||
jclass exceptionClass = NULL;
|
||||
if ((exceptionClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError")) == NULL)
|
||||
return -1; // exception
|
||||
(*env)->ThrowNew(env, exceptionClass, "malloc returned NULL");
|
||||
return -1;
|
||||
}
|
||||
const char **argv = alloca(sizeof(char*) * (len + 1));
|
||||
if (argv == NULL)
|
||||
return Throw(env, "java/lang/OutOfMemoryError", "alloca returned NULL");
|
||||
|
||||
argv[len]=NULL;
|
||||
|
||||
jsize i;
|
||||
for (i = 0; i <= len; ++i)
|
||||
argv[i] = NULL;
|
||||
int argc = len;
|
||||
// From now on, in case of an exception we have to free some resources before
|
||||
// returning.
|
||||
jni_exception = 0;
|
||||
for (i = 0; !jni_exception && i != len; ++i) {
|
||||
const char *empty="";
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
const jstring arg = (jstring)(*env)->GetObjectArrayElement(env, args, i);
|
||||
if (arg == NULL)
|
||||
if ((*env)->ExceptionOccurred(env))
|
||||
jni_exception = 1;
|
||||
else {
|
||||
|
||||
argv[i] = empty;
|
||||
if (arg != NULL && !jni_exception){
|
||||
const char *str = (*env)->GetStringUTFChars(env, arg, NULL);
|
||||
if (str == NULL)
|
||||
if (str == NULL){
|
||||
jni_exception = 1;
|
||||
else
|
||||
}else
|
||||
argv[i] = str;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jni_exception) {
|
||||
// Set up the output buffer.
|
||||
outv_list = outv;
|
||||
jniResults = outv;
|
||||
outv_current = outv_buffer;
|
||||
// Execute the command.
|
||||
jni_env = env;
|
||||
status = parseCommandLine(NULL, argc, argv);
|
||||
jni_env = NULL;
|
||||
}
|
||||
|
||||
// Release argv Java string buffers.
|
||||
for (i = 0; i != len; ++i) {
|
||||
if (argv[i]) {
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (argv[i] && argv[i]!=empty) {
|
||||
const jstring arg = (jstring)(*env)->GetObjectArrayElement(env, args, i);
|
||||
(*env)->ReleaseStringUTFChars(env, arg, argv[i]);
|
||||
}
|
||||
}
|
||||
free(argv);
|
||||
// Deal with Java exceptions: NewStringUTF out of memory in outv_end_field().
|
||||
if (jni_exception || (outv_current != outv_buffer && outv_end_field() == -1))
|
||||
return -1;
|
||||
@ -225,15 +256,14 @@ int parseCommandLine(const char *argv0, int argc, const char *const *args)
|
||||
int cli_putchar(char c)
|
||||
{
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
if (outv_current == outv_limit && outv_growbuf(1) == -1)
|
||||
return EOF;
|
||||
*outv_current++ = c;
|
||||
return (unsigned char) c;
|
||||
}
|
||||
else
|
||||
if (jni_env) {
|
||||
if (outv_current == outv_limit && outv_growbuf(1) == -1)
|
||||
return EOF;
|
||||
*outv_current++ = c;
|
||||
return (unsigned char) c;
|
||||
}
|
||||
#endif
|
||||
return putchar(c);
|
||||
return putchar(c);
|
||||
}
|
||||
|
||||
/* Write a buffer of data to output. If in a JNI call, then this appends the data to the
|
||||
@ -243,23 +273,22 @@ int cli_putchar(char c)
|
||||
int cli_write(const unsigned char *buf, size_t len)
|
||||
{
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
size_t avail = outv_limit - outv_current;
|
||||
if (avail < len) {
|
||||
memcpy(outv_current, buf, avail);
|
||||
outv_current = outv_limit;
|
||||
if (outv_growbuf(len) == -1)
|
||||
return EOF;
|
||||
len -= avail;
|
||||
buf += avail;
|
||||
}
|
||||
memcpy(outv_current, buf, len);
|
||||
outv_current += len;
|
||||
return 0;
|
||||
if (jni_env) {
|
||||
size_t avail = outv_limit - outv_current;
|
||||
if (avail < len) {
|
||||
memcpy(outv_current, buf, avail);
|
||||
outv_current = outv_limit;
|
||||
if (outv_growbuf(len) == -1)
|
||||
return EOF;
|
||||
len -= avail;
|
||||
buf += avail;
|
||||
}
|
||||
else
|
||||
memcpy(outv_current, buf, len);
|
||||
outv_current += len;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return fwrite(buf, len, 1, stdout);
|
||||
return fwrite(buf, len, 1, stdout);
|
||||
}
|
||||
|
||||
/* Write a null-terminated string to output. If in a JNI call, then this appends the string to the
|
||||
@ -309,6 +338,117 @@ int cli_printf(const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cli_columns(int columns, const char *names[]){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, startResultSet, columns);
|
||||
if ((*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod()");
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
for (i=0;i<columns;i++){
|
||||
jstring str = (jstring)(*jni_env)->NewStringUTF(jni_env, names[i]);
|
||||
if (str == NULL) {
|
||||
jni_exception = 1;
|
||||
WHY("Exception thrown from NewStringUTF()");
|
||||
return;
|
||||
}
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, setColumnName, i, str);
|
||||
(*jni_env)->DeleteLocalRef(jni_env, str);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
cli_printf("%d",columns);
|
||||
cli_delim("\n");
|
||||
int i;
|
||||
for (i=0;i<columns;i++){
|
||||
cli_puts(names[i]);
|
||||
if (i+1==columns)
|
||||
cli_delim("\n");
|
||||
else
|
||||
cli_delim(":");
|
||||
}
|
||||
}
|
||||
|
||||
void cli_field_name(const char *name, const char *delim){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
jstring str = (jstring)(*jni_env)->NewStringUTF(jni_env, name);
|
||||
if (str == NULL) {
|
||||
jni_exception = 1;
|
||||
WHY("Exception thrown from NewStringUTF()");
|
||||
return;
|
||||
}
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, setColumnName, -1, str);
|
||||
(*jni_env)->DeleteLocalRef(jni_env, str);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
cli_puts(name);
|
||||
cli_delim(delim);
|
||||
}
|
||||
|
||||
void cli_put_long(int64_t value, const char *delim){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, putLong, value);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
cli_printf("%lld",value);
|
||||
cli_delim(delim);
|
||||
}
|
||||
|
||||
void cli_put_string(const char *value, const char *delim){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
jstring str = NULL;
|
||||
if (value){
|
||||
str = (jstring)(*jni_env)->NewStringUTF(jni_env, value);
|
||||
if (str == NULL) {
|
||||
jni_exception = 1;
|
||||
WHY("Exception thrown from NewStringUTF()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, putString, str);
|
||||
(*jni_env)->DeleteLocalRef(jni_env, str);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (value)
|
||||
cli_puts(value);
|
||||
cli_delim(delim);
|
||||
}
|
||||
|
||||
void cli_put_hexvalue(const unsigned char *value, int length, const char *delim){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
put_blob((jbyte*)value, length);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (value)
|
||||
cli_puts(alloca_tohex(value, length));
|
||||
cli_delim(delim);
|
||||
}
|
||||
|
||||
void cli_row_count(int rows){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (jni_env) {
|
||||
(*jni_env)->CallVoidMethod(jni_env, jniResults, totalRowCount, rows);
|
||||
if ((*jni_env)->ExceptionOccurred(jni_env)) {
|
||||
jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Delimit the current output field. This closes the current field, so that the next cli_ output
|
||||
function will start appending to a new field. Returns 0 on success, -1 on error. If not in a
|
||||
JNI call, then this simply writes a newline to standard output (or the value of the
|
||||
@ -1397,7 +1537,7 @@ int app_rhizome_list(int argc, const char *const *argv, const struct command_lin
|
||||
return -1;
|
||||
if (rhizome_opendb() == -1)
|
||||
return -1;
|
||||
return rhizome_list_manifests(service, name, sender_sid, recipient_sid, atoi(offset), atoi(limit));
|
||||
return rhizome_list_manifests(service, name, sender_sid, recipient_sid, atoi(offset), atoi(limit), 0);
|
||||
}
|
||||
|
||||
int app_keyring_create(int argc, const char *const *argv, const struct command_line_option *o, void *context)
|
||||
|
@ -310,7 +310,7 @@ long long rhizome_bar_version(unsigned char *bar);
|
||||
unsigned long long rhizome_bar_bidprefix_ll(unsigned char *bar);
|
||||
int rhizome_list_manifests(const char *service, const char *name,
|
||||
const char *sender_sid, const char *recipient_sid,
|
||||
int limit, int offset);
|
||||
int limit, int offset, char count_rows);
|
||||
int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest *m);
|
||||
|
||||
#define RHIZOME_DONTVERIFY 0
|
||||
|
@ -930,11 +930,11 @@ rollback:
|
||||
|
||||
int rhizome_list_manifests(const char *service, const char *name,
|
||||
const char *sender_sid, const char *recipient_sid,
|
||||
int limit, int offset)
|
||||
int limit, int offset, char count_rows)
|
||||
{
|
||||
IN();
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
strbuf_sprintf(b, "SELECT id, manifest, version, inserttime, author FROM manifests WHERE 1=1");
|
||||
strbuf_sprintf(b, "SELECT id, manifest, version, inserttime, author, rowid FROM manifests WHERE 1=1");
|
||||
|
||||
if (service && *service)
|
||||
strbuf_sprintf(b, " AND service = ?1");
|
||||
@ -947,8 +947,6 @@ int rhizome_list_manifests(const char *service, const char *name,
|
||||
|
||||
strbuf_sprintf(b, " ORDER BY inserttime DESC");
|
||||
|
||||
if (limit)
|
||||
strbuf_sprintf(b, " LIMIT %u", limit);
|
||||
if (offset)
|
||||
strbuf_sprintf(b, " OFFSET %u", offset);
|
||||
|
||||
@ -977,24 +975,30 @@ int rhizome_list_manifests(const char *service, const char *name,
|
||||
}
|
||||
|
||||
ret=0;
|
||||
|
||||
size_t rows = 0;
|
||||
cli_puts("12"); cli_delim("\n"); // number of columns
|
||||
cli_puts("service"); cli_delim(":");
|
||||
cli_puts("id"); cli_delim(":");
|
||||
cli_puts("version"); cli_delim(":");
|
||||
cli_puts("date"); cli_delim(":");
|
||||
cli_puts(".inserttime"); cli_delim(":");
|
||||
cli_puts(".author"); cli_delim(":");
|
||||
cli_puts(".fromhere"); cli_delim(":");
|
||||
cli_puts("filesize"); cli_delim(":");
|
||||
cli_puts("filehash"); cli_delim(":");
|
||||
cli_puts("sender"); cli_delim(":");
|
||||
cli_puts("recipient"); cli_delim(":");
|
||||
cli_puts("name"); cli_delim("\n"); // should be last, because name may contain ':'
|
||||
|
||||
const char *names[]={
|
||||
"_id",
|
||||
"service",
|
||||
"id",
|
||||
"version",
|
||||
"date",
|
||||
".inserttime",
|
||||
".author",
|
||||
".fromhere",
|
||||
"filesize",
|
||||
"filehash",
|
||||
"sender",
|
||||
"recipient",
|
||||
"name"
|
||||
};
|
||||
cli_columns(13,names);
|
||||
|
||||
while (sqlite_step_retry(&retry, statement) == SQLITE_ROW) {
|
||||
++rows;
|
||||
if (!( sqlite3_column_count(statement) == 5
|
||||
if (limit>0 && rows>limit)
|
||||
break;
|
||||
if (!( sqlite3_column_count(statement) == 6
|
||||
&& sqlite3_column_type(statement, 0) == SQLITE_TEXT
|
||||
&& sqlite3_column_type(statement, 1) == SQLITE_BLOB
|
||||
&& sqlite3_column_type(statement, 2) == SQLITE_INTEGER
|
||||
@ -1017,6 +1021,8 @@ int rhizome_list_manifests(const char *service, const char *name,
|
||||
long long q_version = sqlite3_column_int64(statement, 2);
|
||||
long long q_inserttime = sqlite3_column_int64(statement, 3);
|
||||
const char *q_author = (const char *) sqlite3_column_text(statement, 4);
|
||||
long long rowid = sqlite3_column_int64(statement, 5);
|
||||
|
||||
if (rhizome_read_manifest_file(m, manifestblob, manifestblobsize) == -1) {
|
||||
WARNF("MANIFESTS row id=%s has invalid manifest blob -- skipped", q_manifestid);
|
||||
} else {
|
||||
@ -1024,6 +1030,7 @@ int rhizome_list_manifests(const char *service, const char *name,
|
||||
if (blob_version != q_version)
|
||||
WARNF("MANIFESTS row id=%s version=%lld does not match manifest blob.version=%lld", q_manifestid, q_version, blob_version);
|
||||
int match = 1;
|
||||
|
||||
const char *blob_service = rhizome_manifest_get(m, "service", NULL, 0);
|
||||
if (service[0] && !(blob_service && strcasecmp(service, blob_service) == 0))
|
||||
match = 0;
|
||||
@ -1037,43 +1044,64 @@ int rhizome_list_manifests(const char *service, const char *name,
|
||||
if (!(blob_recipient && strcasecmp(recipient_sid, blob_recipient) == 0))
|
||||
match = 0;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
const char *blob_name = rhizome_manifest_get(m, "name", NULL, 0);
|
||||
long long blob_date = rhizome_manifest_get_ll(m, "date");
|
||||
const char *blob_filehash = rhizome_manifest_get(m, "filehash", NULL, 0);
|
||||
long long blob_filesize = rhizome_manifest_get_ll(m, "filesize");
|
||||
int from_here = 0;
|
||||
unsigned char senderSid[SID_SIZE];
|
||||
unsigned char recipientSid[SID_SIZE];
|
||||
|
||||
if (blob_sender)
|
||||
stowSid(senderSid, 0, blob_sender);
|
||||
if (blob_recipient)
|
||||
stowSid(recipientSid, 0, blob_recipient);
|
||||
|
||||
if (q_author) {
|
||||
if (config.debug.rhizome) DEBUGF("q_author=%s", alloca_str_toprint(q_author));
|
||||
unsigned char authorSid[SID_SIZE];
|
||||
stowSid(authorSid, 0, q_author);
|
||||
stowSid(m->author, 0, q_author);
|
||||
int cn = 0, in = 0, kp = 0;
|
||||
from_here = keyring_find_sid(keyring, &cn, &in, &kp, authorSid);
|
||||
from_here = keyring_find_sid(keyring, &cn, &in, &kp, m->author);
|
||||
}
|
||||
if (!from_here && blob_sender) {
|
||||
if (config.debug.rhizome) DEBUGF("blob_sender=%s", alloca_str_toprint(blob_sender));
|
||||
unsigned char senderSid[SID_SIZE];
|
||||
stowSid(senderSid, 0, blob_sender);
|
||||
int cn = 0, in = 0, kp = 0;
|
||||
from_here = keyring_find_sid(keyring, &cn, &in, &kp, senderSid);
|
||||
}
|
||||
if (config.debug.rhizome) DEBUGF("manifest payload size = %lld", blob_filesize);
|
||||
cli_puts(blob_service ? blob_service : ""); cli_delim(":");
|
||||
cli_puts(q_manifestid); cli_delim(":");
|
||||
cli_printf("%lld", blob_version); cli_delim(":");
|
||||
cli_printf("%lld", blob_date); cli_delim(":");
|
||||
cli_printf("%lld", q_inserttime); cli_delim(":");
|
||||
cli_puts(q_author ? q_author : ""); cli_delim(":");
|
||||
cli_printf("%d", from_here); cli_delim(":");
|
||||
cli_printf("%lld", blob_filesize); cli_delim(":");
|
||||
cli_puts(blob_filehash ? blob_filehash : ""); cli_delim(":");
|
||||
cli_puts(blob_sender ? blob_sender : ""); cli_delim(":");
|
||||
cli_puts(blob_recipient ? blob_recipient : ""); cli_delim(":");
|
||||
cli_puts(blob_name ? blob_name : ""); cli_delim("\n");
|
||||
|
||||
cli_put_long(rowid, ":");
|
||||
cli_put_string(blob_service, ":");
|
||||
cli_put_hexvalue(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES, ":");
|
||||
cli_put_long(blob_version, ":");
|
||||
cli_put_long(blob_date, ":");
|
||||
cli_put_long(q_inserttime, ":");
|
||||
cli_put_hexvalue(q_author?m->author:NULL, SID_SIZE, ":");
|
||||
cli_put_long(from_here, ":");
|
||||
cli_put_long(m->fileLength, ":");
|
||||
|
||||
unsigned char filehash[SHA512_DIGEST_LENGTH];
|
||||
if (m->fileLength)
|
||||
fromhex(filehash, blob_filehash, SHA512_DIGEST_LENGTH);
|
||||
|
||||
cli_put_hexvalue(m->fileLength?filehash:NULL, SHA512_DIGEST_LENGTH, ":");
|
||||
|
||||
cli_put_hexvalue(blob_sender?senderSid:NULL, SID_SIZE, ":");
|
||||
cli_put_hexvalue(blob_recipient?recipientSid:NULL, SID_SIZE, ":");
|
||||
cli_put_string(blob_name, "\n");
|
||||
}
|
||||
}
|
||||
if (m) rhizome_manifest_free(m);
|
||||
}
|
||||
|
||||
if (ret==0 && count_rows){
|
||||
while (sqlite_step_retry(&retry, statement) == SQLITE_ROW)
|
||||
++rows;
|
||||
}
|
||||
cli_row_count(rows);
|
||||
|
||||
cleanup:
|
||||
sqlite3_finalize(statement);
|
||||
RETURN(ret);
|
||||
|
6
serval.h
6
serval.h
@ -630,6 +630,12 @@ int cli_putchar(char c);
|
||||
int cli_puts(const char *str);
|
||||
int cli_printf(const char *fmt, ...);
|
||||
int cli_delim(const char *opt);
|
||||
void cli_columns(int columns, const char *names[]);
|
||||
void cli_row_count(int rows);
|
||||
void cli_field_name(const char *name, const char *delim);
|
||||
void cli_put_long(int64_t value, const char *delim);
|
||||
void cli_put_string(const char *value, const char *delim);
|
||||
void cli_put_hexvalue(const unsigned char *value, int length, const char *delim);
|
||||
|
||||
int overlay_mdp_getmyaddr(int index,unsigned char *sid);
|
||||
int overlay_mdp_bind(unsigned char *localaddr,int port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user