18329232eSGordon Ross /*
28329232eSGordon Ross * This file and its contents are supplied under the terms of the
38329232eSGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0.
48329232eSGordon Ross * You may only use this file in accordance with the terms of version
58329232eSGordon Ross * 1.0 of the CDDL.
68329232eSGordon Ross *
78329232eSGordon Ross * A full copy of the text of the CDDL should have accompanied this
88329232eSGordon Ross * source. A copy of the CDDL is also available via the Internet at
98329232eSGordon Ross * http://www.illumos.org/license/CDDL.
108329232eSGordon Ross */
118329232eSGordon Ross
128329232eSGordon Ross /*
13adee6784SGordon Ross * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
148329232eSGordon Ross */
158329232eSGordon Ross
168329232eSGordon Ross /*
178329232eSGordon Ross * Test & debug program for the SMB client
188329232eSGordon Ross *
198329232eSGordon Ross * This implements a simple command reader which accepts
208329232eSGordon Ross * commands to simulate system calls into the file system.
218329232eSGordon Ross */
228329232eSGordon Ross
238329232eSGordon Ross #include <sys/types.h>
248329232eSGordon Ross #include <sys/file.h>
258329232eSGordon Ross #include <sys/stat.h>
268329232eSGordon Ross #include <sys/mount.h>
278329232eSGordon Ross #include <sys/dirent.h>
288329232eSGordon Ross #include <sys/strlog.h> /* SL_NOTE */
298329232eSGordon Ross
308329232eSGordon Ross #include <stdio.h>
318329232eSGordon Ross #include <stdlib.h>
328329232eSGordon Ross #include <string.h>
338329232eSGordon Ross #include <strings.h>
348329232eSGordon Ross #include <errno.h>
358329232eSGordon Ross #include <fcntl.h>
36adee6784SGordon Ross #include <inttypes.h>
378329232eSGordon Ross #include <unistd.h>
388329232eSGordon Ross
398329232eSGordon Ross #include <sys/fs/smbfs_mount.h>
408329232eSGordon Ross #include <netsmb/smb_lib.h>
418329232eSGordon Ross #include <libfknsmb/common/libfknsmb.h>
428329232eSGordon Ross #include <libfksmbfs/common/libfksmbfs.h>
438329232eSGordon Ross
448329232eSGordon Ross #if _FILE_OFFSET_BITS != 64
458329232eSGordon Ross #error "This calls (fake) VFS code which requires 64-bit off_t"
468329232eSGordon Ross #endif
478329232eSGordon Ross
488329232eSGordon Ross extern int list_shares(struct smb_ctx *);
498329232eSGordon Ross
508329232eSGordon Ross #define MAXARG 10
518329232eSGordon Ross
528329232eSGordon Ross struct cmd_tbl_ent {
538329232eSGordon Ross void (*ce_func)(int, char **);
548329232eSGordon Ross const char *ce_name;
558329232eSGordon Ross const char *ce_argdesc;
568329232eSGordon Ross };
578329232eSGordon Ross static struct cmd_tbl_ent cmd_tbl[];
588329232eSGordon Ross
598329232eSGordon Ross static struct smb_ctx *ctx = NULL;
608329232eSGordon Ross static char *server = NULL;
618329232eSGordon Ross
628329232eSGordon Ross static vfs_t *vfsp = NULL;
638329232eSGordon Ross
648329232eSGordon Ross static void show_dents(vnode_t *, offset_t *, char *, int);
658329232eSGordon Ross static void run_cli(void);
668329232eSGordon Ross
678329232eSGordon Ross #define TBUFSZ 8192
688329232eSGordon Ross static char tbuf[TBUFSZ];
698329232eSGordon Ross
708329232eSGordon Ross static void
fksmbcl_usage(void)718329232eSGordon Ross fksmbcl_usage(void)
728329232eSGordon Ross {
738329232eSGordon Ross printf("usage: fksmbcl //user@server (like smbutil)\n");
748329232eSGordon Ross exit(1);
758329232eSGordon Ross }
768329232eSGordon Ross
778329232eSGordon Ross int
main(int argc,char * argv[])788329232eSGordon Ross main(int argc, char *argv[])
798329232eSGordon Ross {
808329232eSGordon Ross int error, opt;
818329232eSGordon Ross
828329232eSGordon Ross /*
838329232eSGordon Ross * Initializations
848329232eSGordon Ross */
858329232eSGordon Ross nsmb_drv_load();
868329232eSGordon Ross nsmb_drv_init();
878329232eSGordon Ross fksmbfs_init();
888329232eSGordon Ross
898329232eSGordon Ross while ((opt = getopt(argc, argv, "dv")) != -1) {
908329232eSGordon Ross switch (opt) {
918329232eSGordon Ross case 'd':
928329232eSGordon Ross smb_debug++;
938329232eSGordon Ross break;
948329232eSGordon Ross case 'v':
958329232eSGordon Ross smb_verbose++;
968329232eSGordon Ross break;
978329232eSGordon Ross case '?':
988329232eSGordon Ross fksmbcl_usage();
998329232eSGordon Ross break;
1008329232eSGordon Ross }
1018329232eSGordon Ross }
1028329232eSGordon Ross if (optind >= argc)
1038329232eSGordon Ross fksmbcl_usage();
1048329232eSGordon Ross server = argv[optind];
1058329232eSGordon Ross
1068329232eSGordon Ross /*
1078329232eSGordon Ross * Setup the libsmbfs context
1088329232eSGordon Ross */
1098329232eSGordon Ross error = smb_ctx_alloc(&ctx);
1108329232eSGordon Ross if (error) {
1118329232eSGordon Ross fprintf(stderr, "%s: smb_ctx_alloc failed (%d)\n",
1128329232eSGordon Ross argv[0], error);
1138329232eSGordon Ross return (1);
1148329232eSGordon Ross }
1158329232eSGordon Ross
1168329232eSGordon Ross error = smb_ctx_scan_argv(ctx, argc, argv,
1178329232eSGordon Ross SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
1188329232eSGordon Ross if (error) {
1198329232eSGordon Ross fprintf(stderr, "logon: smb_ctx_scan_argv, error %d\n", error);
1208329232eSGordon Ross return (1);
1218329232eSGordon Ross }
1228329232eSGordon Ross error = smb_ctx_readrc(ctx);
1238329232eSGordon Ross if (error) {
1248329232eSGordon Ross fprintf(stderr, "logon: smb_ctx_readrc, error %d\n", error);
1258329232eSGordon Ross return (1);
1268329232eSGordon Ross }
1278329232eSGordon Ross
1288329232eSGordon Ross /* Do smb_ctx_setshare later, and smb_ctx_resolve. */
1298329232eSGordon Ross
1308329232eSGordon Ross /*
1318329232eSGordon Ross * Next would be smb_ctx_get_ssn() but don't do that until
1328329232eSGordon Ross * the "logon" command so one can set breakpoints etc.
1338329232eSGordon Ross */
1348329232eSGordon Ross
1358329232eSGordon Ross /*
1368329232eSGordon Ross * Run the CLI
1378329232eSGordon Ross */
1388329232eSGordon Ross run_cli();
1398329232eSGordon Ross
1408329232eSGordon Ross /*
1418329232eSGordon Ross * Cleanup
1428329232eSGordon Ross */
1438329232eSGordon Ross fksmbfs_fini();
1448329232eSGordon Ross nsmb_drv_fini();
1458329232eSGordon Ross
1468329232eSGordon Ross return (0);
1478329232eSGordon Ross }
1488329232eSGordon Ross
1498329232eSGordon Ross static void
run_cli()1508329232eSGordon Ross run_cli()
1518329232eSGordon Ross {
1528329232eSGordon Ross static char cmdbuf[100];
1538329232eSGordon Ross int argc, i;
1548329232eSGordon Ross char *argv[MAXARG];
1558329232eSGordon Ross char *cmd;
1568329232eSGordon Ross char *savep = NULL;
1578329232eSGordon Ross char *sep = " \t\n";
1588329232eSGordon Ross char *prompt = NULL;
1598329232eSGordon Ross struct cmd_tbl_ent *ce;
1608329232eSGordon Ross
1618329232eSGordon Ross if (isatty(0)) {
1628329232eSGordon Ross fputs("# Start with:\n"
1638329232eSGordon Ross "> logon [user [dom [pw]]]\n"
1648329232eSGordon Ross "> shares\n"
1658329232eSGordon Ross "> mount {share}\n\n",
1668329232eSGordon Ross stdout);
1678329232eSGordon Ross prompt = "> ";
1688329232eSGordon Ross }
1698329232eSGordon Ross
1708329232eSGordon Ross for (;;) {
1718329232eSGordon Ross if (prompt) {
1728329232eSGordon Ross fputs(prompt, stdout);
1738329232eSGordon Ross fflush(stdout);
1748329232eSGordon Ross }
1758329232eSGordon Ross
1768329232eSGordon Ross cmd = fgets(cmdbuf, sizeof (cmdbuf), stdin);
1778329232eSGordon Ross if (cmd == NULL)
1788329232eSGordon Ross break;
1798329232eSGordon Ross if (cmd[0] == '#')
1808329232eSGordon Ross continue;
1818329232eSGordon Ross
1828329232eSGordon Ross if (prompt == NULL) {
1838329232eSGordon Ross /* Put commands in the output too. */
1848329232eSGordon Ross fprintf(stdout, "+ %s", cmdbuf);
1858329232eSGordon Ross }
1868329232eSGordon Ross
1878329232eSGordon Ross argv[0] = strtok_r(cmd, sep, &savep);
1888329232eSGordon Ross if (argv[0] == NULL)
1898329232eSGordon Ross continue;
1908329232eSGordon Ross for (argc = 1; argc < MAXARG; argc++) {
1918329232eSGordon Ross argv[argc] = strtok_r(NULL, sep, &savep);
1928329232eSGordon Ross if (argv[argc] == NULL)
1938329232eSGordon Ross break;
1948329232eSGordon Ross }
1958329232eSGordon Ross for (i = argc; i < MAXARG; i++)
1968329232eSGordon Ross argv[i++] = NULL;
1978329232eSGordon Ross
1988329232eSGordon Ross for (ce = cmd_tbl; ce->ce_name != NULL; ce++)
1998329232eSGordon Ross if (strcmp(ce->ce_name, argv[0]) == 0)
2008329232eSGordon Ross break;
2018329232eSGordon Ross if (ce->ce_name != NULL) {
2028329232eSGordon Ross ce->ce_func(argc, argv);
2038329232eSGordon Ross } else {
2048329232eSGordon Ross fprintf(stderr, "%s unknown command. Try help\n",
2058329232eSGordon Ross argv[0]);
2068329232eSGordon Ross }
2078329232eSGordon Ross }
2088329232eSGordon Ross }
2098329232eSGordon Ross
2108329232eSGordon Ross /*
2118329232eSGordon Ross * Command handlers
2128329232eSGordon Ross */
2138329232eSGordon Ross
2148329232eSGordon Ross static void
do_exit(int argc,char ** argv)2158329232eSGordon Ross do_exit(int argc, char **argv)
2168329232eSGordon Ross {
2178329232eSGordon Ross exit(0);
2188329232eSGordon Ross }
2198329232eSGordon Ross
2208329232eSGordon Ross static void
do_help(int argc,char ** argv)2218329232eSGordon Ross do_help(int argc, char **argv)
2228329232eSGordon Ross {
2238329232eSGordon Ross struct cmd_tbl_ent *ce;
2248329232eSGordon Ross
2258329232eSGordon Ross printf("Commands:\n");
2268329232eSGordon Ross for (ce = cmd_tbl; ce->ce_func != NULL; ce++)
2278329232eSGordon Ross printf("%s %s\n", ce->ce_name, ce->ce_argdesc);
2288329232eSGordon Ross }
2298329232eSGordon Ross
2308329232eSGordon Ross static void
do_logon(int argc,char ** argv)2318329232eSGordon Ross do_logon(int argc, char **argv)
2328329232eSGordon Ross {
2338329232eSGordon Ross int error;
2348329232eSGordon Ross
2358329232eSGordon Ross if (argc > 1) {
2368329232eSGordon Ross if (argv[1][0] == '-') {
2378329232eSGordon Ross smb_ctx_setuser(ctx, "", B_TRUE);
2388329232eSGordon Ross ctx->ct_flags |= SMBCF_NOPWD;
2398329232eSGordon Ross } else {
2408329232eSGordon Ross smb_ctx_setuser(ctx, argv[1], B_TRUE);
2418329232eSGordon Ross }
2428329232eSGordon Ross }
2438329232eSGordon Ross if (argc > 2)
2448329232eSGordon Ross smb_ctx_setdomain(ctx, argv[2], B_TRUE);
2458329232eSGordon Ross if (argc > 3)
246*8509e9caSToomas Soome smb_ctx_setpassword(ctx, argv[3], 0);
2478329232eSGordon Ross
2488329232eSGordon Ross /*
2498329232eSGordon Ross * Resolve the server address, setup derived defaults.
2508329232eSGordon Ross */
2518329232eSGordon Ross error = smb_ctx_resolve(ctx);
2528329232eSGordon Ross if (error) {
2538329232eSGordon Ross fprintf(stderr, "logon: smb_ctx_resolve, error %d\n", error);
2548329232eSGordon Ross return;
2558329232eSGordon Ross }
2568329232eSGordon Ross
2578329232eSGordon Ross /*
2588329232eSGordon Ross * Have server, share, etc. now.
2598329232eSGordon Ross * Get the logon session.
2608329232eSGordon Ross */
2618329232eSGordon Ross again:
2628329232eSGordon Ross error = smb_ctx_get_ssn(ctx);
2638329232eSGordon Ross if (error == EAUTH) {
2648329232eSGordon Ross int err2;
2658329232eSGordon Ross err2 = smb_get_authentication(ctx);
2668329232eSGordon Ross if (err2 == 0)
2678329232eSGordon Ross goto again;
2688329232eSGordon Ross }
2698329232eSGordon Ross if (error) {
2708329232eSGordon Ross fprintf(stderr, "//%s: login failed, error %d\n",
2718329232eSGordon Ross ctx->ct_fullserver, error);
2728329232eSGordon Ross }
2738329232eSGordon Ross }
2748329232eSGordon Ross
2758329232eSGordon Ross /*
2768329232eSGordon Ross * Drop session created by the "logon" command.
2778329232eSGordon Ross */
2788329232eSGordon Ross static void
do_logoff(int argc,char ** argv)2798329232eSGordon Ross do_logoff(int argc, char **argv)
2808329232eSGordon Ross {
2818329232eSGordon Ross
2828329232eSGordon Ross (void) nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_SSN_RELE, NULL);
2838329232eSGordon Ross if (argc > 1) {
2848329232eSGordon Ross smb_ctx_done(ctx);
2858329232eSGordon Ross (void) smb_ctx_init(ctx);
2868329232eSGordon Ross }
2878329232eSGordon Ross }
2888329232eSGordon Ross
2898329232eSGordon Ross /*
2908329232eSGordon Ross * List shares
2918329232eSGordon Ross */
2928329232eSGordon Ross static void
do_shares(int argc,char ** argv)2938329232eSGordon Ross do_shares(int argc, char **argv)
2948329232eSGordon Ross {
2958329232eSGordon Ross int error;
2968329232eSGordon Ross
2978329232eSGordon Ross smb_ctx_setshare(ctx, "IPC$", USE_IPC);
2988329232eSGordon Ross error = smb_ctx_get_tree(ctx);
2998329232eSGordon Ross if (error) {
3008329232eSGordon Ross fprintf(stderr, "shares, tcon IPC$, error=%d\n", error);
3018329232eSGordon Ross return;
3028329232eSGordon Ross }
3038329232eSGordon Ross
3048329232eSGordon Ross error = list_shares(ctx);
3058329232eSGordon Ross if (error) {
3068329232eSGordon Ross fprintf(stderr, "shares, enum, error=%d\n", error);
3078329232eSGordon Ross }
3088329232eSGordon Ross
3098329232eSGordon Ross (void) nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_TREE_RELE, NULL);
3108329232eSGordon Ross }
3118329232eSGordon Ross
3128329232eSGordon Ross char mnt_opt_buf[MAX_MNTOPT_STR];
3138329232eSGordon Ross char mnt_resource[MAXPATHLEN];
3148329232eSGordon Ross
3158329232eSGordon Ross /*
3168329232eSGordon Ross * Minimal excerpt from vfs.c:domount()
3178329232eSGordon Ross */
3188329232eSGordon Ross void
do_mount(int argc,char ** argv)3198329232eSGordon Ross do_mount(int argc, char **argv)
3208329232eSGordon Ross {
3218329232eSGordon Ross struct smbfs_args mdata;
3228329232eSGordon Ross struct mounta ma;
3238329232eSGordon Ross char *shrname;
3248329232eSGordon Ross int error;
3258329232eSGordon Ross
3268329232eSGordon Ross if (vfsp != NULL) {
3278329232eSGordon Ross fprintf(stderr, "Already mounted\n");
3288329232eSGordon Ross return;
3298329232eSGordon Ross }
3308329232eSGordon Ross
3318329232eSGordon Ross if (argc < 2) {
3328329232eSGordon Ross fprintf(stderr, "%s: missing share name\n", argv[0]);
3338329232eSGordon Ross return;
3348329232eSGordon Ross }
3358329232eSGordon Ross shrname = argv[1];
3368329232eSGordon Ross if (argc > 2)
3378329232eSGordon Ross strlcpy(mnt_opt_buf, argv[2], sizeof (mnt_opt_buf));
3388329232eSGordon Ross else
3398329232eSGordon Ross memset(mnt_opt_buf, 0, sizeof (mnt_opt_buf));
3408329232eSGordon Ross
3418329232eSGordon Ross smb_ctx_setshare(ctx, shrname, USE_DISKDEV);
3428329232eSGordon Ross error = smb_ctx_get_tree(ctx);
3438329232eSGordon Ross if (error) {
3448329232eSGordon Ross fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
3458329232eSGordon Ross server, shrname, error);
3468329232eSGordon Ross return;
3478329232eSGordon Ross }
3488329232eSGordon Ross
3498329232eSGordon Ross (void) snprintf(mnt_resource, sizeof (mnt_resource),
3508329232eSGordon Ross "//%s/%s", ctx->ct_fullserver, shrname);
3518329232eSGordon Ross
3528329232eSGordon Ross bzero(&mdata, sizeof (mdata));
3538329232eSGordon Ross mdata.version = SMBFS_VERSION; /* smbfs mount version */
3548329232eSGordon Ross mdata.file_mode = S_IRWXU;
3558329232eSGordon Ross mdata.dir_mode = S_IRWXU;
3568329232eSGordon Ross mdata.devfd = ctx->ct_dev_fd;
3578329232eSGordon Ross
3588329232eSGordon Ross /* Build mount args */
3598329232eSGordon Ross bzero(&ma, sizeof (ma));
3608329232eSGordon Ross ma.spec = mnt_resource;
3618329232eSGordon Ross ma.dir = "/";
3628329232eSGordon Ross ma.flags = MS_DATA | MS_OPTIONSTR | MS_NOSPLICE | MS_NOSUID;
3638329232eSGordon Ross ma.fstype = "smbfs";
3648329232eSGordon Ross ma.dataptr = (void *) &mdata;
3658329232eSGordon Ross ma.datalen = sizeof (mdata);
3668329232eSGordon Ross ma.optptr = mnt_opt_buf;
3678329232eSGordon Ross ma.optlen = sizeof (mnt_opt_buf);
3688329232eSGordon Ross
3698329232eSGordon Ross error = fake_domount("smbfs", &ma, &vfsp);
3708329232eSGordon Ross if (error != 0) {
3718329232eSGordon Ross fprintf(stderr, "domount error=%d\n", error);
3728329232eSGordon Ross }
3738329232eSGordon Ross
3748329232eSGordon Ross /* Mount takes a ref, so always rele here. */
3758329232eSGordon Ross (void) nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_TREE_RELE, NULL);
3768329232eSGordon Ross }
3778329232eSGordon Ross
3788329232eSGordon Ross void
do_unmount(int argc,char ** argv)3798329232eSGordon Ross do_unmount(int argc, char **argv)
3808329232eSGordon Ross {
3818329232eSGordon Ross int error;
3828329232eSGordon Ross
3838329232eSGordon Ross if (vfsp == NULL) {
3848329232eSGordon Ross fprintf(stderr, "Not mounted\n");
3858329232eSGordon Ross return;
3868329232eSGordon Ross }
3878329232eSGordon Ross
3888329232eSGordon Ross error = fake_dounmount(vfsp, 0);
3898329232eSGordon Ross if (error != 0) {
3908329232eSGordon Ross fprintf(stderr, "dounmount error=%d\n", error);
3918329232eSGordon Ross return;
3928329232eSGordon Ross }
3938329232eSGordon Ross vfsp = NULL;
3948329232eSGordon Ross }
3958329232eSGordon Ross
3968329232eSGordon Ross void
do_statfs(int argc,char ** argv)3978329232eSGordon Ross do_statfs(int argc, char **argv)
3988329232eSGordon Ross {
3998329232eSGordon Ross statvfs64_t st;
4008329232eSGordon Ross int error;
4018329232eSGordon Ross
4028329232eSGordon Ross if (vfsp == NULL) {
4038329232eSGordon Ross fprintf(stderr, "Not mounted\n");
4048329232eSGordon Ross return;
4058329232eSGordon Ross }
4068329232eSGordon Ross
4078329232eSGordon Ross error = fsop_statfs(vfsp, &st);
4088329232eSGordon Ross if (error != 0) {
4098329232eSGordon Ross fprintf(stderr, "df error=%d\n", error);
4108329232eSGordon Ross return;
4118329232eSGordon Ross }
4128329232eSGordon Ross printf("bsize=%ld\n", st.f_bsize);
4138329232eSGordon Ross printf("frsize=%ld\n", st.f_frsize);
4148329232eSGordon Ross printf("blocks=%" PRIu64 "\n", st.f_blocks);
4158329232eSGordon Ross printf(" bfree=%" PRIu64 "\n", st.f_bfree);
4168329232eSGordon Ross printf("bavail=%" PRIu64 "\n", st.f_bavail);
4178329232eSGordon Ross }
4188329232eSGordon Ross
4198329232eSGordon Ross void
do_dir(int argc,char ** argv)4208329232eSGordon Ross do_dir(int argc, char **argv)
4218329232eSGordon Ross {
4228329232eSGordon Ross char *rdir;
4238329232eSGordon Ross vnode_t *vp = NULL;
4248329232eSGordon Ross offset_t off;
4258329232eSGordon Ross int cnt;
4268329232eSGordon Ross int error;
4278329232eSGordon Ross
4288329232eSGordon Ross if (vfsp == NULL) {
4298329232eSGordon Ross fprintf(stderr, "mnt required first\n");
4308329232eSGordon Ross return;
4318329232eSGordon Ross }
4328329232eSGordon Ross if (argc > 1)
4338329232eSGordon Ross rdir = argv[1];
4348329232eSGordon Ross else
4358329232eSGordon Ross rdir = "";
4368329232eSGordon Ross
4378329232eSGordon Ross error = vn_open(rdir, 0, FREAD, 0, &vp, 0, 0);
4388329232eSGordon Ross if (error != 0) {
4398329232eSGordon Ross fprintf(stderr, "do_dir, vn_open error=%d\n", error);
4408329232eSGordon Ross return;
4418329232eSGordon Ross }
4428329232eSGordon Ross
4438329232eSGordon Ross off = 0;
4448329232eSGordon Ross do {
4458329232eSGordon Ross cnt = fake_getdents(vp, &off, tbuf, TBUFSZ);
4468329232eSGordon Ross if (cnt < 0) {
4478329232eSGordon Ross fprintf(stderr, "do_dir, getdents %d\n", -cnt);
4488329232eSGordon Ross break;
4498329232eSGordon Ross }
4508329232eSGordon Ross show_dents(vp, &off, tbuf, cnt);
4518329232eSGordon Ross } while (cnt > 0);
4528329232eSGordon Ross
4538329232eSGordon Ross if (vp != NULL)
4548329232eSGordon Ross vn_close_rele(vp, 0);
4558329232eSGordon Ross }
4568329232eSGordon Ross
4578329232eSGordon Ross void
do_dirx(int argc,char ** argv)4588329232eSGordon Ross do_dirx(int argc, char **argv)
4598329232eSGordon Ross {
4608329232eSGordon Ross char *rdir;
4618329232eSGordon Ross vnode_t *vp = NULL;
4628329232eSGordon Ross offset_t off;
4638329232eSGordon Ross int cnt;
4648329232eSGordon Ross int error;
4658329232eSGordon Ross
4668329232eSGordon Ross if (vfsp == NULL) {
4678329232eSGordon Ross fprintf(stderr, "mnt required first\n");
4688329232eSGordon Ross return;
4698329232eSGordon Ross }
4708329232eSGordon Ross if (argc > 1)
4718329232eSGordon Ross rdir = argv[1];
4728329232eSGordon Ross else
4738329232eSGordon Ross rdir = "";
4748329232eSGordon Ross
4758329232eSGordon Ross error = vn_open(rdir, 0, FREAD|FXATTRDIROPEN, 0, &vp, 0, 0);
4768329232eSGordon Ross if (error != 0) {
4778329232eSGordon Ross fprintf(stderr, "do_dirx, vn_open error=%d\n", error);
4788329232eSGordon Ross return;
4798329232eSGordon Ross }
4808329232eSGordon Ross
4818329232eSGordon Ross off = 0;
4828329232eSGordon Ross do {
4838329232eSGordon Ross cnt = fake_getdents(vp, &off, tbuf, TBUFSZ);
4848329232eSGordon Ross if (cnt < 0) {
4858329232eSGordon Ross fprintf(stderr, "do_dirx, getdents %d\n", -cnt);
4868329232eSGordon Ross break;
4878329232eSGordon Ross }
4888329232eSGordon Ross show_dents(vp, &off, tbuf, cnt);
4898329232eSGordon Ross } while (cnt > 0);
4908329232eSGordon Ross
4918329232eSGordon Ross if (vp != NULL)
4928329232eSGordon Ross vn_close_rele(vp, 0);
4938329232eSGordon Ross }
4948329232eSGordon Ross
4958329232eSGordon Ross static void
show_dents(vnode_t * dvp,offset_t * offp,char * buf,int cnt)4968329232eSGordon Ross show_dents(vnode_t *dvp, offset_t *offp, char *buf, int cnt)
4978329232eSGordon Ross {
4988329232eSGordon Ross char time_buf[40];
4998329232eSGordon Ross struct stat64 st;
5008329232eSGordon Ross vnode_t *vp;
5018329232eSGordon Ross char *p;
5028329232eSGordon Ross dirent_t *d;
5038329232eSGordon Ross offset_t offset = (offset_t)-1L;
5048329232eSGordon Ross int error;
5058329232eSGordon Ross uint_t mode;
5068329232eSGordon Ross char type;
5078329232eSGordon Ross
5088329232eSGordon Ross p = buf;
5098329232eSGordon Ross while (p < (buf + cnt)) {
5108329232eSGordon Ross d = (dirent_t *)(void *)p;
5118329232eSGordon Ross p += d->d_reclen;
5128329232eSGordon Ross offset = d->d_off;
5138329232eSGordon Ross
5148329232eSGordon Ross error = fake_lookup(dvp, d->d_name, &vp);
5158329232eSGordon Ross if (error != 0) {
5168329232eSGordon Ross fprintf(stderr, "%s: lookup error=%d\n",
5178329232eSGordon Ross d->d_name, error);
5188329232eSGordon Ross continue;
5198329232eSGordon Ross }
5208329232eSGordon Ross error = fake_stat(vp, &st, 0);
5218329232eSGordon Ross vn_rele(vp);
5228329232eSGordon Ross if (error != 0) {
5238329232eSGordon Ross fprintf(stderr, "%s: stat error=%d\n",
5248329232eSGordon Ross d->d_name, error);
5258329232eSGordon Ross continue;
5268329232eSGordon Ross }
5278329232eSGordon Ross
5288329232eSGordon Ross /*
5298329232eSGordon Ross * Print type, mode, size, name
5308329232eSGordon Ross * First mode (only dir, file expected here)
5318329232eSGordon Ross */
5328329232eSGordon Ross if (S_ISDIR(st.st_mode)) {
5338329232eSGordon Ross type = 'd';
5348329232eSGordon Ross } else if (S_ISREG(st.st_mode)) {
5358329232eSGordon Ross type = ' ';
5368329232eSGordon Ross } else {
5378329232eSGordon Ross type = '?';
5388329232eSGordon Ross }
5398329232eSGordon Ross mode = st.st_mode & 0777;
5408329232eSGordon Ross (void) strftime(time_buf, sizeof (time_buf),
5418329232eSGordon Ross "%b %e %T %Y", localtime(&st.st_mtime));
5428329232eSGordon Ross
5438329232eSGordon Ross printf("%c 0%3o %9" PRIu64 " %s %s\n",
5448329232eSGordon Ross type, mode,
5458329232eSGordon Ross (uint64_t)st.st_size,
5468329232eSGordon Ross time_buf,
5478329232eSGordon Ross d->d_name);
5488329232eSGordon Ross }
5498329232eSGordon Ross *offp = offset;
5508329232eSGordon Ross }
5518329232eSGordon Ross
5528329232eSGordon Ross /*
5538329232eSGordon Ross * get rname [lname]
5548329232eSGordon Ross */
5558329232eSGordon Ross void
do_get(int argc,char ** argv)5568329232eSGordon Ross do_get(int argc, char **argv)
5578329232eSGordon Ross {
5588329232eSGordon Ross struct stat64 st;
5598329232eSGordon Ross char *rname;
5608329232eSGordon Ross char *lname;
5618329232eSGordon Ross vnode_t *vp = NULL;
5628329232eSGordon Ross offset_t off;
5638329232eSGordon Ross ssize_t cnt, x;
5648329232eSGordon Ross int oflg = O_RDWR | O_CREAT;
5658329232eSGordon Ross int lfd = -1;
5668329232eSGordon Ross int error;
5678329232eSGordon Ross
5688329232eSGordon Ross if (vfsp == NULL) {
5698329232eSGordon Ross fprintf(stderr, "mnt required first\n");
5708329232eSGordon Ross return;
5718329232eSGordon Ross }
5728329232eSGordon Ross if (argc < 2) {
5738329232eSGordon Ross fprintf(stderr, "rname required\n");
5748329232eSGordon Ross return;
5758329232eSGordon Ross }
5768329232eSGordon Ross rname = argv[1];
5778329232eSGordon Ross if (argc > 2) {
5788329232eSGordon Ross lname = argv[2];
5798329232eSGordon Ross /*
5808329232eSGordon Ross * When local name is specified, overwrite.
5818329232eSGordon Ross * Convenient for scripts etc.
5828329232eSGordon Ross */
5838329232eSGordon Ross oflg |= O_TRUNC;
5848329232eSGordon Ross } else {
5858329232eSGordon Ross lname = rname;
5868329232eSGordon Ross /* Local file should not exist. */
5878329232eSGordon Ross oflg |= O_EXCL;
5888329232eSGordon Ross }
5898329232eSGordon Ross
5908329232eSGordon Ross lfd = open(lname, oflg, 0644);
5918329232eSGordon Ross if (lfd < 0) {
5928329232eSGordon Ross perror(lname);
5938329232eSGordon Ross return;
5948329232eSGordon Ross }
5958329232eSGordon Ross
5968329232eSGordon Ross error = vn_open(rname, 0, FREAD, 0, &vp, 0, 0);
5978329232eSGordon Ross if (error != 0) {
5988329232eSGordon Ross fprintf(stderr, "do_get, vn_open error=%d\n", error);
5998329232eSGordon Ross goto out;
6008329232eSGordon Ross }
6018329232eSGordon Ross error = fake_stat(vp, &st, 0);
6028329232eSGordon Ross if (error != 0) {
6038329232eSGordon Ross fprintf(stderr, "do_get, stat error=%d\n", error);
6048329232eSGordon Ross goto out;
6058329232eSGordon Ross }
6068329232eSGordon Ross
6078329232eSGordon Ross off = 0;
6088329232eSGordon Ross do {
6098329232eSGordon Ross cnt = fake_pread(vp, tbuf, TBUFSZ, off);
6108329232eSGordon Ross if (cnt < 0) {
6118329232eSGordon Ross fprintf(stderr, "do_get, read %d\n", -cnt);
6128329232eSGordon Ross goto out;
6138329232eSGordon Ross }
6148329232eSGordon Ross x = write(lfd, tbuf, cnt);
6158329232eSGordon Ross if (x < 0) {
6168329232eSGordon Ross fprintf(stderr, "do_get, write %d\n", errno);
6178329232eSGordon Ross goto out;
6188329232eSGordon Ross }
6198329232eSGordon Ross off += x;
6208329232eSGordon Ross } while (off < st.st_size);
6218329232eSGordon Ross
6228329232eSGordon Ross out:
6238329232eSGordon Ross if (vp != NULL)
6248329232eSGordon Ross vn_close_rele(vp, 0);
6258329232eSGordon Ross if (lfd != -1)
6268329232eSGordon Ross close(lfd);
6278329232eSGordon Ross }
6288329232eSGordon Ross
6298329232eSGordon Ross /*
6308329232eSGordon Ross * put lname [rname]
6318329232eSGordon Ross */
6328329232eSGordon Ross void
do_put(int argc,char ** argv)6338329232eSGordon Ross do_put(int argc, char **argv)
6348329232eSGordon Ross {
6358329232eSGordon Ross struct stat64 rst;
6368329232eSGordon Ross struct stat st;
6378329232eSGordon Ross char *rname;
6388329232eSGordon Ross char *lname;
6398329232eSGordon Ross vnode_t *vp = NULL;
6408329232eSGordon Ross offset_t off;
6418329232eSGordon Ross ssize_t cnt, x;
6428329232eSGordon Ross int oflg = FREAD|FWRITE|FCREAT;
6438329232eSGordon Ross int lfd = -1;
6448329232eSGordon Ross int error;
6458329232eSGordon Ross
6468329232eSGordon Ross if (vfsp == NULL) {
6478329232eSGordon Ross fprintf(stderr, "mnt required first\n");
6488329232eSGordon Ross return;
6498329232eSGordon Ross }
6508329232eSGordon Ross if (argc < 2) {
6518329232eSGordon Ross fprintf(stderr, "lname required\n");
6528329232eSGordon Ross return;
6538329232eSGordon Ross }
6548329232eSGordon Ross lname = argv[1];
6558329232eSGordon Ross if (argc > 2) {
6568329232eSGordon Ross rname = argv[2];
6578329232eSGordon Ross /*
6588329232eSGordon Ross * When remote name is specified, overwrite.
6598329232eSGordon Ross * Convenient for scripts etc.
6608329232eSGordon Ross */
6618329232eSGordon Ross oflg |= FTRUNC;
6628329232eSGordon Ross } else {
6638329232eSGordon Ross rname = lname;
6648329232eSGordon Ross /* Remote file should not exist. */
6658329232eSGordon Ross oflg |= FEXCL;
6668329232eSGordon Ross }
6678329232eSGordon Ross
6688329232eSGordon Ross lfd = open(lname, O_RDONLY, 0);
6698329232eSGordon Ross if (lfd < 0) {
6708329232eSGordon Ross perror(lname);
6718329232eSGordon Ross return;
6728329232eSGordon Ross }
6738329232eSGordon Ross error = fstat(lfd, &st);
6748329232eSGordon Ross if (error != 0) {
6758329232eSGordon Ross fprintf(stderr, "do_put, stat error=%d\n", error);
6768329232eSGordon Ross goto out;
6778329232eSGordon Ross }
6788329232eSGordon Ross
6798329232eSGordon Ross error = vn_open(rname, 0, oflg, 0, &vp, 0, 0);
6808329232eSGordon Ross if (error != 0) {
6818329232eSGordon Ross fprintf(stderr, "do_put, vn_open error=%d\n", error);
6828329232eSGordon Ross goto out;
6838329232eSGordon Ross }
6848329232eSGordon Ross
6858329232eSGordon Ross off = 0;
6868329232eSGordon Ross do {
6878329232eSGordon Ross cnt = pread(lfd, tbuf, TBUFSZ, off);
6888329232eSGordon Ross if (cnt < 0) {
6898329232eSGordon Ross fprintf(stderr, "do_put, read %d\n", errno);
6908329232eSGordon Ross goto out;
6918329232eSGordon Ross }
6928329232eSGordon Ross x = fake_pwrite(vp, tbuf, cnt, off);
6938329232eSGordon Ross if (x < 0) {
6948329232eSGordon Ross fprintf(stderr, "do_put, write %d\n", -x);
6958329232eSGordon Ross goto out;
6968329232eSGordon Ross }
6978329232eSGordon Ross off += cnt;
6988329232eSGordon Ross } while (off < st.st_size);
6998329232eSGordon Ross
7008329232eSGordon Ross /* This getattr should go OtW. */
7018329232eSGordon Ross error = fake_stat(vp, &rst, 0);
7028329232eSGordon Ross if (error != 0) {
7038329232eSGordon Ross fprintf(stderr, "do_put, stat error=%d\n", error);
7048329232eSGordon Ross goto out;
7058329232eSGordon Ross }
7068329232eSGordon Ross if (rst.st_size != st.st_size) {
7078329232eSGordon Ross fprintf(stderr, "do_put, wrong size?\n");
7088329232eSGordon Ross }
7098329232eSGordon Ross
7108329232eSGordon Ross out:
7118329232eSGordon Ross if (vp != NULL)
7128329232eSGordon Ross vn_close_rele(vp, 0);
7138329232eSGordon Ross if (lfd != -1)
7148329232eSGordon Ross close(lfd);
7158329232eSGordon Ross }
7168329232eSGordon Ross
7178329232eSGordon Ross /*
7188329232eSGordon Ross * rm rname
7198329232eSGordon Ross */
7208329232eSGordon Ross void
do_rm(int argc,char ** argv)7218329232eSGordon Ross do_rm(int argc, char **argv)
7228329232eSGordon Ross {
7238329232eSGordon Ross char *rname;
7248329232eSGordon Ross int error;
7258329232eSGordon Ross
7268329232eSGordon Ross if (vfsp == NULL) {
7278329232eSGordon Ross fprintf(stderr, "mnt required first\n");
7288329232eSGordon Ross return;
7298329232eSGordon Ross }
7308329232eSGordon Ross if (argc < 2) {
7318329232eSGordon Ross fprintf(stderr, "rname required\n");
7328329232eSGordon Ross return;
7338329232eSGordon Ross }
7348329232eSGordon Ross rname = argv[1];
7358329232eSGordon Ross
7368329232eSGordon Ross error = fake_unlink(rname, 0);
7378329232eSGordon Ross if (error != 0) {
7388329232eSGordon Ross fprintf(stderr, "do_rm, unlink error=%d\n", error);
7398329232eSGordon Ross }
7408329232eSGordon Ross }
7418329232eSGordon Ross
7428329232eSGordon Ross /*
7438329232eSGordon Ross * mv fromname toname
7448329232eSGordon Ross */
7458329232eSGordon Ross void
do_mv(int argc,char ** argv)7468329232eSGordon Ross do_mv(int argc, char **argv)
7478329232eSGordon Ross {
7488329232eSGordon Ross int error;
7498329232eSGordon Ross
7508329232eSGordon Ross if (vfsp == NULL) {
7518329232eSGordon Ross fprintf(stderr, "mnt required first\n");
7528329232eSGordon Ross return;
7538329232eSGordon Ross }
7548329232eSGordon Ross if (argc < 3) {
7558329232eSGordon Ross fprintf(stderr, "from_name to_name required\n");
7568329232eSGordon Ross return;
7578329232eSGordon Ross }
7588329232eSGordon Ross
7598329232eSGordon Ross error = fake_rename(argv[1], argv[2]);
7608329232eSGordon Ross if (error != 0) {
7618329232eSGordon Ross fprintf(stderr, "do_mv, rename error=%d\n", error);
7628329232eSGordon Ross }
7638329232eSGordon Ross }
7648329232eSGordon Ross
7658329232eSGordon Ross /*
7668329232eSGordon Ross * mkdir rname
7678329232eSGordon Ross */
7688329232eSGordon Ross void
do_mkdir(int argc,char ** argv)7698329232eSGordon Ross do_mkdir(int argc, char **argv)
7708329232eSGordon Ross {
7718329232eSGordon Ross char *rname;
7728329232eSGordon Ross vnode_t *vp = NULL;
7738329232eSGordon Ross int error;
7748329232eSGordon Ross
7758329232eSGordon Ross if (vfsp == NULL) {
7768329232eSGordon Ross fprintf(stderr, "mnt required first\n");
7778329232eSGordon Ross return;
7788329232eSGordon Ross }
7798329232eSGordon Ross if (argc < 2) {
7808329232eSGordon Ross fprintf(stderr, "rname required\n");
7818329232eSGordon Ross return;
7828329232eSGordon Ross }
7838329232eSGordon Ross rname = argv[1];
7848329232eSGordon Ross
7858329232eSGordon Ross error = vn_open(rname, 0, FCREAT, 0, &vp, CRMKDIR, 0);
7868329232eSGordon Ross if (error != 0) {
7878329232eSGordon Ross fprintf(stderr, "do_mkdir, vn_open error=%d\n", error);
7888329232eSGordon Ross }
7898329232eSGordon Ross
7908329232eSGordon Ross if (vp != NULL)
7918329232eSGordon Ross vn_close_rele(vp, 0);
7928329232eSGordon Ross }
7938329232eSGordon Ross
7948329232eSGordon Ross /*
7958329232eSGordon Ross * rmdir rname
7968329232eSGordon Ross */
7978329232eSGordon Ross void
do_rmdir(int argc,char ** argv)7988329232eSGordon Ross do_rmdir(int argc, char **argv)
7998329232eSGordon Ross {
8008329232eSGordon Ross char *rname;
8018329232eSGordon Ross int error;
8028329232eSGordon Ross
8038329232eSGordon Ross if (vfsp == NULL) {
8048329232eSGordon Ross fprintf(stderr, "mnt required first\n");
8058329232eSGordon Ross return;
8068329232eSGordon Ross }
8078329232eSGordon Ross if (argc < 2) {
8088329232eSGordon Ross fprintf(stderr, "rname required\n");
8098329232eSGordon Ross return;
8108329232eSGordon Ross }
8118329232eSGordon Ross rname = argv[1];
8128329232eSGordon Ross
8138329232eSGordon Ross error = fake_unlink(rname, AT_REMOVEDIR);
8148329232eSGordon Ross if (error != 0) {
8158329232eSGordon Ross fprintf(stderr, "do_rmdir, unlink error=%d\n", error);
8168329232eSGordon Ross }
8178329232eSGordon Ross }
8188329232eSGordon Ross
8198329232eSGordon Ross /*
8208329232eSGordon Ross * Simple option setting
8218329232eSGordon Ross *
8228329232eSGordon Ross * Each arg is handled as one line in .nsmbrc [default]
8238329232eSGordon Ross */
8248329232eSGordon Ross void
do_opt(int argc,char ** argv)8258329232eSGordon Ross do_opt(int argc, char **argv)
8268329232eSGordon Ross {
8278329232eSGordon Ross static char template[20] = "/tmp/fksmbclXXXXXX";
8288329232eSGordon Ross static char rcname[30];
8298329232eSGordon Ross char *tdname;
8308329232eSGordon Ross char *save_home;
8318329232eSGordon Ross FILE *fp;
8328329232eSGordon Ross int err, i;
8338329232eSGordon Ross
8348329232eSGordon Ross if (argc < 2) {
8358329232eSGordon Ross fprintf(stderr, "opt {key}[=value]\n");
8368329232eSGordon Ross return;
8378329232eSGordon Ross }
8388329232eSGordon Ross
8398329232eSGordon Ross tdname = mkdtemp(template);
8408329232eSGordon Ross if (tdname == NULL) {
8418329232eSGordon Ross perror("mkdtemp");
8428329232eSGordon Ross return;
8438329232eSGordon Ross }
8448329232eSGordon Ross (void) snprintf(rcname, sizeof (rcname),
8458329232eSGordon Ross "%s/.nsmbrc", tdname);
8468329232eSGordon Ross
8478329232eSGordon Ross fp = fopen(rcname, "w");
8488329232eSGordon Ross if (fp == NULL) {
8498329232eSGordon Ross perror(rcname);
8508329232eSGordon Ross goto out;
8518329232eSGordon Ross }
8528329232eSGordon Ross fprintf(fp, "[default]\n");
8538329232eSGordon Ross for (i = 1; i < argc; i++)
8548329232eSGordon Ross fprintf(fp, "%s\n", argv[i]);
8558329232eSGordon Ross fclose(fp);
8568329232eSGordon Ross
8578329232eSGordon Ross save_home = ctx->ct_home;
8588329232eSGordon Ross ctx->ct_home = tdname;
8598329232eSGordon Ross err = smb_ctx_readrc(ctx);
8608329232eSGordon Ross ctx->ct_home = save_home;
8618329232eSGordon Ross
8628329232eSGordon Ross if (err != 0)
8638329232eSGordon Ross fprintf(stderr, "readrc, err=%d\n", err);
8648329232eSGordon Ross
8658329232eSGordon Ross out:
8668329232eSGordon Ross (void) unlink(rcname);
8678329232eSGordon Ross (void) rmdir(tdname);
8688329232eSGordon Ross }
8698329232eSGordon Ross
8708329232eSGordon Ross /*
8718329232eSGordon Ross * Command table
8728329232eSGordon Ross */
8738329232eSGordon Ross static struct cmd_tbl_ent
8748329232eSGordon Ross cmd_tbl[] = {
8758329232eSGordon Ross { do_help, "help", "" },
8768329232eSGordon Ross { do_exit, "exit", "" },
8778329232eSGordon Ross { do_logon, "logon", "[user [dom [pass]]]" },
8788329232eSGordon Ross { do_logoff, "logoff", "[close-driver]" },
8798329232eSGordon Ross { do_shares, "shares", "" },
8808329232eSGordon Ross { do_mount, "mount", "{share} [optstr]" },
8818329232eSGordon Ross { do_unmount, "umount", "" },
8828329232eSGordon Ross { do_unmount, "unmount", "" },
8838329232eSGordon Ross { do_statfs, "statfs", "" },
8848329232eSGordon Ross { do_dir, "dir", "{rdir} [lfile]" },
8858329232eSGordon Ross { do_dirx, "dirx", "{rdir} [lfile]" },
8868329232eSGordon Ross { do_get, "get", "{rfile} [lfile]" },
8878329232eSGordon Ross { do_put, "put", "{lfile} [rfile]" },
8888329232eSGordon Ross { do_mv, "mv", "{from} {to}" },
8898329232eSGordon Ross { do_rm, "rm", "{rfile}" },
8908329232eSGordon Ross { do_mkdir, "mkdir", "{rfile}" },
8918329232eSGordon Ross { do_rmdir, "rmdir", "{rfile}" },
8928329232eSGordon Ross { do_opt, "opt", "{option}" },
8938329232eSGordon Ross { NULL, NULL, NULL }
8948329232eSGordon Ross };
8958329232eSGordon Ross
8968329232eSGordon Ross /*
8978329232eSGordon Ross * Provide a real function (one that prints something) to replace
8988329232eSGordon Ross * the stub in libfakekernel. This prints cmn_err() messages.
8998329232eSGordon Ross */
9008329232eSGordon Ross void
fakekernel_putlog(char * msg,size_t len,int flags)9018329232eSGordon Ross fakekernel_putlog(char *msg, size_t len, int flags)
9028329232eSGordon Ross {
9038329232eSGordon Ross
9048329232eSGordon Ross /*
9058329232eSGordon Ross * [CE_CONT, CE_NOTE, CE_WARN, CE_PANIC] maps to
9068329232eSGordon Ross * [SL_NOTE, SL_NOTE, SL_WARN, SL_FATAL]
9078329232eSGordon Ross */
9088329232eSGordon Ross if (smb_debug == 0 && (flags & SL_NOTE))
9098329232eSGordon Ross return;
9108329232eSGordon Ross (void) fwrite(msg, 1, len, stdout);
9118329232eSGordon Ross (void) fflush(stdout);
9128329232eSGordon Ross }
9138329232eSGordon Ross
914adee6784SGordon Ross /*
915adee6784SGordon Ross * Print nsmb debug messages via driver smb_debugmsg()
916adee6784SGordon Ross */
917adee6784SGordon Ross void
smb_debugmsg(const char * func,char * msg)918adee6784SGordon Ross smb_debugmsg(const char *func, char *msg)
919adee6784SGordon Ross {
920adee6784SGordon Ross if (smb_debug < 2)
921adee6784SGordon Ross return;
922adee6784SGordon Ross printf("[kmod] %s: %s\n", func, msg);
923adee6784SGordon Ross }
924adee6784SGordon Ross
9258329232eSGordon Ross /*
9268329232eSGordon Ross * Enable libumem debugging
9278329232eSGordon Ross */
9288329232eSGordon Ross const char *
_umem_debug_init(void)9298329232eSGordon Ross _umem_debug_init(void)
9308329232eSGordon Ross {
9318329232eSGordon Ross return ("default,verbose"); /* $UMEM_DEBUG setting */
9328329232eSGordon Ross }
9338329232eSGordon Ross
9348329232eSGordon Ross const char *
_umem_logging_init(void)9358329232eSGordon Ross _umem_logging_init(void)
9368329232eSGordon Ross {
9378329232eSGordon Ross return ("fail,contents"); /* $UMEM_LOGGING setting */
9388329232eSGordon Ross }
939