Пример #1
0
static void text_insert_help(struct menu *menu)
{
	GtkTextBuffer *buffer;
	GtkTextIter start, end;
	const char *prompt = _(menu_get_prompt(menu));
	struct gstr help = str_new();

	menu_get_ext_help(menu, &help);

	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
	gtk_text_buffer_get_bounds(buffer, &start, &end);
	gtk_text_buffer_delete(buffer, &start, &end);
	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);

	gtk_text_buffer_get_end_iter(buffer, &end);
	gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
					 NULL);
	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
	gtk_text_buffer_get_end_iter(buffer, &end);
	gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
					 NULL);
	str_free(&help);
}
Пример #2
0
void
notify_script_err_msg (enum err_contest idxc, int fline, int lline,
                       const char * msg, ...)
{
    struct msg_cell *cell = emalloc (sizeof(struct msg_cell));
    str_t tail;
    va_list ap;

    str_init_from_c (cell->msg, contest_id[idxc]);

    va_start (ap, msg);
    str_init (tail, 64);
    str_vprintf (tail, msg, 0, ap);
    str_append (cell->msg, tail, ' ');
    str_free (tail);
    va_end (ap);

    cell->line = emalloc(sizeof(struct line_info));
    cell->line->first = fline;
    cell->line->last  = lline;
    cell->next = top;
    top = cell;
}
Пример #3
0
void
str_replace_text(struct mystr* p_str, const char* p_from, const char* p_to)
{
  static struct mystr s_lhs_chunk_str;
  static struct mystr s_rhs_chunk_str;
  unsigned int lhs_len;
  str_copy(&s_lhs_chunk_str, p_str);
  str_free(p_str);
  do
  {
    lhs_len = str_getlen(&s_lhs_chunk_str);
    str_split_text(&s_lhs_chunk_str, &s_rhs_chunk_str, p_from);
    /* Copy lhs to destination */
    str_append_str(p_str, &s_lhs_chunk_str);
    /* If this was a 'hit', append the 'to' text */
    if (str_getlen(&s_lhs_chunk_str) < lhs_len)
    {
      str_append_text(p_str, p_to);
    }
    /* Current rhs becomes new lhs */
    str_copy(&s_lhs_chunk_str, &s_rhs_chunk_str);
  } while (!str_isempty(&s_lhs_chunk_str));
}
Пример #4
0
/*            <MedlineDate>2003 Jan-Feb</MedlineDate> */
static int
medin_medlinedate( fields *info, char *p, int level )
{
	int fstatus;
	str tmp;

	str_init( &tmp );

	p = str_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );
	if ( str_memerr( &tmp ) ) return BIBL_ERR_MEMERR;

	if ( str_has_value( &tmp ) ) {
		fstatus = fields_add( info, "PARTDATE:YEAR", str_cstr( &tmp ), level );
		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
	}

	p = str_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );
	if ( str_memerr( &tmp ) ) return BIBL_ERR_MEMERR;

	if ( str_has_value( &tmp ) ) {
		str_findreplace( &tmp, "-", "/" );
		fstatus = fields_add( info, "PARTDATE:MONTH", str_cstr( &tmp ), level );
		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
	}

	(void) str_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );
	if ( str_memerr( &tmp ) ) return BIBL_ERR_MEMERR;

	if ( str_has_value( &tmp ) ) {
		fstatus = fields_add( info, "PARTDATE:DAY", str_cstr( &tmp ), level );
		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
	}

	str_free( &tmp );

	return BIBL_OK;
}
Пример #5
0
static int
mtime_interpret(string_list_ty *result, const string_list_ty *args,
    const struct expr_position_ty *pp, const struct opcode_context_ty *ocp)
{
    size_t          j;

    trace(("mtime\n"));
    (void)pp;
    assert(result);
    assert(args);
    assert(args->nstrings);
    for (j = 1; j < args->nstrings; j++)
    {
        time_t          mtime;
        long            depth;

        depth = 32767;
        mtime = cook_mtime_newest(ocp, args->string[j], &depth, depth);
        if (mtime < 0)
            return -1;
        if (mtime == 0)
            string_list_append(result, str_false);
        else
        {
            struct tm       *tm;
            char            buffer[1000];
            string_ty       *s;

            tm = localtime(&mtime);
            strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", tm);
            s = str_from_c(buffer);
            string_list_append(result, s);
            str_free(s);
        }
    }
    return 0;
}
Пример #6
0
void add_common_resource(resp r)
{
    char outTemp[256];
    strp outType;
    NAMEINFO_NODE   *new_nameinfo;

    if (!r || !r->b || !r->b->buffer)
        return; /* Refuse to add a resource without data */

    ALLOC(new_nameinfo, NAMEINFO_NODE);
    new_nameinfo->next = NULL;
    new_nameinfo->data.rcslength = r->b->len;
    new_nameinfo->data.rcsdata = (LPBYTE)buff_ind(r->b);
    r->b = NULL;
    new_nameinfo->data.rcsflags = r->flags;
    if (!HIWORD(r->name))
    {
        if (LOWORD(r->name) > 0x7fff)
            FATAL(("Resource identifier %d is too large", (int)(LOWORD(r->name))));
        new_nameinfo->data.rcsitemname = (char *)(LOWORD(r->name) | (r->type == RT_STRING ? 0x0000 : 0x8000));
    }
    else
        new_nameinfo->data.rcsitemname = (char *)(r->name);
    if (HIWORD(r->type))
        new_nameinfo->data.wType = (WORD)(RT_USER_DEF);
    else
        new_nameinfo->data.wType = LOWORD(r->type);
    incr_res_count((char *)r->type, new_nameinfo);
    if (!HIWORD(r->name))
        sprintf(outTemp, "%d", (int)r->name);
    else
        sprintf(outTemp, "%s", r->name);
    outType = resource_type_name(r->type);
    VPRINT(("Added resource: %s %s", outType, outTemp));
    str_free(outType);
    res_free(r);
}
Пример #7
0
void ben_free_r(BEN * node)
{
	ITEM *item = NULL;

	if (node == NULL) {
		return;
	}

	switch (node->t) {
	case BEN_DICT:
		if (node->v.d != NULL) {
			item = list_start(node->v.d);
			while (item != NULL) {
				item = ben_free_item(node, item);
			}

			list_free(node->v.d);
		}
		break;

	case BEN_LIST:
		if (node->v.l != NULL) {
			item = list_start(node->v.l);
			while (item != NULL) {
				item = ben_free_item(node, item);
			}

			list_free(node->v.l);
		}
		break;
	case BEN_STR:
		if (node->v.s != NULL) {
			str_free(node->v.s);
		}
		break;
	}
}
Пример #8
0
void
multi_fit_engine_print_fit_results(struct multi_fit_engine *fit,
                                   str_t text)
{
    str_t pname;
    size_t k, j, kp;

    str_set_null(text);

    str_init(pname, 16);

    for(j = 0, kp = 0; j < fit->common_parameters->number; j++, kp++) {
        fit_param_t *fp = fit->common_parameters->values + j;
        get_param_name(fp, pname);
        str_printf_add(text, "COMMON    / %9s : %.6g\n", CSTR(pname),
                       gsl_vector_get(fit->results, j));
    }


    for(k = 0; k < fit->samples_number; k++) {
        for(j = 0; j < fit->private_parameters->number; j++, kp++) {
            fit_param_t *fp = fit->private_parameters->values + j;
            get_param_name(fp, pname);
            str_printf_add(text, "SAMPLE(%02i)/ %9s : %.6g\n", k, CSTR(pname),
                           gsl_vector_get(fit->results, kp));
        }
    }

    str_append_c(text, "Residual Chi Square by sample:\n", '\n');
    for(k = 0; k < fit->samples_number; k++) {
        double chisq = gsl_vector_get(fit->chisq, k);
        str_printf_add(text, "ChiSq(%02i): %g\n", k, chisq);
    }

    str_free(pname);
}
Пример #9
0
NOEXPORT void win_log(LPCTSTR txt) {
    struct LIST *curr;
    size_t txt_len;
    static size_t log_len=0;

    txt_len=_tcslen(txt);
    curr=str_alloc(sizeof(struct LIST)+txt_len*sizeof(TCHAR));
    curr->len=txt_len;
    _tcscpy(curr->txt, txt);
    curr->next=NULL;
    if(tail)
        tail->next=curr;
    tail=curr;
    if(!head)
        head=tail;
    log_len++;
    while(log_len>LOG_LINES) {
        curr=head;
        head=head->next;
        str_free(curr);
        log_len--;
    }
    new_logs=1;
}
Пример #10
0
static int
prepost_interpret(string_list_ty *result, const string_list_ty *args,
    const expr_position_ty *pp, const struct opcode_context_ty *ocp)
{
    size_t          j;

    trace(("prepost\n"));
    (void)ocp;
    assert(result);
    assert(args);
    assert(args->nstrings);
    if (args->nstrings < 3)
    {
        sub_context_ty  *scp;

        scp = sub_context_new();
        sub_var_set_string(scp, "Name", args->string[0]);
        error_with_position
        (
            pp,
            scp,
            i18n("$name: requires two or more arguments")
        );
        sub_context_delete(scp);
        return -1;
    }
    for (j = 3; j < args->nstrings; j++)
    {
        string_ty       *s;

        s = str_cat_three(args->string[1], args->string[j], args->string[2]);
        string_list_append(result, s);
        str_free(s);
    }
    return 0;
}
Пример #11
0
unsigned name2addrlist(SOCKADDR_LIST *addr_list, char *name) {
    char *tmp, *host_name, *port_name;
    unsigned retval;

    /* first check if this is a UNIX socket */
#ifdef HAVE_STRUCT_SOCKADDR_UN
    if(*name=='/') {
        if(offsetof(struct sockaddr_un, sun_path)+strlen(name)+1
                > sizeof(struct sockaddr_un)) {
            s_log(LOG_ERR, "Unix socket path is too long");
            return 0; /* no results */
        }
        addr_list->addr=str_realloc(addr_list->addr,
            (addr_list->num+1)*sizeof(SOCKADDR_UNION));
        addr_list->addr[addr_list->num].un.sun_family=AF_UNIX;
        strcpy(addr_list->addr[addr_list->num].un.sun_path, name);
        return ++(addr_list->num); /* ok - return the number of addresses */
    }
#endif

    /* setup host_name and port_name */
    tmp=str_dup(name);
    port_name=strrchr(tmp, ':');
    if(port_name) {
        host_name=tmp;
        *port_name++='\0';
    } else { /* no ':' - use default host IP */
        host_name=NULL;
        port_name=tmp;
    }

    /* fill addr_list structure */
    retval=hostport2addrlist(addr_list, host_name, port_name);
    str_free(tmp);
    return retval;
}
Пример #12
0
static void search_conf(void)
{
	struct symbol **sym_arr;
	struct gstr res;

again:
	switch (dialog_inputbox("Search Configuration Parameter",
				"Enter Keyword", 10, 75,
				NULL)) {
	case 0:
		break;
	case 1:
		show_helptext("Search Configuration", search_help);
		goto again;
	default:
		return;
	}

	sym_arr = sym_re_search(dialog_input_result);
	res = get_relations_str(sym_arr);
	free(sym_arr);
	show_textbox("Search Results", str_get(&res), 0, 0);
	str_free(&res);
}
Пример #13
0
void http_client_request_unref(struct http_client_request **_req)
{
	struct http_client_request *req = *_req;
	struct http_client *client = req->client;

	i_assert(req->refcount > 0);

	if (--req->refcount > 0)
		return;

	if (req->destroy_callback != NULL) {
		req->destroy_callback(req->destroy_context);
		req->destroy_callback = NULL;
	}

	/* only decrease pending request counter if this request was submitted */
	if (req->state > HTTP_REQUEST_STATE_NEW)
		req->client->pending_requests--;

	http_client_request_debug(req, "Destroy (requests left=%d)",
		client->pending_requests);

	if (client->pending_requests == 0 && client->ioloop != NULL)
		io_loop_stop(client->ioloop);

	if (req->delayed_error != NULL)
		http_client_host_remove_request_error(req->host, req);
	if (req->payload_input != NULL)
		i_stream_unref(&req->payload_input);
	if (req->payload_output != NULL)
		o_stream_unref(&req->payload_output);
	if (req->headers != NULL)
		str_free(&req->headers);
	pool_unref(&req->pool);
	*_req = NULL;
}
Пример #14
0
NOEXPORT void smtp_server(CLI *c) {
    char *line;

    s_poll_init(c->fds);
    s_poll_add(c->fds, c->local_rfd.fd, 1, 0);
    switch(s_poll_wait(c->fds, 0, 200)) { /* wait up to 200ms */
    case 0: /* fd not ready to read */
        s_log(LOG_DEBUG, "RFC 2487 detected");
        break;
    case 1: /* fd ready to read */
        s_log(LOG_DEBUG, "RFC 2487 not detected");
        return; /* return if RFC 2487 is not used */
    default: /* -1 */
        sockerror("RFC2487 (s_poll_wait)");
        longjmp(c->err, 1);
    }

    line=fd_getline(c, c->remote_fd.fd);
    if(!is_prefix(line, "220")) {
        s_log(LOG_ERR, "Unknown server welcome");
        str_free(line);
        longjmp(c->err, 1);
    }
    fd_printf(c, c->local_wfd.fd, "%s + stunnel", line);
    str_free(line);
    line=fd_getline(c, c->local_rfd.fd);
    if(!is_prefix(line, "EHLO ")) {
        s_log(LOG_ERR, "Unknown client EHLO");
        str_free(line);
        longjmp(c->err, 1);
    }
    fd_printf(c, c->local_wfd.fd, "250-%s Welcome", line);
    fd_putline(c, c->local_wfd.fd, "250 STARTTLS");
    str_free(line);
    line=fd_getline(c, c->local_rfd.fd);
    if(!is_prefix(line, "STARTTLS")) {
        s_log(LOG_ERR, "STARTTLS expected");
        str_free(line);
        longjmp(c->err, 1);
    }
    fd_putline(c, c->local_wfd.fd, "220 Go ahead");
    str_free(line);
}
Пример #15
0
NOEXPORT void connect_server(CLI *c) {
    char *request, *proto, *header;
    NAME_LIST host_list;

    request=fd_getline(c, c->local_rfd.fd);
    if(!is_prefix(request, "CONNECT ")) {
        fd_putline(c, c->local_wfd.fd, "HTTP/1.0 400 Bad Request Method");
        fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
        fd_putline(c, c->local_wfd.fd, "");
        str_free(request);
        longjmp(c->err, 1);
    }
    proto=strchr(request+8, ' ');
    if(!proto || !is_prefix(proto, " HTTP/")) {
        fd_putline(c, c->local_wfd.fd, "HTTP/1.0 400 Bad Request Protocol");
        fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
        fd_putline(c, c->local_wfd.fd, "");
        str_free(request);
        longjmp(c->err, 1);
    }
    *proto='\0';

    header=str_dup("");
    do { /* ignore any headers */
        str_free(header);
        header=fd_getline(c, c->local_rfd.fd);
    } while(*header); /* not empty */
    str_free(header);

    host_list.name=request+8;
    host_list.next=NULL;
    if(!namelist2addrlist(&c->connect_addr, &host_list, DEFAULT_LOOPBACK)) {
        fd_putline(c, c->local_wfd.fd, "HTTP/1.0 404 Not Found");
        fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
        fd_putline(c, c->local_wfd.fd, "");
        str_free(request);
        longjmp(c->err, 1);
    }
    str_free(request);
    fd_putline(c, c->local_wfd.fd, "HTTP/1.0 200 OK");
    fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
    fd_putline(c, c->local_wfd.fd, "");
}
Пример #16
0
static void
handle_dir_common(struct vsf_session* p_sess, int full_details)
{
  static struct mystr s_option_str;
  static struct mystr s_filter_str;
  static struct mystr s_dir_name_str;
  static struct vsf_sysutil_statbuf* s_p_dirstat;
  int remote_fd;
  int dir_allow_read = 1;
  struct vsf_sysutil_dir* p_dir = 0;
  str_empty(&s_option_str);
  str_empty(&s_filter_str);
  /* By default open the current directory */
  str_alloc_text(&s_dir_name_str, ".");
  if (!pasv_active(p_sess) && !port_active(p_sess))
  {
    vsf_cmdio_write(p_sess, FTP_BADSENDCONN, "Use PORT or PASV first.");
    return;
  }
  /* Do we have an option? Going to be strict here - the option must come
   * first. e.g. "ls -a .." fine, "ls .. -a" not fine
   */
  if (!str_isempty(&p_sess->ftp_arg_str) &&
      str_get_char_at(&p_sess->ftp_arg_str, 0) == '-')
  {
    /* Chop off the '-' */
    str_mid_to_end(&p_sess->ftp_arg_str, &s_option_str, 1);
    /* A space will separate options from filter (if any) */
    str_split_char(&s_option_str, &s_filter_str, ' ');
  }
  else
  {
    /* The argument, if any, is just a filter */
    str_copy(&s_filter_str, &p_sess->ftp_arg_str);
  }
  if (!str_isempty(&s_filter_str))
  {
    /* First check - is it an outright directory, as in "ls /pub" */
    p_dir = str_opendir(&s_filter_str);
    if (p_dir != 0)
    {
      /* Listing a directory! */
      str_copy(&s_dir_name_str, &s_filter_str);
      str_free(&s_filter_str);
    }
    else
    {
      struct str_locate_result locate_result =
        str_locate_char(&s_filter_str, '/');
      if (locate_result.found)
      {
        /* Includes a path! Reverse scan for / in the arg, to get the
         * base directory and filter (if any)
         */
        str_copy(&s_dir_name_str, &s_filter_str);
        str_split_char_reverse(&s_dir_name_str, &s_filter_str, '/');
        /* If we have e.g. "ls /.message", we just ripped off the leading
         * slash because it is the only one!
         */
        if (str_isempty(&s_dir_name_str))
        {
          str_alloc_text(&s_dir_name_str, "/");
        }
      }
    }
  }
  if (p_dir == 0)
  {
    /* NOTE - failure check done below, it's not forgotten */
    p_dir = str_opendir(&s_dir_name_str);
  }
  /* Fine, do it */
  remote_fd = get_remote_transfer_fd(p_sess);
  if (vsf_sysutil_retval_is_error(remote_fd))
  {
    goto dir_close_out;
  }
  vsf_cmdio_write(p_sess, FTP_DATACONN, "Here comes the directory listing.");
  if (p_sess->is_anonymous && p_dir && tunable_anon_world_readable_only)
  {
    vsf_sysutil_dir_stat(p_dir, &s_p_dirstat);
    if (!vsf_sysutil_statbuf_is_readable_other(s_p_dirstat))
    {
      dir_allow_read = 0;
    }
  }
  if (p_dir == 0 || !dir_allow_read)
  {
    vsf_cmdio_write(p_sess, FTP_TRANSFEROK,
                    "Transfer done (but failed to open directory).");
  }
  else
  {
    (void) vsf_ftpdataio_transfer_dir(p_sess, remote_fd, p_dir,
                                      &s_dir_name_str, &s_option_str,
                                      &s_filter_str, full_details);
  }
  (void) dispose_remote_transfer_fd(p_sess);
dir_close_out:
  if (p_dir)
  {
    vsf_sysutil_closedir(p_dir);
  }
  port_cleanup(p_sess);
  pasv_cleanup(p_sess);
}
Пример #17
0
static opcode_status_ty
execute(const opcode_ty *op, opcode_context_ty *icp)
{
    opcode_status_ty status;
    const opcode_setenv_append_ty *this;
    string_list_ty  *name;
    string_list_ty  *value;
    string_ty       *s;
    char            *tmp;

    trace(("opcode_setenv_append::execute()\n{\n"));
    status = opcode_status_success;
    this = (const opcode_setenv_append_ty *)op;

    value = opcode_context_string_list_pop(icp);
    name = opcode_context_string_list_pop(icp);

    switch (name->nstrings)
    {
    case 0:
        error_with_position
        (
            &this->pos,
            0,
            i18n("lefthand side of assignment is empty")
        );
        status = opcode_status_error;
        break;

    case 1:
        /*
         * If the environment variable is already set, prepend
         * its existing value to the value list the user gave us.
         */
        tmp = getenv(name->string[0]->str_text);
        if (tmp)
        {
            string_ty       *tmp2;

            tmp2 = str_from_c(tmp);
            string_list_prepend(value, tmp2);
            str_free(tmp2);
        }
        s = wl2str(value, 0, value->nstrings, " ");
        env_set(name->string[0]->str_text, s->str_text);
        str_free(s);
        break;

    default:
        error_with_position
        (
            &this->pos,
            0,
            i18n("lefthand side of assignment is more than one word")
        );
        status = opcode_status_error;
        break;
    }

    string_list_delete(name);
    string_list_delete(value);
    trace(("return %s;\n", opcode_status_name(status)));
    trace(("}\n"));
    return status;
}
Пример #18
0
static opcode_status_ty
script(const opcode_ty *op, opcode_context_ty *icp)
{
    opcode_status_ty status;
    const opcode_setenv_append_ty *this;
    string_list_ty  *name;
    string_list_ty  *value;
    string_ty       *name1;
    string_ty       *name2;
    string_ty       *value1;
    string_ty       *value2;

    trace(("opcode_setenv_append::script()\n{\n"));
    status = opcode_status_success;
    this = (const opcode_setenv_append_ty *)op;

    value = opcode_context_string_list_pop(icp);
    name = opcode_context_string_list_pop(icp);

    switch (name->nstrings)
    {
    case 0:
        error_with_position
        (
            &this->pos,
            0,
            i18n("lefthand side of assignment is empty")
        );
        status = opcode_status_error;
        break;

    case 1:
        name1 = wl2str(name, 0, name->nstrings, " ");
        name2 = str_quote_shell(name1);
        str_free(name1);

        value1 = wl2str(value, 0, value->nstrings, " ");
        value2 = str_quote_shell(value1);
        str_free(value1);

        printf("%s=%s\n", name2->str_text, value2->str_text);
        printf("export %s\n", name2->str_text);
        str_free(name1);
        str_free(value2);
        break;

    default:
        error_with_position
        (
            &this->pos,
            0,
            i18n("lefthand side of assignment is more than one word")
        );
        status = opcode_status_error;
        break;
    }

    string_list_delete(name);
    string_list_delete(value);
    trace(("return %s;\n", opcode_status_name(status)));
    trace(("}\n"));
    return status;
}
Пример #19
0
int s_poll_wait(s_poll_set *fds, int sec, int msec) {
    CONTEXT *context; /* current context */
    static CONTEXT *to_free=NULL; /* delayed memory deallocation */

    /* FIXME: msec parameter is currently ignored with UCONTEXT threads */
    (void)msec; /* skip warning about unused parameter */

    /* remove the current context from ready queue */
    context=ready_head;
    ready_head=ready_head->next;
    if(!ready_head) /* the queue is empty */
        ready_tail=NULL;
    /* it it safe to s_log() after new ready_head is set */

    /* it's illegal to deallocate the stack of the current context */
    if(to_free) { /* a delayed deallocation is scheduled */
#ifdef DEBUG_UCONTEXT
        s_log(LOG_DEBUG, "Releasing context %ld", to_free->id);
#endif
        str_free(to_free->stack);
        str_free(to_free);
        to_free=NULL;
    }

    /* manage the current thread */
    if(fds) { /* something to wait for -> swap the context */
        context->fds=fds; /* set file descriptors to wait for */
        context->finish=sec<0 ? -1 : time(NULL)+sec;

        /* append the current context to the waiting queue */
        context->next=NULL;
        if(waiting_tail)
            waiting_tail->next=context;
        waiting_tail=context;
        if(!waiting_head)
            waiting_head=context;
    } else { /* nothing to wait for -> drop the context */
        to_free=context; /* schedule for delayed deallocation */
    }

    while(!ready_head) /* wait until there is a thread to switch to */
        scan_waiting_queue();

    /* switch threads */
    if(fds) { /* swap the current context */
        if(context->id!=ready_head->id) {
#ifdef DEBUG_UCONTEXT
            s_log(LOG_DEBUG, "Context swap: %ld -> %ld",
                context->id, ready_head->id);
#endif
            swapcontext(&context->context, &ready_head->context);
#ifdef DEBUG_UCONTEXT
            s_log(LOG_DEBUG, "Current context: %ld", ready_head->id);
#endif
        }
        return ready_head->ready;
    } else { /* drop the current context */
#ifdef DEBUG_UCONTEXT
        s_log(LOG_DEBUG, "Context set: %ld (dropped) -> %ld",
            context->id, ready_head->id);
#endif
        setcontext(&ready_head->context);
        ioerror("setcontext"); /* should not ever happen */
        return 0;
    }
}
Пример #20
0
/*
 *	run the request
 */
static HTTPResponse *_runRequest(WOAppReq *app, WOAppHandle woappHandle, WOInstanceHandle instHandle, HTTPRequest *req) {
   WOConnection *c;
   HTTPResponse *resp = NULL;
   int send_status, keepConnection, retryRequest = 0;
   const char *idString = NULL;

   WOLog(WO_INFO,"Trying to contact %s:%s on %s(%d)", app->name,app->instance,app->host,app->port);

   /* Tag the request with a unique identifier (if it hasn't been already) */
   /* (It might already have been tagged if we are retrying the request due to refusing new sessions, for example) */
   idString = req_HeaderForKey(req, REQUEST_ID_HEADER);
   if (idString == NULL)
   {
      String *requestID = tr_uniqueID();
      if (requestID)
      {
         req_addHeader(req, REQUEST_ID_HEADER, requestID->text, STR_COPYVALUE);
         idString = req_HeaderForKey(req, REQUEST_ID_HEADER);
         str_free(requestID);
      }
   }
   
   do {
      c = tr_open(instHandle);				/* connect */

      if (c == NULL) {
         WOLog(WO_INFO,"%s:%s NOT LISTENING on %s(%d)", app->name,app->instance,app->host,app->port);
         app->error = err_connect;
         return NULL;
      }

      /*
       *	app found and is listening on port
       */
      if (app->scheduler->beginTransaction)
         app->scheduler->beginTransaction(app, instHandle);

      /* Make sure that we're the only connection header, and we're explicit about the setting */
      req_removeHeader(req,CONNECTION);
      if (c->isPooled) {
         req_addHeader(req,CONNECTION,HTTP_KEEP_ALIVE,0);
      } else {
	 req_addHeader(req,CONNECTION,HTTP_CLOSE,0);
      }

      WOLog(WO_INFO,"%s:%s on %s(%d) connected [pooled: %s]", app->name, app->instance, app->host, app->port, c->isPooled ? "Yes" : "No");

      /*
       *	send the request....
       */
      send_status = req_sendRequest(req, c->fd);
      if (send_status != 0) {
         if ((send_status == TR_RESET) && (retryRequest == 0) && !req->haveReadStreamedData)  {
              /* If we get here the connection was reset. This means the instance has either quit or crashed. */
              /* Bump the generation number so all pooled connections to this instance will be invalidated. */
              /* Then retry the request with a new connection. If the instance is not running the retry will */
              /* fail with a different error and the instance will be marked dead. */
              _WOInstance *inst = ac_lockInstance(instHandle);
              /* note: if we get here, keepConnection == 0 --> this connection will be closed */
              if (inst)
              {
                  ac_cycleInstance(inst, c->generation);
                  ac_unlockInstance(instHandle);
              }
              retryRequest++;
              WOLog(WO_INFO, "retrying request due to connection reset");

              /* Must close connection before continuing */
              tr_close(c, instHandle, 0);
              continue;
          } else {
              WOLog(WO_ERR,"Failed to send request");
              tr_close(c, instHandle, 0);          /* close app connection */
              if (send_status == -1)
                 app->error = err_read;
              else
                 app->error = err_send;
              return NULL;
          }
      }

      /* Note that we have a request queued */
      WOLog(WO_INFO,"Request %s sent, awaiting response", req->request_str);

      /* While the app is processing the request, take the opportunity to check/update the config. */
      ac_readConfiguration();

      /*
       *	now wait for the response...
       */
      resp = resp_getResponseHeaders(c, instHandle);
      /* go ahead and read the first chunk of response data */
      if (resp && req->method != HTTP_HEAD_METHOD)
      {
         if (resp_getResponseContent(resp, 1) == -1)
         {
            resp_free(resp);
            resp = NULL;
         }
      }

      /* Validate the ID */
      if (idString && resp)
      {
         const char *respID = st_valueFor(resp->headers, REQUEST_ID_HEADER);
         if (respID != NULL)
         {
            if (strcmp(respID, idString) != 0)
            {
               WOLog(WO_ERR, "Got response with wrong ID! Dumping response. request ID = %s, response ID = %s", idString, respID);
               /* note this will cause the connection to be closed below */
               resp_free(resp);
               resp = NULL;
            } else
               st_removeKey(resp->headers, REQUEST_ID_HEADER);
         } else
            WOLog(WO_WARN, "Got response with no ID.");
      }
               
      app->response = resp;

      /*
       *	check if this connection can be kept open
       */
      keepConnection = 0;

#ifndef CGI /* doesn't make sense to keep the connection for CGI */
      if (resp && resp->headers)
      {
         const char *keepAlive;
         keepAlive = st_valueFor(resp->headers, CONNECTION);
         if (keepAlive)
         {
            /* if the keep alive header is set, honor the value */
            if (strcasecmp(keepAlive, HTTP_KEEP_ALIVE) == 0)
               keepConnection = 1;
         } else {
            /* no keep alive header - keep alive by default for HTTP/1.1 only */
            if (resp->flags & RESP_HTTP11)
               keepConnection = 1;
         }
      }
#endif

      if (resp != NULL) {
         if (app->scheduler->finalizeTransaction)
            if (app->scheduler->finalizeTransaction(app, instHandle))
               keepConnection = 0;

         st_removeKey(resp->headers, REFUSING_SESSIONS_HEADER);
         st_removeKey(resp->headers, LOAD_AVERAGE_HEADER);
         st_removeKey(resp->headers, CONNECTION);

         WOLog(WO_INFO,"received ->%d %s",resp->status,resp->statusMsg);
         retryRequest = 0;
      } else {
         if (c != NULL && tr_connectionWasReset(c))
         {
            /* If we get here the connection was reset. This means the instance has either quit or crashed. */
            /* Bump the generation number so all pooled connections to this instance will be invalidated. */
            /* Then retry the request with a new connection. If the instance is not running the retry will */
            /* fail with a different error and the instance will be marked dead. */
            /* Note that only one retry due to a connection reset error is allowed. This is to prevent an */
            /* infinite loop if the instance dies while processing the request and restarts quickly enough */
            /* to process the retry. */
            _WOInstance *inst = ac_lockInstance(instHandle);
            /* note: if we get here, keepConnection == 0 --> this connection will be closed */
            if (inst)
            {
               ac_cycleInstance(inst, c->generation);
               ac_unlockInstance(instHandle);
            }
            retryRequest++;
            if (retryRequest == 1)
               WOLog(WO_INFO, "retrying request due to connection reset");
         } else
         app->error = err_response;
      }
      if (resp && resp->content_read < resp->content_length)
      {
         resp->keepConnection = keepConnection;
         resp->instHandle = instHandle;
         resp->flags |= RESP_CLOSE_CONNECTION;
      } else {
         tr_close(c, instHandle, keepConnection);
      }
   } while (retryRequest == 1);

   return resp;
}
Пример #21
0
NOEXPORT void cache_transfer(SSL_CTX *ctx, const u_char type,
        const long timeout,
        const u_char *key, const size_t key_len,
        const u_char *val, const size_t val_len,
        unsigned char **ret, size_t *ret_len) {
    char session_id_txt[2*SSL_MAX_SSL_SESSION_ID_LENGTH+1];
    const char hex[16]="0123456789ABCDEF";
    const char *type_description[]={"new", "get", "remove"};
    unsigned i;
    SOCKET s;
    ssize_t len;
    struct timeval t;
    CACHE_PACKET *packet;
    SERVICE_OPTIONS *section;

    if(ret) /* set error as the default result if required */
        *ret=NULL;

    /* log the request information */
    for(i=0; i<key_len && i<SSL_MAX_SSL_SESSION_ID_LENGTH; ++i) {
        session_id_txt[2*i]=hex[key[i]>>4];
        session_id_txt[2*i+1]=hex[key[i]&0x0f];
    }
    session_id_txt[2*i]='\0';
    s_log(LOG_INFO,
        "cache_transfer: request=%s, timeout=%ld, id=%s, length=%lu",
        type_description[type], timeout, session_id_txt, (long unsigned)val_len);

    /* allocate UDP packet buffer */
    if(key_len>SSL_MAX_SSL_SESSION_ID_LENGTH) {
        s_log(LOG_ERR, "cache_transfer: session id too big (%lu bytes)",
            (unsigned long)key_len);
        return;
    }
    if(val_len>MAX_VAL_LEN) {
        s_log(LOG_ERR, "cache_transfer: encoded session too big (%lu bytes)",
            (unsigned long)key_len);
        return;
    }
    packet=str_alloc(sizeof(CACHE_PACKET));

    /* setup packet */
    packet->version=1;
    packet->type=type;
    packet->timeout=htons((u_short)(timeout<64800?timeout:64800));/* 18 hours */
    memcpy(packet->key, key, key_len);
    memcpy(packet->val, val, val_len);

    /* create the socket */
    s=s_socket(AF_INET, SOCK_DGRAM, 0, 0, "cache_transfer: socket");
    if(s==INVALID_SOCKET) {
        str_free(packet);
        return;
    }

    /* retrieve pointer to the section structure of this ctx */
    section=SSL_CTX_get_ex_data(ctx, index_opt);
    if(sendto(s, (void *)packet,
#ifdef USE_WIN32
            (int)
#endif
            (sizeof(CACHE_PACKET)-MAX_VAL_LEN+val_len),
            0, &section->sessiond_addr.sa,
            addr_len(&section->sessiond_addr))<0) {
        sockerror("cache_transfer: sendto");
        closesocket(s);
        str_free(packet);
        return;
    }

    if(!ret || !ret_len) { /* no response is required */
        closesocket(s);
        str_free(packet);
        return;
    }

    /* set recvfrom timeout to 200ms */
    t.tv_sec=0;
    t.tv_usec=200;
    if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (void *)&t, sizeof t)<0) {
        sockerror("cache_transfer: setsockopt SO_RCVTIMEO");
        closesocket(s);
        str_free(packet);
        return;
    }

    /* retrieve response */
    len=recv(s, (void *)packet, sizeof(CACHE_PACKET), 0);
    closesocket(s);
    if(len<0) {
        if(get_last_socket_error()==S_EWOULDBLOCK ||
                get_last_socket_error()==S_EAGAIN)
            s_log(LOG_INFO, "cache_transfer: recv timeout");
        else
            sockerror("cache_transfer: recv");
        str_free(packet);
        return;
    }

    /* parse results */
    if(len<(int)sizeof(CACHE_PACKET)-MAX_VAL_LEN || /* too short */
            packet->version!=1 || /* wrong version */
            safe_memcmp(packet->key, key, key_len)) { /* wrong session id */
        s_log(LOG_DEBUG, "cache_transfer: malformed packet received");
        str_free(packet);
        return;
    }
    if(packet->type!=CACHE_RESP_OK) {
        s_log(LOG_INFO, "cache_transfer: session not found");
        str_free(packet);
        return;
    }
    *ret_len=(size_t)len-(sizeof(CACHE_PACKET)-MAX_VAL_LEN);
    *ret=str_alloc(*ret_len);
    s_log(LOG_INFO, "cache_transfer: session found");
    memcpy(*ret, packet->val, *ret_len);
    str_free(packet);
}
Пример #22
0
NOEXPORT int conf_init(SERVICE_OPTIONS *section) {
#if OPENSSL_VERSION_NUMBER>=0x10002000L
    SSL_CONF_CTX *cctx;
    NAME_LIST *curr;
    char *cmd, *param;

    if(!section->config)
        return 0; /* OK */
    cctx=SSL_CONF_CTX_new();
    if(!cctx) {
        sslerror("SSL_CONF_CTX_new");
        return 1; /* FAILED */
    }
    SSL_CONF_CTX_set_ssl_ctx(cctx, section->ctx);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
    SSL_CONF_CTX_set_flags(cctx, section->option.client ?
        SSL_CONF_FLAG_CLIENT : SSL_CONF_FLAG_SERVER);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);

    for(curr=section->config; curr; curr=curr->next) {
        cmd=str_dup(curr->name);
        param=strchr(cmd, ':');
        if(param)
            *param++='\0';
        switch(SSL_CONF_cmd(cctx, cmd, param)) {
        case 2:
            s_log(LOG_DEBUG, "OpenSSL config \"%s\" set to \"%s\"", cmd, param);
            break;
        case 1:
            s_log(LOG_DEBUG, "OpenSSL config command \"%s\" executed", cmd);
            break;
        case -2:
            s_log(LOG_ERR,
                "OpenSSL config command \"%s\" was not recognised", cmd);
            str_free(cmd);
            SSL_CONF_CTX_free(cctx);
            return 1; /* FAILED */
        case -3:
            s_log(LOG_ERR,
                "OpenSSL config command \"%s\" requires a parameter", cmd);
            str_free(cmd);
            SSL_CONF_CTX_free(cctx);
            return 1; /* FAILED */
        default:
            sslerror("SSL_CONF_cmd");
            str_free(cmd);
            SSL_CONF_CTX_free(cctx);
            return 1; /* FAILED */
        }
        str_free(cmd);
    }

    if(!SSL_CONF_CTX_finish(cctx)) {
        sslerror("SSL_CONF_CTX_finish");
        SSL_CONF_CTX_free(cctx);
        return 1; /* FAILED */
    }
    SSL_CONF_CTX_free(cctx);
#else /* OpenSSL earlier than 1.0.2 */
    (void)section; /* squash the unused parameter warning */
#endif /* OpenSSL 1.0.2 or later */
    return 0; /* OK */
}
Пример #23
0
static void dropbox_free(void *data)
{
	struct dropbox_section *section = data;
	str_free(&section->status);
	free(section);
}
Пример #24
0
void fpga_loader_free(struct fpga_loader_t *loader) {

	str_free(loader->blif);
	str_free(loader->cwd);
	free(loader);
}
Пример #25
0
void client_destroy(struct client *client, const char *reason)
{
	if (client->destroyed)
		return;
	client->destroyed = TRUE;

	if (!client->login_success && reason != NULL) {
		reason = t_strconcat(reason, " ",
			client_get_extra_disconnect_reason(client), NULL);
	}
	if (reason != NULL)
		client_log(client, reason);

	if (last_client == client)
		last_client = client->prev;
	DLLIST_REMOVE(&clients, client);

	if (client->input != NULL)
		i_stream_close(client->input);
	if (client->output != NULL)
		o_stream_close(client->output);

	if (client->master_tag != 0) {
		i_assert(client->auth_request == NULL);
		i_assert(client->authenticating);
		i_assert(client->refcount > 1);
		client->authenticating = FALSE;
		master_auth_request_abort(master_auth, client->master_tag);
		client->refcount--;
	} else if (client->auth_request != NULL) {
		i_assert(client->authenticating);
		sasl_server_auth_abort(client);
	} else {
		i_assert(!client->authenticating);
	}

	if (client->io != NULL)
		io_remove(&client->io);
	if (client->to_disconnect != NULL)
		timeout_remove(&client->to_disconnect);
	if (client->to_auth_waiting != NULL)
		timeout_remove(&client->to_auth_waiting);
	if (client->auth_response != NULL)
		str_free(&client->auth_response);

	if (client->fd != -1) {
		net_disconnect(client->fd);
		client->fd = -1;
	}

	if (client->proxy_password != NULL) {
		safe_memset(client->proxy_password, 0,
			    strlen(client->proxy_password));
		i_free_and_null(client->proxy_password);
	}

	if (client->proxy_sasl_client != NULL)
		dsasl_client_free(&client->proxy_sasl_client);
	if (client->login_proxy != NULL)
		login_proxy_free(&client->login_proxy);
	if (client->v.destroy != NULL)
		client->v.destroy(client);
	if (client_unref(&client) && initial_service_count == 1) {
		/* as soon as this connection is done with proxying
		   (or whatever), the process will die. there's no need for
		   authentication anymore, so close the connection.
		   do this only with initial service_count=1, in case there
		   are other clients with pending authentications */
		auth_client_disconnect(auth_client, "unnecessary connection");
	}
	login_client_destroyed();
	login_refresh_proctitle();
}
Пример #26
0
int req_sendRequest(HTTPRequest *req, net_fd socket) 
{
   struct iovec *buffers;
   int bufferCount, appStatus;
   int browserStatus = 0;
   String *headersString;

   buffers = WOMALLOC(3 * sizeof(struct iovec));

   headersString = str_create(req->request_str, 0);
   if (headersString) 
   {
      st_perform(req->headers, (st_perform_callback)req_appendHeader, headersString);
   }
   buffers[0].iov_base = headersString->text;
   buffers[0].iov_len = headersString->length;
   buffers[1].iov_base = "\r\n";
   buffers[1].iov_len = 2;
   bufferCount = 2;
   if (req->content_length > 0) 
   {
      bufferCount++;
      buffers[2].iov_base = req->content;
      buffers[2].iov_len = req->content_buffer_size;
   }
   appStatus = transport->sendBuffers(socket, buffers, bufferCount);
   str_free(headersString);

   /* If we are streaming the content data, continue until we have sent everything. */
   /* Note that we reuse buffers, and the existing content-data buffer. */
   if (req->content_length > req->content_buffer_size)
   {
      long total_sent = req->content_buffer_size;
      long len_read, amount_to_read;
      req->haveReadStreamedData = 1;
      while (total_sent < req->content_length)
      {
         amount_to_read = req->content_length - total_sent;
         if (amount_to_read > req->content_buffer_size)
            amount_to_read = req->content_buffer_size;
         len_read = req->getMoreContent(req, req->content, amount_to_read, 0);
         if (len_read > 0)
         {
            if(appStatus == 0)
            {
               buffers[0].iov_base = req->content;
               buffers[0].iov_len = len_read;
               appStatus = transport->sendBuffers(socket, buffers, 1);
               // 2009/04/28: in case of a transport error, carry on with reading
               //             incoming input stream (= browser data).  That way,
               //             the browser (hopefully) switch to the receive mode
               //             after sending the complete request and receives/shows
               //             the adaptor error message (old behaviour: endless
               //             sending/uploading view).
               if(appStatus != 0)
               {
                  WOLog(WO_ERR, "Failed to send streamed content.");
               }
            }
            total_sent += len_read;
         } else if (len_read < 0) {
            WOLog(WO_ERR, "Failed to read streamed content.");
            browserStatus = -1;
            break;
         }
      }
   }
   WOFREE(buffers);
   if(browserStatus != 0) WOLog(WO_ERR, "error receiving request");
   if (appStatus == 0)
   {
      // 2009/04/30: as long as we haven't received any error message from
      //             the instance, flush the socket to complete the data
      //             transfer!
      appStatus = transport->flush_connection(socket);
   }
   else
      WOLog(WO_ERR, "error sending request");

   return
       ((appStatus != 0)
          ? appStatus
          : browserStatus);
}
Пример #27
0
static int
transfer_dir_internal(struct vsf_session* p_sess, int is_control,
                      struct vsf_sysutil_dir* p_dir,
                      const struct mystr* p_base_dir_str,
                      const struct mystr* p_option_str,
                      const struct mystr* p_filter_str,
                      int is_verbose)
{
  struct mystr_list dir_list = INIT_STRLIST;
  struct mystr_list subdir_list = INIT_STRLIST;
  struct mystr dir_prefix_str = INIT_MYSTR;
  struct mystr_list* p_subdir_list = 0;
  struct str_locate_result loc_result = str_locate_char(p_option_str, 'R');
  int failed = 0;
  enum EVSFRWTarget target = kVSFRWData;
  if (is_control)
  {
    target = kVSFRWControl;
  }
  if (loc_result.found && tunable_ls_recurse_enable)
  {
    p_subdir_list = &subdir_list;
  }
  vsf_ls_populate_dir_list(&dir_list, p_subdir_list, p_dir, p_base_dir_str,
                           p_option_str, p_filter_str, is_verbose);
  if (p_subdir_list)
  {
    int retval;
    str_copy(&dir_prefix_str, p_base_dir_str);
    str_append_text(&dir_prefix_str, ":\r\n");
    retval = ftp_write_str(p_sess, &dir_prefix_str, target);
    if (retval != 0)
    {
      failed = 1;
    }
  }
  if (!failed)
  {
    failed = write_dir_list(p_sess, &dir_list, target);
  }
  /* Recurse into the subdirectories if required... */
  if (!failed)
  {
    struct mystr sub_str = INIT_MYSTR;
    unsigned int num_subdirs = str_list_get_length(&subdir_list);
    unsigned int subdir_index;
    for (subdir_index = 0; subdir_index < num_subdirs; subdir_index++)
    {
      int retval;
      struct vsf_sysutil_dir* p_subdir;
      const struct mystr* p_subdir_str = 
        str_list_get_pstr(&subdir_list, subdir_index);
      if (str_equal_text(p_subdir_str, ".") ||
          str_equal_text(p_subdir_str, ".."))
      {
        continue;
      }
      str_copy(&sub_str, p_base_dir_str);
      str_append_char(&sub_str, '/');
      str_append_str(&sub_str, p_subdir_str);
      p_subdir = str_opendir(&sub_str);
      if (p_subdir == 0)
      {
        /* Unreadable, gone missing, etc. - no matter */
        continue;
      }
      str_alloc_text(&dir_prefix_str, "\r\n");
      retval = ftp_write_str(p_sess, &dir_prefix_str, target);
      if (retval != 0)
      {
        failed = 1;
        vsf_sysutil_closedir(p_subdir);
        break;
      }
      retval = transfer_dir_internal(p_sess, is_control, p_subdir, &sub_str,
                                     p_option_str, p_filter_str, is_verbose);
      vsf_sysutil_closedir(p_subdir);
      if (retval != 0)
      {
        failed = 1;
        break;
      }
    }
    str_free(&sub_str);
  }
  str_list_free(&dir_list);
  str_list_free(&subdir_list);
  str_free(&dir_prefix_str);
  if (!failed)
  {
    return 0;
  }
  else
  {
    return -1;
  }
}
Пример #28
0
void
process_post_login(struct vsf_session* p_sess)
{
  int retval;

  if (p_sess->is_anonymous)
  {
    vsf_sysutil_set_umask(tunable_anon_umask);
    p_sess->bw_rate_max = tunable_anon_max_rate;
  }
  else
  {
    vsf_sysutil_set_umask(tunable_local_umask);
    p_sess->bw_rate_max = tunable_local_max_rate;
  }
  if (tunable_async_abor_enable)
  {
    vsf_sysutil_install_sighandler(kVSFSysUtilSigURG, handle_sigurg, p_sess);
    vsf_sysutil_activate_sigurg(VSFTP_COMMAND_FD);
  }

  /* Kitsune */	
  vsf_sysutil_kitsune_set_update_point("postlogin.c");
  if(!kitsune_is_updating()) {
    /* Handle any login message */
    vsf_banner_dir_changed(p_sess, FTP_LOGINOK);
    vsf_cmdio_write(p_sess, FTP_LOGINOK, "Login successful. Have fun.");
	} else {
    /* Set sigchld function pointer (normally done in twoprocess.c) */    
    vsf_sysutil_default_sig(kVSFSysUtilSigCHLD);
    vsf_sysutil_install_async_sighandler(kVSFSysUtilSigCHLD, twoproc_handle_sigchld);
  }
  /* End Kitsune */

  while(1)
  {
    if (tunable_setproctitle_enable)
    {
      vsf_sysutil_setproctitle("IDLE");
    }

		/* Kitsune update point */
    kitsune_update("postlogin.c");  /**DSU updatepoint */
    
    /* Blocks */
	  vsf_cmdio_get_cmd_and_arg(p_sess, &p_sess->ftp_cmd_str,
	                            &p_sess->ftp_arg_str, 1);
	  if (tunable_setproctitle_enable)
	  {
	    struct mystr proctitle_str = INIT_MYSTR;
	    str_copy(&proctitle_str, &p_sess->ftp_cmd_str);
	    if (!str_isempty(&p_sess->ftp_arg_str))
	    {
	      str_append_char(&proctitle_str, ' ');
	      str_append_str(&proctitle_str, &p_sess->ftp_arg_str);
	    }
	    /* Suggestion from Solar */
	    str_replace_unprintable(&proctitle_str, '?');
	    vsf_sysutil_setproctitle_str(&proctitle_str);
	    str_free(&proctitle_str);
	  }
	  if (str_equal_text(&p_sess->ftp_cmd_str, "QUIT"))
	  {
	    vsf_cmdio_write(p_sess, FTP_GOODBYE, "Goodbye.");
	    vsf_sysutil_exit(0);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "PWD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XPWD"))
	  {
	    handle_pwd(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "CWD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XCWD"))
	  {
	    handle_cwd(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "CDUP") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XCUP"))
	  {
	    handle_cdup(p_sess);
	  }
	  else if (tunable_pasv_enable &&
	           str_equal_text(&p_sess->ftp_cmd_str, "PASV"))
	  {
	    handle_pasv(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "RETR"))
	  {
	    handle_retr(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "NOOP"))
	  {
	    vsf_cmdio_write(p_sess, FTP_NOOPOK, "NOOP ok.");
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "SYST"))
	  {
	    vsf_cmdio_write(p_sess, FTP_SYSTOK, "UNIX Type: L8");
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "HELP"))
	  {
	    vsf_cmdio_write(p_sess, FTP_BADHELP, "Sorry, I don't have help.");
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "LIST"))
	  {
	    handle_list(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "TYPE"))
	  {
	    handle_type(p_sess);
	  }
	  else if (tunable_port_enable &&
	           str_equal_text(&p_sess->ftp_cmd_str, "PORT"))
	  {
	    handle_port(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_upload_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "STOR"))
	  {
	    handle_stor(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_mkdir_write_enable || !p_sess->is_anonymous) &&
	           (str_equal_text(&p_sess->ftp_cmd_str, "MKD") ||
	            str_equal_text(&p_sess->ftp_cmd_str, "XMKD")))
	  {
	    handle_mkd(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           (str_equal_text(&p_sess->ftp_cmd_str, "RMD") ||
	            str_equal_text(&p_sess->ftp_cmd_str, "XRMD")))
	  {
	    handle_rmd(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "DELE"))
	  {
	    handle_dele(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "REST"))
	  {
	    handle_rest(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "RNFR"))
	  {
	    handle_rnfr(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "RNTO"))
	  {
	    handle_rnto(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "NLST"))
	  {
	    handle_nlst(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "SIZE"))
	  {
	    handle_size(p_sess);
	  }
	  else if (!p_sess->is_anonymous &&
	           str_equal_text(&p_sess->ftp_cmd_str, "SITE"))
	  {
	    handle_site(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "ABOR"))
	  {
	    vsf_cmdio_write(p_sess, FTP_ABOR_NOCONN, "No transfer to ABOR.");
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "APPE"))
	  {
	    handle_appe(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "MDTM"))
	  {
	    handle_mdtm(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "PASV") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "PORT") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "STOR") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "MKD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XMKD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "RMD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XRMD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "DELE") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "RNFR") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "RNTO") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "SITE") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "APPE"))
	  {
	    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");
	  }
	  else
	  {
	    vsf_cmdio_write(p_sess, FTP_BADCMD, "Unknown command.");
	  }
	}

}
Пример #29
0
time_t
cook_mtime_newest(const opcode_context_ty *ocp, string_ty *path,
    long *depth_p, long max_fp_depth)
{
    time_t          result;

    trace(("cook_mtime_newest(path = \"%s\")\n{\n", path->str_text));
    if (path->str_text[0] == '/')
    {
        result = os_mtime_newest(path);
        *depth_p = 0;
    }
    else
    {
        fp_value_ty     *prv_fp;
        string_list_ty  sl;
        size_t          j;

        prv_fp = 0;
        result = 0;
        cook_search_list(ocp, &sl);
        *depth_p = sl.nstrings;
        for (j = 0; j < sl.nstrings; ++j)
        {
            fp_value_ty     *fp;
            string_ty       *s1;
            string_ty       *s2;
            time_t          t;

            s1 = sl.string[j];
            s2 = os_path_cat(s1, path);

            /*
             * This allows the safe use of fp_search below,
             * since os_mtime_newest updates the fingerprint
             * cache for the file.
             */
            t = os_mtime_newest(s2);

            if (!t)
            {
                /* File was not found */
                str_free(s2);
                continue;
            }

            trace(("mtime(\"%s\") was %ld\n", s2->str_text, (long)t));

            /* File found */
            if (!prv_fp)
            {
                /* Shallowest file found */
                result = t;
                *depth_p = j;
                trace(("is the first\n"));

                if (option_test(OPTION_FINGERPRINT))
                {
                    prv_fp = fp_search(s2);
                    if (prv_fp)
                    {
                        /* Look for deeper copies */
                        str_free(s2);
                        continue;
                    }
                }
                str_free(s2);
                break;
            }

            /* Found a deeper version */
            assert(option_test(OPTION_FINGERPRINT));
            if ((long)j >= max_fp_depth)
            {
                str_free(s2);
                break;
            }
            fp = fp_search(s2);
            str_free(s2);

            if
            (
                fp
            &&
                str_equal
                (
                    fp->contents_fingerprint,
                    prv_fp->contents_fingerprint
                )
            )
            {
                /* Deeper version is same as shallow one */
                if (t > result)
                    result = t;
                /* do not alter depth */
            }
            else
            {
                trace(("was different\n"));
                break;
            }
        }
        string_list_destructor(&sl);
    }
    trace(("return %ld (%d);\n", (long)result, *depth_p));
    trace(("}\n"));
    return result;
}
Пример #30
0
void
match_free(struct match *match)
{
	str_free(match->str);
	free(match);
}