From 5a0596bd82e5511e1f34a00b08d8b923dbc5590a Mon Sep 17 00:00:00 2001 From: "psyc://loupsycedyglgamf.onion/~lynX" Date: Tue, 16 Feb 2016 07:07:25 +0000 Subject: [PATCH] stub for a gnunet package --- src/Makefile.in | 4 +- src/main.c | 6 + src/pkg-gnunet.c | 654 +++++++++++++++++++++++++++++++++++++++++++++++ src/pkg-gnunet.h | 36 +++ src/simul_efun.c | 4 +- src/version.sh | 2 +- src/xalloc.c | 6 +- 7 files changed, 704 insertions(+), 8 deletions(-) create mode 100644 src/pkg-gnunet.c create mode 100644 src/pkg-gnunet.h diff --git a/src/Makefile.in b/src/Makefile.in index 8912017..26bf895 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -107,7 +107,7 @@ SRC = access_check.c actions.c array.c backend.c bitstrings.c call_out.c \ otable.c\ parser.c parse.c pkg-alists.c pgk-iksemel.c pkg-idna.c pkg-expat.c \ pkg-psyc.c pkg-mccp.c pkg-mysql.c pkg-pcre.c \ - pkg-pgsql.c pkg-sqlite.c pkg-tls.c \ + pkg-pgsql.c pkg-sqlite.c pkg-tls.c pkg-gnunet.c \ ptmalloc.c port.c ptrtable.c \ random.c regexp.c sha1.c simulate.c simul_efun.c stdstrings.c \ strfuns.c structs.c sprintf.c swap.c wiz_list.c xalloc.c pkg-expat.c @@ -119,7 +119,7 @@ OBJ = access_check.o actions.o array.o backend.o bitstrings.o call_out.o \ otable.o \ parser.o parse.o pkg-alists.o pkg-iksemel.o pkg-idna.o pkg-expat.o \ pkg-psyc.o pkg-mccp.o pkg-mysql.o pkg-pcre.o \ - pkg-pgsql.o pkg-sqlite.o pkg-tls.o \ + pkg-pgsql.o pkg-sqlite.o pkg-tls.o pkg-gnunet.o \ ptmalloc.o port.o ptrtable.o \ random.o regexp.o sha1.o simulate.o simul_efun.o stdstrings.o \ strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@ diff --git a/src/main.c b/src/main.c index 88c4118..15f08e3 100644 --- a/src/main.c +++ b/src/main.c @@ -440,6 +440,9 @@ main (int argc, char **argv) #ifdef USE_TLS tls_global_init(); #endif +#ifdef USE_GNUNET + gnunet_global_init(); +#endif if (numports < 1) /* then use the default port */ numports = 1; @@ -658,6 +661,9 @@ main (int argc, char **argv) #ifdef USE_TLS tls_global_deinit(); #endif +#ifdef USE_GNUNET + gnunet_global_deinit(); +#endif return rc; /* TODO: There are constants for this */ } /* main() */ diff --git a/src/pkg-gnunet.c b/src/pkg-gnunet.c new file mode 100644 index 0000000..e6056ae --- /dev/null +++ b/src/pkg-gnunet.c @@ -0,0 +1,654 @@ +/*------------------------------------------------------------------ + * GNUnet module currently implements virtual circuits over CADET. + * Would be useful to also have services higher in the stack. + * + * --lynX 2016 + * + * Actually no, this file is just an initial stub. + * + * Suspended: exploring how to get the peer's id. + *------------------------------------------------------------------ + */ +#ifdef USE_GNUNET +#ifdef HAS_GNUNET + +# include "driver.h" +# include "machine.h" +# define DEBUG 1 + +# include + +# include "pkg-gnunet.h" +# include + +/*---------------------------------------------------------------*/ +/* Variables */ + +static Bool cadet_available = MY_FALSE; + /* Set to TRUE when GNUnet's CADET service is available. */ + +static struct GNUNET_CADET_Handle *mh; +static struct GNUNET_CADET_Channel *ch; +static struct GNUNET_CADET_TransmitHandle *th; +static struct GNUNET_SCHEDULER_Task *sd; +static struct GNUNET_SCHEDULER_Task *job; + +/*---------------------------------------------------------------*/ +/* Local Functions */ + +static int +data_callback (void *cls, + struct GNUNET_CADET_Channel *channel, + void **channel_ctx, + const struct GNUNET_MessageHeader *message) { + GNUNET_CADET_receive_done (channel); + if (th) { + // ouch + } + th = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, + GNUNET_TIME_UNIT_FOREVER_REL, + sizeof (struct GNUNET_MessageHeader), + &data_ready, NULL); + return GNUNET_OK; +} + + +/*---------------------------------------------------------------*/ +/* External Functions */ + +void gnunet_global_init (int listen_port) { + static const struct GNUNET_CADET_MessageHandler handlers[] = { + /* we may want to define our own message types but + * using CADET_CLI has the advantage of allowing to + * debug using the gnunet-cadet CLI tool + */ + {&data_callback, GNUNET_MESSAGE_TYPE_CADET_CLI, 0}, + {NULL, 0, 0} + }; + +// GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET service\n"); + debug_message("%s Connecting to CADET service\n", time_stamp()); + mh = GNUNET_CADET_connect (cfg, + NULL, /* cls */ + &channel_ended, /* cleaner */ + handlers); + if (NULL == mh) + GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + else + sd = GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); + + debug_message("%s Opening CADET listen port\n", time_stamp()); + GNUNET_CADET_open_port (mh, GC_u2h (listen_port), + &channel_incoming, NULL); +} /* gnunet_global_init() */ + + +void gnunet_global_deinit (void) { + cadet_available = MY_FALSE; +} + + +#if 0 + +/*---------------------------------------------------------------*/ +int +cadet_read (interactive_t *ip, char *buffer, int length) + +/* Read up to bytes data for the TLS connection of + * and store it in . + * Return then number of bytes read, or a negative number if an error + * occured. + */ + +{ + int ret = -11; + +#ifdef HAS_OPENSSL + int err; + + do { + ret = SSL_read(ip->tls_session, buffer, length); + } while (ret < 0 && (err = SSL_get_error(ip->tls_session, ret)) + && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)); + + if (ret == 0) + { + cadet_deinit_connection(ip); + } + else if (ret < 0) + { + ret = SSL_get_error(ip->tls_session, ret); + debug_message("%s TLS: Received corrupted data (%d, errno %d). " + "Closing the connection.\n" + , time_stamp(), ret, errno); + switch (ret) { + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + ERR_print_errors_fp(stderr); + break; + default: + break; + } + ip->tls_status = TLS_BROKEN; + cadet_deinit_connection(ip); + } + +#elif defined(HAS_GNUTLS) + do { + ret = gnutls_record_recv(ip->tls_session, buffer, length); + } while ( ret < 0 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) ); + + if (ret == 0) + { + tls_deinit_connection(ip); + } + else if (ret < 0) + { + debug_message("%s GnuTLS: Error in receiving data (%s). " + "Closing the connection.\n" + , time_stamp(), gnutls_strerror(ret)); + tls_deinit_connection(ip); + } +#endif /* SSL Package */ + + return (ret < 0 ? -1 : ret); +} /* tls_read() */ + +/*---------------------------------------------------------------*/ +int +cadet_write (interactive_t *ip, char *buffer, int length) + +/* Write bytes from to the TLS connection of + * Return the number of bytes written, or a negative number if an error + * occured. + */ + +{ + int ret = -1; + +#ifdef HAS_OPENSSL + + int err; + + do { + ret = SSL_write(ip->tls_session, buffer, length); + } while (ret < 0 && (err = SSL_get_error(ip->tls_session, ret)) + && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)); + + if (ret == 0) + { + tls_deinit_connection(ip); + } + else if (ret < 0) + { + ret = SSL_get_error(ip->tls_session, ret); + debug_message("%s TLS: Sending data failed (%d). " + "Closing the connection.\n" + , time_stamp(), ret); + tls_deinit_connection(ip); + } + +#elif defined(HAS_GNUTLS) + + ret = gnutls_record_send( ip->tls_session, buffer, length ); + if (ret < 0) + { + debug_message("%s GnuTLS: Error in sending data (%s). " + "Closing the connection.\n" + , time_stamp(), gnutls_strerror(ret)); + tls_deinit_connection(ip); + } +#endif /* SSL Package */ + + return (ret<0 ? -1 : ret); +} /* tls_write() */ + +/*---------------------------------------------------------------*/ +/* To protect the tls callback during it's execution, it is pushed onto + * the stack as an T_ERROR_HANDLER value for guaranteed cleanup. + */ + +typedef struct tls_cb_handler_s +{ + svalue_t val; + callback_t * cb; +} tls_cb_handler_t; + +/*---------------------------------------------------------------*/ +static void +handle_tls_cb_error (svalue_t * arg) + +{ + tls_cb_handler_t * data = (tls_cb_handler_t *)arg; + free_callback(data->cb); + xfree(data->cb); + xfree(arg); +} /* handle_tls_cb_error() */ + +/*---------------------------------------------------------------*/ +svalue_t * +v_cadet_init_connection (svalue_t *sp, int num_arg) + +/* EFUN cadet_init_connection() + * + * int cadet_init_connection(object ob) + * int cadet_init_connection(object ob, string fun, string|object fob, mixed extra...) + * int cadet_init_connection(object ob, closure fun, mixed extra...) + * + * cadet_init_connection() tries to start a TLS secured connection to the + * interactive object (or this_object() if is not given). + * Result: + * errorcode < 0: unsuccessful, use cadet_error() to get an useful + * description of the error + * number > 0: the secure connection is still being set up in the + * background + * number == 0: the secure connection is active. + * + * If the callback /: is specified, it will be called once + * the fate of the secure connection has been determined. The first argument + * will be the return code from the handshake (errorcode < 0 on failure, + * or 0 on success), followed by the interactive object and any + * arguments. + */ + +{ + svalue_t * argp = sp - num_arg + 1; + long ret; + object_t * obj; + interactive_t *ip; + + if (!cadet_available) + errorf("cadet_init_connection(): TLS layer hasn't been initialized.\n"); + + if (num_arg > 0) + { + obj = argp->u.ob; + put_number(argp, 0); /* remove obj reference from the stack */ + } + else + { + obj = ref_object(current_object, "cadet_init_connection"); + } + + if (!O_SET_INTERACTIVE(ip, obj)) + { + free_object(obj, "cadet_init_connection"); + errorf("Bad arg 1 to cadet_init_connection(): " + "object not interactive.\n"); + } + + free_object(obj, "cadet_init_connection"); + /* ip has another reference to obj, so this is safe to do */ + + if (ip->cadet_status != TLS_INACTIVE) + errorf("cadet_init_connection(): Interactive already has a secure " + "connection.\n"); + + /* Extract the callback information from the stack */ + if (num_arg > 1) + { + /* Extract the callback information from the stack */ + int error_index; + callback_t * cb; + + inter_sp = sp; + + memsafe(cb = xalloc(sizeof *cb) , sizeof *cb , "callback structure"); + + assign_eval_cost(); + + error_index = setup_efun_callback(cb, argp+1, num_arg-1); + + if (error_index >= 0) + { + /* The callback values have already been removed. */ + + xfree(cb); + inter_sp = sp = argp; + vefun_bad_arg(error_index+2, argp); + /* NOTREACHED */ + return argp; + } + + /* Callback creation successful */ + ip->cadet_cb = cb; + + inter_sp = sp = argp; + } + + /* Flush the connection */ + + { + object_t * save_c_g = command_giver; + command_giver = obj; + add_message(message_flush); + command_giver = save_c_g; + } + + ret = 0; + + do { + +#ifdef HAS_OPENSSL + + SSL * session = SSL_new(context); + + if (session == NULL) + { + ret = - ERR_get_error(); + break; + } + + if (!SSL_set_fd(session, ip->socket)) + { + SSL_free(session); + ret = - ERR_get_error(); + break; + } + if (ip->outgoing_conn) + { +#if 1 + /* circumvent a bug in google talk or java ssl + * see also http://twistedmatrix.com/trac/changeset/25471 + */ + SSL_set_options(session, SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET); +#endif + /* simply using the contexts default would send old + * handshakes not containing new features like compression + */ + if (SSL_set_ssl_method(session, TLSv1_client_method()) != 1) { + ret = - ERR_get_error(); + break; + } + SSL_set_connect_state(session); + } + else + { + SSL_set_accept_state(session); + /* request a client certificate */ + if (ip->tls_want_peer_cert) { + SSL_set_verify( session, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE + , tls_verify_callback); + } else { + SSL_set_verify( session, SSL_VERIFY_NONE + , tls_verify_callback); + } + } + ip->tls_session = session; + +#elif defined(HAS_GNUTLS) + + initialize_tls_session(&ip->tls_session); + gnutls_transport_set_ptr(ip->tls_session, (gnutls_transport_ptr)(ip->socket)); + +#endif /* SSL Package */ + + ip->tls_status = TLS_HANDSHAKING; + ret = tls_continue_handshake(ip); + + /* Adjust the return value of tls_continue_handshake() */ + if (ret == 1) + ret = 0; + else if (ret == 0) + ret = 1; + + } while(0); + + put_number(sp, ret); + return sp; +} /* f_cadet_init_connection() */ + +/*---------------------------------------------------------------*/ +void +cadet_deinit_connection (interactive_t *ip) + +/* Close the TLS connection for the interactive if there is one. + */ + +{ +#ifdef HAS_OPENSSL + if (ip->tls_status != TLS_INACTIVE) { + /* when an SSL_ERROR_SYSCALL is produced, calling + * SSL_shutdown may lead to a crash. SSL_set_shutdown + * seems to be safer. --lynX + * + * update july: worse than that, SSL_shutdown has crashed + * on me even when SSL_read returned an innocent '0'. + * let's try SSL_set_shutdown by default. probably we + * don't need that TLS_BROKEN flag after all. + */ +/* if (ip->tls_status == TLS_BROKEN) { */ + SSL_set_shutdown(ip->tls_session, + SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); +/* } else { + SSL_shutdown(ip->tls_session); + } */ + SSL_free(ip->tls_session); + ip->tls_session = NULL; + } +#elif defined(HAS_GNUTLS) + if (ip->tls_status != TLS_INACTIVE) { + gnutls_bye( ip->tls_session, GNUTLS_SHUT_WR); + gnutls_deinit(ip->tls_session); + ip->tls_session = NULL; + } +#endif /* SSL Package */ + if (ip->tls_cb != NULL) { + free_callback(ip->tls_cb); + xfree(ip->tls_cb); + ip->tls_cb = NULL; + } + ip->tls_status = TLS_INACTIVE; +} /* tls_deinit_connection() */ + +/*---------------------------------------------------------------*/ +svalue_t * +f_cadet_deinit_connection(svalue_t *sp) + +/* EFUN cadet_deinit_connection() + * + * void cadet_deinit_connection(object ob) + * + * cadet_deinit_connection() shuts down a TLS connection to the interactive + * object (or this_object() if is not given) but the connection is + * not closed. + */ + +{ + interactive_t *ip; + + if (!O_SET_INTERACTIVE(ip, sp->u.ob)) + errorf("Bad arg 1 to cadet_deinit_connection(): " + "object not interactive.\n"); + + /* Flush the connection */ + + { + object_t * save_c_g = command_giver; + command_giver = sp->u.ob; + add_message(message_flush); + command_giver = save_c_g; + } + + cadet_deinit_connection(ip); + + free_svalue(sp--); + return sp; +} /* f_cadet_deinit_connection() */ + +/*---------------------------------------------------------------*/ +svalue_t * +f_cadet_error(svalue_t *sp) + +/* EFUN tls_error() + * + * string tls_error(int errorno) + * + * tls_error() returns a string describing the error behind the + * error number . + */ + +{ + string_t *s; + const char *text; + int err = sp->u.number; + +#ifdef HAS_PSYC + if (err == ERR_TLS_NOT_DETECTED) text = "Unencrypted connection detected"; + else +#endif + { +#ifdef HAS_OPENSSL + text = ERR_error_string(-err, NULL); +#elif defined(HAS_GNUTLS) + text = gnutls_strerror(err); +#endif /* SSL Package */ + } + + if (text) + { + memsafe(s = new_mstring(text), strlen(text), "tls_error()"); + free_svalue(sp); + put_string(sp, s); + } + else + { + free_svalue(sp); + put_number(sp, 0); + } + + return sp; +} /* f_tls_error() */ + +/*---------------------------------------------------------------*/ +svalue_t * +f_cadet_query_connection_state (svalue_t *sp) + +/* EFUN cadet_query_connection_state() + * + * int cadet_query_connection_state(object ob) + * + * cadet_query_connection_state() returns a positive number if 's connection + * is TLS secured, 0 if it's unsecured, and a negative number if the + * TLS connection setup is still being set-up. + * Returns 0 for non-interactive objects. + */ + +{ + interactive_t *ip; + Bool rc; + + if (!O_SET_INTERACTIVE(ip, sp->u.ob)) + rc = 0; + else if (ip->tls_status == TLS_HANDSHAKING) + rc = -1; + else if (ip->tls_status == TLS_INACTIVE) + rc = 0; + else + rc = 1; + free_svalue(sp); + put_number(sp, rc); + return sp; +} /* f_tls_query_connection_state() */ + +/*---------------------------------------------------------------*/ +svalue_t * +f_cadet_query_connection_info (svalue_t *sp) + +/* EFUN cadet_query_connection_info() + * + * + * #include + * int *cadet_query_connection_info (object ob) + * + * If does not have a TLS connection, or if the TLS connection is + * still being set up, the efun returns 0. + * + * If has a TLS connection, cadet_query_connection_info() returns an array + * that contains some parameters of 's connection: + * + * int|string [TLS_CIPHER]: the cipher used + * int [TLS_COMP]: the compression used + * int [TLS_KX]: the key-exchange used + * int [TLS_MAC]: the digest algorithm used + * int|string [TLS_PROT]: the protocol used + * string [TLS_SESSION]: the session id + * + * To translate these numbers into strings, offers a number of macros: + * + * TLS_xxx_TABLE: a literal array of strings describing the value in + * question. + * TLS_xxx_NAME(x): a macro translating the numeric result value into a + * string. + * + * xxx: CIPHER, COMP, KX, MAC, PROT + */ + +{ + interactive_t *ip; + + if (O_SET_INTERACTIVE(ip, sp->u.ob) && ip->tls_status == TLS_ACTIVE) + { + vector_t * rc; + rc = allocate_array(TLS_INFO_MAX); +#ifdef HAS_OPENSSL + put_c_string(&(rc->item[TLS_CIPHER]) + , SSL_get_cipher(ip->tls_session)); + put_number(&(rc->item[TLS_COMP]), ip->tls_session->session->compress_meth); + put_number(&(rc->item[TLS_KX]), 0); + put_number(&(rc->item[TLS_MAC]), 0); + put_c_string(&(rc->item[TLS_PROT]) + , SSL_get_version(ip->tls_session)); + /* warning: this session id is binary .. maybe fix it someday */ + put_c_n_string(&(rc->item[TLS_SESSION]) + , (char*) ip->tls_session->session->session_id, ip->tls_session->session->session_id_length); +#elif defined(HAS_GNUTLS) + put_number(&(rc->item[TLS_CIPHER]) + , gnutls_cipher_get(ip->tls_session)); + put_number(&(rc->item[TLS_COMP]) + , gnutls_compression_get(ip->tls_session)); + put_number(&(rc->item[TLS_KX]) + , gnutls_kx_get(ip->tls_session)); + put_number(&(rc->item[TLS_MAC]) + , gnutls_mac_get(ip->tls_session)); + put_number(&(rc->item[TLS_PROT]) + , gnutls_protocol_get_version(ip->tls_session)); + put_c_string(&(rc->item[TLS_SESSION]) + , ""); +#endif /* SSL Package */ + free_svalue(sp); + put_array(sp, rc); + } + else + { + free_svalue(sp); + put_number(sp, 0); + } + + return sp; +} /* cadet_query_connection_info() */ + +/*---------------------------------------------------------------*/ +svalue_t * +f_cadet_available (svalue_t *sp) + +/* EFUN cadet_available() + * + * int cadet_available () + * + * If the global TLS Initialisation could not been set up, cadet_available() + * returns 0, otherwise 1. + */ + +{ + sp++; + put_number(sp, cadet_available == MY_TRUE ? 1 : 0); + return sp; +} /* f_cadet_available() */ + +#endif // 0 + +/*---------------------------------------------------------------*/ +#endif /* HAS_GNUNET */ +#endif /* USE_GNUNET */ + diff --git a/src/pkg-gnunet.h b/src/pkg-gnunet.h new file mode 100644 index 0000000..d466093 --- /dev/null +++ b/src/pkg-gnunet.h @@ -0,0 +1,36 @@ +#ifndef PKG_GNUNET_H__ +#define PKG_GNUNET_H__ 1 + +#include "driver.h" + +#ifdef USE_GNUNET +# ifdef HAS_GNUNET + +#include + +#include "typedefs.h" + +/* --- Types --- */ + +/* --- Macros --- */ + +/* --- Variables --- */ + +/* --- Prototypes --- */ + +extern void gnunet_global_init(void); +extern void gnunet_global_deinit(void); + +extern int cadet_read(interactive_t *ip, char *buffer, int length); +extern int cadet_write(interactive_t *ip, char *buffer, int length); +extern void cadet_deinit_connection (interactive_t *ip); + +/* --- Efun Prototypes --- */ + +extern svalue_t *v_cadet_init_connection(svalue_t *sp, int num_arg); +extern svalue_t *f_cadet_deinit_connection(svalue_t *sp); + +# endif /* HAS_GNUNET */ +# endif /* USE_GNUNET */ +#endif /* PKG_GNUNET_H__ */ + diff --git a/src/simul_efun.c b/src/simul_efun.c index 1961807..c8df7ed 100644 --- a/src/simul_efun.c +++ b/src/simul_efun.c @@ -347,13 +347,13 @@ assert_simul_efun_object (void) string_t *function_name; ident_t *p; vartype_t type; - unsigned char num_arg, num_locals; + unsigned char num_arg; //num_locals; memcpy( &function_name, FUNCTION_NAMEP(funstart) , sizeof function_name); memcpy(&type, FUNCTION_TYPEP(funstart), sizeof(type)); num_arg = FUNCTION_NUM_ARGS(funstart) & 0x7f; - num_locals = FUNCTION_NUM_VARS(funstart); + //num_locals = FUNCTION_NUM_VARS(funstart); /* Find or make the identifier for the function */ p = make_shared_identifier(get_txt(function_name), I_TYPE_GLOBAL, 0); diff --git a/src/version.sh b/src/version.sh index 34552a7..b6c667f 100644 --- a/src/version.sh +++ b/src/version.sh @@ -17,7 +17,7 @@ version_longtype="stable" # A timestamp, to be used by bumpversion and other scripts. # It can be used, for example, to 'touch' this file on every build, thus # forcing revision control systems to add it on every checkin automatically. -version_stamp="Wed Jan 28 16:33:10 CET 2015" +version_stamp="Mon Aug 8 19:43:32 CEST 2016" # Okay, LDMUD is using 3.x.x so to avoid conflicts let's just use 4.x.x version_major=4 diff --git a/src/xalloc.c b/src/xalloc.c index 686aa9d..5fb4dc4 100644 --- a/src/xalloc.c +++ b/src/xalloc.c @@ -1627,7 +1627,7 @@ reallocate_reserved_areas (void) } else { p = "Reallocated System reserve.\n"; - write(1, p, strlen(p)); + write(1, p, strlen(p)); } } if (reserved_master_size && !reserved_master_area) { @@ -1637,7 +1637,7 @@ reallocate_reserved_areas (void) } else { p = "Reallocated Master reserve.\n"; - write(1, p, strlen(p)); + write(1, p, strlen(p)); } } if (reserved_user_size && !reserved_user_area) { @@ -1647,7 +1647,7 @@ reallocate_reserved_areas (void) } else { p = "Reallocated User reserve.\n"; - write(1, p, strlen(p)); + write(1, p, strlen(p)); } } slow_shut_down_to_do = 0;