/* DF-0907 step-1 diagnostic: does SMBIOC_LOOKUP alone crash? */
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <vfs/smbfs/smbfs.h>
#include <netproto/smb/smb.h>
#include <netproto/smb/smb_dev.h>
#include <netproto/smb/smb_conn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    int fd, rv;
    struct sockaddr_in sin;
    struct smbioc_lookup iol;
    int ulen = (argc > 1) ? atoi(argv[1]) : 80;
    char user[140];

    if (ulen < 1) ulen = 1;
    if (ulen > 127) ulen = 127;
    memset(user, 'A', ulen);
    user[ulen] = '\0';

    mkdir("/mnt/df0907", 0755);
    fd = open("/dev/nsmb", O_RDWR);
    if (fd < 0) { perror("open nsmb"); return 1; }
    fprintf(stderr, "[1] opened /dev/nsmb fd=%d, username len=%d\n", fd, ulen);

    memset(&sin, 0, sizeof(sin));
    sin.sin_len = sizeof(sin);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(139);
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");

    memset(&iol, 0, sizeof(iol));
    iol.ioc_level = SMBL_SHARE;
    iol.ioc_flags = SMBLK_CREATE;
    iol.ioc_ssn.ioc_opt = SMBVOPT_PRIVATE;
    iol.ioc_ssn.ioc_server = (struct sockaddr *)&sin;
    iol.ioc_ssn.ioc_svlen = sizeof(sin);
    iol.ioc_ssn.ioc_local = (struct sockaddr *)&sin;
    iol.ioc_ssn.ioc_lolen = sizeof(sin);
    iol.ioc_ssn.ioc_timeout = 3;
    iol.ioc_ssn.ioc_retrycount = 1;
    strlcpy(iol.ioc_ssn.ioc_srvname, "X", sizeof(iol.ioc_ssn.ioc_srvname));
    strlcpy(iol.ioc_ssn.ioc_localcs, "ASCII", sizeof(iol.ioc_ssn.ioc_localcs));
    strlcpy(iol.ioc_ssn.ioc_servercs, "ASCII", sizeof(iol.ioc_ssn.ioc_servercs));
    strlcpy(iol.ioc_ssn.ioc_user, user, sizeof(iol.ioc_ssn.ioc_user));
    iol.ioc_ssn.ioc_owner = 0;
    iol.ioc_ssn.ioc_group = 0;
    iol.ioc_ssn.ioc_mode = SMBM_EXEC;
    iol.ioc_ssn.ioc_rights = SMBM_EXEC;
    strlcpy(iol.ioc_sh.ioc_share, "SHARE", sizeof(iol.ioc_sh.ioc_share));
    iol.ioc_sh.ioc_owner = 0; iol.ioc_sh.ioc_group = 0;
    iol.ioc_sh.ioc_mode = SMBM_EXEC; iol.ioc_sh.ioc_rights = SMBM_EXEC;

    fprintf(stderr, "[2] calling SMBIOC_LOOKUP...\n"); fflush(stderr);
    rv = ioctl(fd, SMBIOC_LOOKUP, &iol);
    fprintf(stderr, "[3] SMBIOC_LOOKUP returned rv=%d errno=%d (%s)\n",
            rv, errno, strerror(errno)); fflush(stderr);
    close(fd);
    return 0;
}
