static int get_pkcs11_key_value(libzfs_handle_t *hdl, zfs_cmd_t *zc, zfs_crypto_zckey_t cmd, pkcs11_uri_t *p11uri, char **keydata, size_t *keydatalen) { KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; KMF_KEY_CLASS keyclass = KMF_SYMMETRIC; KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; KMF_ATTRIBUTE attr[10]; KMF_KEY_HANDLE keys; KMF_CREDENTIAL cred; KMF_RAW_SYM_KEY rkey; KMF_HANDLE_T kmfh; KMF_RETURN err; boolean_t true_val = B_TRUE; CK_SLOT_ID slot; CK_TOKEN_INFO info; size_t n = 0; uint32_t numkeys = 0; /* Ask for all of the named keys */ char *token = NULL; if (kmf_initialize(&kmfh, NULL, NULL) != KMF_OK) { errno = EINVAL; return (-1); } kmf_set_attr_at_index(attr, n++, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); if (p11uri->token) { token = strdup((const char *)p11uri->token); } else { /* If the token wasn't set we assume the metaslot */ token = strdup(METASLOT_TOKEN_LABEL); } kmf_set_attr_at_index(attr, n++, KMF_TOKEN_LABEL_ATTR, token, strlen(token)); kmf_set_attr_at_index(attr, n++, KMF_READONLY_ATTR, &true_val, sizeof (true_val)); kmf_set_attr_at_index(attr, n++, KMF_TOKEN_BOOL_ATTR, &true_val, sizeof (true_val)); err = kmf_configure_keystore(kmfh, n, attr); if (err != KMF_OK) goto out; if ((err = kmf_pk11_token_lookup(kmfh, token, &slot)) != KMF_OK || (err = C_GetTokenInfo(slot, &info)) != CKR_OK) goto out; /* Always prompt for PIN since the key is likey CKA_SENSITIVE */ if (prompt_pkcs11_pin(hdl, zc, cmd, p11uri, &cred.cred, &cred.credlen) != 0) goto out; kmf_set_attr_at_index(attr, n++, KMF_CREDENTIAL_ATTR, &cred, sizeof (KMF_CREDENTIAL)); kmf_set_attr_at_index(attr, n++, KMF_KEYLABEL_ATTR, p11uri->object, strlen((const char *)p11uri->object)); kmf_set_attr_at_index(attr, n++, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); kmf_set_attr_at_index(attr, n++, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); kmf_set_attr_at_index(attr, n++, KMF_COUNT_ATTR, &numkeys, sizeof (numkeys)); err = kmf_find_key(kmfh, n, attr); if (err != KMF_OK || numkeys != 1) goto out; kmf_set_attr_at_index(attr, n++, KMF_KEY_HANDLE_ATTR, &keys, sizeof (KMF_KEY_HANDLE)); err = kmf_find_key(kmfh, n, attr); err = kmf_get_sym_key_value(kmfh, &keys, &rkey); if (err != KMF_OK) goto out; if (rkey.keydata.len == *keydatalen) { *keydata = zfs_alloc(hdl, rkey.keydata.len); bcopy(rkey.keydata.val, *keydata, rkey.keydata.len); } *keydatalen = rkey.keydata.len; kmf_free_bigint(&rkey.keydata); out: if (token != NULL) free(token); (void) kmf_finalize(kmfh); if (numkeys == 1 && err == KMF_OK) { return (0); } else if (err == KMF_ERR_AUTH_FAILED) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "PKCS#11 token login failed.")); } else if (numkeys == 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "PKCS#11 token object not found.")); } else if (numkeys > 1) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "keysource points to multiple PKCS#11" " objects")); } ASSERT(errno != 0); return (-1); }
/* * Attempts to fetch key material, no matter where it might live. The key * material is allocated and returned in km_out. *can_retry_out will be set * to B_TRUE if the user is providing the key material interactively, allowing * for re-entry attempts. */ static int get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey, zfs_keyformat_t keyformat, char *keylocation, const char *fsname, uint8_t **km_out, size_t *kmlen_out, boolean_t *can_retry_out) { int ret, i; zfs_keylocation_t keyloc = ZFS_KEYLOCATION_NONE; FILE *fd = NULL; uint8_t *km = NULL, *km2 = NULL; size_t kmlen, kmlen2; boolean_t can_retry = B_FALSE; /* verify and parse the keylocation */ keyloc = zfs_prop_parse_keylocation(keylocation); /* open the appropriate file descriptor */ switch (keyloc) { case ZFS_KEYLOCATION_PROMPT: fd = stdin; if (isatty(fileno(fd))) { can_retry = B_TRUE; /* raw keys cannot be entered on the terminal */ if (keyformat == ZFS_KEYFORMAT_RAW) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Cannot enter raw keys on the terminal")); goto error; } } break; case ZFS_KEYLOCATION_URI: fd = fopen(&keylocation[7], "r"); if (!fd) { ret = errno; errno = 0; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Failed to open key material file")); goto error; } break; default: ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Invalid keylocation.")); goto error; } /* fetch the key material into the buffer */ ret = get_key_material_raw(fd, fsname, keyformat, B_FALSE, newkey, &km, &kmlen); if (ret != 0) goto error; /* do basic validation of the key material */ switch (keyformat) { case ZFS_KEYFORMAT_RAW: /* verify the key length is correct */ if (kmlen < WRAPPING_KEY_LEN) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Raw key too short (expected %u)."), WRAPPING_KEY_LEN); goto error; } if (kmlen > WRAPPING_KEY_LEN) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Raw key too long (expected %u)."), WRAPPING_KEY_LEN); goto error; } break; case ZFS_KEYFORMAT_HEX: /* verify the key length is correct */ if (kmlen < WRAPPING_KEY_LEN * 2) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Hex key too short (expected %u)."), WRAPPING_KEY_LEN * 2); goto error; } if (kmlen > WRAPPING_KEY_LEN * 2) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Hex key too long (expected %u)."), WRAPPING_KEY_LEN * 2); goto error; } /* check for invalid hex digits */ for (i = 0; i < WRAPPING_KEY_LEN * 2; i++) { if (!isxdigit((char)km[i])) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Invalid hex character detected.")); goto error; } } break; case ZFS_KEYFORMAT_PASSPHRASE: /* verify the length is within bounds */ if (kmlen > MAX_PASSPHRASE_LEN) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Passphrase too long (max %u)."), MAX_PASSPHRASE_LEN); goto error; } if (kmlen < MIN_PASSPHRASE_LEN) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Passphrase too short (min %u)."), MIN_PASSPHRASE_LEN); goto error; } break; default: /* can't happen, checked above */ break; } if (do_verify && isatty(fileno(fd))) { ret = get_key_material_raw(fd, fsname, keyformat, B_TRUE, newkey, &km2, &kmlen2); if (ret != 0) goto error; if (kmlen2 != kmlen || (memcmp((char *)km, (char *)km2, kmlen) != 0)) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Provided keys do not match.")); goto error; } } if (fd != stdin) fclose(fd); if (km2 != NULL) free(km2); *km_out = km; *kmlen_out = kmlen; if (can_retry_out != NULL) *can_retry_out = can_retry; return (0); error: if (km != NULL) free(km); if (km2 != NULL) free(km2); if (fd != NULL && fd != stdin) fclose(fd); *km_out = NULL; *kmlen_out = 0; if (can_retry_out != NULL) *can_retry_out = can_retry; return (ret); }
int zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props, nvlist_t *pool_props, uint8_t **wkeydata_out, uint_t *wkeylen_out) { int ret; char errbuf[1024]; uint64_t crypt = ZIO_CRYPT_INHERIT, pcrypt = ZIO_CRYPT_INHERIT; uint64_t keyformat = ZFS_KEYFORMAT_NONE; char *keylocation = NULL; zfs_handle_t *pzhp = NULL; uint8_t *wkeydata = NULL; uint_t wkeylen = 0; boolean_t local_crypt = B_TRUE; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "Encryption create error")); /* lookup crypt from props */ ret = nvlist_lookup_uint64(props, zfs_prop_to_name(ZFS_PROP_ENCRYPTION), &crypt); if (ret != 0) local_crypt = B_FALSE; /* lookup key location and format from props */ (void) nvlist_lookup_uint64(props, zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &keyformat); (void) nvlist_lookup_string(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation); if (parent_name != NULL) { /* get a reference to parent dataset */ pzhp = make_dataset_handle(hdl, parent_name); if (pzhp == NULL) { ret = ENOENT; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Failed to lookup parent.")); goto out; } /* Lookup parent's crypt */ pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION); /* Params require the encryption feature */ if (!encryption_feature_is_enabled(pzhp->zpool_hdl)) { if (proplist_has_encryption_props(props)) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Encryption feature not enabled.")); goto out; } ret = 0; goto out; } } else { /* * special case for root dataset where encryption feature * feature won't be on disk yet */ if (!nvlist_exists(pool_props, "feature@encryption")) { if (proplist_has_encryption_props(props)) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Encryption feature not enabled.")); goto out; } ret = 0; goto out; } pcrypt = ZIO_CRYPT_OFF; } /* Check for encryption being explicitly truned off */ if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Invalid encryption value. Dataset must be encrypted.")); goto out; } /* Get the inherited encryption property if we don't have it locally */ if (!local_crypt) crypt = pcrypt; /* * At this point crypt should be the actual encryption value. If * encryption is off just verify that no encryption properties have * been specified and return. */ if (crypt == ZIO_CRYPT_OFF) { if (proplist_has_encryption_props(props)) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Encryption must be turned on to set encryption " "properties.")); goto out; } ret = 0; goto out; } /* * If we have a parent crypt it is valid to specify encryption alone. * This will result in a child that is encrypted with the chosen * encryption suite that will also inherit the parent's key. If * the parent is not encrypted we need an encryption suite provided. */ if (pcrypt == ZIO_CRYPT_OFF && keylocation == NULL && keyformat == ZFS_KEYFORMAT_NONE) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Keyformat required for new encryption root.")); goto out; } /* * Specifying a keylocation implies this will be a new encryption root. * Check that a keyformat is also specified. */ if (keylocation != NULL && keyformat == ZFS_KEYFORMAT_NONE) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Keyformat required for new encryption root.")); goto out; } /* default to prompt if no keylocation is specified */ if (keyformat != ZFS_KEYFORMAT_NONE && keylocation == NULL) { keylocation = "prompt"; ret = nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION), keylocation); if (ret != 0) goto out; } /* * If a local key is provided, this dataset will be a new * encryption root. Populate the encryption params. */ if (keylocation != NULL) { ret = populate_create_encryption_params_nvlists(hdl, NULL, B_FALSE, keyformat, keylocation, props, &wkeydata, &wkeylen); if (ret != 0) goto out; } if (pzhp != NULL) zfs_close(pzhp); *wkeydata_out = wkeydata; *wkeylen_out = wkeylen; return (0); out: if (pzhp != NULL) zfs_close(pzhp); if (wkeydata != NULL) free(wkeydata); *wkeydata_out = NULL; *wkeylen_out = 0; return (ret); }
static void hn_others_menu_get_items (GtkMenu *menu, HNOthersButton *button, GtkTreeModel *model, GtkTreeIter *iter) { GtkMenu *submenu = NULL; GtkWidget *menu_item = NULL; gchar *item_name = NULL; gchar *item_comment = NULL; GdkPixbuf *item_icon = NULL; GdkPixbuf *item_thumb_icon = NULL; gchar *item_exec = NULL; gchar *item_service = NULL; gchar *item_desktop_id = NULL; gchar *item_text_domain = NULL; GtkTreeIter child_iter; gint children; gboolean my_iterator = FALSE; g_return_if_fail (menu); if (!model) { GtkTreeIter iter0; model = get_menu_contents(); iter = g_malloc0 (sizeof (GtkTreeIter)); my_iterator = TRUE; /* Get the top level iterator. */ if (!gtk_tree_model_get_iter_first(model, &iter0) || !gtk_tree_model_iter_children(model, iter, &iter0)) { g_object_unref (G_OBJECT (model)); return; } } else { g_object_ref (G_OBJECT (model)); } /* Loop! */ do { item_name = NULL; item_icon = NULL; item_thumb_icon = NULL; item_exec = NULL; item_service = NULL; item_desktop_id = NULL; item_text_domain = NULL; gtk_tree_model_get (model, iter, TREE_MODEL_NAME, &item_name, TREE_MODEL_ICON, &item_icon, TREE_MODEL_THUMB_ICON, &item_thumb_icon, TREE_MODEL_EXEC, &item_exec, TREE_MODEL_SERVICE, &item_service, TREE_MODEL_DESKTOP_ID, &item_desktop_id, TREE_MODEL_COMMENT, &item_comment, TREE_MODEL_TEXT_DOMAIN, &item_text_domain, -1); children = 0; /* If the item has children. */ if (gtk_tree_model_iter_children (model, &child_iter, iter)) { gchar *child_string = NULL; /* It's a submenu */ submenu = GTK_MENU (gtk_menu_new ()); gtk_widget_set_name (GTK_WIDGET (submenu), NAVIGATOR_MENU_NAME); /* Create a menu item and add it to the menu. */ children = gtk_tree_model_iter_n_children (model, iter); child_string = g_strdup_printf(MENU_ITEM_N_ITEMS (children), children); menu_item = hildon_thumb_menu_item_new_with_labels ( (item_text_domain && *item_text_domain) ? dgettext(item_text_domain, item_name): _(item_name), NULL, child_string); g_free(child_string); gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (menu_item)); /* Add the submenu icon */ if (item_icon && item_thumb_icon) { hildon_thumb_menu_item_set_images ( HILDON_THUMB_MENU_ITEM (menu_item), gtk_image_new_from_pixbuf (item_icon), gtk_image_new_from_pixbuf (item_thumb_icon)); } gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), GTK_WIDGET (submenu)); /* Recurse! */ hn_others_menu_get_items(submenu, button, model, &child_iter); } else if ( !item_desktop_id || strlen( item_desktop_id ) == 0 ) { /* Empty submenu. Skip "Extras" */ if (strcmp (item_name, "tana_fi_extras") != 0) { gchar *child_string; submenu = GTK_MENU(gtk_menu_new()); gtk_widget_set_name (GTK_WIDGET(submenu), NAVIGATOR_MENU_NAME); /* Create a menu item and add it to the menu. */ child_string = g_strdup_printf(MENU_ITEM_N_ITEMS(children), children); menu_item = hildon_thumb_menu_item_new_with_labels ( (item_text_domain && *item_text_domain)? dgettext(item_text_domain, item_name): dgettext("maemo-af-desktop", item_name), NULL, child_string); g_free(child_string); gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (menu_item)); /* Add the submenu icon */ if (item_icon) { hildon_thumb_menu_item_set_images( HILDON_THUMB_MENU_ITEM(menu_item), gtk_image_new_from_pixbuf(item_icon), gtk_image_new_from_pixbuf(item_thumb_icon)); } gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), GTK_WIDGET (submenu)); /* Create a menu item and add it to the menu. */ GtkWidget *submenu_item = gtk_image_menu_item_new_with_label (MENU_ITEM_EMPTY_SUBMENU_STRING); gtk_widget_set_sensitive (submenu_item, FALSE); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), GTK_WIDGET (submenu_item)); } } else if (strcmp(item_desktop_id, SEPARATOR_STRING) == 0) { /* Separator */ menu_item = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (menu_item)); } else { /* Application */ menu_item = hildon_thumb_menu_item_new_with_labels ( (item_text_domain && *item_text_domain)? dgettext(item_text_domain, item_name): dgettext("maemo-af-desktop", item_name), NULL, /* work around strange behaviour of gettext for * empty strings */ (item_comment && *item_comment)?_(item_comment):""); if (!item_icon) { item_icon = get_icon (MENU_ITEM_DEFAULT_APP_ICON, MENU_ITEM_ICON_SIZE); } if (!item_thumb_icon) { item_thumb_icon = get_icon (MENU_ITEM_DEFAULT_APP_ICON, MENU_ITEM_THUMB_ICON_SIZE); } if (item_icon && item_thumb_icon) { hildon_thumb_menu_item_set_images ( HILDON_THUMB_MENU_ITEM (menu_item), gtk_image_new_from_pixbuf (item_icon), gtk_image_new_from_pixbuf (item_thumb_icon)); } gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (menu_item)); g_object_set_data_full (G_OBJECT (menu_item), DESKTOP_ENTRY_EXEC_FIELD, g_strdup (item_exec), g_free); g_object_set_data_full (G_OBJECT(menu_item), DESKTOP_ENTRY_SERVICE_FIELD, g_strdup (item_service), g_free); /* Connect the signal and callback */ g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (hn_others_menu_activate_item), button); } g_free (item_name); if (item_icon) g_object_unref (G_OBJECT (item_icon)); if (item_thumb_icon) g_object_unref (G_OBJECT (item_thumb_icon)); g_free (item_exec); g_free (item_service); g_free (item_desktop_id); g_free (item_comment); g_free (item_text_domain); } while (gtk_tree_model_iter_next(model, iter)); if (my_iterator) { gtk_tree_iter_free (iter); g_debug ("ref count remaining on model %d (should be 1)", G_OBJECT (model)->ref_count); } g_object_unref (G_OBJECT (model)); }
int zfs_crypto_unload_key(zfs_handle_t *zhp) { int ret; char errbuf[1024]; char prop_encroot[MAXNAMELEN]; uint64_t keystatus, keyformat; boolean_t is_encroot; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "Key unload error")); /* check that encryption is enabled for the pool */ if (!encryption_feature_is_enabled(zhp->zpool_hdl)) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Encryption feature not enabled.")); ret = EINVAL; goto error; } /* Fetch the keyformat. Check that the dataset is encrypted. */ keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT); if (keyformat == ZFS_KEYFORMAT_NONE) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "'%s' is not encrypted."), zfs_get_name(zhp)); ret = EINVAL; goto error; } /* * Fetch the key location. Check that we are working with an * encryption root. */ ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to get encryption root for '%s'."), zfs_get_name(zhp)); goto error; } else if (!is_encroot) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Keys must be unloaded for encryption root of '%s' (%s)."), zfs_get_name(zhp), prop_encroot); ret = EINVAL; goto error; } /* check that the key is loaded */ keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS); if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key already unloaded for '%s'."), zfs_get_name(zhp)); ret = ENOENT; goto error; } /* call the ioctl */ ret = lzc_unload_key(zhp->zfs_name); if (ret != 0) { switch (ret) { case EPERM: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Permission denied.")); break; case ENOENT: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key already unloaded for '%s'."), zfs_get_name(zhp)); break; case EBUSY: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "'%s' is busy."), zfs_get_name(zhp)); break; } zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf); } return (ret); error: zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf); return (ret); }
char *_p_CDGetText (char *domainname, char *msgid) { return dgettext (domainname, msgid); }
recognizer recognizer_load(char* directory, char* name, char** subset) { recognizer rec; /*the recognizer*/ rec_info* rinf; /*rec_info for recognizer information*/ static bool intl_init = false; /*true if recog. manager initted.*/ if( intl_init == false ) { intl_init = true; intl_initialize(); } /*The name takes precedence.*/ rinf = make_rec_info(directory, name, subset); if (rinf == nil) { the_last_error = dgettext(INTL_DOMAIN, "Ran out of memory during prelinking initialization."); return((recognizer)nil); } /* fprint(2, "Got past make_rec_info.\n"); */ /*Let recognition code create recognizer and initialize*/ rec = __recognizer_internal_initialize(rinf); if (rec == nil) { return((recognizer)nil); } /* fprint(2, "Did rii.\n"); */ /*Check whether it's been correctly initialized*/ if( rec->recognizer_load_state == nil || rec->recognizer_save_state == nil || rec->recognizer_load_dictionary == nil || rec->recognizer_save_dictionary == nil || rec->recognizer_free_dictionary == nil || rec->recognizer_add_to_dictionary == nil || rec->recognizer_delete_from_dictionary == nil || rec->recognizer_error == nil || rec->recognizer_set_context == nil || rec->recognizer_get_context == nil || rec->recognizer_clear == nil || rec->recognizer_get_buffer == nil || rec->recognizer_set_buffer == nil || rec->recognizer_translate == nil || rec->recognizer_get_extension_functions == nil || rec->recognizer_get_gesture_names == nil || rec->recognizer_set_gesture_action == nil ) { recognizer_unload(rec); /* fprint(2, "Unloading b/c null function pointer.\n"); */ the_last_error = dgettext(INTL_DOMAIN, "One or more recognizer function pointers is nil."); return((recognizer)nil); } /*Set the rec_info structure.*/ rec->recognizer_info = rinf; /*Check whether home directory is there for recognizer info.*/ /* * ari -- don't bother. We're not going to load from each user's * home directory at this point. Instead, we'll use a stupid * little a-b-c file because it loads FAST. * * if( check_for_user_home() < 0 ) { * recognizer_unload(rec); * return((recognizer)nil); * } */ /*We got it!*/ /* fprint(2, "Done.\n"); */ return(rec); }
const char * uu_strerror(uint32_t code) { const char *str; switch (code) { case UU_ERROR_NONE: str = dgettext(TEXT_DOMAIN, "No error"); break; case UU_ERROR_INVALID_ARGUMENT: str = dgettext(TEXT_DOMAIN, "Invalid argument"); break; case UU_ERROR_UNKNOWN_FLAG: str = dgettext(TEXT_DOMAIN, "Unknown flag passed"); break; case UU_ERROR_NO_MEMORY: str = dgettext(TEXT_DOMAIN, "Out of memory"); break; case UU_ERROR_CALLBACK_FAILED: str = dgettext(TEXT_DOMAIN, "Callback-initiated failure"); break; case UU_ERROR_NOT_SUPPORTED: str = dgettext(TEXT_DOMAIN, "Operation not supported"); break; case UU_ERROR_EMPTY: str = dgettext(TEXT_DOMAIN, "No value provided"); break; case UU_ERROR_UNDERFLOW: str = dgettext(TEXT_DOMAIN, "Value too small"); break; case UU_ERROR_OVERFLOW: str = dgettext(TEXT_DOMAIN, "Value too large"); break; case UU_ERROR_INVALID_CHAR: str = dgettext(TEXT_DOMAIN, "Value contains unexpected character"); break; case UU_ERROR_INVALID_DIGIT: str = dgettext(TEXT_DOMAIN, "Value contains digit not in base"); break; case UU_ERROR_SYSTEM: str = dgettext(TEXT_DOMAIN, "Underlying system error"); break; case UU_ERROR_UNKNOWN: str = dgettext(TEXT_DOMAIN, "Error status not known"); break; default: errno = ESRCH; str = NULL; break; } return (str); }
static int rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp, struct share_info **entries_listp) { char ctx_string[2+16+1]; /* enough for 64-bit pointer, in hex */ unsigned_char_p_t binding; unsigned32 binding_status; rpc_binding_handle_t binding_h; int error, i, entries; char *addrstr, *srvnamestr; unsigned short *usrvnamestr; unsigned32 level; SHARE_ENUM_STRUCT share_info; SHARE_INFO_1_CONTAINER share_info_1_container; SHARE_INFO_1 *shares, *share; unsigned32 total_entries; unsigned32 status, free_status; struct share_info *entry_list, *elp; static EXCEPTION rpc_x_connect_rejected; static int exceptions_initialized; sprintf(ctx_string, "%p", ctx); rpc_string_binding_compose(NULL, "ncacn_np", ctx_string, "srvsvc", NULL, &binding, &binding_status); if (binding_status != rpc_s_ok) { smb_error(dgettext(TEXT_DOMAIN, "rpc_string_binding_compose failed with %d"), 0, binding_status); return (EINVAL); } rpc_binding_from_string_binding(binding, &binding_h, &status); rpc_string_free(&binding, (unsigned32 *)&free_status); if (binding_status != rpc_s_ok) { smb_error(dgettext(TEXT_DOMAIN, "rpc_binding_from_string_binding failed with %d"), 0, binding_status); return (EINVAL); } level = 1; share_info.share_union.level = 1; share_info.share_union.tagged_union.share1 = &share_info_1_container; share_info_1_container.share_count = 0; share_info_1_container.shares = NULL; /* * Convert the server IP address to a string, and send that as * the "server name" - that's what Windows appears to do, and * that avoids problems with NetBIOS names containing * non-ASCII characters. */ addrstr = inet_ntoa(ctx->ct_srvinaddr.sin_addr); srvnamestr = malloc(strlen(addrstr) + 3); if (srvnamestr == NULL) { status = errno; smb_error(dgettext(TEXT_DOMAIN, "can't allocate string for server address"), status); rpc_binding_free(&binding_h, &free_status); return (status); } strcpy(srvnamestr, "\\\\"); strcat(srvnamestr, addrstr); usrvnamestr = convert_utf8_to_leunicode(srvnamestr); if (usrvnamestr == NULL) { smb_error(dgettext(TEXT_DOMAIN, "can't convert string for server address to Unicode"), 0); rpc_binding_free(&binding_h, &free_status); free(srvnamestr); return (EINVAL); } if (!exceptions_initialized) { EXCEPTION_INIT(rpc_x_connect_rejected); exc_set_status(&rpc_x_connect_rejected, rpc_s_connect_rejected); exceptions_initialized = 1; } /* printf("Calling NetrShareEnum.."); XXX */ TRY status = NetrShareEnum(binding_h, usrvnamestr, &level, &share_info, 4294967295U, &total_entries, NULL); if (status != 0) smb_error(dgettext(TEXT_DOMAIN, "error from NetrShareEnum call: status = 0x%08x"), 0, status); /*CSTYLED*/ CATCH (rpc_x_connect_rejected) /* * This is what we get if we can't open the pipe. * That's a normal occurrence when we're talking * to a system that (presumably) doesn't support * DCE RPC on the server side, such as Windows 95/98/Me, * so we don't log an error. */ /*CSTYLED*/ status = ENOTSUP; CATCH_ALL /* * XXX - should we handle some exceptions differently, * returning different errors, and try RAP only for * ENOTSUP? */ smb_error(dgettext(TEXT_DOMAIN, "error from NetrShareEnum call: exception = %u"), 0, THIS_CATCH->match.value); status = ENOTSUP; ENDTRY rpc_binding_free(&binding_h, &free_status); free(srvnamestr); free(usrvnamestr); if (status != 0) return (ENOTSUP); /* * XXX - if the IDL is correct, it's not clear whether the * unmarshalling code will properly handle the case where * a packet where "share_count" and the max count for the * array of shares don't match; a valid DCE RPC implementation * won't marshal something like that, but there's no guarantee * that the server we're talking to has a valid implementation * (which could be a *malicious* implementation!). */ entries = share_info.share_union.tagged_union.share1->share_count; shares = share_info.share_union.tagged_union.share1->shares; entry_list = calloc(entries, sizeof (struct share_info)); if (entry_list == NULL) { error = errno; goto cleanup_and_return; } for (share = shares, elp = entry_list, i = 0; i < entries; i++, share++) { elp->type = share->shi1_type; elp->netname = convert_unicode_to_utf8(share->shi1_share); if (elp->netname == NULL) goto fail; elp->remark = convert_unicode_to_utf8(share->shi1_remark); if (elp->remark == NULL) goto fail; elp++; } *entriesp = entries; *totalp = total_entries; *entries_listp = entry_list; error = 0; goto cleanup_and_return; fail: error = errno; for (elp = entry_list, i = 0; i < entries; i++, elp++) { /* * elp->netname is set before elp->remark, so if * elp->netname is null, elp->remark is also null. * If either of them is null, we haven't done anything * to any entries after this one. */ if (elp->netname == NULL) break; free(elp->netname); if (elp->remark == NULL) break; free(elp->remark); } free(entry_list); cleanup_and_return: for (share = shares, i = 0; i < entries; i++, share++) { free(share->shi1_share); free(share->shi1_remark); } free(shares); /* * XXX - "share1" should be a unique pointer, but we haven't * changed the marshalling code to support non-full pointers * in unions, so we leave it as a full pointer. * * That means that this might, or might not, be changed from * pointing to "share_info_1_container" to pointing to a * mallocated structure, according to the DCE RPC 1.1 IDL spec; * we free it only if it's changed. */ if (share_info.share_union.tagged_union.share1 != &share_info_1_container) free(share_info.share_union.tagged_union.share1); return (error); }
/** * gimp_enum_get_value: * @enum_type: the #GType of a registered enum * @value: an integer value * @value_name: return location for the value's name (or %NULL) * @value_nick: return location for the value's nick (or %NULL) * @value_desc: return location for the value's translated description (or %NULL) * @value_help: return location for the value's translated help (or %NULL) * * Checks if @value is valid for the enum registered as @enum_type. * If the value exists in that enum, its name, nick and its translated * description and help are returned (if @value_name, @value_nick, * @value_desc and @value_help are not %NULL). * * Return value: %TRUE if @value is valid for the @enum_type, * %FALSE otherwise * * Since: GIMP 2.2 **/ gboolean gimp_enum_get_value (GType enum_type, gint value, const gchar **value_name, const gchar **value_nick, const gchar **value_desc, const gchar **value_help) { GEnumClass *enum_class; GEnumValue *enum_value; gboolean success = FALSE; g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), FALSE); enum_class = g_type_class_ref (enum_type); enum_value = g_enum_get_value (enum_class, value); if (enum_value) { if (value_name) *value_name = enum_value->value_name; if (value_nick) *value_nick = enum_value->value_nick; if (value_desc || value_help) { GimpEnumDesc *enum_desc; enum_desc = gimp_enum_get_desc (enum_class, value); if (value_desc) { if (enum_desc && enum_desc->value_desc) { const gchar *context; context = gimp_type_get_translation_context (enum_type); if (context) /* the new way, using NC_() */ *value_desc = g_dpgettext2 (gimp_type_get_translation_domain (enum_type), context, enum_desc->value_desc); else /* for backward compatibility */ *value_desc = g_strip_context (enum_desc->value_desc, dgettext (gimp_type_get_translation_domain (enum_type), enum_desc->value_desc)); } else { *value_desc = NULL; } } if (value_help) { *value_help = ((enum_desc && enum_desc->value_help) ? dgettext (gimp_type_get_translation_domain (enum_type), enum_desc->value_help) : NULL); } } success = TRUE; } g_type_class_unref (enum_class); return success; }
void trecruit::refresh_tooltip(twindow& window) { int idx_in_resistances; std::stringstream text; tstacked_widget* stacked = find_widget<tstacked_widget>(&window, "middle_top_part", false, true); stacked->set_dirty(true); stacked = find_widget<tstacked_widget>(&window, "right_part", false, true); stacked->set_dirty(true); if (checked_heros_.empty()) { // It is necessary set all relative tips to empty. tcontrol* control = find_widget<tcontrol>(&window, "master_png", false, true); control->set_label(""); tlabel* label = find_widget<tlabel>(&window, "master_name", false, true); label->set_label(""); // leadership label = find_widget<tlabel>(&window, "tip_leadership", false, true); label->set_label(""); // force label = find_widget<tlabel>(&window, "tip_force", false, true); label->set_label(""); // intellect label = find_widget<tlabel>(&window, "tip_intellect", false, true); label->set_label(""); // politics label = find_widget<tlabel>(&window, "tip_politics", false, true); label->set_label(""); // charm label = find_widget<tlabel>(&window, "tip_charm", false, true); label->set_label(""); // hp label = find_widget<tlabel>(&window, "tip_hp", false, true); label->set_label(""); // xp label = find_widget<tlabel>(&window, "tip_xp", false, true); label->set_label(""); // movement label = find_widget<tlabel>(&window, "tip_movement", false, true); label->set_label(""); // arm label = find_widget<tlabel>(&window, "tip_arm", false, true); label->set_label(""); // adaptability label = find_widget<tlabel>(&window, "tip_adaptability", false, true); label->set_label(""); // abilities label = find_widget<tlabel>(&window, "tip_abilities", false, true); label->set_label(""); // feature label = find_widget<tlabel>(&window, "tip_feature", false, true); label->set_label(""); // attack label = find_widget<tlabel>(&window, "tip_attack", false, true); label->set_label(""); // resistance for (idx_in_resistances = 0; idx_in_resistances < 7; idx_in_resistances ++) { text.str(""); text << "tip_resistance" << idx_in_resistances; label = find_widget<tlabel>(&window, text.str(), false, true); label->set_label(""); } return; } const unit_type* t = unit_types_[type_index_]; std::vector<const hero*> v; int index = 0; for (std::set<int>::const_iterator itor = checked_heros_.begin(); itor != checked_heros_.end(); ++ itor, index ++) { if (index == 0) { v.push_back(fresh_heros_[*itor]); } else if (index == 1) { v.push_back(fresh_heros_[*itor]); } else if (index == 2) { v.push_back(fresh_heros_[*itor]); } } type_heros_pair pair(t, v); unit temp(units_, heros_, pair, city_.cityno(), false); std::stringstream str; // refresh to gui tcontrol* control = find_widget<tcontrol>(&window, "master_png", false, true); control->set_label(temp.master().image()); tlabel* label = find_widget<tlabel>(&window, "master_name", false, true); label->set_label(temp.master().name()); control = find_widget<tcontrol>(&window, "second_png", false, true); label = find_widget<tlabel>(&window, "second_name", false, true); if (temp.second().valid()) { control->set_label(temp.second().image()); label->set_label(temp.second().name()); } else { control->set_label(""); label->set_label(""); } control = find_widget<tcontrol>(&window, "third_png", false, true); label = find_widget<tlabel>(&window, "third_name", false, true); if (temp.third().valid()) { control->set_label(temp.third().image()); label->set_label(temp.third().name()); } else { control->set_label(""); label->set_label(""); } // leadership label = find_widget<tlabel>(&window, "tip_leadership", false, true); label->set_label(lexical_cast<std::string>(temp.leadership_)); // force label = find_widget<tlabel>(&window, "tip_force", false, true); label->set_label(lexical_cast<std::string>(temp.force_)); // intellect label = find_widget<tlabel>(&window, "tip_intellect", false, true); label->set_label(lexical_cast<std::string>(temp.intellect_)); // politics label = find_widget<tlabel>(&window, "tip_politics", false, true); label->set_label(lexical_cast<std::string>(temp.politics_)); // charm label = find_widget<tlabel>(&window, "tip_charm", false, true); label->set_label(lexical_cast<std::string>(temp.charm_)); // hp label = find_widget<tlabel>(&window, "tip_hp", false, true); label->set_label(lexical_cast<std::string>(temp.max_hitpoints())); // xp label = find_widget<tlabel>(&window, "tip_xp", false, true); label->set_label(lexical_cast<std::string>(temp.max_experience())); // movement label = find_widget<tlabel>(&window, "tip_movement", false, true); label->set_label(lexical_cast<std::string>(temp.total_movement())); // arm label = find_widget<tlabel>(&window, "tip_arm", false, true); str << temp.type_name() << "(Lv" << temp.level() << ")"; label->set_label(str.str()); // adaptability str.str(""); label = find_widget<tlabel>(&window, "tip_adaptability", false, true); str << hero::arms_str(temp.arms()) << "(" << hero::adaptability_str2(ftofxp12(temp.adaptability_[temp.arms()])) << ")"; label->set_label(str.str()); // abilities str.str(""); std::vector<std::string> abilities_tt; abilities_tt = temp.ability_tooltips(true); if (!abilities_tt.empty()) { std::vector<t_string> abilities; for (std::vector<std::string>::const_iterator a = abilities_tt.begin(); a != abilities_tt.end(); a += 2) { abilities.push_back(*a); } for (std::vector<t_string>::const_iterator a = abilities.begin(); a != abilities.end(); a++) { if (a != abilities.begin()) { if (a - abilities.begin() != 2) { str << ", "; } else { str << "\n"; } } str << (*a); } } label = find_widget<tlabel>(&window, "tip_abilities", false, true); label->set_label(str.str()); // feature str.str(""); index = 0; for (int i = 0; i < HEROS_MAX_FEATURE; i ++) { if (unit_feature_val2(temp, i) == hero_feature_single_result) { if (index > 0) { if (index != 2) { str << ", "; } else { str << "\n"; } } index ++; str << temp.master().feature_str(i); } } label = find_widget<tlabel>(&window, "tip_feature", false, true); label->set_label(str.str()); // attack str.str(""); std::vector<attack_type>* attacks_ptr = const_cast<std::vector<attack_type>*>(&temp.attacks()); for (std::vector<attack_type>::const_iterator at_it = attacks_ptr->begin(); at_it != attacks_ptr->end(); ++at_it) { // see generate_report() in generate_report.cpp str << at_it->name() << " (" << dgettext("wesnoth", at_it->type().c_str()) << ")\n"; std::string accuracy = at_it->accuracy_parry_description(); if(accuracy.empty() == false) { accuracy += " "; } str << " " << at_it->damage() << "-" << at_it->num_attacks() << " " << accuracy << "- " << dgettext("wesnoth", at_it->range().c_str()); std::string special = at_it->weapon_specials(true); if (!special.empty()) { str << "(" << special << ")"; } str << "\n"; } label = find_widget<tlabel>(&window, "tip_attack", false, true); label->set_label(str.str()); // resistance std::set<std::string> resistances_table; utils::string_map resistances = temp.get_base_resistances(); bool att_def_diff = false; const map_location& loc = temp.get_location(); idx_in_resistances = 0; for (utils::string_map::iterator resist = resistances.begin(); resist != resistances.end(); ++resist, idx_in_resistances ++) { // str << gettext(resist->first.c_str()) << ": "; str.str(""); if (loc.valid()) { // Some units have different resistances when // attacking or defending. int res_att = 100 - temp.resistance_against(resist->first, true, loc); int res_def = 100 - temp.resistance_against(resist->first, false, loc); if (res_att == res_def) { str << res_def; } else { str << res_att << "% / " << res_def; // (Att / Def) att_def_diff = true; } } else { str << 100 - lexical_cast_default<int>(resist->second.c_str()); } str << "%"; text.str(""); text << "tip_resistance" << idx_in_resistances; label = find_widget<tlabel>(&window, text.str(), false, true); label->set_label(str.str()); } // gui_.show_unit_tooltip(temp, window.get_x() + window.get_width(), window.get_y()); }
const char * KRB5_CALLCONV error_message(long code) { unsigned long offset; unsigned long l_offset; struct et_list *e; unsigned long table_num; int started = 0; unsigned int divisor = 100; char *cp, *cp1; const struct error_table *table; if (CALL_INIT_FUNCTION(com_err_initialize)) return 0; l_offset = (unsigned long)code & ((1<<ERRCODE_RANGE)-1); offset = l_offset; table_num = ((unsigned long)code - l_offset) & ERRCODE_MAX; if (table_num == 0 #ifdef __sgi /* Irix 6.5 uses a much bigger table than other UNIX systems I've looked at, but the table is sparse. The sparse entries start around 500, but sys_nerr is only 152. */ || (code > 0 && code <= 1600) #endif ) { if (code == 0) goto oops; /* This could trip if int is 16 bits. */ if ((unsigned long)(int)code != (unsigned long)code) abort (); cp = get_thread_buffer(); if (cp && strerror_r(code, cp, ET_EBUFSIZ) == 0) return cp; return strerror(code); } k5_mutex_lock(&et_list_lock); dprintf(("scanning list for %x\n", table_num)); for (e = et_list; e != NULL; e = e->next) { dprintf(("\t%x = %s\n", e->table->base & ERRCODE_MAX, e->table->msgs[0])); if ((e->table->base & ERRCODE_MAX) == table_num) { table = e->table; goto found; } } goto no_table_found; found: k5_mutex_unlock(&et_list_lock); dprintf (("found it!\n")); /* This is the right table */ /* This could trip if int is 16 bits. */ if ((unsigned long)(unsigned int)offset != offset) goto no_table_found; if (table->n_msgs <= (unsigned int) offset) goto no_table_found; /* If there's a string at the end of the table, it's a text domain. */ if (table->msgs[table->n_msgs] != NULL) return dgettext(table->msgs[table->n_msgs], table->msgs[offset]); else return table->msgs[offset]; no_table_found: k5_mutex_unlock(&et_list_lock); #if defined(_WIN32) /* * WinSock errors exist in the 10000 and 11000 ranges * but might not appear if WinSock is not initialized */ if (code >= WSABASEERR && code < WSABASEERR + 1100) { table_num = 0; offset = code; divisor = WSABASEERR; } #endif #ifdef _WIN32 { LPVOID msgbuf; if (! FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL /* lpSource */, (DWORD) code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msgbuf, (DWORD) 0 /*sizeof(buffer)*/, NULL /* va_list */ )) { /* * WinSock errors exist in the 10000 and 11000 ranges * but might not appear if WinSock is not initialized */ if (code >= WSABASEERR && code < WSABASEERR + 1100) { table_num = 0; offset = code; divisor = 10000; } goto oops; } else { char *buffer; cp = get_thread_buffer(); if (cp == NULL) return "Unknown error code"; buffer = cp; strncpy(buffer, msgbuf, ET_EBUFSIZ); buffer[ET_EBUFSIZ-1] = '\0'; cp = buffer + strlen(buffer) - 1; if (*cp == '\n') *cp-- = '\0'; if (*cp == '\r') *cp-- = '\0'; if (*cp == '.') *cp-- = '\0'; LocalFree(msgbuf); return buffer; } } #endif oops: cp = get_thread_buffer(); if (cp == NULL) return "Unknown error code"; cp1 = cp; strlcpy(cp, "Unknown code ", ET_EBUFSIZ); cp += sizeof("Unknown code ") - 1; if (table_num != 0L) { (void) error_table_name_r(table_num, cp); while (*cp != '\0') cp++; *cp++ = ' '; } while (divisor > 1) { if (started != 0 || offset >= divisor) { *cp++ = '0' + offset / divisor; offset %= divisor; started++; } divisor /= 10; } *cp++ = '0' + offset; *cp = '\0'; return(cp1); }
int zfs_key_load(zfs_handle_t *zhp, boolean_t mount, boolean_t share, boolean_t recursive) { zfs_handle_t *pzhp = NULL; zprop_source_t propsrctype; char source[ZFS_MAXNAMELEN]; char keysource[MAXNAMELEN]; uint64_t ret, crypt, keystatus; zfs_cmd_t zc = { {0 }}; char errbuf[1024]; fprintf(stderr, "zfs_key_load\r\n"); (void) strlcpy(zc.zc_name, zfs_get_name(zhp), sizeof (zc.zc_name)); (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot load key for '%s'"), zc.zc_name); zfs_refresh_properties(zhp); crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION); if (crypt == ZIO_CRYPT_OFF) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "encryption not enabled on dataset %s."), zc.zc_name); return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS); if (keystatus == ZFS_CRYPT_KEY_AVAILABLE && !recursive) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "already loaded.")); return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } if (zfs_prop_get(zhp, ZFS_PROP_KEYSOURCE, keysource, ZFS_MAXNAMELEN, &propsrctype, source, sizeof (source), FALSE) != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "no keysource property available.")); return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } if (propsrctype == ZPROP_SRC_INHERITED) { #if 0 // FIXME if (strcmp(source, ZONE_INVISIBLE_SOURCE) == 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "key must be loaded from global zone.")); return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } #endif pzhp = make_dataset_handle(zhp->zfs_hdl, source); if (pzhp == NULL) { errno = EINVAL; return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } keystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS); zfs_close(pzhp); } if (propsrctype == ZPROP_SRC_DEFAULT) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "invalid keysource property.")); return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } if (!zfs_can_prompt_if_needed(keysource)) { errno = ENOTTY; return (-1); } /* * NONE we are the top ds asking for crypto so we * need to get and load the key. * * UNAVAILABLE we need to load the key of a higher level * dataset. * * AVAILABLE we are done other than filling in who we * are inheriting the wrapping key from. */ if (propsrctype == ZPROP_SRC_INHERITED && keystatus == ZFS_CRYPT_KEY_AVAILABLE) { (void) strlcpy(zc.zc_crypto.zic_inherit_dsname, source, sizeof (zc.zc_crypto.zic_inherit_dsname)); ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CRYPTO_KEY_INHERIT, &zc); goto out; } zc.zc_crypto.zic_crypt = crypt; ret = key_hdl_to_zc(zhp->zfs_hdl, zhp, keysource, crypt, &zc, ZFS_CRYPTO_KEY_LOAD); if (ret != 0) { if (errno == ENOTTY) ret = 0; goto out; } ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CRYPTO_KEY_LOAD, &zc); out: if (ret != 0) { if (errno == EACCES) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "incorrect key.")); return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } else if (!recursive) { if (errno == EEXIST) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "already loaded.")); } else if (zhp->zfs_hdl->libzfs_desc_active == 0) { zfs_error_aux(zhp->zfs_hdl, strerror(errno)); } return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf)); } } zfs_refresh_properties(zhp); if (mount) { if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) { if (recursive) { ret = zfs_mountall(zhp, 0); } else { ret = zfs_mount(zhp, NULL, 0); } if (ret == 0 && share) { ret = zfs_share(zhp); } } } return (ret); }
static int key_hdl_to_zc(libzfs_handle_t *hdl, zfs_handle_t *zhp, char *keysource, int crypt, zfs_cmd_t *zc, zfs_crypto_zckey_t cmd) { // CK_SESSION_HANDLE session; int ret = 0; key_format_t format; key_locator_t locator; char *uri; //pkcs11_uri_t p11uri; size_t keylen = zio_crypt_table[crypt].ci_keylen; char *keydata = NULL; size_t keydatalen = 0; char *tmpkeydata = NULL; size_t tmpkeydatalen = 0; uint64_t salt; //struct cb_arg_curl cb_curl = { 0 }; fprintf(stderr, "in key_hdl_to_zc\r\n"); zc->zc_crypto.zic_clone_newkey = hdl->libzfs_crypt.zc_clone_newkey; if (!keysource_prop_parser(keysource, &format, &locator, &uri)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid keysource property.")); return (-1); } /* * First check if there was anything in the handle already * if so we use that and we are done with locating the data. * Note that we may be looking at other fields * and zic_clone_newkey even if zc_key_data_len is empty. * * We allow this regardless of the locator so that things * like a PAM module can provide the passphrase but the user * can still have "passphrase,prompt" to use zfs(1M) interactively. */ if (hdl->libzfs_crypt.zc_key_data_len != 0) { keydata = zfs_alloc(hdl, hdl->libzfs_crypt.zc_key_data_len); bcopy(hdl->libzfs_crypt.zc_key_data, keydata, hdl->libzfs_crypt.zc_key_data_len); keydatalen = hdl->libzfs_crypt.zc_key_data_len; goto format_key; } /* * Get the key from the URI or prompt for it. * If the format is raw then prompting is a simple read(2) * otherwise we put up a prompt saying what we are asking for. * We can't do this with the 'zfs mount -a' that is in * sys:/system/filesystem/local:default but we shouldn't * cause errors or warnings there either. */ switch (locator) { case KEY_LOCATOR_PROMPT: if (format == KEY_FORMAT_RAW) { keydata = zfs_alloc(hdl, keylen); errno = 0; keydatalen = read(STDIN_FILENO, keydata, keylen); if (keydatalen != keylen) { free(keydata); return (-1); } } else { int tries = 0; do { /* get_passphrase allocates keydata */ ret = get_passphrase(hdl, &keydata, &keydatalen, format, zc, cmd); } while (ret != 0 && ++tries < 3); if (ret) return (-1); } break; case KEY_LOCATOR_FILE_URI: /* * Need to tell pkcs11_read_data() how big of a key * we want in case the locator URI is a device (eg, /dev/random) * to be read from and not a file. * * Note that pkcs11_read_data allocates memory with malloc * that we need to free. */ #if 0 // FIXME keydatalen = keylen; ret = pkcs11_read_data(&(uri[7]), (void **)&keydata, &keydatalen); if (ret != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to read key file: %s"), strerror(ret)); errno = ret; return (-1); } #endif break; case KEY_LOCATOR_PKCS11_URI: #if 0 // FIXME keydatalen = keylen; /* * Parse out the PKCS#11 URI and * get the value of the wrapping key. */ if (pkcs11_parse_uri(uri, &p11uri) != PK11_URI_OK) { errno = EINVAL; return (-1); } ret = get_pkcs11_key_value(hdl, zc, cmd, &p11uri, &keydata, &keydatalen); pkcs11_free_uri(&p11uri); if (ret != 0) { return (-1); } #endif break; case KEY_LOCATOR_HTTPS_URI: { #if 0 CURL *curl_hdl = curl_easy_init(); CURLcode cerr; cerr = curl_easy_setopt(curl_hdl, CURLOPT_URL, uri); if (cerr != CURLE_OK) goto curl_fail; cerr = curl_easy_setopt(curl_hdl, CURLOPT_FAILONERROR, 1L); if (cerr != CURLE_OK) goto curl_fail; cerr = curl_easy_setopt(curl_hdl, CURLOPT_WRITEFUNCTION, get_keydata_curl); if (cerr != CURLE_OK) goto curl_fail; cb_curl.cb_hdl = hdl; cerr = curl_easy_setopt(curl_hdl, CURLOPT_WRITEDATA, &cb_curl); if (cerr != CURLE_OK) goto curl_fail; cerr = curl_easy_perform(curl_hdl); curl_fail: /* * Just deal with libcurl errors here, reading the wrong key * size is dealt with generically in the format_key section. */ if (cerr != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to retreive key from '%s': '%s'"), uri, curl_easy_strerror(cerr)); return (-1); } keydata = cb_curl.cb_keydata; keydatalen = cb_curl.cb_keydatalen; curl_easy_cleanup(curl_hdl); #endif break; case KEY_LOCATOR_NONE: // Avoid Warning break; } } format_key: if (keydata == NULL || keydatalen == 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "key can not be of zero size")); errno = ret; return (-1); } /* * Now that we have the key do any transform that is necessary * such as turning the hex format into raw or in the case of * a passphrase running it through PKCS#5 to get the raw key. * * Note that zic_keydata is not malloc'd memory so that we * don't have to worry about our caller freeing it. */ switch (format) { case KEY_FORMAT_RAW: bcopy(keydata, zc->zc_crypto.zic_keydata, keydatalen); zc->zc_crypto.zic_keydatalen = keydatalen; zc->zc_crypto.zic_salt = 0; break; case KEY_FORMAT_HEX: /* * If the keylen is not on the byte boundary, in terms of hex * format, and that extra char is a linefeed, we can trim it */ if (keydatalen == (keylen * 2) + 1 && keydata[keydatalen] == '\n') { keydatalen--; } /* * hexstr_to_bytes allocates memory with malloc * but we want the data in zic_keydata which isn't malloc'd * so to avoid a memory leak we use a tmpkeydata buffer * and bcopy it. */ #if 0 // FIXME ret = hexstr_to_bytes(keydata, keydatalen, (uchar_t **)&tmpkeydata, &tmpkeydatalen); #endif if (ret) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid hex format key.")); errno = EACCES; ret = -1; goto out; } bcopy(tmpkeydata, zc->zc_crypto.zic_keydata, tmpkeydatalen); bzero(tmpkeydata, tmpkeydatalen); free(tmpkeydata); zc->zc_crypto.zic_keydatalen = tmpkeydatalen; zc->zc_crypto.zic_salt = 0; break; case KEY_FORMAT_PASSPHRASE: /* Remove any extra linefeed that may be on the end */ if (keydata[keydatalen - 1] == '\n') keydatalen--; if (cmd == ZFS_CRYPTO_KEY_LOAD) { salt = zfs_prop_get_int(zhp, ZFS_PROP_SALT); } else { #if 0 // FIXME ret = pkcs11_get_random(&salt, sizeof (uint64_t)); if (ret) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to obtain salt: %s."), pkcs11_strerror(ret)); errno = EINVAL; ret = -1; goto out; } #endif } fprintf(stderr, "Key is '%s' and is len %u\r\n", keydata, keydatalen); // FIXME tmpkeydata = strdup(keydata); tmpkeydatalen = keydatalen; salt = 0x1234; #if 0 // FIXME ret = SUNW_C_GetMechSession(CKM_PKCS5_PBKD2, &session); if (ret) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to access CKM_PKCS5_PBKD2: %s."), pkcs11_strerror(ret)); errno = EINVAL; ret = -1; goto out; } /* * pkcs11_PasswdToKey allocates memory with malloc * but we want the data in zic_keydata which isn't malloc'd * so to avoid a memory leak we use a tmpkeydata buffer * and bcopy it. */ ret = pkcs11_PasswdToKey(session, keydata, keydatalen, (void *)&salt, sizeof (uint64_t), CKK_AES, keylen, (void **)&tmpkeydata, &tmpkeydatalen); (void) C_CloseSession(session); if (ret) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to generate key: %s."), pkcs11_strerror(ret)); errno = EINVAL; ret = -1; goto out; } #endif bcopy(tmpkeydata, zc->zc_crypto.zic_keydata, tmpkeydatalen); bzero(tmpkeydata, tmpkeydatalen); free(tmpkeydata); zc->zc_crypto.zic_keydatalen = tmpkeydatalen; zc->zc_crypto.zic_salt = salt; break; default: ASSERT(format); } if (zc->zc_crypto.zic_keydatalen != keylen) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "key length invalid. expected %lu bytes have %lu"), keylen, zc->zc_crypto.zic_keydatalen); errno = EIO; ret = -1; } if (tmpkeydatalen) // Only decrease if NOT zero. tmpkeydatalen--; while (zc->zc_crypto.zic_keydata[tmpkeydatalen] == 0 && tmpkeydatalen > 0) tmpkeydatalen--; if (tmpkeydatalen == 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid all zeros key %lu"), tmpkeydatalen); errno = EIO; ret = -1; } out: if (keydata) { bzero(keydata, keydatalen); free(keydata); } return (ret); }
int fontforge_main( int argc, char **argv ) { extern const char *source_modtime_str; extern const char *source_version_str; const char *load_prefs = getenv("FONTFORGE_LOADPREFS"); int i; int recover=2; int any; int next_recent=0; GRect pos; GWindowAttrs wattrs; char *display = NULL; FontRequest rq; int ds, ld; int openflags=0; int doopen=0, quit_request=0; bool use_cairo = true; #if !(GLIB_CHECK_VERSION(2, 35, 0)) g_type_init(); #endif /* Must be done before we cache the current directory */ /* Change to HOME dir if specified on the commandline */ for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if (strcmp(pt,"-home")==0 || strncmp(pt,"-psn_",5)==0) { /* OK, I don't know what _-psn_ means, but to GW it means */ /* we've been started on the mac from the FontForge.app */ /* structure, and the current directory is (shudder) "/" */ if (getenv("HOME")!=NULL) chdir(getenv("HOME")); break; /* Done - Unnecessary to check more arguments */ } if (strcmp(pt,"-quiet")==0) quiet = 1; } if (!quiet) { fprintf( stderr, "Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.\n" ); fprintf( stderr, " License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n" ); fprintf( stderr, " with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.\n" ); fprintf( stderr, " Based on sources from %s" "-ML" #ifdef FREETYPE_HAS_DEBUGGER "-TtfDb" #endif #ifdef _NO_PYTHON "-NoPython" #endif #ifdef FONTFORGE_CONFIG_USE_DOUBLE "-D" #endif ".\n", FONTFORGE_MODTIME_STR ); fprintf( stderr, " Based on source from git with hash: %s\n", FONTFORGE_GIT_VERSION ); } #if defined(__Mac) /* Start X if they haven't already done so. Well... try anyway */ /* Must be before we change DYLD_LIBRARY_PATH or X won't start */ /* (osascript depends on a libjpeg which isn't found if we look in /sw/lib first */ int local_x = uses_local_x(argc,argv); if ( local_x==1 && getenv("DISPLAY")==NULL ) { /* Don't start X if we're just going to quit. */ /* if X exists, it isn't needed. If X doesn't exist it's wrong */ if ( !hasquit(argc,argv)) { /* This sequence is supposed to bring up an app without a window */ /* but X still opens an xterm */ system( "osascript -e 'tell application \"X11\" to launch'" ); system( "osascript -e 'tell application \"X11\" to activate'" ); } setenv("DISPLAY",":0.0",0); } else if ( local_x==1 && *getenv("DISPLAY")!='/' && strcmp(getenv("DISPLAY"),":0.0")!=0 && strcmp(getenv("DISPLAY"),":0")!=0 ) /* 10.5.7 uses a named socket or something "/tmp/launch-01ftWX:0" */ local_x = 0; #endif #if defined(__MINGW32__) if( getenv("DISPLAY")==NULL ) { putenv("DISPLAY=127.0.0.1:0.0"); } if( getenv("LC_ALL")==NULL ){ char lang[8]; char env[32]; if( GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, 8) > 0 ){ strcpy(env, "LC_ALL="); strcat(env, lang); putenv(env); } } #endif FF_SetUiInterface(&gdraw_ui_interface); FF_SetPrefsInterface(&gdraw_prefs_interface); FF_SetSCInterface(&gdraw_sc_interface); FF_SetCVInterface(&gdraw_cv_interface); FF_SetBCInterface(&gdraw_bc_interface); FF_SetFVInterface(&gdraw_fv_interface); FF_SetFIInterface(&gdraw_fi_interface); FF_SetMVInterface(&gdraw_mv_interface); FF_SetClipInterface(&gdraw_clip_interface); #ifndef _NO_PYTHON PythonUI_Init(); #endif FindProgDir(argv[0]); InitSimpleStuff(); #if defined(__MINGW32__) { char path[MAX_PATH]; unsigned int len = GetModuleFileNameA(NULL, path, MAX_PATH); path[len] = '\0'; //The '.exe' must be removed as resources presumes it's not there. GResourceSetProg(GFileRemoveExtension(GFileNormalizePath(path))); } #else GResourceSetProg(argv[0]); #endif #if defined(__Mac) /* The mac seems to default to the "C" locale, LANG and LC_MESSAGES are not*/ /* defined. This means that gettext will not bother to look up any message*/ /* files -- even if we have a "C" or "POSIX" entry in the locale diretory */ /* Now if X11 gives us the command key, I want to force a rebinding to use */ /* Cmd rather than Control key -- more mac-like. But I can't do that if */ /* there is no locale. So I force a locale if there is none specified */ /* I force the US English locale, because that's the what the messages are */ /* by default so I'm changing as little as I can. I think. */ /* Now the locale command will treat a LANG which is "" as undefined, but */ /* gettext will not. So I don't bother to check for null strings or "C" */ /* or "POSIX". If they've mucked with the locale perhaps they know what */ /* they are doing */ { int did_keybindings = 0; int useCommandKey = get_mac_x11_prop("enable_key_equivalents") <= 0; if ( local_x && useCommandKey ) { hotkeySystemSetCanUseMacCommand( 1 ); /* Ok, we get the command key */ if ( getenv("LANG")==NULL && getenv("LC_MESSAGES")==NULL ) { setenv("LC_MESSAGES","en_US.UTF-8",0); } /* Can we find a set of keybindings designed for the mac with cmd key? */ bind_textdomain_codeset("Mac-FontForge-MenuShortCuts","UTF-8"); bindtextdomain("Mac-FontForge-MenuShortCuts", getLocaleDir()); if ( *dgettext("Mac-FontForge-MenuShortCuts","Flag0x10+")!='F' ) { GMenuSetShortcutDomain("Mac-FontForge-MenuShortCuts"); did_keybindings = 1; } } if ( !did_keybindings ) { /* Nope. we can't. Fall back to the normal stuff */ #endif GMenuSetShortcutDomain("FontForge-MenuShortCuts"); bind_textdomain_codeset("FontForge-MenuShortCuts","UTF-8"); bindtextdomain("FontForge-MenuShortCuts", getLocaleDir()); #if defined(__Mac) } } #endif bind_textdomain_codeset("FontForge","UTF-8"); bindtextdomain("FontForge", getLocaleDir()); textdomain("FontForge"); GResourceUseGetText(); { char shareDir[PATH_MAX]; char* sd = getShareDir(); strncpy( shareDir, sd, PATH_MAX ); shareDir[PATH_MAX-1] = '\0'; if(!sd) { strcpy( shareDir, SHAREDIR ); } char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s%s", shareDir, "/pixmaps" ); GGadgetSetImageDir( path ); snprintf(path, PATH_MAX, "%s%s", shareDir, "/resources/fontforge.resource" ); GResourceAddResourceFile(path, GResourceProgramName,false); } hotkeysLoad(); // loadPrefsFiles(); Prefs_LoadDefaultPreferences(); if ( load_prefs!=NULL && strcasecmp(load_prefs,"Always")==0 ) LoadPrefs(); if ( default_encoding==NULL ) default_encoding=FindOrMakeEncoding("ISO8859-1"); if ( default_encoding==NULL ) default_encoding=&custom; /* In case iconv is broken */ // This no longer starts embedded Python unless control passes to the Python executors, // which exit independently rather than returning here. CheckIsScript(argc,argv); /* Will run the script and exit if it is a script */ /* If there is no UI, there is always a script */ /* and we will never return from the above */ if ( load_prefs==NULL || (strcasecmp(load_prefs,"Always")!=0 && /* Already loaded */ strcasecmp(load_prefs,"Never")!=0 )) LoadPrefs(); GrokNavigationMask(); for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( pt[0]=='-' && pt[1]=='-' ) ++pt; if ( strcmp(pt,"-sync")==0 ) GResourceAddResourceString("Gdraw.Synchronize: true",argv[0]); else if ( strcmp(pt,"-depth")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.Depth", argv[++i]); else if ( strcmp(pt,"-vc")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.VisualClass", argv[++i]); else if ( (strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0) && i<argc-1 ) AddR(argv[0],"Gdraw.Colormap", argv[++i]); else if ( (strcmp(pt,"-dontopenxdevices")==0) ) AddR(argv[0],"Gdraw.DontOpenXDevices", "true"); else if ( strcmp(pt,"-keyboard")==0 && i<argc-1 ) AddR(argv[0],"Gdraw.Keyboard", argv[++i]); else if ( strcmp(pt,"-display")==0 && i<argc-1 ) display = argv[++i]; # if MyMemory else if ( strcmp(pt,"-memory")==0 ) __malloc_debug(5); # endif else if ( strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ) { if ( strcmp(pt,"-usecairo=no")==0 ) use_cairo = false; else use_cairo = true; GDrawEnableCairo(use_cairo); } else if ( strcmp(pt,"-nosplash")==0 ) splash = 0; else if ( strcmp(pt,"-quiet")==0 ) /* already checked for this earlier, no need to do it again */; else if ( strcmp(pt,"-unique")==0 ) unique = 1; else if ( strcmp(pt,"-forceuihidden")==0 ) cmdlinearg_forceUIHidden = 0; else if ( strcmp(pt,"-recover")==0 && i<argc-1 ) { ++i; if ( strcmp(argv[i],"none")==0 ) recover=0; else if ( strcmp(argv[i],"clean")==0 ) recover= -1; else if ( strcmp(argv[i],"auto")==0 ) recover= 1; else if ( strcmp(argv[i],"inquire")==0 ) recover= 2; else { fprintf( stderr, "Invalid argument to -recover, must be none, auto, inquire or clean\n" ); dousage(); } } else if ( strcmp(pt,"-recover=none")==0 ) { recover = 0; } else if ( strcmp(pt,"-recover=clean")==0 ) { recover = -1; } else if ( strcmp(pt,"-recover=auto")==0 ) { recover = 1; } else if ( strcmp(pt,"-recover=inquire")==0 ) { recover = 2; } else if ( strcmp(pt,"-docs")==0 ) dohelp(); else if ( strcmp(pt,"-help")==0 ) dousage(); else if ( strcmp(pt,"-version")==0 || strcmp(pt,"-v")==0 || strcmp(pt,"-V")==0 ) doversion(FONTFORGE_MODTIME_STR); else if ( strcmp(pt,"-quit")==0 ) quit_request = true; else if ( strcmp(pt,"-home")==0 ) /* already did a chdir earlier, don't need to do it again */; #if defined(__Mac) else if ( strncmp(pt,"-psn_",5)==0 ) { /* OK, I don't know what _-psn_ means, but to GW it means */ /* we've been started on the mac from the FontForge.app */ /* structure, and the current directory was (shudder) "/" */ /* (however, we changed to HOME earlier in main routine). */ unique = 1; listen_to_apple_events = true; // This has been problematic on Mavericks and later. } #endif } ensureDotFontForgeIsSetup(); #if defined(__MINGW32__) && !defined(_NO_LIBCAIRO) //Load any custom fonts for the user interface if (use_cairo) { char *system_load = getGResourceProgramDir(); char *user_load = getFontForgeUserDir(Data); char lbuf[MAX_PATH]; int lret; if (system_load != NULL) { //Follow the FontConfig APPSHAREFONTDIR location lret = snprintf(lbuf, MAX_PATH, "%s/../share/fonts", system_load); if (lret > 0 && lret < MAX_PATH) { WinLoadUserFonts(lbuf); } } if (user_load != NULL) { lret = snprintf(lbuf, MAX_PATH, "%s/%s", user_load, "ui-fonts"); if (lret > 0 && lret < MAX_PATH) { WinLoadUserFonts(lbuf); } free(user_load); } } #endif InitImageCache(); // This is in gtextinfo.c. It zeroes imagecache for us. atexit(&ClearImageCache); // We register the destructor, which is also in gtextinfo.c. GDrawCreateDisplays(display,argv[0]); atexit(&GDrawDestroyDisplays); // We register the destructor so that it runs even if we call exit without finishing this function. default_background = GDrawGetDefaultBackground(screen_display); InitToolIconClut(default_background); InitToolIcons(); InitCursors(); /** * we have to do a quick sniff of argv[] here to see if the user * wanted to skip loading these python init files. */ for ( i=1; i<argc; ++i ) { char *pt = argv[i]; if ( !strcmp(pt,"-SkipPythonInitFiles")) { ProcessPythonInitFiles = 0; } } #ifndef _NO_PYTHON /*# ifndef GWW_TEST*/ FontForge_InitializeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */ /*# endif*/ #endif #ifndef _NO_PYTHON if( ProcessPythonInitFiles ) PyFF_ProcessInitFiles(); #endif /* the splash screen used not to have a title bar (wam_nodecor) */ /* but I found I needed to know how much the window manager moved */ /* the window around, which I can determine if I have a positioned */ /* decorated window created at the begining */ /* Actually I don't care any more */ wattrs.mask = wam_events|wam_cursor|wam_bordwidth|wam_backcol|wam_positioned|wam_utf8_wtitle|wam_isdlg; wattrs.event_masks = ~(1<<et_charup); wattrs.positioned = 1; wattrs.cursor = ct_pointer; wattrs.utf8_window_title = "FontForge"; wattrs.border_width = 2; wattrs.background_color = 0xffffff; wattrs.is_dlg = !listen_to_apple_events; pos.x = pos.y = 200; pos.width = splashimage.u.image->width; pos.height = splashimage.u.image->height-56; /* 54 */ GDrawBindSelection(NULL,sn_user1,"FontForge"); if ( unique && GDrawSelectionOwned(NULL,sn_user1)) { /* Different event handler, not a dialog */ wattrs.is_dlg = false; splashw = GDrawCreateTopWindow(NULL,&pos,request_e_h,NULL,&wattrs); PingOtherFontForge(argc,argv); } else { if ( quit_request ) exit( 0 ); splashw = GDrawCreateTopWindow(NULL,&pos,splash_e_h,NULL,&wattrs); } memset(&rq,0,sizeof(rq)); rq.utf8_family_name = SERIF_UI_FAMILIES; rq.point_size = 12; rq.weight = 400; splash_font = GDrawInstanciateFont(NULL,&rq); splash_font = GResourceFindFont("Splash.Font",splash_font); GDrawDecomposeFont(splash_font, &rq); rq.style = fs_italic; splash_italic = GDrawInstanciateFont(NULL,&rq); splash_italic = GResourceFindFont("Splash.ItalicFont",splash_italic); GDrawSetFont(splashw,splash_font); SplashLayout(); localsplash = splash; if ( localsplash && !listen_to_apple_events ) start_splash_screen(); // // The below call will initialize the fontconfig cache if required. // That can take a while the first time it happens. // GDrawWindowFontMetrics(splashw,splash_font,&as,&ds,&ld); fh = as+ds+ld; if ( AutoSaveFrequency>0 ) autosave_timer=GDrawRequestTimer(splashw,2*AutoSaveFrequency*1000,AutoSaveFrequency*1000,NULL); GDrawProcessPendingEvents(NULL); GDrawSetBuildCharHooks(BuildCharHook,InsCharHook); any = 0; if ( recover==-1 ) CleanAutoRecovery(); else if ( recover ) any = DoAutoRecoveryExtended( recover-1 ); openflags = 0; for ( i=1; i<argc; ++i ) { char buffer[1025]; char *pt = argv[i]; GDrawProcessPendingEvents(NULL); if ( pt[0]=='-' && pt[1]=='-' && pt[2]!='\0') ++pt; if ( strcmp(pt,"-new")==0 ) { FontNew(); any = 1; # if HANYANG } else if ( strcmp(pt,"-newkorean")==0 ) { MenuNewComposition(NULL,NULL,NULL); any = 1; # endif } else if ( !strcmp(pt,"-SkipPythonInitFiles")) { // already handled above. } else if ( strcmp(pt,"-last")==0 ) { if ( next_recent<RECENT_MAX && RecentFiles[next_recent]!=NULL ) if ( ViewPostScriptFont(RecentFiles[next_recent++],openflags)) any = 1; } else if ( strcmp(pt,"-sync")==0 || strcmp(pt,"-memory")==0 || strcmp(pt,"-nosplash")==0 || strcmp(pt,"-recover=none")==0 || strcmp(pt,"-recover=clean")==0 || strcmp(pt,"-recover=auto")==0 || strcmp(pt,"-dontopenxdevices")==0 || strcmp(pt,"-unique")==0 || strncmp(pt,"-usecairo",strlen("-usecairo"))==0 || strcmp(pt,"-home")==0 || strcmp(pt,"-quiet")==0 || strcmp(pt,"-forceuihidden")==0 ) /* Already done, needed to be before display opened */; else if ( strncmp(pt,"-psn_",5)==0 ) /* Already done */; else if ( (strcmp(pt,"-depth")==0 || strcmp(pt,"-vc")==0 || strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0 || strcmp(pt,"-keyboard")==0 || strcmp(pt,"-display")==0 || strcmp(pt,"-recover")==0 ) && i<argc-1 ) ++i; /* Already done, needed to be before display opened */ else if ( strcmp(pt,"-allglyphs")==0 ) openflags |= of_all_glyphs_in_ttc; else if ( strcmp(pt,"-open")==0 ) doopen = true; else { printf("else argv[i]:%s\n", argv[i] ); if ( strstr(argv[i],"://")!=NULL ) { /* Assume an absolute URL */ strncpy(buffer,argv[i],sizeof(buffer)); buffer[sizeof(buffer)-1]= '\0'; } else GFileGetAbsoluteName(argv[i],buffer,sizeof(buffer)); if ( GFileIsDir(buffer) || (strstr(buffer,"://")!=NULL && buffer[strlen(buffer)-1]=='/')) { char *fname; fname = malloc(strlen(buffer)+strlen("/glyphs/contents.plist")+1); strcpy(fname,buffer); strcat(fname,"/glyphs/contents.plist"); if ( GFileExists(fname)) { /* It's probably a Unified Font Object directory */ free(fname); if ( ViewPostScriptFont(buffer,openflags) ) any = 1; } else { strcpy(fname,buffer); strcat(fname,"/font.props"); if ( GFileExists(fname)) { /* It's probably a sf dir collection */ free(fname); if ( ViewPostScriptFont(buffer,openflags) ) any = 1; } else { free(fname); if ( buffer[strlen(buffer)-1]!='/' ) { /* If dirname doesn't end in "/" we'll be looking in parent dir */ buffer[strlen(buffer)+1]='\0'; buffer[strlen(buffer)] = '/'; } fname = GetPostScriptFontName(buffer,false); if ( fname!=NULL ) ViewPostScriptFont(fname,openflags); any = 1; /* Even if we didn't get a font, don't bring up dlg again */ free(fname); } } } else if ( ViewPostScriptFont(buffer,openflags)!=0 ) any = 1; } } if ( !any && !doopen ) any = ReopenLastFonts(); collabclient_ensureClientBeacon(); collabclient_sniffForLocalServer(); #ifndef _NO_PYTHON PythonUI_namedpipe_Init(); #endif #if defined(__Mac) if ( listen_to_apple_events ) { install_apple_event_handlers(); install_mac_timer(); setup_cocoa_app(); // WARNING: See declaration of RunApplicationEventLoop() above as to // why you might not want to call that function anymore. // RunApplicationEventLoop(); } else #endif if ( doopen || !any ) _FVMenuOpen(NULL); GDrawEventLoop(NULL); GDrawDestroyDisplays(); #ifndef _NO_PYTHON /*# ifndef GWW_TEST*/ FontForge_FinalizeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */ /*# endif*/ #endif // These free menu translations, mostly. BitmapViewFinishNonStatic(); MetricsViewFinishNonStatic(); CharViewFinishNonStatic(); FontViewFinishNonStatic(); ClearImageCache(); // This frees the contents of imagecache. hotkeysSave(); LastFonts_Save(); #ifndef _NO_LIBUNICODENAMES uninm_names_db_close(names_db); /* close this database before exiting */ uninm_blocks_db_close(blocks_db); #endif lt_dlexit(); return( 0 ); }
static gboolean _show_group_dialog (CairoDockGroupDescription *pGroupDescription) { gchar *cDescription = NULL; if (pGroupDescription->cDescription != NULL) { if (*pGroupDescription->cDescription == '/') { //g_print ("on recupere la description de %s\n", pGroupDescription->cDescription); gsize length = 0; GError *erreur = NULL; g_file_get_contents (pGroupDescription->cDescription, &cDescription, &length, &erreur); if (erreur != NULL) { cd_warning (erreur->message); g_error_free (erreur); } } } int iPreviewWidgetWidth; GtkWidget *pPreviewImage = cairo_dock_get_preview_image (&iPreviewWidgetWidth); if (pGroupDescription->cPreviewFilePath != NULL && strcmp (pGroupDescription->cPreviewFilePath, "none") != 0) { //g_print ("on recupere la prevue de %s\n", pGroupDescription->cPreviewFilePath); int iPreviewWidth, iPreviewHeight; GdkPixbuf *pPreviewPixbuf = NULL; if (gdk_pixbuf_get_file_info (pGroupDescription->cPreviewFilePath, &iPreviewWidth, &iPreviewHeight) != NULL) { if (iPreviewWidth > CAIRO_DOCK_PREVIEW_WIDTH) { iPreviewHeight *= 1.*CAIRO_DOCK_PREVIEW_WIDTH/iPreviewWidth; iPreviewWidth = CAIRO_DOCK_PREVIEW_WIDTH; } if (iPreviewHeight > CAIRO_DOCK_PREVIEW_HEIGHT) { iPreviewWidth *= 1.*CAIRO_DOCK_PREVIEW_HEIGHT/iPreviewHeight; iPreviewHeight = CAIRO_DOCK_PREVIEW_HEIGHT; } if (iPreviewWidth > iPreviewWidgetWidth) { iPreviewHeight *= 1.*iPreviewWidgetWidth/iPreviewWidth; iPreviewWidth = iPreviewWidgetWidth; } g_print ("preview : %dx%d\n", iPreviewWidth, iPreviewHeight); pPreviewPixbuf = gdk_pixbuf_new_from_file_at_size (pGroupDescription->cPreviewFilePath, iPreviewWidth, iPreviewHeight, NULL); } if (pPreviewPixbuf == NULL) { cd_warning ("pas de prevue disponible"); pPreviewPixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1); } gtk_image_set_from_pixbuf (GTK_IMAGE (pPreviewImage), pPreviewPixbuf); gdk_pixbuf_unref (pPreviewPixbuf); gtk_widget_show (pPreviewImage); } if (s_pDialog != NULL) if (! cairo_dock_dialog_unreference (s_pDialog)) cairo_dock_dialog_unreference (s_pDialog); Icon *pIcon = cairo_dock_get_current_active_icon (); if (pIcon == NULL || pIcon->cParentDockName == NULL || pIcon->fPersonnalScale > 0) pIcon = cairo_dock_get_dialogless_icon (); CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon != NULL ? pIcon->cParentDockName : NULL); s_pDialog = cairo_dock_show_temporary_dialog_with_icon (dgettext (pGroupDescription->cGettextDomain, cDescription != NULL ? cDescription : pGroupDescription->cDescription), pIcon, CAIRO_CONTAINER (pDock), 0., pGroupDescription->cIcon); cairo_dock_dialog_reference (s_pDialog); g_free (cDescription); s_iSidShowGroupDialog = 0; return FALSE; }
const char* _inf_gettext(const char* msgid) { return dgettext(GETTEXT_PACKAGE, msgid); }
/* * Search the list of devices under SVM for the specified device. */ int inuse_svm(char *slice, nvlist_t *attrs, int *errp) { struct svm_list *listp; int found = 0; *errp = 0; if (slice == NULL) { return (found); } (void) mutex_lock(&init_lock); if (!initialized) { /* dynamically load libmeta */ if (init_svm()) { /* * need to initialize the cluster library to * avoid seg faults */ (mdl_sdssc_bind_library)(); /* load the SVM cache */ *errp = load_svm(); if (*errp == 0) { /* start a thread to monitor the svm config */ sysevent_handle_t *shp; const char *subclass_list[1]; /* * Only start the svmevent thread if * we are not doing an install */ if (getenv("_LIBDISKMGT_INSTALL") == NULL) { shp = sysevent_bind_handle( event_handler); if (shp != NULL) { subclass_list[0] = EC_SUB_ALL; if (sysevent_subscribe_event( shp, EC_SVM_CONFIG, subclass_list, 1) != 0) { *errp = errno; } } else { *errp = errno; } if (*errp) { /* * If the sysevent thread fails, * log the error but continue * on. This failing to start * is not catastrophic in * particular for short lived * consumers of libdiskmgt. */ syslog(LOG_WARNING, dgettext(TEXT_DOMAIN, "libdiskmgt: sysevent " "thread for SVM failed " "to start\n")); *errp = 0; } } } } if (*errp == 0) { initialized = 1; } } (void) mutex_unlock(&init_lock); (void) rw_rdlock(&svm_lock); listp = svm_listp; while (listp != NULL) { if (strcmp(slice, listp->slice) == 0) { libdiskmgt_add_str(attrs, DM_USED_BY, DM_USE_SVM, errp); if (strcmp(listp->type, "mdb") == 0 || strcmp(listp->type, "hs") == 0) { libdiskmgt_add_str(attrs, DM_USED_NAME, listp->type, errp); } else { char name[MAXPATHLEN]; (void) snprintf(name, MAXPATHLEN, "%s:%s", listp->type, listp->name); libdiskmgt_add_str(attrs, DM_USED_NAME, name, errp); } found = 1; break; } listp = listp->next; } (void) rw_unlock(&svm_lock); return (found); }
GimpInitStatusFunc gui_init (Gimp *gimp, gboolean no_splash) { GimpInitStatusFunc status_callback = NULL; gchar *abort_message; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (the_gui_gimp == NULL, NULL); abort_message = gui_sanity_check (); if (abort_message) gui_abort (abort_message); the_gui_gimp = gimp; /* TRANSLATORS: there is no need to translate this in GIMP. This uses * "gtk20" domain as a special trick to determine language direction, * but xgettext extracts it anyway mistakenly into GIMP po files. * Leave an empty string as translation. It does not matter. */ if (g_strcmp0 (dgettext ("gtk20", "default:LTR"), "default:RTL") == 0) /* Normally this should have been taken care of during command line * parsing as a post-parse hook of gtk_get_option_group(), using the * system locales. * But user config may have overriden the language, therefore we must * check the widget directions again. */ gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL); else gtk_widget_set_default_direction (GTK_TEXT_DIR_LTR); gui_unique_init (gimp); gimp_language_store_parser_init (); gimp_widgets_init (gui_help_func, gui_get_foreground_func, gui_get_background_func, NULL); g_type_class_ref (GIMP_TYPE_COLOR_SELECT); /* disable automatic startup notification */ gtk_window_set_auto_startup_notification (FALSE); gimp_dnd_init (gimp); themes_init (gimp); initial_monitor = gimp_get_monitor_at_pointer (&initial_screen); gtk_widget_set_default_colormap (gdk_screen_get_rgb_colormap (initial_screen)); if (! no_splash) { splash_create (gimp->be_verbose, initial_screen, initial_monitor); status_callback = splash_update; } g_signal_connect_after (gimp, "initialize", G_CALLBACK (gui_initialize_after_callback), NULL); g_signal_connect (gimp, "restore", G_CALLBACK (gui_restore_callback), NULL); g_signal_connect_after (gimp, "restore", G_CALLBACK (gui_restore_after_callback), NULL); g_signal_connect (gimp, "exit", G_CALLBACK (gui_exit_callback), NULL); g_signal_connect_after (gimp, "exit", G_CALLBACK (gui_exit_after_callback), NULL); return status_callback; }
/* * mv_xattrs - Copies the content of the extended attribute files. Then * moves the extended system attributes from the input attribute files * to the target attribute files. Moves the extended system attributes * from source to the target file. This function returns 0 on success * and nonzero on error. */ int mv_xattrs(char *cmd, char *infile, char *outfile, int sattr, int silent) { int srcfd = -1; int indfd = -1; int outdfd = -1; int tmpfd = -1; int sattrfd = -1; int tattrfd = -1; int asfd = -1; int atfd = -1; DIR *dirp = NULL; struct dirent *dp = NULL; char *etext = NULL; struct stat st1; struct stat st2; nvlist_t *response = NULL; nvlist_t *res = NULL; if ((srcfd = open(infile, O_RDONLY)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot open source"); goto error; } if (sattr) response = sysattr_list(cmd, srcfd, infile); if ((indfd = openat(srcfd, ".", O_RDONLY|O_XATTR)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot openat source"); goto error; } if ((outdfd = attropen(outfile, ".", O_RDONLY)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot attropen target"); goto error; } if ((tmpfd = dup(indfd)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot dup descriptor"); goto error; } if ((dirp = fdopendir(tmpfd)) == NULL) { etext = dgettext(TEXT_DOMAIN, "cannot access source"); goto error; } while ((dp = readdir(dirp)) != NULL) { if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') || (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == '\0') || (sysattr_type(dp->d_name) == _RO_SATTR) || (sysattr_type(dp->d_name) == _RW_SATTR)) continue; if ((sattrfd = openat(indfd, dp->d_name, O_RDONLY)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot open src attribute file"); goto error; } if (fstat(sattrfd, &st1) < 0) { etext = dgettext(TEXT_DOMAIN, "could not stat attribute file"); goto error; } if ((tattrfd = openat(outdfd, dp->d_name, O_RDWR|O_CREAT|O_TRUNC, st1.st_mode)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot open target attribute file"); goto error; } if (fstat(tattrfd, &st2) < 0) { etext = dgettext(TEXT_DOMAIN, "could not stat attribute file"); goto error; } if (writefile(sattrfd, tattrfd, infile, outfile, dp->d_name, dp->d_name, &st1, &st2) != 0) { etext = dgettext(TEXT_DOMAIN, "failed to copy extended attribute " "from source to target"); goto error; } errno = 0; if (sattr) { /* * Gets non default extended system attributes from * source to copy to target. */ if (dp->d_name != NULL) res = sysattr_list(cmd, sattrfd, dp->d_name); if (res != NULL && get_attrdirs(indfd, outdfd, dp->d_name, &asfd, &atfd) != 0) { etext = dgettext(TEXT_DOMAIN, "Failed to open attribute files"); goto error; } /* * Copy extended system attribute from source * attribute file to target attribute file */ if (res != NULL && (renameat(asfd, VIEW_READWRITE, atfd, VIEW_READWRITE) != 0)) { if (errno == EPERM) etext = dgettext(TEXT_DOMAIN, "Permission denied -" "failed to move system attribute"); else etext = dgettext(TEXT_DOMAIN, "failed to move extended " "system attribute"); goto error; } } if (sattrfd != -1) (void) close(sattrfd); if (tattrfd != -1) (void) close(tattrfd); if (asfd != -1) (void) close(asfd); if (atfd != -1) (void) close(atfd); if (res != NULL) { nvlist_free(res); res = NULL; } } errno = 0; /* Copy extended system attribute from source to target */ if (response != NULL) { if (renameat(indfd, VIEW_READWRITE, outdfd, VIEW_READWRITE) == 0) goto done; if (errno == EPERM) etext = dgettext(TEXT_DOMAIN, "Permission denied"); else etext = dgettext(TEXT_DOMAIN, "failed to move system attribute"); } error: nvlist_free(res); if (silent == 0 && etext != NULL) { if (!sattr) (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "%s: %s: cannot move extended attributes, "), cmd, infile); else (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "%s: %s: cannot move extended system " "attributes, "), cmd, infile); perror(etext); } done: if (dirp) (void) closedir(dirp); if (sattrfd != -1) (void) close(sattrfd); if (tattrfd != -1) (void) close(tattrfd); if (asfd != -1) (void) close(asfd); if (atfd != -1) (void) close(atfd); if (indfd != -1) (void) close(indfd); if (outdfd != -1) (void) close(outdfd); nvlist_free(response); if (etext != NULL) return (1); else return (0); }
static PyObject * PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw) { int sqlstate = 0; char *volatile sqlstatestr = NULL; char *volatile message = NULL; char *volatile detail = NULL; char *volatile hint = NULL; char *volatile column_name = NULL; char *volatile constraint_name = NULL; char *volatile datatype_name = NULL; char *volatile table_name = NULL; char *volatile schema_name = NULL; volatile MemoryContext oldcontext; PyObject *key, *value; PyObject *volatile so; Py_ssize_t pos = 0; if (PyTuple_Size(args) == 1) { /* * Treat single argument specially to avoid undesirable ('tuple',) * decoration. */ PyObject *o; if (!PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o)) PLy_elog(ERROR, "could not unpack arguments in plpy.elog"); so = PyObject_Str(o); } else so = PyObject_Str(args); if (so == NULL || ((message = PyString_AsString(so)) == NULL)) { level = ERROR; message = dgettext(TEXTDOMAIN, "could not parse error message in plpy.elog"); } message = pstrdup(message); Py_XDECREF(so); if (kw != NULL) { while (PyDict_Next(kw, &pos, &key, &value)) { char *keyword = PyString_AsString(key); if (strcmp(keyword, "message") == 0) { /* the message should not be overwriten */ if (PyTuple_Size(args) != 0) { PLy_exception_set(PyExc_TypeError, "Argument 'message' given by name and position"); return NULL; } if (message) pfree(message); message = object_to_string(value); } else if (strcmp(keyword, "detail") == 0) detail = object_to_string(value); else if (strcmp(keyword, "hint") == 0) hint = object_to_string(value); else if (strcmp(keyword, "sqlstate") == 0) sqlstatestr = object_to_string(value); else if (strcmp(keyword, "schema_name") == 0) schema_name = object_to_string(value); else if (strcmp(keyword, "table_name") == 0) table_name = object_to_string(value); else if (strcmp(keyword, "column_name") == 0) column_name = object_to_string(value); else if (strcmp(keyword, "datatype_name") == 0) datatype_name = object_to_string(value); else if (strcmp(keyword, "constraint_name") == 0) constraint_name = object_to_string(value); else { PLy_exception_set(PyExc_TypeError, "'%s' is an invalid keyword argument for this function", keyword); return NULL; } } } if (sqlstatestr != NULL) { if (strlen(sqlstatestr) != 5) { PLy_exception_set(PyExc_ValueError, "invalid SQLSTATE code"); return NULL; } if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5) { PLy_exception_set(PyExc_ValueError, "invalid SQLSTATE code"); return NULL; } sqlstate = MAKE_SQLSTATE(sqlstatestr[0], sqlstatestr[1], sqlstatestr[2], sqlstatestr[3], sqlstatestr[4]); } oldcontext = CurrentMemoryContext; PG_TRY(); { if (message != NULL) pg_verifymbstr(message, strlen(message), false); if (detail != NULL) pg_verifymbstr(detail, strlen(detail), false); if (hint != NULL) pg_verifymbstr(hint, strlen(hint), false); if (schema_name != NULL) pg_verifymbstr(schema_name, strlen(schema_name), false); if (table_name != NULL) pg_verifymbstr(table_name, strlen(table_name), false); if (column_name != NULL) pg_verifymbstr(column_name, strlen(column_name), false); if (datatype_name != NULL) pg_verifymbstr(datatype_name, strlen(datatype_name), false); if (constraint_name != NULL) pg_verifymbstr(constraint_name, strlen(constraint_name), false); ereport(level, ((sqlstate != 0) ? errcode(sqlstate) : 0, (message != NULL) ? errmsg_internal("%s", message) : 0, (detail != NULL) ? errdetail_internal("%s", detail) : 0, (hint != NULL) ? errhint("%s", hint) : 0, (column_name != NULL) ? err_generic_string(PG_DIAG_COLUMN_NAME, column_name) : 0, (constraint_name != NULL) ? err_generic_string(PG_DIAG_CONSTRAINT_NAME, constraint_name) : 0, (datatype_name != NULL) ? err_generic_string(PG_DIAG_DATATYPE_NAME, datatype_name) : 0, (table_name != NULL) ? err_generic_string(PG_DIAG_TABLE_NAME, table_name) : 0, (schema_name != NULL) ? err_generic_string(PG_DIAG_SCHEMA_NAME, schema_name) : 0)); } PG_CATCH(); { ErrorData *edata; MemoryContextSwitchTo(oldcontext); edata = CopyErrorData(); FlushErrorState(); PLy_exception_set_with_details(PLy_exc_error, edata); FreeErrorData(edata); return NULL; } PG_END_TRY(); /* * return a legal object so the interpreter will continue on its merry way */ Py_INCREF(Py_None); return Py_None; }
/* * Mount the given filesystem. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; char overlay[ZFS_MAXPROPLEN]; libzfs_handle_t *hdl = zhp->zfs_hdl; int remount = 0, rc; if (options == NULL) { (void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts)); } else { (void) strlcpy(mntopts, options, sizeof (mntopts)); } if (strstr(mntopts, MNTOPT_REMOUNT) != NULL) remount = 1; /* * If the pool is imported read-only then all mounts must be read-only */ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); /* * Append default mount options which apply to the mount point. * This is done because under Linux (unlike Solaris) multiple mount * points may reference a single super block. This means that just * given a super block there is no back reference to update the per * mount point options. */ rc = zfs_add_options(zhp, mntopts, sizeof (mntopts)); if (rc) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "default options unavailable")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* * Append zfsutil option so the mount helper allow the mount */ strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts)); /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } /* * Overlay mounts are disabled by default but may be enabled * via the 'overlay' property or the 'zfs mount -O' option. */ if (!(flags & MS_OVERLAY)) { if (zfs_prop_get(zhp, ZFS_PROP_OVERLAY, overlay, sizeof (overlay), NULL, NULL, 0, B_FALSE) == 0) { if (strcmp(overlay, "on") == 0) { flags |= MS_OVERLAY; } } } /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if 'remount' is * specified or if overlay option(-O) is given */ if ((flags & MS_OVERLAY) == 0 && !remount && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* perform the mount */ rc = do_mount(zfs_get_name(zhp), mountpoint, mntopts); if (rc) { /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (rc == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (rc == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else if (rc == ENOTSUP) { char buf[256]; int spa_version; VERIFY(zfs_spa_version(zhp, &spa_version) == 0); (void) snprintf(buf, sizeof (buf), dgettext(TEXT_DOMAIN, "Can't mount a version %lld " "file system on a version %d pool. Pool must be" " upgraded to mount this file system."), (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); } else { zfs_error_aux(hdl, strerror(rc)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } /* remove the mounted entry before re-adding on remount */ if (remount) libzfs_mnttab_remove(hdl, zhp->zfs_name); /* add the mounted entry into our cache */ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); }
int zfs_crypto_load_key(zfs_handle_t *zhp, boolean_t noop, char *alt_keylocation) { int ret, attempts = 0; char errbuf[1024]; uint64_t keystatus, iters = 0, salt = 0; uint64_t keyformat = ZFS_KEYFORMAT_NONE; char prop_keylocation[MAXNAMELEN]; char prop_encroot[MAXNAMELEN]; char *keylocation = NULL; uint8_t *key_material = NULL, *key_data = NULL; size_t key_material_len; boolean_t is_encroot, can_retry = B_FALSE, correctible = B_FALSE; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "Key load error")); /* check that encryption is enabled for the pool */ if (!encryption_feature_is_enabled(zhp->zpool_hdl)) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Encryption feature not enabled.")); ret = EINVAL; goto error; } /* Fetch the keyformat. Check that the dataset is encrypted. */ keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT); if (keyformat == ZFS_KEYFORMAT_NONE) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "'%s' is not encrypted."), zfs_get_name(zhp)); ret = EINVAL; goto error; } /* * Fetch the key location. Check that we are working with an * encryption root. */ ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to get encryption root for '%s'."), zfs_get_name(zhp)); goto error; } else if (!is_encroot) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Keys must be loaded for encryption root of '%s' (%s)."), zfs_get_name(zhp), prop_encroot); ret = EINVAL; goto error; } /* * if the caller has elected to override the keylocation property * use that instead */ if (alt_keylocation != NULL) { keylocation = alt_keylocation; } else { ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION, prop_keylocation, sizeof (prop_keylocation), NULL, NULL, 0, B_TRUE); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to get keylocation for '%s'."), zfs_get_name(zhp)); goto error; } keylocation = prop_keylocation; } /* check that the key is unloaded unless this is a noop */ if (!noop) { keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS); if (keystatus == ZFS_KEYSTATUS_AVAILABLE) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key already loaded for '%s'."), zfs_get_name(zhp)); ret = EEXIST; goto error; } } /* passphrase formats require a salt and pbkdf2_iters property */ if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) { salt = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_SALT); iters = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_ITERS); } try_again: /* fetching and deriving the key are correctible errors. set the flag */ correctible = B_TRUE; /* get key material from key format and location */ ret = get_key_material(zhp->zfs_hdl, B_FALSE, B_FALSE, keyformat, keylocation, zfs_get_name(zhp), &key_material, &key_material_len, &can_retry); if (ret != 0) goto error; /* derive a key from the key material */ ret = derive_key(zhp->zfs_hdl, keyformat, iters, key_material, key_material_len, salt, &key_data); if (ret != 0) goto error; correctible = B_FALSE; /* pass the wrapping key and noop flag to the ioctl */ ret = lzc_load_key(zhp->zfs_name, noop, key_data, WRAPPING_KEY_LEN); if (ret != 0) { switch (ret) { case EPERM: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Permission denied.")); break; case EINVAL: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Invalid parameters provided for dataset %s."), zfs_get_name(zhp)); break; case EEXIST: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key already loaded for '%s'."), zfs_get_name(zhp)); break; case EBUSY: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "'%s' is busy."), zfs_get_name(zhp)); break; case EACCES: correctible = B_TRUE; zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Incorrect key provided for '%s'."), zfs_get_name(zhp)); break; } goto error; } free(key_material); free(key_data); return (0); error: zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf); if (key_material != NULL) free(key_material); if (key_data != NULL) free(key_data); /* * Here we decide if it is ok to allow the user to retry entering their * key. The can_retry flag will be set if the user is entering their * key from an interactive prompt. The correctible flag will only be * set if an error that occured could be corrected by retrying. Both * flags are needed to allow the user to attempt key entry again */ if (can_retry && correctible && attempts <= MAX_KEY_PROMPT_ATTEMPTS) { attempts++; goto try_again; } return (ret); }
/* * Share the given filesystem according to the options in the specified * protocol specific properties (sharenfs, sharesmb). We rely * on "libshare" to do the dirty work for us. */ static int zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) { char mountpoint[ZFS_MAXPROPLEN]; char shareopts[ZFS_MAXPROPLEN]; char sourcestr[ZFS_MAXPROPLEN]; libzfs_handle_t *hdl = zhp->zfs_hdl; sa_share_t share; zfs_share_proto_t *curr_proto; zprop_source_t sourcetype; int ret; if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) { /* * Return success if there are no share options. */ if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop, shareopts, sizeof (shareopts), &sourcetype, sourcestr, ZFS_MAXPROPLEN, B_FALSE) != 0 || strcmp(shareopts, "off") == 0) continue; ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API); if (ret != SA_OK) { (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED, dgettext(TEXT_DOMAIN, "cannot share '%s': %s"), zfs_get_name(zhp), sa_errorstr(ret)); return (-1); } /* * If the 'zoned' property is set, then zfs_is_mountable() * will have already bailed out if we are in the global zone. * But local zones cannot be NFS servers, so we ignore it for * local zones as well. */ if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) continue; share = sa_find_share(hdl->libzfs_sharehdl, mountpoint); if (share == NULL) { /* * This may be a new file system that was just * created so isn't in the internal cache * (second time through). Rather than * reloading the entire configuration, we can * assume ZFS has done the checking and it is * safe to add this to the internal * configuration. */ if (sa_zfs_process_share(hdl->libzfs_sharehdl, NULL, NULL, mountpoint, proto_table[*curr_proto].p_name, sourcetype, shareopts, sourcestr, zhp->zfs_name) != SA_OK) { (void) zfs_error_fmt(hdl, proto_table[*curr_proto].p_share_err, dgettext(TEXT_DOMAIN, "cannot share '%s'"), zfs_get_name(zhp)); return (-1); } hdl->libzfs_shareflags |= ZFSSHARE_MISS; share = sa_find_share(hdl->libzfs_sharehdl, mountpoint); } if (share != NULL) { int err; err = sa_enable_share(share, proto_table[*curr_proto].p_name); if (err != SA_OK) { (void) zfs_error_fmt(hdl, proto_table[*curr_proto].p_share_err, dgettext(TEXT_DOMAIN, "cannot share '%s'"), zfs_get_name(zhp)); return (-1); } } else { (void) zfs_error_fmt(hdl, proto_table[*curr_proto].p_share_err, dgettext(TEXT_DOMAIN, "cannot share '%s'"), zfs_get_name(zhp)); return (-1); } } return (0); }
int zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey) { int ret; char errbuf[1024]; boolean_t is_encroot; nvlist_t *props = NULL; uint8_t *wkeydata = NULL; uint_t wkeylen = 0; dcp_cmd_t cmd = (inheritkey) ? DCP_CMD_INHERIT : DCP_CMD_NEW_KEY; uint64_t crypt, pcrypt, keystatus, pkeystatus; uint64_t keyformat = ZFS_KEYFORMAT_NONE; zfs_handle_t *pzhp = NULL; char *keylocation = NULL; char origin_name[MAXNAMELEN]; char prop_keylocation[MAXNAMELEN]; char parent_name[ZFS_MAX_DATASET_NAME_LEN]; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "Key change error")); /* check that encryption is enabled for the pool */ if (!encryption_feature_is_enabled(zhp->zpool_hdl)) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Encryption feature not enabled.")); ret = EINVAL; goto error; } /* get crypt from dataset */ crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION); if (crypt == ZIO_CRYPT_OFF) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Dataset not encrypted.")); ret = EINVAL; goto error; } /* get the encryption root of the dataset */ ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to get encryption root for '%s'."), zfs_get_name(zhp)); goto error; } /* Clones use their origin's key and cannot rewrap it */ ret = zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin_name, sizeof (origin_name), NULL, NULL, 0, B_TRUE); if (ret == 0 && strcmp(origin_name, "") != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Keys cannot be changed on clones.")); ret = EINVAL; goto error; } /* * If the user wants to use the inheritkey variant of this function * we don't need to collect any crypto arguments. */ if (!inheritkey) { /* validate the provided properties */ ret = zfs_crypto_verify_rewrap_nvlist(zhp, raw_props, &props, errbuf); if (ret != 0) goto error; /* * Load keyformat and keylocation from the nvlist. Fetch from * the dataset properties if not specified. */ (void) nvlist_lookup_uint64(props, zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &keyformat); (void) nvlist_lookup_string(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation); if (is_encroot) { /* * If this is already an ecryption root, just keep * any properties not set by the user. */ if (keyformat == ZFS_KEYFORMAT_NONE) { keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT); ret = nvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_KEYFORMAT), keyformat); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to " "get existing keyformat " "property.")); goto error; } } if (keylocation == NULL) { ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION, prop_keylocation, sizeof (prop_keylocation), NULL, NULL, 0, B_TRUE); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to " "get existing keylocation " "property.")); goto error; } keylocation = prop_keylocation; } } else { /* need a new key for non-encryption roots */ if (keyformat == ZFS_KEYFORMAT_NONE) { ret = EINVAL; zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Keyformat required " "for new encryption root.")); goto error; } /* default to prompt if no keylocation is specified */ if (keylocation == NULL) { keylocation = "prompt"; ret = nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION), keylocation); if (ret != 0) goto error; } } /* fetch the new wrapping key and associated properties */ ret = populate_create_encryption_params_nvlists(zhp->zfs_hdl, zhp, B_TRUE, keyformat, keylocation, props, &wkeydata, &wkeylen); if (ret != 0) goto error; } else { /* check that zhp is an encryption root */ if (!is_encroot) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key inheritting can only be performed on " "encryption roots.")); ret = EINVAL; goto error; } /* get the parent's name */ ret = zfs_parent_name(zhp, parent_name, sizeof (parent_name)); if (ret != 0) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Root dataset cannot inherit key.")); ret = EINVAL; goto error; } /* get a handle to the parent */ pzhp = make_dataset_handle(zhp->zfs_hdl, parent_name); if (pzhp == NULL) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Failed to lookup parent.")); ret = ENOENT; goto error; } /* parent must be encrypted */ pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION); if (pcrypt == ZIO_CRYPT_OFF) { zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Parent must be encrypted.")); ret = EINVAL; goto error; } /* check that the parent's key is loaded */ pkeystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS); if (pkeystatus == ZFS_KEYSTATUS_UNAVAILABLE) { zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Parent key must be loaded.")); ret = EACCES; goto error; } } /* check that the key is loaded */ keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS); if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) { zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key must be loaded.")); ret = EACCES; goto error; } /* call the ioctl */ ret = lzc_change_key(zhp->zfs_name, cmd, props, wkeydata, wkeylen); if (ret != 0) { switch (ret) { case EPERM: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Permission denied.")); break; case EINVAL: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Invalid properties for key change.")); break; case EACCES: zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN, "Key is not currently loaded.")); break; } zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf); } if (pzhp != NULL) zfs_close(pzhp); if (props != NULL) nvlist_free(props); if (wkeydata != NULL) free(wkeydata); return (ret); error: if (pzhp != NULL) zfs_close(pzhp); if (props != NULL) nvlist_free(props); if (wkeydata != NULL) free(wkeydata); zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf); return (ret); }
QString u2dTr(const char* text, const char* domain) { return QString::fromUtf8(dgettext(domain, text)); }
static int populate_create_encryption_params_nvlists(libzfs_handle_t *hdl, zfs_handle_t *zhp, boolean_t newkey, zfs_keyformat_t keyformat, char *keylocation, nvlist_t *props, uint8_t **wkeydata, uint_t *wkeylen) { int ret; uint64_t iters = 0, salt = 0; uint8_t *key_material = NULL; size_t key_material_len = 0; uint8_t *key_data = NULL; const char *fsname = (zhp) ? zfs_get_name(zhp) : NULL; /* get key material from keyformat and keylocation */ ret = get_key_material(hdl, B_TRUE, newkey, keyformat, keylocation, fsname, &key_material, &key_material_len, NULL); if (ret != 0) goto error; /* passphrase formats require a salt and pbkdf2 iters property */ if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) { /* always generate a new salt */ random_init(); ret = random_get_bytes((uint8_t *)&salt, sizeof (uint64_t)); if (ret != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Failed to generate salt.")); goto error; } random_fini(); ret = nvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_SALT), salt); if (ret != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Failed to add salt to properties.")); goto error; } /* * If not otherwise specified, use the default number of * pbkdf2 iterations. If specified, we have already checked * that the given value is greater than MIN_PBKDF2_ITERATIONS * during zfs_valid_proplist(). */ ret = nvlist_lookup_uint64(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters); if (ret == ENOENT) { iters = DEFAULT_PBKDF2_ITERATIONS; ret = nvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), iters); if (ret != 0) goto error; } else if (ret != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Failed to get pbkdf2 iterations.")); goto error; } } else { /* check that pbkdf2iters was not specified by the user */ ret = nvlist_lookup_uint64(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters); if (ret == 0) { ret = EINVAL; zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Cannot specify pbkdf2iters with a non-passphrase " "keyformat.")); goto error; } } /* derive a key from the key material */ ret = derive_key(hdl, keyformat, iters, key_material, key_material_len, salt, &key_data); if (ret != 0) goto error; free(key_material); *wkeydata = key_data; *wkeylen = WRAPPING_KEY_LEN; return (0); error: if (key_material != NULL) free(key_material); if (key_data != NULL) free(key_data); *wkeydata = NULL; *wkeylen = 0; return (ret); }
/* * Given a list of directories to search, find all pools stored on disk. This * includes partial pools which are not available to import. If no args are * given (argc is 0), then the default directory (/dev/dsk) is searched. * poolname or guid (but not both) are provided by the caller when trying * to import a specific pool. */ static nvlist_t * zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) { int i, dirs = iarg->paths; struct dirent64 *dp; char path[MAXPATHLEN]; char *end, **dir = iarg->path; size_t pathleft; nvlist_t *ret = NULL; static char *default_dir = "/dev/dsk"; pool_list_t pools = { 0 }; pool_entry_t *pe, *penext; vdev_entry_t *ve, *venext; config_entry_t *ce, *cenext; name_entry_t *ne, *nenext; avl_tree_t slice_cache; rdsk_node_t *slice; void *cookie; if (dirs == 0) { dirs = 1; dir = &default_dir; } /* * Go through and read the label configuration information from every * possible device, organizing the information according to pool GUID * and toplevel GUID. */ for (i = 0; i < dirs; i++) { tpool_t *t; char *rdsk; int dfd; boolean_t config_failed = B_FALSE; DIR *dirp; /* use realpath to normalize the path */ if (realpath(dir[i], path) == 0) { (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]); goto error; } end = &path[strlen(path)]; *end++ = '/'; *end = 0; pathleft = &path[sizeof (path)] - end; /* * Using raw devices instead of block devices when we're * reading the labels skips a bunch of slow operations during * close(2) processing, so we replace /dev/dsk with /dev/rdsk. */ if (strcmp(path, "/dev/dsk/") == 0) rdsk = "/dev/rdsk/"; else rdsk = path; if ((dfd = open64(rdsk, O_RDONLY)) < 0 || (dirp = fdopendir(dfd)) == NULL) { if (dfd >= 0) (void) close(dfd); zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), rdsk); goto error; } avl_create(&slice_cache, slice_cache_compare, sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node)); /* * This is not MT-safe, but we have no MT consumers of libzfs */ while ((dp = readdir64(dirp)) != NULL) { const char *name = dp->d_name; if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; slice = zfs_alloc(hdl, sizeof (rdsk_node_t)); slice->rn_name = zfs_strdup(hdl, name); slice->rn_avl = &slice_cache; slice->rn_dfd = dfd; slice->rn_hdl = hdl; slice->rn_nozpool = B_FALSE; avl_add(&slice_cache, slice); } /* * create a thread pool to do all of this in parallel; * rn_nozpool is not protected, so this is racy in that * multiple tasks could decide that the same slice can * not hold a zpool, which is benign. Also choose * double the number of processors; we hold a lot of * locks in the kernel, so going beyond this doesn't * buy us much. */ t = tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL); for (slice = avl_first(&slice_cache); slice; (slice = avl_walk(&slice_cache, slice, AVL_AFTER))) (void) tpool_dispatch(t, zpool_open_func, slice); tpool_wait(t); tpool_destroy(t); cookie = NULL; while ((slice = avl_destroy_nodes(&slice_cache, &cookie)) != NULL) { if (slice->rn_config != NULL && !config_failed) { nvlist_t *config = slice->rn_config; boolean_t matched = B_TRUE; if (iarg->poolname != NULL) { char *pname; matched = nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &pname) == 0 && strcmp(iarg->poolname, pname) == 0; } else if (iarg->guid != 0) { uint64_t this_guid; matched = nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &this_guid) == 0 && iarg->guid == this_guid; } if (!matched) { nvlist_free(config); } else { /* * use the non-raw path for the config */ (void) strlcpy(end, slice->rn_name, pathleft); if (add_config(hdl, &pools, path, config) != 0) config_failed = B_TRUE; } } free(slice->rn_name); free(slice); } avl_destroy(&slice_cache); (void) closedir(dirp); if (config_failed) goto error; } ret = get_configs(hdl, &pools, iarg->can_be_active); error: for (pe = pools.pools; pe != NULL; pe = penext) { penext = pe->pe_next; for (ve = pe->pe_vdevs; ve != NULL; ve = venext) { venext = ve->ve_next; for (ce = ve->ve_configs; ce != NULL; ce = cenext) { cenext = ce->ce_next; if (ce->ce_config) nvlist_free(ce->ce_config); free(ce); } free(ve); } free(pe); } for (ne = pools.names; ne != NULL; ne = nenext) { nenext = ne->ne_next; free(ne->ne_name); free(ne); } return (ret); }
/* * Given a cache file, return the contents as a list of importable pools. * poolname or guid (but not both) are provided by the caller when trying * to import a specific pool. */ nvlist_t * zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, char *poolname, uint64_t guid) { char *buf; int fd; struct stat64 statbuf; nvlist_t *raw, *src, *dst; nvlist_t *pools; nvpair_t *elem; char *name; uint64_t this_guid; boolean_t active; verify(poolname == NULL || guid == 0); if ((fd = open(cachefile, O_RDONLY)) < 0) { zfs_error_aux(hdl, "%s", strerror(errno)); (void) zfs_error(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "failed to open cache file")); return (NULL); } if (fstat64(fd, &statbuf) != 0) { zfs_error_aux(hdl, "%s", strerror(errno)); (void) close(fd); (void) zfs_error(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "failed to get size of cache file")); return (NULL); } if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) { (void) close(fd); return (NULL); } if (read(fd, buf, statbuf.st_size) != statbuf.st_size) { (void) close(fd); free(buf); (void) zfs_error(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "failed to read cache file contents")); return (NULL); } (void) close(fd); if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) { free(buf); (void) zfs_error(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "invalid or corrupt cache file contents")); return (NULL); } free(buf); /* * Go through and get the current state of the pools and refresh their * state. */ if (nvlist_alloc(&pools, 0, 0) != 0) { (void) no_memory(hdl); nvlist_free(raw); return (NULL); } elem = NULL; while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) { verify(nvpair_value_nvlist(elem, &src) == 0); verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME, &name) == 0); if (poolname != NULL && strcmp(poolname, name) != 0) continue; verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID, &this_guid) == 0); if (guid != 0) { verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID, &this_guid) == 0); if (guid != this_guid) continue; } if (pool_active(hdl, name, this_guid, &active) != 0) { nvlist_free(raw); nvlist_free(pools); return (NULL); } if (active) continue; if ((dst = refresh_config(hdl, src)) == NULL) { nvlist_free(raw); nvlist_free(pools); return (NULL); } if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) { (void) no_memory(hdl); nvlist_free(dst); nvlist_free(raw); nvlist_free(pools); return (NULL); } nvlist_free(dst); } nvlist_free(raw); return (pools); }
static int prompt_pkcs11_pin(libzfs_handle_t *hdl, zfs_cmd_t *zc, zfs_crypto_zckey_t cmd, pkcs11_uri_t *p11uri, char **pin, uint32_t *pinlen) { char prompt[MAXPROMPTLEN]; char *input; char dsname[MAXNAMELEN]; /* * If the PKCS#11 uri has a pinfile argument read the pin from * there. * * Otherwise if the libzfs_handle_t has crypto data we assume this is * the PIN given we can only be in here with a PKCS#11 uri. * * Finally if that is empty then if we can prompt then do so using * getpassphrase(). * * Abuse zfs_can_prompt_if_needed() by pretending we are * "passphrase,prompt". */ if (p11uri->pinfile) { struct stat sbuf; int pinfd = open(p11uri->pinfile, O_RDONLY); char *pbuf; if (pinfd == -1) return (-1); if (fstat(pinfd, &sbuf) != 0) return (-1); pbuf = zfs_alloc(hdl, sbuf.st_size); if (read(pinfd, pbuf, sbuf.st_size) != sbuf.st_size) { free(pbuf); return (-1); } (void) close(pinfd); pbuf[sbuf.st_size] = '\0'; *pinlen = sbuf.st_size; if (pbuf[sbuf.st_size - 1] == '\n' || pbuf[sbuf.st_size - 1] == '\r') { *pinlen = *pinlen - 1; } *pin = pbuf; return (0); } if (hdl->libzfs_crypt.zc_key_data != NULL && hdl->libzfs_crypt.zc_key_data_len != 0) { *pinlen = hdl->libzfs_crypt.zc_key_data_len; *pin = zfs_alloc(hdl, *pinlen); bcopy(hdl->libzfs_crypt.zc_key_data, *pin, *pinlen); return (0); } if (!zfs_can_prompt_if_needed("passphrase,prompt")) { errno = ENOTTY; return (-1); } zfs_cmd_target_dsname(zc, cmd, dsname, sizeof (dsname)); if (p11uri->token) { (void) snprintf(prompt, MAXPROMPTLEN, dgettext(TEXT_DOMAIN, "Enter '%s' PKCS#11 token PIN for '%s': "), p11uri->token, dsname); } else { (void) snprintf(prompt, MAXPROMPTLEN, dgettext(TEXT_DOMAIN, "Enter PKCS#11 token PIN for '%s': "), dsname); } input = getpassphrase(prompt); if (input != NULL) { *pin = strdup(input); *pinlen = strlen(*pin); } else { return (-1); } return (0); }