Example #1
0
int dmenu_switcher_dialog ( char **input )
{
    char          *dmenu_prompt = "dmenu ";
    int           selected_line = -1;
    int           retv          = FALSE;
    int           length        = 0;
    char          **list        = get_dmenu ( &length );
    int           restart       = FALSE;
    char          *message      = NULL;
    menu_match_cb filter        = token_match;

    find_arg_str ( "-mesg", &message );

    // By default we print the unescaped line back.
    char *format = "s";
    // This is here for compatibility reason.
    // Use -format 'i' instead.
    if ( find_arg (  "-i" ) >= 0 ) {
        format = "i";
    }
    // Allow user to override the output format.
    find_arg_str ( "-format", &format );
    // Check prompt
    find_arg_str (  "-p", &dmenu_prompt );
    find_arg_int (  "-l", &selected_line );
    // Urgent.
    char *str = NULL;
    find_arg_str (  "-u", &str );
    if ( str != NULL ) {
        parse_ranges ( str, &urgent_list, &num_urgent_list );
    }
    // Active
    str = NULL;
    find_arg_str (  "-a", &str );
    if ( str != NULL ) {
        parse_ranges ( str, &active_list, &num_active_list );
    }

    int only_selected = FALSE;
    if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) {
        only_selected = TRUE;
        if ( length == 0 ) {
            return TRUE;
        }
    }
    find_arg_str_alloc ( "-filter", input );

    if ( find_arg ( "-z" ) >= 0 ) {
        filter = fuzzy_token_match;
    }

    char *select = NULL;
    find_arg_str ( "-select", &select );
    if ( select != NULL ) {
        char **tokens = tokenize ( select, config.case_sensitive );
        int  i        = 0;
        for ( i = 0; i < length; i++ ) {
            if ( token_match ( tokens, list[i], config.case_sensitive, 0, NULL ) ) {
                selected_line = i;
                break;
            }
        }
        g_strfreev ( tokens );
    }

    do {
        int next_pos = selected_line;
        int mretv    = menu ( list, length, input, dmenu_prompt,
                              filter, NULL, &selected_line, config.levenshtein_sort, get_display_data, list, &next_pos, message );
        // Special behavior.
        if ( only_selected ) {
            /**
             * Select item mode.
             */
            restart = ( find_arg ( "-only-match" ) >= 0 );
            if ( ( mretv & ( MENU_OK | MENU_QUICK_SWITCH ) ) && list[selected_line] != NULL ) {
                dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input );
                retv = TRUE;
                if ( ( mretv & MENU_QUICK_SWITCH ) ) {
                    retv = 10 + ( mretv & MENU_LOWER_MASK );
                }
                return retv;
            }
            selected_line = next_pos - 1;
            continue;
        }
        // We normally do not want to restart the loop.
        restart = FALSE;
        // Normal mode
        if ( ( mretv & MENU_OK  ) && list[selected_line] != NULL ) {
            dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input );
            if ( ( mretv & MENU_SHIFT ) ) {
                restart = TRUE;
                // Move to next line.
                selected_line = MIN ( next_pos, length - 1 );
            }
            retv = TRUE;
        }
        // Custom input
        else if ( ( mretv & ( MENU_CUSTOM_INPUT ) ) ) {
            dmenu_output_formatted_line ( format, *input, -1, *input );
            if ( ( mretv & MENU_SHIFT ) ) {
                restart = TRUE;
                // Move to next line.
                selected_line = MIN ( next_pos, length - 1 );
            }

            retv = TRUE;
        }
        // Quick switch with entry selected.
        else if ( ( mretv & MENU_QUICK_SWITCH ) && selected_line >= 0 ) {
            dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input );

            restart = FALSE;
            retv    = 10 + ( mretv & MENU_LOWER_MASK );
        }
        // Quick switch without entry selected.
        else if ( ( mretv & MENU_QUICK_SWITCH ) && selected_line == -1 ) {
            dmenu_output_formatted_line ( format, *input, -1, *input );

            restart = FALSE;
            retv    = 10 + ( mretv & MENU_LOWER_MASK );
        }
    } while ( restart );

    g_strfreev ( list );
    g_free ( urgent_list );
    g_free ( active_list );

    return retv;
}
Example #2
0
static int dmenu_mode_init ( Mode *sw )
{
    if ( mode_get_private_data ( sw ) != NULL ) {
        return TRUE;
    }
    mode_set_private_data ( sw, g_malloc0 ( sizeof ( DmenuModePrivateData ) ) );
    DmenuModePrivateData *pd = (DmenuModePrivateData *) mode_get_private_data ( sw );

    pd->prompt        = "dmenu ";
    pd->separator     = '\n';
    pd->selected_line = UINT32_MAX;

    find_arg_str ( "-mesg", &( pd->message ) );

    // Input data separator.
    find_arg_char ( "-sep", &( pd->separator ) );

    // Check prompt
    find_arg_str (  "-p", &( pd->prompt ) );
    find_arg_uint (  "-selected-row", &( pd->selected_line ) );
    // By default we print the unescaped line back.
    pd->format = "s";

    // Allow user to override the output format.
    find_arg_str ( "-format", &( pd->format ) );
    // Urgent.
    char *str = NULL;
    find_arg_str (  "-u", &str );
    if ( str != NULL ) {
        parse_ranges ( str, &( pd->urgent_list ), &( pd->num_urgent_list ) );
    }
    // Active
    str = NULL;
    find_arg_str (  "-a", &str );
    if ( str != NULL ) {
        parse_ranges ( str, &( pd->active_list ), &( pd->num_active_list ) );
    }

    // DMENU COMPATIBILITY
    find_arg_uint (  "-l", &( config.menu_lines ) );

    /**
     * Dmenu compatibility.
     * `-b` put on bottom.
     */
    if ( find_arg ( "-b" ) >= 0 ) {
        config.location = 6;
    }
    /* -i case insensitive */
    config.case_sensitive = TRUE;
    if ( find_arg ( "-i" ) >= 0 ) {
        config.case_sensitive = FALSE;
    }
    FILE *fd = NULL;
    str = NULL;
    if ( find_arg_str ( "-input", &str ) ) {
        char *estr = rofi_expand_path ( str );
        fd = fopen ( str, "r" );
        if ( fd == NULL ) {
            char *msg = g_markup_printf_escaped ( "Failed to open file: <b>%s</b>:\n\t<i>%s</i>", estr, strerror ( errno ) );
            rofi_view_error_dialog ( msg, TRUE );
            g_free ( msg );
            g_free ( estr );
            return TRUE;
        }
        g_free ( estr );
    }
    pd->cmd_list = get_dmenu ( pd, fd == NULL ? stdin : fd, &( pd->cmd_list_length ) );
    if ( fd != NULL ) {
        fclose ( fd );
    }
    return TRUE;
}
Example #3
0
// XXX fixme
static void
solve_op(enum R_OP op)
{
    target_addr_t rv = 0;
    struct R_OPDEF *r = &optab[op];
    if (r->addr) {
        return;
    }
    if (!binmap) {
        r->addr = 0xFF000000 + op;
        return;
    }
    if (!ranges) {
        ranges = parse_ranges(binmap);
    }
    switch (op) {
        case NOP:
        case LABEL:
        case BX_IMM:
        case BX_IMM_1:
            return;
        case LDR_R4:
            rv = parse_gadgets(ranges, binmap, NULL, is_LOAD_R4);
            break;
        case LDR_R0:
            rv = parse_gadgets(ranges, binmap, NULL, is_LOAD_R0);
            break;
        case LDR_R0R1:
            rv = parse_gadgets(ranges, binmap, NULL, is_LOAD_R0R1);
            break;
        case LDR_R0TO3:
            rv = parse_gadgets(ranges, binmap, NULL, is_LOAD_R0R3);
            break;
        case LDR_R0_R0:
            rv = parse_gadgets(ranges, binmap, NULL, is_LOAD_R0);
            break;
        case ADD_R0_R1:
            rv = parse_gadgets(ranges, binmap, NULL, is_ADD_R0_R1);
            break;
        case MOV_R1_R0: {
            const unsigned char *pp[2] = { NULL, NULL };
            rv = parse_gadgets(ranges, binmap, pp, solve_MOV_Rx_R0, 1);
            if (pp[1]) {
                rv = (target_addr_t)(uintptr_t)pp[1];
                r->output = *pp[0];
                r->auxout = r->output;
            }
            break;
        }
        case MOV_R0_R1:
            rv = parse_gadgets(ranges, binmap, NULL, is_MOV_R0_Rx, 1);
            break;
        case ADD_SP: {
            const unsigned char *pp[3] = { NULL, NULL, NULL };
            rv = parse_gadgets(ranges, binmap, pp, solve_ADD_SP, inloop_stack);
            if (pp[1]) {
                rv = (target_addr_t)(uintptr_t)pp[1];
                r->output = *pp[0];
                r->auxout = r->output;
                r->spill = r->output;
                r->incsp = (int)(long)pp[2];
            }
            break;
        }
        case BLX_R4:
            rv = parse_gadgets(ranges, binmap, NULL, is_BLX_R4);
            break;
        case BLX_R4_1:
        case BLX_R4_2:
        case BLX_R4_3:
        case BLX_R4_4: {
            const unsigned char *pp[2] = { NULL, NULL };
            rv = parse_gadgets(ranges, binmap, pp, solve_BLX_R4_SP, r->incsp);
            if (pp[1]) {
                rv = (target_addr_t)(uintptr_t)pp[1];
                r->output = *pp[0];
                r->auxout = r->output;
            }
            break;
        }
        case STR_R0_R4:
            rv = parse_gadgets(ranges, binmap, NULL, is_STR_R0_R4);
            break;
        case CMP_R0:
            rv = parse_gadgets(ranges, binmap, NULL, is_COMPARE);
            break;
        case LDR_R4R5:
            rv = parse_gadgets(ranges, binmap, NULL, is_LOAD_R4R5);
            break;
        case LDMIA_R0:
        case LDMIA_R0_C: {
            const unsigned char *p;
            rv = parse_gadgets(ranges, binmap, &p, is_ldmia, 0, -1, R0|R4);
            if (rv) {
                r->output = (p[1] << 8) | p[0];
                r->auxout = r->output & ~(SP|PC);
            } else {
                rv = parse_gadgets(ranges, binmap, &p, is_ldmiaw, 0, -1, 0);
                if (rv) {
                    r->output = (p[3] << 8) | p[2];
                    r->auxout = r->output & ~(SP|PC);
                }
            }
            break;
        }
    }
    if (!rv) {
        die("undefined gadget '%s'\n", r->text);
    }
    r->addr = rv;
}
Example #4
0
int
server_partial_file_request(struct httpd *env, struct client *clt, char *path,
    struct stat *st, char *range_str)
{
	struct server_config	*srv_conf = clt->clt_srv_conf;
	struct http_descriptor	*resp = clt->clt_descresp;
	struct http_descriptor	*desc = clt->clt_descreq;
	struct media_type	*media, multipart_media;
	struct range_data	*r = &clt->clt_ranges;
	struct range		*range;
	size_t			 content_length = 0;
	int			 code = 500, fd = -1, i, nranges, ret;
	char			 content_range[64];
	const char		*errstr = NULL;

	/* Ignore range request for methods other than GET */
	if (desc->http_method != HTTP_METHOD_GET)
		return server_file_request(env, clt, path, st);

	if ((nranges = parse_ranges(clt, range_str, st->st_size)) < 1) {
		code = 416;
		(void)snprintf(content_range, sizeof(content_range),
		    "bytes */%lld", st->st_size);
		errstr = content_range;
		goto abort;
	}

	/* Now open the file, should be readable or we have another problem */
	if ((fd = open(path, O_RDONLY)) == -1)
		goto abort;

	media = media_find_config(env, srv_conf, path);
	r->range_media = media;

	if (nranges == 1) {
		range = &r->range[0];
		(void)snprintf(content_range, sizeof(content_range),
		    "bytes %lld-%lld/%lld", range->start, range->end,
		    st->st_size);
		if (kv_add(&resp->http_headers, "Content-Range",
		    content_range) == NULL)
			goto abort;

		range = &r->range[0];
		content_length += range->end - range->start + 1;
	} else {
		/* Add boundary, all parts will be handled by the callback */
		arc4random_buf(&clt->clt_boundary, sizeof(clt->clt_boundary));

		/* Calculate Content-Length of the complete multipart body */
		for (i = 0; i < nranges; i++) {
			range = &r->range[i];

			/* calculate Content-Length of the complete body */
			if ((ret = snprintf(NULL, 0,
			    "\r\n--%llu\r\n"
			    "Content-Type: %s/%s\r\n"
			    "Content-Range: bytes %lld-%lld/%lld\r\n\r\n",
			    clt->clt_boundary,
			    media->media_type, media->media_subtype,
			    range->start, range->end, st->st_size)) < 0)
				goto abort;

			/* Add data length */
			content_length += ret + range->end - range->start + 1;

		}
		if ((ret = snprintf(NULL, 0, "\r\n--%llu--\r\n",
		    clt->clt_boundary)) < 0)
			goto abort;
		content_length += ret;

		/* prepare multipart/byteranges media type */
		(void)strlcpy(multipart_media.media_type, "multipart",
		    sizeof(multipart_media.media_type));
		(void)snprintf(multipart_media.media_subtype,
		    sizeof(multipart_media.media_subtype),
		    "byteranges; boundary=%llu", clt->clt_boundary);
		media = &multipart_media;
	}

	/* Start with first range */
	r->range_toread = TOREAD_HTTP_RANGE;

	ret = server_response_http(clt, 206, media, content_length,
	    MINIMUM(time(NULL), st->st_mtim.tv_sec));
	switch (ret) {
	case -1:
		goto fail;
	case 0:
		/* Connection is already finished */
		close(fd);
		goto done;
	default:
		break;
	}

	clt->clt_fd = fd;
	if (clt->clt_srvbev != NULL)
		bufferevent_free(clt->clt_srvbev);

	clt->clt_srvbev_throttled = 0;
	clt->clt_srvbev = bufferevent_new(clt->clt_fd, server_read_httprange,
	    server_write, server_file_error, clt);
	if (clt->clt_srvbev == NULL) {
		errstr = "failed to allocate file buffer event";
		goto fail;
	}

	/* Adjust read watermark to the socket output buffer size */
	bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
	    clt->clt_sndbufsiz);

	bufferevent_settimeout(clt->clt_srvbev,
	    srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
	bufferevent_enable(clt->clt_srvbev, EV_READ);
	bufferevent_disable(clt->clt_bev, EV_READ);

 done:
	server_reset_http(clt);
	return (0);
 fail:
	bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE);
	bufferevent_free(clt->clt_bev);
	clt->clt_bev = NULL;
 abort:
	if (fd != -1)
		close(fd);
	if (errstr == NULL)
		errstr = strerror(errno);
	server_abort_http(clt, code, errstr);
	return (-1);
}