Exemplo n.º 1
0
const char *
auto_recode(const char *utf_str)
{
	char *res;
	static char result_buf[MAX_BUFSIZE];
	if (is_ascii_string (utf_str)) {
		res = (char*)utf_str;
	} else if (utf8_validate (utf_str)) {
		/* UTF-8 string */
		/* Replace em dash with "#$%" sequence */
		const char *utf_src = utf_str;
		char iso_8859_1[MAX_BUFSIZE];
		if (simple_recode (utf_str, "UTF-8", "ISO8859-1", iso_8859_1) &&
				utf8_validate(iso_8859_1))
			utf_src = iso_8859_1;
		/* Now find out, how is UTF-8 string constructed */
		if (is_cp1251 (utf_src)) {
			/* May be ISO8859-1 or CP1251 */
			char tmp[MAX_BUFSIZE];
			res = simple_recode (utf_src, "UTF-8", "ISO8859-1", tmp);
			if (res) res = simple_recode (res, "CP1251", "UTF-8", result_buf);
			if (!res) res = (char*)utf_src;
		} else {
			res = strncpy(result_buf, utf_src, MAX_BUFSIZE);
		}
	} else {
		res = simple_recode (utf_str, "CP1251", "UTF-8", result_buf);
		if (!res) res = (char*)utf_str;
	}
	return res;
}
Exemplo n.º 2
0
Arquivo: gutf8.c Projeto: Joe-xXx/mono
/**
 * g_utf8_validate:
 * @str: a utf-8 encoded string
 * @max_len: max number of bytes to validate (or -1 to validate the entire null-terminated string)
 * @end: output parameter to mark the end of the valid input
 *
 * Checks @utf for being valid UTF-8. @str is assumed to be
 * null-terminated. This function is not super-strict, as it will
 * allow longer UTF-8 sequences than necessary. Note that Java is
 * capable of producing these sequences if provoked. Also note, this
 * routine checks for the 4-byte maximum size, but does not check for
 * 0x10ffff maximum value.
 *
 * Return value: %TRUE if @str is valid or %FALSE otherwise.
 **/
gboolean
g_utf8_validate (const gchar *str, gssize max_len, const gchar **end)
{
	guchar *inptr = (guchar *) str;
	gboolean valid = TRUE;
	guint length, min;
	gssize n = 0;
	
	if (max_len == 0)
		return FALSE;
	
	if (max_len < 0) {
		while (*inptr != 0) {
			length = g_utf8_jump_table[*inptr];
			if (!utf8_validate (inptr, length)) {
				valid = FALSE;
				break;
			}
			
			inptr += length;
		}
	} else {
		while (n < max_len) {
			if (*inptr == 0) {
				/* Note: return FALSE if we encounter nul-byte
				 * before max_len is reached. */
				valid = FALSE;
				break;
			}
			
			length = g_utf8_jump_table[*inptr];
			min = MIN (length, max_len - n);
			
			if (!utf8_validate (inptr, min)) {
				valid = FALSE;
				break;
			}
			
			if (min < length) {
				valid = FALSE;
				break;
			}
			
			inptr += length;
			n += length;
		}
	}
	
	if (end != NULL)
		*end = (gchar *) inptr;
	
	return valid;
}
Exemplo n.º 3
0
Arquivo: gutf8.c Projeto: Joe-xXx/mono
gunichar
g_utf8_get_char_validated (const gchar *str, gssize max_len)
{
	unsigned char *inptr = (unsigned char *) str;
	gunichar u = *inptr;
	int n, i;
	
	if (max_len == 0)
		return -2;
	
	if (u < 0x80) {
		/* simple ascii case */
		return u;
	} else if (u < 0xc2) {
		return -1;
	} else if (u < 0xe0) {
		u &= 0x1f;
		n = 2;
	} else if (u < 0xf0) {
		u &= 0x0f;
		n = 3;
	} else if (u < 0xf8) {
		u &= 0x07;
		n = 4;
	} else if (u < 0xfc) {
		u &= 0x03;
		n = 5;
	} else if (u < 0xfe) {
		u &= 0x01;
		n = 6;
	} else {
		return -1;
	}
	
	if (max_len > 0) {
		if (!utf8_validate (inptr, MIN (max_len, n)))
			return -1;
		
		if (max_len < n)
			return -2;
	} else {
		if (!utf8_validate (inptr, n))
			return -1;
	}
	
	for (i = 1; i < n; i++)
		u = (u << 6) | (*++inptr ^ 0x80);
	
	return u;
}
Exemplo n.º 4
0
static void add_tag(vorbis_comment *vc, oe_options *opt,char *name, char *value)
{
    char *utf8;
    if (opt->isutf8)
    {
	if (!utf8_validate(value)) {
	    fprintf(stderr, _("'%s' is not valid UTF-8, cannot add\n"), name?name:"comment");
	} else {
	    if(name == NULL) {
		vorbis_comment_add(vc, value);
            }
            else {
		vorbis_comment_add_tag(vc, name, value);
            }
	}
    }
    else if(utf8_encode(value, &utf8) >= 0)
    {
        if(name == NULL) {
            vorbis_comment_add(vc, utf8);
        }
        else {
            vorbis_comment_add_tag(vc, name, utf8);
        }
        free(utf8);
    }
    else {
        fprintf(stderr, _("Couldn't convert comment to UTF-8, cannot add\n"));
    }
}
Exemplo n.º 5
0
char* pa_utf8_filter (const char *str) {
    char *new_str;

    pa_assert(str);
    new_str = pa_xmalloc(strlen(str) + 1);
    return utf8_validate(str, new_str);
}
Exemplo n.º 6
0
std::string
parseDisplayName(const pjsip_name_addr* sip_name_addr)
{
    if (not sip_name_addr->display.ptr or not sip_name_addr->display.slen)
        return {};

    std::string displayName {sip_name_addr->display.ptr,
            static_cast<size_t>(sip_name_addr->display.slen)};

    // Filter out invalid UTF-8 characters to avoid getting kicked from D-Bus
    if (not utf8_validate(displayName))
        return utf8_make_valid(displayName);

    return displayName;
}
Exemplo n.º 7
0
static inline int
enc_string(Encoder* e, ERL_NIF_TERM val)
{
    ErlNifBinary bin;
    char atom[512];

    unsigned char* data;
    size_t size;

    int esc_extra = 0;
    int ulen;
    int uval;
    int i;

    if(enif_is_binary(e->env, val)) {
        if(!enif_inspect_binary(e->env, val, &bin)) {
            return 0;
        }
        data = bin.data;
        size = bin.size;
    } else if(enif_is_atom(e->env, val)) {
        if(!enif_get_atom(e->env, val, atom, 512, ERL_NIF_LATIN1)) {
            return 0;
        }
        data = (unsigned char*) atom;
        size = strlen(atom);
    } else {
        return 0;
    }

    i = 0;
    while(i < size) {
        switch((char) data[i]) {
            case '\"':
            case '\\':
            case '\b':
            case '\f':
            case '\n':
            case '\r':
            case '\t':
                esc_extra += 1;
                i++;
                continue;
            default:
                if(data[i] < 0x20) {
                    esc_extra += 5;
                    i++;
                    continue;
                } else if(data[i] < 0x80) {
                    i++;
                    continue;
                }
                ulen = utf8_validate(&(data[i]), size - i);
                if(ulen < 0) {
                    return 0;
                }
                if(e->uescape) {
                    uval = utf8_to_unicode(&(data[i]), ulen);
                    if(uval < 0) {
                        return 0;
                    }
                    esc_extra += utf8_esc_len(uval);
                    if(ulen < 0) {
                        return 0;
                    }
                }
                i += ulen;
        }
    }

    if(!enc_ensure(e, size + esc_extra + 2)) {
        return 0;
    }

    e->p[e->i++] = '\"';

    i = 0;
    while(i < size) {
        switch((char) data[i]) {
            case '\"':
            case '\\':
                e->p[e->i++] = '\\';
                e->u[e->i++] = data[i];
                i++;
                continue;
            case '\b':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'b';
                i++;
                continue;
            case '\f':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'f';
                i++;
                continue;
            case '\n':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'n';
                i++;
                continue;
            case '\r':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 'r';
                i++;
                continue;
            case '\t':
                e->p[e->i++] = '\\';
                e->p[e->i++] = 't';
                i++;
                continue;
            default:
                if(data[i] < 0x20) {
                    ulen = unicode_uescape(data[i], &(e->p[e->i]));
                    if(ulen < 0) {
                        return 0;
                    }
                    e->i += ulen;
                    i++;
                } else if((data[i] & 0x80) && e->uescape) {
                    uval = utf8_to_unicode(&(data[i]), size-i);
                    if(uval < 0) {
                        return 0;
                    }

                    ulen = unicode_uescape(uval, &(e->p[e->i]));
                    if(ulen < 0) {
                        return 0;
                    }
                    e->i += ulen;

                    ulen = utf8_len(uval);
                    if(ulen < 0) {
                        return 0;
                    }
                    i += ulen;
                } else {
                    e->u[e->i++] = data[i++];
                }
        }
    }

    e->p[e->i++] = '\"';
    e->count++;

    return 1;
}
Exemplo n.º 8
0
char* pa_utf8_valid (const char *str) {
    return utf8_validate(str, NULL);
}
int main(void)
{
	int trial;
	
	plan_tests(TRIAL_COUNT);
	
	for (trial = 1; trial <= TRIAL_COUNT; trial++) {
		int i, count;
		uchar_t codepoints[MAX_CHARS_PER_TRIAL];
		uchar_t c;
		bool c_valid;
		
		char write_buffer[MAX_CHARS_PER_TRIAL * 4];
		char *o = write_buffer;
		char *oe = write_buffer + sizeof(write_buffer);
		
		char *string;
		const char *s;
		const char *e;
		
		int len;
		
		count = rand32() % MAX_CHARS_PER_TRIAL + 1;
		
		for (i = 0; i < count; i++) {
			if (o >= oe) {
				fail("utf8_write_char: Buffer overflow (1)");
				goto next_trial;
			}
			
			switch (rand32() % 7) {
				case 0:
					c = range(rand32(), 0x0, 0x7F);
					c_valid = true;
					break;
				case 1:
					c = range(rand32(), 0x80, 0x7FF);
					c_valid = true;
					break;
				case 2:
					c = range(rand32(), 0x800, 0xD7FF);
					c_valid = true;
					break;
				case 3:
					c = range(rand32(), 0xD800, 0xDFFF);
					c_valid = false;
					break;
				case 4:
					c = range(rand32(), 0xE000, 0xFFFF);
					c_valid = true;
					break;
				case 5:
					c = range(rand32(), 0x10000, 0x10FFFF);
					c_valid = true;
					break;
				default:
					do {
						c = rand32();
					} while (c < 0x110000);
					c_valid = false;
					break;
			}
			
			codepoints[i] = c_valid ? c : REPLACEMENT_CHARACTER;
			
			len = utf8_write_char(c, o);
			if (len < 1 || len > 4) {
				fail("utf8_write_char: Return value is not 1 thru 4.");
				goto next_trial;
			}
			o += len;
		}
		if (o > oe) {
			fail("utf8_write_char: Buffer overflow (2)");
			goto next_trial;
		}
		
		string = malloc(o - write_buffer);
		memcpy(string, write_buffer, o - write_buffer);
		s = string;
		e = string + (o - write_buffer);
		
		if (!utf8_validate(s, e - s)) {
			fail("Invalid string produced by utf8_write_char.");
			goto next_trial_free_string;
		}
		
		for (i = 0; i < count; i++) {
			if (s >= e) {
				fail("utf8_read_char: Buffer overflow (1)");
				goto next_trial_free_string;
			}
			
			len = utf8_read_char(s, &c);
			if (len < 1 || len > 4) {
				fail("utf8_read_char: Return value is not 1 thru 4.");
				goto next_trial_free_string;
			}
			if (c != codepoints[i]) {
				fail("utf8_read_char: Character read differs from that written.");
				goto next_trial_free_string;
			}
			s += len;
		}
		if (s > e) {
			fail("utf8_read_char: Buffer overflow (2)");
			goto next_trial_free_string;
		}
		if (s < e) {
			fail("utf8_read_char: Did not reach end of string.");
			goto next_trial_free_string;
		}
		
		pass("Trial %d: %d characters", trial, count);
		
	next_trial_free_string:
		free(string);
	next_trial:;
	}
	
	return exit_status();
}
Exemplo n.º 10
0
int
dec_string(Decoder* d, ERL_NIF_TERM* value)
{
    int has_escape = 0;
    int num_escapes = 0;
    int st;
    int ulen;
    int ui;
    int hi;
    int lo;
    char* chrbuf;
    int chrpos;

    if(d->p[d->i] != '\"') {
        return 0;
    }
    d->i++;

    st = d->i;

    while(d->i < d->len) {
        if(d->u[d->i] < 0x20) {
            return 0;
        } else if(d->p[d->i] == '\"') {
            d->i++;
            goto parse;
        } else if(d->p[d->i] == '\\') {
            if(d->i+1 >= d->len) {
                return 0;
            }
            has_escape = 1;
            num_escapes += 1;
            d->i++;
            switch(d->p[d->i]) {
                case '\"':
                case '\\':
                case '/':
                case 'b':
                case 'f':
                case 'n':
                case 'r':
                case 't':
                    d->i++;
                    break;
                case 'u':
                    hi = 0;
                    lo = 0;
                    d->i++;
                    if(d->i + 4 >= d->len) {
                        return 0;
                    }
                    hi = int_from_hex(&(d->u[d->i]));
                    if(hi < 0) {
                        return 0;
                    }
                    d->i += 4;
                    if(hi >= 0xD800 && hi < 0xDC00) {
                        if(d->i + 6 >= d->len) {
                            return 0;
                        }
                        if(d->p[d->i++] != '\\') {
                            return 0;
                        } else if(d->p[d->i++] != 'u') {
                            return 0;
                        }
                        lo = int_from_hex(&(d->u[d->i]));
                        if(lo < 0) {
                            return 0;
                        }
                        hi = unicode_from_pair(hi, lo);
                        if(hi < 0) {
                            return 0;
                        }
                    }
                    hi = utf8_len(hi);
                    if(hi < 0) {
                        return 0;
                    }
                    if(lo == 0) {
                        num_escapes += 5 - hi;
                    } else {
                        num_escapes += 11 - hi;
                    }
                    break;
                default:
                    return 0;
            }
        } else if(d->u[d->i] < 0x80) {
            d->i++;
        } else {
            ulen = utf8_validate(&(d->u[d->i]), d->len - d->i);
            if(ulen < 0) {
                return 0;
            }
            d->i += ulen;
        }
    }

    // The goto above ensures that we only
    // hit this when a string is not terminated
    // correctly.
    return 0;

parse:
    if(!has_escape) {
        *value = enif_make_sub_binary(d->env, d->arg, st, (d->i - st - 1));
        return 1;
    }

    hi = 0;
    lo = 0;

    ulen = (d->i - 1) - st - num_escapes;
    chrbuf = (char*) enif_make_new_binary(d->env, ulen, value);
    chrpos = 0;
    ui = st;
    while(ui < d->i - 1) {
        if(d->p[ui] != '\\') {
            chrbuf[chrpos++] = d->p[ui++];
            continue;
        }
        ui++;
        switch(d->p[ui]) {
            case '\"':
            case '\\':
            case '/':
                chrbuf[chrpos++] = d->p[ui];
                ui++;
                break;
            case 'b':
                chrbuf[chrpos++] = '\b';
                ui++;
                break;
            case 'f':
                chrbuf[chrpos++] = '\f';
                ui++;
                break;
            case 'n':
                chrbuf[chrpos++] = '\n';
                ui++;
                break;
            case 'r':
                chrbuf[chrpos++] = '\r';
                ui++;
                break;
            case 't':
                chrbuf[chrpos++] = '\t';
                ui++;
                break;
            case 'u':
                ui++;
                hi = int_from_hex(&(d->u[ui]));
                if(hi < 0) {
                    return 0;
                }
                if(hi >= 0xD800 && hi < 0xDC00) {
                    lo = int_from_hex(&(d->u[ui+6]));
                    if(lo < 0) {
                        return 0;
                    }
                    hi = unicode_from_pair(hi, lo);
                    ui += 10;
                } else {
                    ui += 4;
                }
                hi = unicode_to_utf8(hi, (unsigned char*) chrbuf+chrpos);
                if(hi < 0) {
                    return 0;
                }
                chrpos += hi;
                break;
            default:
                return 0;
        }
    }

    return 1;
}
Exemplo n.º 11
0
gpgme_error_t
seahorse_passphrase_get (gconstpointer dummy, const gchar *passphrase_hint,
                         const char* passphrase_info, int flags, int fd)
{
	gchar **split_uid = NULL;
	gchar *label = NULL;
	gchar *errmsg = NULL;
	const gchar *pass;
	GcrPrompt *prompt;
	SyncClosure sync;
	GError *error = NULL;
	gchar *msg;

	sync.result = NULL;
	sync.loop = g_main_loop_new (NULL, FALSE);

	gcr_system_prompt_open_async (-1, NULL, on_sync_complete, &sync);

	g_main_loop_run (sync.loop);
	g_assert (sync.result != NULL);

	prompt = gcr_system_prompt_open_finish (sync.result, &error);

	g_main_loop_unref (sync.loop);
	g_object_unref (sync.result);

	if (error != NULL) {
		g_message ("Couldn't open system prompt: %s", error->message);
		g_error_free (error);
		return gpgme_error (GPG_ERR_CANCELED);
	}

	if (passphrase_info && strlen(passphrase_info) < 16)
		flags |= SEAHORSE_PASS_NEW;

	if (passphrase_hint)
		split_uid = g_strsplit (passphrase_hint, " ", 2);

	if (flags & SEAHORSE_PASS_BAD)
		errmsg = g_strdup_printf (_("Wrong passphrase."));

	if (split_uid && split_uid[0] && split_uid[1]) {
		if (flags & SEAHORSE_PASS_NEW)
			label = g_strdup_printf (_("Enter new passphrase for “%s”"), split_uid[1]);
		else
			label = g_strdup_printf (_("Enter passphrase for “%s”"), split_uid[1]);
	} else {
		if (flags & SEAHORSE_PASS_NEW)
			label = g_strdup (_("Enter new passphrase"));
		else
			label = g_strdup (_("Enter passphrase"));
	}

	g_strfreev (split_uid);

	gcr_prompt_set_message (prompt, _("Passphrase"));

	msg = utf8_validate (errmsg ? errmsg : label);
	gcr_prompt_set_description (prompt, msg);
	g_free (msg);

	gcr_prompt_set_password_new (prompt, flags & SEAHORSE_PASS_NEW);

	gcr_prompt_set_continue_label (prompt, _("OK"));
	gcr_prompt_set_cancel_label (prompt, _("Cancel"));

	g_free (label);
	g_free (errmsg);

	pass = gcr_prompt_password_run (prompt, NULL, &error);
	if (pass != NULL)
		seahorse_util_printf_fd (fd, "%s\n", pass);

	gcr_system_prompt_close_async (GCR_SYSTEM_PROMPT (prompt), NULL, NULL, NULL);
	g_object_unref (prompt);

	if (error != NULL) {
		g_message ("Couldn't prompt for password: %s", error->message);
		g_error_free (error);
		return gpgme_error (GPG_ERR_CANCELED);
	}

	return 0;
}
Exemplo n.º 12
0
GtkDialog*
seahorse_passphrase_prompt_show (const gchar *title, const gchar *description, 
                                 const gchar *prompt, const gchar *check,
                                 gboolean confirm)
{
    GtkEntryBuffer *buffer;
    GtkEntry *entry;
    GtkDialog *dialog;
    GtkWidget *w;
    GtkWidget *box;
    GtkTable *table;
    GtkWidget *wvbox;
    GtkWidget *chbox;
    gchar *msg;
    
    if (!title)
        title = _("Passphrase");

    if (!prompt)
        prompt = _("Password:"******"size-request", G_CALLBACK (constrain_size), NULL);
    g_signal_connect (G_OBJECT (dialog), "map-event", G_CALLBACK (grab_keyboard), NULL);
    g_signal_connect (G_OBJECT (dialog), "unmap-event", G_CALLBACK (ungrab_keyboard), NULL);
    g_signal_connect (G_OBJECT (dialog), "window-state-event", G_CALLBACK (window_state_changed), NULL); 

    wvbox = gtk_vbox_new (FALSE, HIG_LARGE * 2);
    gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), wvbox);
    gtk_container_set_border_width (GTK_CONTAINER (wvbox), HIG_LARGE);

    chbox = gtk_hbox_new (FALSE, HIG_LARGE);
    gtk_box_pack_start (GTK_BOX (wvbox), chbox, FALSE, FALSE, 0);

    /* The image */
    w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
    gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0);
    gtk_box_pack_start (GTK_BOX (chbox), w, FALSE, FALSE, 0);

    box = gtk_vbox_new (FALSE, HIG_SMALL);
    gtk_box_pack_start (GTK_BOX (chbox), box, TRUE, TRUE, 0);

    /* The description text */
    if (description) {
        msg = utf8_validate (description);
        w = gtk_label_new (msg);
        g_free (msg);

        gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
        gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
        gtk_box_pack_start (GTK_BOX (box), w, TRUE, FALSE, 0);
    }

    /* Two entries (usually on is hidden)  in a vbox */
    table = GTK_TABLE (gtk_table_new (3, 2, FALSE));
    gtk_table_set_row_spacings (table, HIG_SMALL);
    gtk_table_set_col_spacings (table, HIG_LARGE);
    gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (table), FALSE, FALSE, 0);

    /* The first entry if we have one */
    if (confirm) {
        msg = utf8_validate (prompt);
        w = gtk_label_new (msg);
        g_free (msg);
        gtk_table_attach (table, w, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);

        buffer = seahorse_secure_buffer_new ();
        entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
        g_object_unref (buffer);
        gtk_entry_set_visibility (entry, FALSE);
        gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1);
        g_object_set_data (G_OBJECT (dialog), "confirm-entry", entry);
        g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (confirm_callback), dialog);
        g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (entry_changed), dialog);
        gtk_table_attach_defaults (table, GTK_WIDGET (entry), 1, 2, 0, 1);
        gtk_widget_grab_focus (GTK_WIDGET (entry));
    }

    /* The second and main entry */
    msg = utf8_validate (confirm ? _("Confirm:") : prompt);
    w = gtk_label_new (msg);
    g_free (msg);
    gtk_table_attach (table, w, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);

    buffer = seahorse_secure_buffer_new ();
    entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
    g_object_unref (buffer);
    gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1);
    gtk_entry_set_visibility (entry, FALSE);
    g_object_set_data (G_OBJECT (dialog), "secure-entry", entry);
    g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (enter_callback), dialog);
    gtk_table_attach_defaults (table, GTK_WIDGET (entry), 1, 2, 1, 2);
    if (!confirm)
        gtk_widget_grab_focus (GTK_WIDGET (entry));
    else
        g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (entry_changed), dialog);

    /* The checkbox */
    if (check) {
        w = gtk_check_button_new_with_mnemonic (check);
        gtk_table_attach_defaults (table, w, 1, 2, 2, 3);
        g_object_set_data (G_OBJECT (dialog), "check-option", w);
    }

    gtk_widget_show_all (GTK_WIDGET (table));
    
    w = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
    gtk_dialog_add_action_widget (dialog, w, GTK_RESPONSE_REJECT);
    gtk_widget_set_can_default (w, TRUE);

    w = gtk_button_new_from_stock (GTK_STOCK_OK);
    gtk_dialog_add_action_widget (dialog, w, GTK_RESPONSE_ACCEPT);
    gtk_widget_set_can_default (w, TRUE);
    g_signal_connect_object (G_OBJECT (entry), "focus_in_event",
                             G_CALLBACK (gtk_widget_grab_default), G_OBJECT (w), 0);
    gtk_widget_grab_default (w);
    
    g_signal_connect (dialog, "key_press_event", G_CALLBACK (key_press), NULL);

    gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
    gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);    
    gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_NORMAL);
    gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
    gtk_widget_show_all (GTK_WIDGET (dialog));
    gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (dialog)), GDK_CURRENT_TIME);

    if (confirm)
        entry_changed (NULL, dialog);
    
    return dialog;
}