void *incoming_connection(void *arg) { char readline[MAXLINE]; struct thread_argument *ta = (struct thread_argument *)arg; struct context *context = context_new(true, true); context->find = ta->find; for (;;) { bzero(readline, sizeof(readline)); int n; if (((n = CyaSSL_read(ta->ssl, readline, MAXLINE)) <= 0)) { fprintf(stderr, "client closed connection\n"); goto free_ssl; } fprintf(stderr, "%d bytes received: %s\n", n, readline); struct byte_array *raw_message = byte_array_new_size(n); raw_message->data = (uint8_t*)readline; int32_t raw_message_length = serial_decode_int(raw_message); assert_message(raw_message_length < MAXLINE, "todo: handle long messages"); struct variable *message = variable_deserialize(context, raw_message); struct variable *listener = (struct variable *)map_get(server_listeners, (void*)(VOID_INT)ta->fd); vm_call(context, listener, message); } free_ssl: CyaSSL_free(ta->ssl); // Free CYASSL object free(ta); context_del(context); return NULL; }
void repl() { char str[FG_MAX_INPUT]; struct context *context = context_new(NULL, true, true); for (;;) { fflush(stdin); str[0] = 0; printf("f> "); if (!fgets(str, FG_MAX_INPUT, stdin)) { if (feof(stdin)) return; if (ferror(stdin)) { printf("unknown error reading stdin\n"); return; } } struct byte_array *input = byte_array_from_string(str); struct byte_array *program = build_string(input, NULL); if (!setjmp(trying)) run(context, program, NULL, true); byte_array_del(input); byte_array_del(program); } context_del(context); }
void seq_save (struct msgs *mp) { size_t i; char flags, *cp, attr[BUFSIZ], seqfile[PATH_MAX]; FILE *fp; sigset_t set, oset; /* check if sequence information has changed */ if (!(mp->msgflags & SEQMOD)) { if (mp->seqhandle) { lkfclosedata (mp->seqhandle, mp->seqname); mp->seqhandle = NULL; free(mp->seqname); mp->seqname = NULL; } return; } mp->msgflags &= ~SEQMOD; fp = NULL; flags = mp->msgflags; /* record folder flags */ /* * If no mh-sequences file is defined, or if a mh-sequences file * is defined but empty (*mh_seq == '\0'), then pretend folder * is readonly. This will force all sequences to be private. */ if (mh_seq == NULL || *mh_seq == '\0') set_readonly (mp); else snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq); for (i = 0; i < svector_size (mp->msgattrs); i++) { snprintf (attr, sizeof(attr), "atr-%s-%s", svector_at (mp->msgattrs, i), mp->foldpath); /* get space separated list of sequence ranges */ if (!(cp = seq_list(mp, svector_at (mp->msgattrs, i)))) { context_del (attr); /* delete sequence from context */ continue; } if (is_readonly(mp) || is_seq_private(mp, i)) { priv: /* * sequence is private */ context_replace (attr, cp); /* update sequence in context */ } else { /* * sequence is public */ context_del (attr); /* delete sequence from context */ if (!fp) { /* * Attempt to open file for public sequences. * If that fails (probably because folder is * readonly), then make sequence private. */ if (mp->seqhandle) { fp = mp->seqhandle; mp->seqhandle = NULL; free(mp->seqname); mp->seqname = NULL; rewind(fp); ftruncate(fileno(fp), 0); } else if ((fp = lkfopendata (seqfile, "w")) == NULL && (m_unlink (seqfile) == -1 || (fp = lkfopendata (seqfile, "w")) == NULL)) { admonish (attr, "unable to write"); goto priv; } /* block a few signals */ sigemptyset (&set); sigaddset(&set, SIGHUP); sigaddset(&set, SIGINT); sigaddset(&set, SIGQUIT); sigaddset(&set, SIGTERM); sigprocmask (SIG_BLOCK, &set, &oset); } fprintf (fp, "%s: %s\n", svector_at (mp->msgattrs, i), cp); } } if (fp) { lkfclosedata (fp, seqfile); sigprocmask (SIG_SETMASK, &oset, &set); /* reset signal mask */ } else { /* * If folder is not readonly, and we didn't save any * public sequences, then remove that file. */ if (!is_readonly(mp)) (void) m_unlink (seqfile); } /* * Reset folder flag, since we may be * pretending that folder is readonly. */ mp->msgflags = flags; }