예제 #1
0
void ShowAlert(const std::string message, const std::runtime_error& error) {
    std::string alertMessage = std::string(message).append("\n\nCause: ").append(error.what());
    CFStringRef cfTitle = CFStringCreateWithCString(NULL, "Oops something is wrong...", kCFStringEncodingUTF8);
    CFStringRef cfMessage = CFStringCreateWithCString(NULL, alertMessage.c_str(), kCFStringEncodingUTF8);
    CFUserNotificationDisplayNotice(0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, cfTitle, cfMessage, NULL);
    CFRelease(cfTitle);
    CFRelease(cfMessage);
}
예제 #2
0
void NotifyEmergency( const char *pMessage )
{
    CFStringRef header = CFStringCreateWithFormat( NULL, NULL, CFSTR( "Emergency in %s" ), app_name );
    CFStringRef message = CFStringCreateWithCString( NULL, pMessage, kCFStringEncodingUTF8 );

    ( void ) CFUserNotificationDisplayNotice( 30.0, kCFUserNotificationStopAlertLevel, 
                                              NULL, NULL, NULL, header, message, NULL );
}
예제 #3
0
static void report( neko_vm *vm, value exc ) {
#if OSX
	CFStringRef title = CFSTR("Uncaught exception");
	CFStringRef message;
#endif
	int i = 0;
	buffer b = alloc_buffer(NULL);
	value st = neko_exc_stack(vm);
	if( val_array_size(st) > 20 ) {
		i = val_array_size(st) - 20;
		buffer_append(b,"...\n");
	}
	for(i;i<val_array_size(st);i++) {
		value s = val_array_ptr(st)[i];
		if( val_is_null(s) )
			buffer_append(b,"Called from a C function\n");
		else if( val_is_string(s) ) {
			buffer_append(b,"Called from ");
			buffer_append(b,val_string(s));
			buffer_append(b," (no debug available)\n");
		} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) {
			buffer_append(b,"Called from ");
			buffer_append(b,val_string(val_array_ptr(s)[0]));
			buffer_append(b," line ");
			val_buffer(b,val_array_ptr(s)[1]);
			buffer_append(b,"\n");
		} else {
			buffer_append(b,"Called from ");
			val_buffer(b,s);
			buffer_append(b,"\n");
		}
	}
	val_buffer(b,exc);
#if _WIN32
	MessageBox(NULL,val_string(buffer_to_string(b)),"Uncaught exception",MB_OK | MB_ICONERROR);
#elif OSX
	message = CFStringCreateWithCString(NULL,val_string(buffer_to_string(b)), kCFStringEncodingUTF8);
	CFUserNotificationDisplayNotice(0,0,NULL,NULL,NULL,title,message,NULL);
#elif LINUX
	fprintf(stderr,"Uncaught Exception: %s\n",val_string(buffer_to_string(b)));
#endif
}
예제 #4
0
파일: i_system.c 프로젝트: Slipyx/Mint-Doom
void I_Error (char *error, ...)
{
    va_list	argptr;

    if (already_quitting)
    {
        fprintf(stderr, "Warning: recursive call to I_Error detected.\n");
        exit(-1);
    }
    else
    {
        already_quitting = true;
    }
    
    // Message first.
    va_start(argptr, error);
    //fprintf(stderr, "\nError: ");
    vfprintf(stderr, error, argptr);
    fprintf(stderr, "\n\n");
    va_end(argptr);
    fflush(stderr);

    // Shutdown. Here might be other errors.

    if (demorecording)
    {
	G_CheckDemoStatus();
    }

    D_QuitNetGame ();
    I_ShutdownGraphics();
    S_Shutdown();
    
#ifdef _WIN32
    // On Windows, pop up a dialog box with the error message.
    {
        char msgbuf[512];
        wchar_t wmsgbuf[512];

        va_start(argptr, error);
        memset(msgbuf, 0, sizeof(msgbuf));
        vsnprintf(msgbuf, sizeof(msgbuf) - 1, error, argptr);
        va_end(argptr);

        MultiByteToWideChar(CP_ACP, 0,
                            msgbuf, strlen(msgbuf) + 1,
                            wmsgbuf, sizeof(wmsgbuf));

        MessageBoxW(NULL, wmsgbuf, L"", MB_OK);
    }
#endif

#ifdef __MACOSX__
    if (!I_ConsoleStdout())
    {
        CFStringRef message;
        char msgbuf[512];
	int i;

        va_start(argptr, error);
        memset(msgbuf, 0, sizeof(msgbuf));
        vsnprintf(msgbuf, sizeof(msgbuf) - 1, error, argptr);
        va_end(argptr);

	// The CoreFoundation message box wraps text lines, so replace
	// newline characters with spaces so that multiline messages
	// are continuous.

	for (i = 0; msgbuf[i] != '\0'; ++i)
        {
            if (msgbuf[i] == '\n')
            {
                msgbuf[i] = ' ';
            }
        }

        message = CFStringCreateWithCString(NULL, msgbuf,
                                            kCFStringEncodingUTF8);

        CFUserNotificationDisplayNotice(0,
                                        kCFUserNotificationCautionAlertLevel,
                                        NULL,
                                        NULL,
                                        NULL,
                                        CFSTR(PACKAGE_STRING),
                                        message,
                                        NULL);
    }
#endif

    // abort();

    exit(-1);
}
예제 #5
0
void I_Error (char *error, ...)
{
    va_list argptr;
    atexit_listentry_t *entry;
    boolean exit_gui_popup;

    if (already_quitting)
    {
        fprintf(stderr, "Warning: recursive call to I_Error detected.\n");
        exit(-1);
    }
    else
    {
        already_quitting = true;
    }
    
    // Message first.
    va_start(argptr, error);
    //fprintf(stderr, "\nError: ");
    vfprintf(stderr, error, argptr);
    fprintf(stderr, "\n\n");
    va_end(argptr);
    fflush(stderr);

    // Shutdown. Here might be other errors.

    entry = exit_funcs;

    while (entry != NULL)
    {
        if (entry->run_on_error)
        {
            entry->func();
        }

        entry = entry->next;
    }

    exit_gui_popup = !M_ParmExists("-nogui");

#ifdef _WIN32
    // On Windows, pop up a dialog box with the error message.

    if (exit_gui_popup)
    {
        char msgbuf[512];
        wchar_t wmsgbuf[512];

        va_start(argptr, error);
        memset(msgbuf, 0, sizeof(msgbuf));
        M_vsnprintf(msgbuf, sizeof(msgbuf), error, argptr);
        va_end(argptr);

        MultiByteToWideChar(CP_ACP, 0,
                            msgbuf, strlen(msgbuf) + 1,
                            wmsgbuf, sizeof(wmsgbuf));

        MessageBoxW(NULL, wmsgbuf, L"", MB_OK);
    }
#elif defined(__MACOSX__)
    if (exit_gui_popup && !I_ConsoleStdout())
    {
        CFStringRef message;
        char msgbuf[512];
	int i;

        va_start(argptr, error);
        memset(msgbuf, 0, sizeof(msgbuf));
        M_vsnprintf(msgbuf, sizeof(msgbuf), error, argptr);
        va_end(argptr);

	// The CoreFoundation message box wraps text lines, so replace
	// newline characters with spaces so that multiline messages
	// are continuous.

	for (i = 0; msgbuf[i] != '\0'; ++i)
        {
            if (msgbuf[i] == '\n')
            {
                msgbuf[i] = ' ';
            }
        }

        message = CFStringCreateWithCString(NULL, msgbuf,
                                            kCFStringEncodingUTF8);

        CFUserNotificationDisplayNotice(0,
                                        kCFUserNotificationCautionAlertLevel,
                                        NULL,
                                        NULL,
                                        NULL,
                                        CFSTR(PACKAGE_STRING),
                                        message,
                                        NULL);
    }
#else
    if (exit_gui_popup && !I_ConsoleStdout())
    {
        ZenityErrorBox(error);
    }
#endif

    // abort();

    exit(-1);
}
예제 #6
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       cfd       = -1;
    char     *fdnam     = NULL;
    char     *dev       = NULL;
    int       r         = 0;
    char      devpath[MAXPATHLEN];
    int       fd        = -1;
    int32_t   dindex    = -1;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    // Drop to real uid and gid
    seteuid(getuid());
    setegid(getgid());

    if (!getenv("MOUNT_OSXFUSE_CALL_BY_LIB")) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    while (true) {
        static struct option long_options[] = {
            { "help",    no_argument, NULL, 'h' },
            { "version", no_argument, NULL, 'v' },
            { NULL, 0, NULL, 0 }
        };

        int c = getopt_long(argc, argv, "ho:qv", long_options, NULL);
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'o':
                getmntopts(optarg, mopts, &mntflags, &altflags);
                for (mv = mvals; mv->mv_mntflag; ++mv) {
                    if (!(altflags & mv->mv_mntflag)) {
                        continue;
                    }
                    for (mo = mopts; mo->m_option; ++mo) {
                        char *p, *q;
                        if (!mo->m_altloc || mo->m_flag != mv->mv_mntflag) {
                            continue;
                        }
                        p = strstr(optarg, mo->m_option);
                        if (p) {
                            p += strlen(mo->m_option);
                            q = p;
                            while (*q != '\0' && *q != ',') {
                                q++;
                            }
                            mv->mv_len = q - p + 1;
                            mv->mv_value = malloc(mv->mv_len);
                            memcpy(mv->mv_value, p, mv->mv_len - 1);
                            ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                            break;
                        }
                    }
                }
                break;

            case 'q':
                quiet_mode = true;
                break;

            case 'v':
                showversion(true);
                break;

            case 'h':
            case '?':
            default:
                showhelp();
                break;
        }
    }

    argc -= optind;
    argv += optind;

    if (argc >= 1) {
        mntpath = argv[0];
        argc--;
        argv++;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    {
        char *commfd;

        commfd = getenv("_FUSE_COMMFD");
        if (commfd == NULL) {
            errx(EX_USAGE, "mew style mounting requires commfd");
        }

        errno = 0;
        cfd = (int)strtol(commfd, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || cfd < 0) {
            errx(EX_USAGE, "invalid commfd");
        }
    }

    result = load_kext();
    if (result) {
        if (result == EINVAL) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too new for the operating system. Please downgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_OLD, NULL, 0);
        }
        if (result == ENOENT) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too old for the operating system. Please upgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_NEW, NULL, 0);
        } else if (result == EBUSY) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("FUSE version mismatch"),
                    CFSTR("FUSE has been updated but an incompatible or old version of the FUSE kernel extension is already loaded. It failed to unload, possibly because a FUSE volume is currently mounted.\n\nPlease eject all FUSE volumes and try again, or simply restart the system for changes to take effect."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_VERSION_MISMATCH, NULL, 0);
        }
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME " file system is not available (%d)", result);
    }

    result = check_kext_status();
    switch (result) {
        case 0:
            break;

        case ESRCH:
            errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
                 " kernel extension is not loaded");
            break;

        case EINVAL:
            errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension has a mismatched version");
            break;

        default:
            errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension (%d)", result);
            break;
    }

    fdnam = getenv("FUSE_DEV_FD");
    if (fdnam) {
        errno = 0;
        fd = (int)strtol(fdnam, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || fd < 0) {
            errx(EX_USAGE, "invalid value given in FUSE_DEV_FD");
        }

        goto mount;
    }

    dev = getenv("FUSE_DEV_NAME");
    if (dev) {
        fd = open(dev, O_RDWR);
        if (fd < 0) {
            errx(EX_USAGE, "failed to open device");
        }

        goto mount;
    }

    for (r = 0; r < OSXFUSE_NDEVICES; r++) {
        snprintf(devpath, MAXPATHLEN - 1,
                 _PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r);
        fd = open(devpath, O_RDWR);
        if (fd >= 0) {
            dindex = r;
            break;
        }
    }
    if (dindex == -1) {
        errx(EX_OSERR, "failed to open device");
    }

mount:
    signal_fd = fd;
    atexit(&signal_idx_atexit_handler);

    {
        struct stat sb;
        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME " device file descriptor");
        }
        args.rdev = sb.st_rdev;
    }

    if (dindex < 0) {
        char  ndev[MAXPATHLEN];
        char *ndevbas;

        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(args.rdev, S_IFCHR, ndevbas, (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME, strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME), NULL, 10);
        if (errno == EINVAL || errno == ERANGE || dindex < 0 || dindex > OSXFUSE_NDEVICES) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME " device unit (#%d)\n", dindex);
        }
    }

    while (true) {
        struct stat sb;

        if (realpath(mntpath, args.mntpath) != NULL &&
            stat(args.mntpath, &sb) == 0) {

            if (S_ISDIR(sb.st_mode)) {
                break;
            } else {
                errx(EX_USAGE, "%s: not a directory", args.mntpath);
            }

        } else if (errno == ENOENT) {
            bool volumes = strncmp(args.mntpath, "/Volumes/", 9) == 0 &&
                           strchr(args.mntpath + 9, '/') == NULL;

            if (volumes) {
                (void)seteuid(0);
                (void)setegid(0);
            }

            if (mkdir(args.mntpath, 0755)) {
                errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
            }

            if (volumes) {
                uid_t uid = getuid();
                gid_t gid = getgid();

                (void)chown(args.mntpath, uid, gid);
                (void)seteuid(uid);
                (void)setegid(gid);
            }

        } else {
            errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
        }
    }

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t)blocksize;
    args.daemon_timeout = (uint32_t)daemon_timeout;
    args.fsid           = (uint32_t)fsid;
    args.fssubtype      = (uint32_t)fssubtype;
    args.iosize         = (uint32_t)iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    if (cfd != -1) {
        result = send_fd(cfd, fd);
        if (result == -1) {
            err(EX_OSERR, "failed to send file descriptor");
        }
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_fd = -1;
    exit(0);
}