Exemple #1
0
TEST(stdlib, realpath__ENOENT) {
  errno = 0;
  char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
  ASSERT_TRUE(p == NULL);
  ASSERT_EQ(ENOENT, errno);
}
Exemple #2
0
int start_server(int port_number, const char* dir_name, int period)
{
	pthread_t tid;                                  /* Passed to pthread_create */
	struct thread_arg* targ;                /* Used to pass arguments to threads */
	pthread_attr_t tattr;                   /* Specifies that thread should be detached */
	fd_set master;                                  /* Keep track of all connections / pipes to multiplex */
	fd_set read_fds;                        /* Copy of master for select to populate */
	int fdmax;                                              /* Highest numbered file descriptor */
	int i;                                                  /* Used to index the master fd list */
	int listener;                                   /* Listening socket of the server */
	int newfd;                                      /* New connection socket fd */
	struct sockaddr_in local_addr;  /* Local connection info */
	struct sockaddr_in remote_addr; /* Remote connection info */
	socklen_t addr_len;                     /* Address length */
	int pipe_buff[1];                               /* Get sockets into here */
	pipe_buff[0] = 0;

	// Init signal mask
	struct sigaction sa;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = SIG_IGN;

	// Start each thread in detached mode, since we don't care about
	// their return values
	pthread_attr_init(&tattr);
	pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);

	// Initialize the memory pool to store the direntries
	direntry_pool = init_mempool(sizeof(struct direntry), 512);

	// Set done to 0
	done = 0;

	// Initialize the clients linked list
	clients = (struct clientlist*)malloc(sizeof(struct clientlist));
	clients->head = NULL;
	clients->tail = NULL;
	clients->count = 0;

	// Copy into global init_dir
	strcpy(init_dir, dir_name);
	gperiod = period;

	// Initialize pipe
	if (pipe(remove_client_pipes) < 0) {
		syslog(LOG_ERR, "Cannot create IPC in server.");
		exit(1);
	}

	// Get full path of the directory
	if (realpath(dir_name, full_path) == NULL) {
		syslog(LOG_ERR, "Cannot resolve full path.");
		exit(1);
	}

#ifdef DAEMONIZE
	create_daemon("dirapp");
#endif
#ifndef DAEMONIZE
	openlog("dirapp", LOG_CONS, LOG_DAEMON);
#endif

	// Make sure SIGPIPE is blocked
	if (sigaction(SIGPIPE, &sa, NULL) < 0) {
		syslog(LOG_WARNING, "SIGPIPE error");
	}

	// Signals for the signal thread to handle
	sigemptyset(&mask);
	sigaddset(&mask, SIGHUP);
	sigaddset(&mask, SIGTERM);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGALRM);

	// Set the mask
	if (pthread_sigmask(SIG_BLOCK, &mask, NULL) != 0)
		syslog(LOG_WARNING, "pthread_sigmask failed");

	// Initialize file descriptor lists
	FD_ZERO(&master);
	FD_ZERO(&read_fds);

	// Setup local connection info
	memset(&local_addr, 0, sizeof(local_addr));
	local_addr.sin_family = AF_INET;
	local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	local_addr.sin_port = htons(port_number);

	// Create listener socket
	listener = socket(AF_INET, SOCK_STREAM, 0);

	// Try to bind
	if (bind(listener, (struct sockaddr*)&local_addr, sizeof(local_addr))) {
		syslog(LOG_ERR, "Cannot bind socket to address");
		exit(1);
	}

	// Now listen!
	if (listen(listener, MAX_CLIENTS) < 0) {
		syslog(LOG_ERR, "Cannot listen on socket");
		exit(1);
	}

	syslog(LOG_INFO, "Starting server!");

	// Have select check for incoming data
	FD_SET(remove_client_pipes[0], &master);
	FD_SET(listener, &master);
	fdmax = listener;

	// Initialize the direntry lists
	prevdir = init_direntrylist();
	curdir = init_direntrylist();

	// Initially populate list of file entries in monitored directory
	exploredir(prevdir, (const char*)full_path);

	// Start signal thread
	pthread_create(&tid, NULL, signal_thread, NULL);

	int errno = 0;

	// Main server loop
	while (1) {
		read_fds = master;

		if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1) {
			syslog(LOG_ERR, "select: %s", strerror(errno));
			exit(1);
		}

		for (i = 0; i <= fdmax; i++) {
			if (FD_ISSET(i, &read_fds)) {
				if (i == listener) {
					addr_len = sizeof(remote_addr);
					newfd = accept(listener, (struct sockaddr*)&remote_addr, &addr_len);

					if (newfd == -1) {
						syslog(LOG_WARNING, "Cannot new client.");
					} else {
						FD_SET(newfd, &master);
						if (newfd > fdmax) {
							fdmax = newfd;
						}

						syslog(LOG_INFO, "New connection from: %s:%d",
						       inet_ntoa(remote_addr.sin_addr),
						       ntohs(remote_addr.sin_port));
						// Add client to clients list in order to receive
						// updates
						pthread_create(&tid, &tattr, init_client, (void*)newfd);
					}
				} else if (i == remove_client_pipes[0]) {
					// Get the file descriptor of the socket that is to
					// be removed and store into the first position of
					// tmp_buff
					if (read(remove_client_pipes[0], pipe_buff, 1) <= 0) {
						syslog(LOG_ERR, "Cannot read in socket to close.");
					} else {
						// Remove socket from master list
						pthread_mutex_lock(&slock);
						FD_CLR(pipe_buff[0], &master);
						done = 1;
						pthread_mutex_unlock(&slock);

						// Tell kill_clients or whoever they
						// can procede
						pthread_cond_signal(&sready);
					}
				} else {
					// Handle disconnect
					targ = (struct thread_arg*)malloc(sizeof(struct thread_arg));
					targ->socket = i;
					targ->pipe = remove_client_pipes[1];

					pthread_create(&tid, &tattr, remove_client, (void*)targ);
					FD_CLR(i, &master);
				}
			}
		}
	}

	return 0;
}
Exemple #3
0
/**
 * Plugin name structure *MUST* be  `PLUGIN_DIR/[<priority>]<name>.<ext>`
 * <priority> is an int in [1, 9]. If <priority> is found as the first char of the
 * file name, it will be applied to the plugin. If no priority is specify, a default
 * priority will be applied.
 *
 * If a file does not match this pattern, it will be discarded
 *
 * @param plugin_path is the path to look for plugins
 * @param plugin_name is the name of the plugin to add. If NULL, this function will try
 *        to *all* the files in the directory.
 * @return the number of added plugins on success, -1 on error
 */
int proxenet_add_new_plugins(char* plugin_path, char* plugin_name)
{
	struct dirent *dir_ptr=NULL;
	DIR *dir = NULL;
	char* name = NULL;
	short type=-1, priority;
	int d_name_len;
        bool add_all = (plugin_name==NULL)?true:false;
        unsigned int nb_plugin_added = 0;

#ifdef DEBUG
        if (add_all)
                xlog(LOG_DEBUG, "Trying to add all files in '%s'\n", plugin_path);
        else
                xlog(LOG_DEBUG, "Trying to add '%s/%s'\n", plugin_path, plugin_name);
#endif
	dir = opendir(plugin_path);
	if (dir == NULL) {
		xlog(LOG_ERROR, "Failed to open '%s': %s\n", plugin_path, strerror(errno));
		return -1;
	}

	while ((dir_ptr=readdir(dir))) {
		if (strcmp(dir_ptr->d_name,".")==0)
                        continue;

		if (strcmp(dir_ptr->d_name,"..")==0)
                        continue;

                /* if add one plugin, loop until the right name */
                if (!add_all && strcmp(dir_ptr->d_name, plugin_name)!=0)
                        continue;

                if (dir_ptr->d_type == DT_LNK){
                        /* if entry is a symlink, ensure it's pointing to a file in plugins_path */
                        ssize_t l = -1;
                        char fullpath[PATH_MAX] = {0, };
                        char realpath_buf[PATH_MAX] = {0, };

                        l = snprintf(fullpath, PATH_MAX, "%s/%s", plugin_path, dir_ptr->d_name);
                        if(l == -1){
			        xlog(LOG_ERROR, "snprintf() failed on '%s'\n",
				     dir_ptr->d_name ,
				     errno,
				     strerror(errno));
				continue;
			}

                        if(!realpath(fullpath, realpath_buf)){
                                xlog(LOG_ERROR, "realpath failed on '%s': %d - %s\n",
                                     fullpath,
                                     errno,
                                     strerror(errno));
                                continue;
                        }

                        l = strlen(cfg->plugins_path);

                        if( strncmp(realpath_buf, cfg->plugins_path, l) != 0 )
                                continue;

                } else {
                        /* if not a symlink nor regular file, continue */
                        if (dir_ptr->d_type != DT_REG)
                                continue;
                }

                /* if first char is valid integer, this will be the plugin priority */
		if (atoi(&(dir_ptr->d_name[0])) > 0)
                        priority = (unsigned short)atoi(&(dir_ptr->d_name[0]));
                else
                        priority = (unsigned short) CFG_DEFAULT_PLUGIN_PRIORITY;

		/* plugin name  */
		d_name_len = strlen(dir_ptr->d_name);
		if (d_name_len > 510)
                        continue;

		name = dir_ptr->d_name;

		/* plugin type */
		type = proxenet_get_plugin_type(name);
		if (type < 0)
                        continue;

                if ( proxenet_is_plugin_loaded(name) ){
                        xlog(LOG_WARNING, "A plugin named '%s' is already loaded\n", name);
                        continue;
                }

		/* add plugin in correct place (1: high priority, 9: low priority) */
		insert_new_plugin_in_list(name, type, priority);

		nb_plugin_added++;

		/* if add one plugin only, there is no need to keep looping */
		if (!add_all)
			break;
	}

	if (closedir(dir) < 0){
		xlog(LOG_WARNING, "Error while closing '%s': %s\n", plugin_path, strerror(errno));
        }

	return nb_plugin_added;
}
Exemple #4
0
int
main (int argc, char *argv[]) {
    int portable = 0;
#if STATICLINK
    int staticlink = 1;
#else
    int staticlink = 0;
#endif
#if PORTABLE
    portable = 1;
    if (!realpath (argv[0], dbinstalldir)) {
        strcpy (dbinstalldir, argv[0]);
    }
    char *e = strrchr (dbinstalldir, '/');
    if (e) {
        *e = 0;
    }
    else {
        fprintf (stderr, "couldn't determine install folder from path %s\n", argv[0]);
        exit (-1);
    }
#else
    if (!realpath (argv[0], dbinstalldir)) {
        strcpy (dbinstalldir, argv[0]);
    }
    char *e = strrchr (dbinstalldir, '/');
    if (e) {
        *e = 0;
        struct stat st;
        char checkpath[PATH_MAX];
        snprintf (checkpath, sizeof (checkpath), "%s/.ddb_portable", dbinstalldir);
        if (!stat (checkpath, &st)) {
            if (S_ISREG (st.st_mode)) {
                portable = 1;
            }
        }
    }
    if (!portable) {
        strcpy (dbinstalldir, PREFIX);
    }
#endif

#ifdef __GLIBC__
    signal (SIGSEGV, sigsegv_handler);
#endif
    setlocale (LC_ALL, "");
    setlocale (LC_NUMERIC, "C");
#ifdef ENABLE_NLS
//    fprintf (stderr, "enabling gettext support: package=" PACKAGE ", dir=" LOCALEDIR "...\n");
    if (portable) {
        char localedir[PATH_MAX];
        snprintf (localedir, sizeof (localedir), "%s/locale", dbinstalldir);
        bindtextdomain (PACKAGE, localedir);
    }
    else {
        bindtextdomain (PACKAGE, LOCALEDIR);
    }
	bind_textdomain_codeset (PACKAGE, "UTF-8");
	textdomain (PACKAGE);
#endif

    fprintf (stderr, "starting deadbeef " VERSION "%s%s\n", staticlink ? " [static]" : "", portable ? " [portable]" : "");
    srand (time (NULL));
#ifdef __linux__
    prctl (PR_SET_NAME, "deadbeef-main", 0, 0, 0, 0);
#endif

#if PORTABLE_FULL
    if (snprintf (confdir, sizeof (confdir), "%s/config", dbinstalldir) > sizeof (confdir)) {
        fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
        return -1;
    }

    strcpy (dbconfdir, confdir);
#else
    char *homedir = getenv ("HOME");
    if (!homedir) {
        fprintf (stderr, "unable to find home directory. stopping.\n");
        return -1;
    }

    char *xdg_conf_dir = getenv ("XDG_CONFIG_HOME");
    if (xdg_conf_dir) {
        if (snprintf (confdir, sizeof (confdir), "%s", xdg_conf_dir) > sizeof (confdir)) {
            fprintf (stderr, "fatal: XDG_CONFIG_HOME value is too long: %s\n", xdg_conf_dir);
            return -1;
        }
    }
    else {
        if (snprintf (confdir, sizeof (confdir), "%s/.config", homedir) > sizeof (confdir)) {
            fprintf (stderr, "fatal: HOME value is too long: %s\n", homedir);
            return -1;
        }
    }
    if (snprintf (dbconfdir, sizeof (dbconfdir), "%s/deadbeef", confdir) > sizeof (dbconfdir)) {
        fprintf (stderr, "fatal: out of memory while configuring\n");
        return -1;
    }
    mkdir (confdir, 0755);
#endif


    if (portable) {
        if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
#ifdef HAVE_COCOAUI
        char respath[PATH_MAX];
        cocoautil_get_resources_path (respath, sizeof (respath));
        if (snprintf (dbplugindir, sizeof (dbplugindir), "%s", respath) > sizeof (dbplugindir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
#else
        if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
#endif
        if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
        mkdir (dbplugindir, 0755);
    }
    else {
        if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
        if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
        if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) {
            fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir);
            return -1;
        }
    }

    for (int i = 1; i < argc; i++) {
        // help, version and nowplaying are executed with any filter
        if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h")) {
            print_help ();
            return 0;
        }
        else if (!strcmp (argv[i], "--version")) {
            fprintf (stderr, "DeaDBeeF " VERSION " Copyright © 2009-2013 Alexey Yakovenko\n");
            return 0;
        }
        else if (!strcmp (argv[i], "--gui")) {
            if (i == argc-1) {
                break;
            }
            i++;
            strncpy (use_gui_plugin, argv[i], sizeof(use_gui_plugin) - 1);
            use_gui_plugin[sizeof(use_gui_plugin) - 1] = 0;
        }
    }

    trace ("installdir: %s\n", dbinstalldir);
    trace ("confdir: %s\n", confdir);
    trace ("docdir: %s\n", dbdocdir);
    trace ("plugindir: %s\n", dbplugindir);
    trace ("pixmapdir: %s\n", dbpixmapdir);

    mkdir (dbconfdir, 0755);

    int size = 0;
    char *cmdline = prepare_command_line (argc, argv, &size);

    // try to connect to remote player
    int s, len;
    struct sockaddr_un remote;

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    memset (&remote, 0, sizeof (remote));
    remote.sun_family = AF_UNIX;
#if USE_ABSTRACT_SOCKET_NAME
    memcpy (remote.sun_path, server_id, sizeof (server_id));
    len = offsetof(struct sockaddr_un, sun_path) + sizeof (server_id)-1;
#else
    char *socketdirenv = getenv ("DDB_SOCKET_DIR");
    snprintf (remote.sun_path, sizeof (remote.sun_path), "%s/socket", socketdirenv ? socketdirenv : dbconfdir);
    len = offsetof(struct sockaddr_un, sun_path) + strlen (remote.sun_path);
#endif
    if (connect(s, (struct sockaddr *)&remote, len) == 0) {
        // pass args to remote and exit
        if (send(s, cmdline, size, 0) == -1) {
            perror ("send");
            exit (-1);
        }
        // end of message
        shutdown(s, SHUT_WR);

        int sz = -1;
        char *out = read_entire_message(s, &sz);
        if (sz == -1) {
            fprintf (stderr, "failed to pass args to remote!\n");
            exit (-1);
        }
        else {
            // check if that's nowplaying response
            const char np[] = "nowplaying ";
            const char err[] = "error ";
            if (!strncmp (out, np, sizeof (np)-1)) {
                const char *prn = &out[sizeof (np)-1];
                fwrite (prn, 1, strlen (prn), stdout);
            }
            else if (!strncmp (out, err, sizeof (err)-1)) {
                const char *prn = &out[sizeof (err)-1];
                fwrite (prn, 1, strlen (prn), stderr);
            }
            else if (sz > 0 && out[0]) {
                fprintf (stderr, "%s\n", out);
            }
        }
        if (out) {
            free (out);
        }
        close (s);
        exit (0);
    }
//    else {
//        perror ("INFO: failed to connect to existing session:");
//    }
    close(s);

    // become a server
    if (server_start () < 0) {
        exit (-1);
    }

    // hack: report nowplaying
    if (!strcmp (cmdline, "--nowplaying")) {
        char nothing[] = "nothing";
        fwrite (nothing, 1, sizeof (nothing)-1, stdout);
        return 0;
    }

    pl_init ();
    conf_init ();
    conf_load (); // required by some plugins at startup

    if (use_gui_plugin[0]) {
        conf_set_str ("gui_plugin", use_gui_plugin);
    }

    conf_set_str ("deadbeef_version", VERSION);

    volume_set_db (conf_get_float ("playback.volume", 0)); // volume need to be initialized before plugins start

    messagepump_init (); // required to push messages while handling commandline
    if (plug_load_all ()) { // required to add files to playlist from commandline
        exit (-1);
    }
    pl_load_all ();
    plt_set_curr_idx (conf_get_int ("playlist.current", 0));

    // execute server commands in local context
    int noloadpl = 0;
    if (argc > 1) {
        int res = server_exec_command_line (cmdline, size, NULL, 0);
        // some of the server commands ran on 1st instance should terminate it
        if (res == 2) {
            noloadpl = 1;
        }
        else if (res > 0) {
            exit (0);
        }
        else if (res < 0) {
            exit (-1);
        }
    }

    free (cmdline);

#if 0
    signal (SIGTERM, sigterm_handler);
    atexit (atexit_handler); // helps to save in simple cases
#endif

    streamer_init ();

    plug_connect_all ();
    messagepump_push (DB_EV_PLUGINSLOADED, 0, 0, 0);

    if (!noloadpl) {
        restore_resume_state ();
    }

    server_tid = thread_start (server_loop, NULL);

    mainloop_tid = thread_start (mainloop_thread, NULL);

    DB_plugin_t *gui = plug_get_gui ();
    if (gui) {
        gui->start ();
    }

    fprintf (stderr, "gui plugin has quit; waiting for mainloop thread to finish\n");
    thread_join (mainloop_tid);

    // terminate server and wait for completion
    if (server_tid) {
        server_terminate = 1;
        thread_join (server_tid);
        server_tid = 0;
    }

    // save config
    pl_save_all ();
    conf_save ();

    // delete legacy session file
    {
        char sessfile[1024]; // $HOME/.config/deadbeef/session
        if (snprintf (sessfile, sizeof (sessfile), "%s/deadbeef/session", confdir) < sizeof (sessfile)) {
            unlink (sessfile);
        }
    }

    // stop receiving messages from outside
    server_close ();

    // plugins might still hold references to playitems,
    // and query configuration in background
    // so unload everything 1st before final cleanup
    plug_disconnect_all ();
    plug_unload_all ();

    // at this point we can simply do exit(0), but let's clean up for debugging
    pl_free (); // may access conf_*
    conf_free ();

    fprintf (stderr, "messagepump_free\n");
    messagepump_free ();
    fprintf (stderr, "plug_cleanup\n");
    plug_cleanup ();

    fprintf (stderr, "hej-hej!\n");

    return 0;
}
Exemple #5
0
jboolean rvmInitOptions(int argc, char* argv[], Options* options, jboolean ignoreRvmArgs) {
    char path[PATH_MAX];
    if (!realpath(argv[0], path)) {
        return FALSE;
    }

    strcpy(options->executablePath, path);

    jint i = strlen(path);
    while (i >= 0 && path[i] != '/') {
        path[i--] = '\0';
    }
    if (i >= 0 && path[i] == '/') {
        path[i] = '\0';
    }

    strcpy(options->basePath, path);

    jint firstJavaArg = 1;
    for (i = 1; i < argc; i++) {
        if (startsWith(argv[i], "-rvm:")) {
            if (!ignoreRvmArgs) {
                char* arg = &argv[i][5];
                if (startsWith(arg, "log=trace")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_TRACE;
                } else if (startsWith(arg, "log=debug")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_DEBUG;
                } else if (startsWith(arg, "log=info")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_INFO;
                } else if (startsWith(arg, "log=warn")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_WARN;
                } else if (startsWith(arg, "log=error")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_ERROR;
                } else if (startsWith(arg, "log=fatal")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_FATAL;
                } else if (startsWith(arg, "log=silent")) {
                    if (options->logLevel == 0) options->logLevel = LOG_LEVEL_SILENT;
                } else if (startsWith(arg, "mx") || startsWith(arg, "ms")) {
                    char* unit;
                    jlong n = strtol(&arg[2], &unit, 10);
                    if (n > 0) {
                        if (unit[0] != '\0') {
                            switch (unit[0]) {
                            case 'g':
                            case 'G':
                                n *= 1024 * 1024 * 1024;
                                break;
                            case 'm':
                            case 'M':
                                n *= 1024 * 1024;
                                break;
                            case 'k':
                            case 'K':
                                n *= 1024;
                                break;
                            }
                        }
                    }
                    if (startsWith(arg, "mx")) {
                        options->maxHeapSize = n;
                    } else {
                        options->initialHeapSize = n;
                    }
                } else if (startsWith(arg, "MainClass=")) {
                    if (!options->mainClass) {
                        char* s = strdup(&arg[10]);
                        jint j;
                        for (j = 0; s[j] != 0; j++) {
                            if (s[j] == '.') s[j] = '/';
                        }
                        options->mainClass = s;
                    }
                }
            }
            firstJavaArg++;
        } else {
            break;
        }
    }

    options->commandLineArgs = NULL;
    options->commandLineArgsCount = argc - firstJavaArg;
    if (options->commandLineArgsCount > 0) {
        options->commandLineArgs = &argv[firstJavaArg];
    }

    return options->mainClass != NULL;
}
Exemple #6
0
// Resolve a path and append it to the CLI settings structure
// The FSEvents API will, internally, resolve paths using a similar scheme.
// Performing this ahead of time makes things less confusing, IMHO.
static void append_path(const char* path)
{
#ifdef DEBUG
  fprintf(stderr, "\n");
  fprintf(stderr, "append_path called for: %s\n", path);
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060

#ifdef DEBUG
  fprintf(stderr, "compiled against 10.6+, using CFURLCreateFileReferenceURL\n");
#endif

  CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)path, (CFIndex)strlen(path), false);
  CFURLRef placeholder = CFURLCopyAbsoluteURL(url);
  CFRelease(url);

  CFMutableArrayRef imaginary = NULL;

  // if we don't have an existing url, spin until we get to a parent that
  // does exist, saving any imaginary components for appending back later
  while(!CFURLResourceIsReachable(placeholder, NULL)) {
#ifdef DEBUG
    fprintf(stderr, "path does not exist\n");
#endif

    CFStringRef child;

    if (imaginary == NULL) {
      imaginary = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    }

    child = CFURLCopyLastPathComponent(placeholder);
    CFArrayInsertValueAtIndex(imaginary, 0, child);
    CFRelease(child);

    url = CFURLCreateCopyDeletingLastPathComponent(NULL, placeholder);
    CFRelease(placeholder);
    placeholder = url;

#ifdef DEBUG
    fprintf(stderr, "parent: ");
    CFShow(placeholder);
#endif
  }

#ifdef DEBUG
  fprintf(stderr, "path exists\n");
#endif

  // realpath() doesn't always return the correct case for a path, so this
  // is a funky workaround that converts a path into a (volId/inodeId) pair
  // and asks what the path should be for that. since it looks at the actual
  // inode instead of returning the same case passed in like realpath()
  // appears to do for HFS+, it should always be correct.
  url = CFURLCreateFileReferenceURL(NULL, placeholder, NULL);
  CFRelease(placeholder);
  placeholder = CFURLCreateFilePathURL(NULL, url, NULL);
  CFRelease(url);

#ifdef DEBUG
  fprintf(stderr, "path resolved to: ");
  CFShow(placeholder);
#endif

  // if we stripped off any imaginary path components, append them back on
  if (imaginary != NULL) {
    CFIndex count = CFArrayGetCount(imaginary);
    for (CFIndex i = 0; i<count; i++) {
      CFStringRef component = CFArrayGetValueAtIndex(imaginary, i);
#ifdef DEBUG
      fprintf(stderr, "appending component: ");
      CFShow(component);
#endif
      url = CFURLCreateCopyAppendingPathComponent(NULL, placeholder, component, false);
      CFRelease(placeholder);
      placeholder = url;
    }
    CFRelease(imaginary);
  }

#ifdef DEBUG
  fprintf(stderr, "result: ");
  CFShow(placeholder);
#endif

  CFStringRef cfPath = CFURLCopyFileSystemPath(placeholder, kCFURLPOSIXPathStyle);
  CFArrayAppendValue(config.paths, cfPath);
  CFRelease(cfPath);
  CFRelease(placeholder);

#else

#ifdef DEBUG
  fprintf(stderr, "compiled against 10.5, using realpath()\n");
#endif

  char fullPath[PATH_MAX + 1];

  if (realpath(path, fullPath) == NULL) {
#ifdef DEBUG
    fprintf(stderr, "  realpath not directly resolvable from path\n");
#endif

    if (path[0] != '/') {
#ifdef DEBUG
      fprintf(stderr, "  passed path is not absolute\n");
#endif
      size_t len;
      getcwd(fullPath, sizeof(fullPath));
#ifdef DEBUG
      fprintf(stderr, "  result of getcwd: %s\n", fullPath);
#endif
      len = strlen(fullPath);
      fullPath[len] = '/';
      strlcpy(&fullPath[len + 1], path, sizeof(fullPath) - (len + 1));
    } else {
#ifdef DEBUG
      fprintf(stderr, "  assuming path does not YET exist\n");
#endif
      strlcpy(fullPath, path, sizeof(fullPath));
    }
  }

#ifdef DEBUG
  fprintf(stderr, "  resolved path to: %s\n", fullPath);
  fprintf(stderr, "\n");
#endif

  CFStringRef pathRef = CFStringCreateWithCString(kCFAllocatorDefault,
                                                  fullPath,
                                                  kCFStringEncodingUTF8);
  CFArrayAppendValue(config.paths, pathRef);
  CFRelease(pathRef);

#endif
}
Exemple #7
0
/*
 * Displays size of file system and percent of data blocks and inodes used.
 */
void ShowFileSystemSize(char *fileSystem)
{
#ifndef _WIN32                  /* FIXME */
        char realPath[PATH_MAX];
        char *fileSystemUnitStr;
        long long int totalFileSystemSize;
        long long int freeFileSystemSize;
        long long int totalInodes;
        long long int freeInodes;
        double totalFileSystemSizeHR;
        double usedFileSystemPercentage;
        double usedInodePercentage;
#ifdef __sun                    /* SunOS does not support statfs(), instead uses statvfs() */
        struct statvfs statusBuffer;
#else                           /* !__sun */
        struct statfs statusBuffer;
#endif                          /* __sun */

#ifdef __sun
        if (statvfs(fileSystem, &statusBuffer) != 0) {
                ERR("unable to statvfs() file system");
        }
#else                           /* !__sun */
        if (statfs(fileSystem, &statusBuffer) != 0) {
                ERR("unable to statfs() file system");
        }
#endif                          /* __sun */

        /* data blocks */
#ifdef __sun
        totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_frsize;
        freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_frsize;
#else                           /* !__sun */
        totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_bsize;
        freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_bsize;
#endif                          /* __sun */

        usedFileSystemPercentage = (1 - ((double)freeFileSystemSize
                                         / (double)totalFileSystemSize)) * 100;
        totalFileSystemSizeHR =
                (double)totalFileSystemSize / (double)(1<<30);
        fileSystemUnitStr = "GiB";
        if (totalFileSystemSizeHR > 1024) {
                totalFileSystemSizeHR = (double)totalFileSystemSize / (double)((long long)1<<40);
                fileSystemUnitStr = "TiB";
        }

        /* inodes */
        totalInodes = statusBuffer.f_files;
        freeInodes = statusBuffer.f_ffree;
        usedInodePercentage =
            (1 - ((double)freeInodes / (double)totalInodes)) * 100;

        /* show results */
        if (realpath(fileSystem, realPath) == NULL) {
                ERR("unable to use realpath()");
        }
        fprintf(stdout, "Path: %s\n", realPath);
        fprintf(stdout, "FS: %.1f %s   Used FS: %2.1f%%   ",
                totalFileSystemSizeHR, fileSystemUnitStr,
                usedFileSystemPercentage);
        fprintf(stdout, "Inodes: %.1f Mi   Used Inodes: %2.1f%%\n",
                (double)totalInodes / (double)(1<<20),
                usedInodePercentage);
        fflush(stdout);
#endif /* !_WIN32 */

        return;
}
Exemple #8
0
/**
 * Reads the list of files from the host IDE runs on,
 * creates files, fills internal file table
 */
static int init_files() {
    trace("Files list initialization\n");
    int bufsize = PATH_MAX + 32;
    char buffer[bufsize];
    int success = false;
    file_elem* list = NULL;
    file_elem* tail = NULL;
    start_adding_file_data();
    while (1) {
        if( !fgets(buffer, bufsize, stdin)) {
            report_error("protocol error while reading file info: unexpected EOF\n");
            return false;
        }
        if (buffer[0] == '\n') {
            success = true;
            break;
        }
        trace("\tFile init: %s", buffer); // no trailing LF since it's in the buffer
        // remove trailing LF
        char* lf = strchr(buffer, '\n');
        if (lf) {
            *lf = 0;
        }
        if (strchr(buffer, '\r')) {
            report_error("protocol error: unexpected CR: %s\n", buffer);
            return false;
        }

        enum file_state state;
        int file_size;
        char *path;
        struct timeval file_time;
        file_time.tv_sec = file_time.tv_usec = 0;

        if (!scan_line(buffer, bufsize, &state, &file_size, &file_time, (const char**) &path)) {
            report_error("protocol error: %s\n", buffer);
            break;
        }
        trace("\t\tpath=%s size=%d state=%c (0x%x) time=%d.%d\n", path, file_size, (char) state, (char) state, file_time.tv_sec, file_time.tv_usec);

        if (state == -1) {
            report_error("protocol error: %s\n", buffer);
            break;
        } else if (state == DIRECTORY) { // directory
            create_dir(path);
        } else if (state == LINK) { // symbolic link
            char lnk_src[bufsize]; // it is followed by a line that contains the link source
            if( !fgets(lnk_src, sizeof lnk_src, stdin)) {
                report_error("protocol error while reading link info: unexpected EOF\n");
                return false;
            }
            char* lf = strchr(lnk_src, '\n');
            if (lf) {
                *lf = 0;
            }
            if (strchr(buffer, '\r')) {
                report_error("protocol error: unexpected CR: %s\n", buffer);
                return false;
            }
            create_lnk(path, lnk_src);
        } else { // plain file
            int touch = false;
            if (state == INITIAL) {
                touch = true;
            } else if (state == COPIED || state == TOUCHED) {
                touch = !file_exists(path, file_size);
            } else if (state == UNCONTROLLED || state == INEXISTENT) {
                // nothing
            } else {
                report_error("protocol error: %s\n", buffer);
            }

            enum file_state new_state = state;
            if (touch) {
                if (touch_file(path, file_size, &file_time)) {
                    new_state = TOUCHED;
                } else {
                    new_state = ERROR;
                }
            }

            if (*path == '/') {
                char real_path [PATH_MAX + 1];
                if (state == UNCONTROLLED || state == INEXISTENT) {
                    char *dir = path;
                    char *file = path;
                    // find trailing zero
                    while (*file) {
                        file++;
                    }
                    // we'll find '/' for sure - at least the starting one
                    while(*file != '/') {
                        file--;
                    }
                    if (file == path) { // the file resides in root directory
                        strcpy(real_path, path);
                    } else {
                        // NB: we modify the path! but we'll restore later
                        char *pfile_start = file; // save file start char
                        char file_start = *file;  // save file start char
                        *file = 0; // replace the '/' that separates file from dir by zero
                        file++; 
                        if (!realpath(dir, real_path)) {
                            report_unresolved_path(dir);
                            break;
                        }
                        char *p = real_path;
                        while (*p) {
                            p++;
                        }
                        *(p++) = '/';
                        strncpy(p, file, sizeof real_path - (p - real_path));
                        *pfile_start = file_start; // restore file start char
                    }
                } else {
                    if (!realpath(path, real_path)) {
                       report_unresolved_path(path);
                       break; 
                    }
                }
                trace("\t\tadding %s with state '%c' (0x%x) -> %s\n", path, (char) new_state, (char) new_state, real_path);
                add_file_data(real_path, new_state);
                // send real path to local controller
                tail = add_file_to_list(tail, path, new_state, real_path);
                //trace("\t\tadded to list %s with state '%c' (0x%x) -> %s\n", tail->filename, tail->state, tail->state, tail->real_path);
                if (list == NULL) {
                    list = tail;
                }
            } else {
                report_error("protocol error: %s is not absoulte\n", path);
                break;
            }
        }
    }
    stop_adding_file_data();
    trace("Files list initialization done\n");
    if (success) {
        // send info about touched files which were passed as copied files
        tail = list;
        while (tail != NULL) {
            fprintf(stdout, "*%c%s\n%s\n", tail->state, tail->filename, tail->real_path);
            fflush(stdout);
            tail = tail->next;
        }
        free_file_list(list);
        // empty line as indication of finished files list
        fprintf(stdout, "\n");
        fflush(stdout);
    }
    return success;
}
Exemple #9
0
int main(int argc, char **argv)
{
  int arch = 32;
  magic_t magic;
  char dll_real_path[PATH_MAX];
  char wineprefix_real_path[PATH_MAX];

  if (argc != 3 && argc != 4) {
    fprintf(stderr, "usage: %s <vst.dll> <vst.so> [<wine-prefix>]\n", argv[0]);
    return 2;
  }

  int has_wineprefix = argc == 4;

  struct stat st_dll;
  if (stat(argv[1], &st_dll) ||
      !realpath(argv[1], dll_real_path)) {
    fprintf(stderr, "%s: %m\n", argv[1]);
    return 1;
  }

  struct stat st_tpl;
  if (stat(VST_BRIDGE_TPL_PATH, &st_tpl)) {
    fprintf(stderr, "%s: %m\n", VST_BRIDGE_TPL_PATH);
    return 1;
  }

  if (has_wineprefix) {
    struct stat st_wineprefix;

    if (stat(argv[3], &st_wineprefix) ||
        !realpath(argv[3], wineprefix_real_path)) {
      fprintf(stderr, "%s: %m\n", argv[3]);
      return 1;
    }

    if (!S_ISDIR(st_wineprefix.st_mode)) {
      fprintf(stderr, "%s: %s\n", argv[3], strerror(ENOTDIR));
      return 1;
    }
  }

  magic = magic_open(MAGIC_NONE);
  if (!magic)
    fprintf(stderr, "failed to initialize magic\n");
  else {
    magic_load(magic, NULL);
    if (strstr(magic_file(magic, dll_real_path), "80386"))
      arch = 32;
    else if (strstr(magic_file(magic, dll_real_path), "x86-64"))
      arch = 64;
    printf("detected %d bits dll\n", arch);
    magic_close(magic);
  }

  // copy file
  int fd_tpl = open(VST_BRIDGE_TPL_PATH, O_RDONLY, 0644);
  if (fd_tpl < 0) {
    fprintf(stderr, "%s: %m\n", VST_BRIDGE_TPL_PATH);
    return 1;
  }

  int fd_so = open(argv[2], O_CREAT | O_TRUNC | O_RDWR, 0755);
  if (fd_so < 0) {
    fprintf(stderr, "%s: %m\n", argv[2]);
    return 1;
  }

  if (fchmod(fd_so, 0755))
    fprintf(stderr, "chmod(%s, 0755): %m\n", argv[2]);

  if (sendfile(fd_so, fd_tpl, NULL, st_tpl.st_size) != st_tpl.st_size) {
    fprintf(stderr, "copy %s to %s: %m\n", VST_BRIDGE_TPL_PATH, argv[2]);
    return 1;
  }

  close(fd_tpl);

  void *mem_so = mmap(NULL, st_tpl.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
                      fd_so, 0);
  if (mem_so == MAP_FAILED) {
    fprintf(stderr, "mmap(%s): %m\n", argv[2]);
    return 1;
  }

  replace_magic(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_DLL, dll_real_path);
  replace_magic(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_HOST, arch == 32 ? VST_BRIDGE_HOST32_PATH : VST_BRIDGE_HOST64_PATH);
  if (has_wineprefix)
    replace_magic(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_WINEPREFIX, wineprefix_real_path);

  munmap(mem_so, st_tpl.st_size);

  close(fd_so);

  return 0;
}
Exemple #10
0
int main(int argc, char *argv[]) {

	int n;
	extern char *optarg;		/* for getopt */
	extern int optind, opterr;	/* for getopt */

	option_l = 0;
	option_a = 0;
	
	while((n = getopt(argc, argv, "la")) != -1) {
		switch(n) {
		case 'l':
			option_l = 1;
			break;
		case 'a':
			option_a = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	struct list list;
	list.head = NULL;
	list.size = 0;
	int num;
	for(num = 0; num < argc; num++) {
		appendbypath(&list, argv[num], 1023);
	}

	int iterator = 0;
	struct node *node;
	DIR *dir;
	struct dirent *dirent;
	// check file type and print.
	while( (node = getnode_ite(&list, &iterator)) != NULL) {
		if(lstat(node->path, node->buf) != 0) {
			perror("lstat");
		}
		if(S_ISDIR(node->buf->st_mode)) {	// dir
			//if(strncmp(dirent->d_name, "/", 1)) {
			fprintf(stdout, "%s:\n", node->path);
			dir = opendir(node->path);
			struct stat *buf;
			buf = malloc(sizeof(struct stat));
			while( (dirent = readdir(dir)) != NULL) {
				memset(buf, 0, sizeof(buf));
				if(option_l == 1) {
					char path[1024];
					memcpy(path, node->path, strlen(node->path));
			fprintf(stdout, "%s:%d:%d\n", path, strlen(path), strlen(node->path));
			fprintf(stdout, "%s\n", path[1]);
					if(strncmp(&path[strlen(node->path) - 1], "/", 1)) {
						strcat(path, "/");
					}
					strcat(path, dirent->d_name);
					if(lstat(path, buf) != 0) 
						perror("lstat");
					print_fileinfo(dirent->d_name, *buf, option_a);
				} else {
					fprintf(stdout, "%s\n", dirent->d_name);	
				}
			}
			closedir(dir);
		} else if(S_ISLNK(node->buf->st_mode)) {	//symbolic link
			if(option_a != 1 && !strncmp(dirent->d_name, ".", 1)) {
			} else {
				char *rpath;
				rpath = realpath(node->path, NULL);
				char time[25];
				struct passwd *pw;
				// get username by passwd
				pw = getpwuid(node->buf->st_uid);
				fprintf(stdout, "%o\t%d\t%s\t%d\t%d", 
						node->buf->st_mode, node->buf->st_nlink, pw->pw_name, 
						node->buf->st_gid, node->buf->st_size
					);
				memcpy(time, (char *)ctime(&node->buf->st_mtime), 24);
				fprintf(stdout, "\t%s\t%s -> %s\n", time, node->path, rpath);

				free(rpath);
			}
		} else {	//regular file
			if(option_l == 1) {
				char time[25];
				struct passwd *pw;
				// get username by passwd
				pw = getpwuid(node->buf->st_uid);
				fprintf(stdout, "%o\t%d\t%s\t%d\t%d", 
						node->buf->st_mode, node->buf->st_nlink, pw->pw_name, 
						node->buf->st_gid, node->buf->st_size
					);
				memcpy(time, (char *)ctime(&node->buf->st_mtime), 24);
				fprintf(stdout, "\t%s\t%s\n", time, node->path);
			} else {
				fprintf(stdout, "%s\n", node->path);	
			}
		}
		fprintf(stdout, "\n");
	}

	return 0;
}
Exemple #11
0
/* paths_setup
** Modify the lua path and cpath, prepending standard directories
** relative to this executable.
*/
static void paths_setup(lua_State *L, char *app) {
	char *temp, *binpath, *path;
	
	temp = malloc(PATH_MAX+1);
	if (!temp) {
		l_message("Error", "malloc failure for temp");
		exit(-1);
	}
	binpath = malloc(PATH_MAX+1);
	if (!binpath) {
		l_message("Error", "malloc failure for binpath");
		exit(-1);
	}
	path = malloc(PATH_MAX+1);
	if (!path) {
		l_message("Error", "malloc failure for path");
		exit(-1);
	}

	// full path to jive binary
	if (app[0] == '/') {
		// we were called with a full path
		strcpy(path, app);
	}
	else {
		// add working dir + app and resolve
		getcwd(temp, PATH_MAX+1);
		strcat(temp, "/");       
		strcat(temp, app);
		realpath(temp, path);
	}

	// directory containing jive
	strcpy(binpath, dirname(path));

	// set paths in lua (package.path & package cpath)
	lua_getglobal(L, "package");
	if (lua_istable(L, -1)) {
		luaL_Buffer b;
		luaL_buffinit(L, &b);

		// default lua path
		lua_getfield(L, -1, "path");
		luaL_addvalue(&b);
		luaL_addstring(&b, ";");

		// lua path relative to executable
#if !defined(WIN32)
		strcpy(temp, binpath);
		strcat(temp, "/../share/lua/5.1");
		realpath(temp, path);
#endif

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?.lua;");
		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?" DIR_SEPARATOR_STR "?.lua;");

		// script path relative to executale
		strcpy(temp, binpath);
		strcat(temp, "/" LUA_DEFAULT_PATH);
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?.lua;");
		
		// set lua path
		luaL_pushresult(&b);
		lua_setfield(L, -2, "path");

		luaL_buffinit(L, &b);

		// default lua cpath
		lua_getfield(L, -1, "cpath");
		luaL_addvalue(&b);
		luaL_addstring(&b, ";");

		// lua cpath
#if !defined(WIN32)
		strcpy(temp, binpath);
		strcat(temp, "/../lib/lua/5.1");
		realpath(temp, path);
#endif

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?." LIBRARY_EXT ";");
		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?" DIR_SEPARATOR_STR "core." LIBRARY_EXT ";");

		// cpath relative to executable
		strcpy(temp, binpath);
		strcat(temp, "/" LUA_DEFAULT_PATH);
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?." LIBRARY_EXT ";");

		// set lua cpath
		luaL_pushresult(&b);

		lua_setfield(L, -2, "cpath");
	}
	else {
		l_message("Error", "'package' is not a table");
	}

	// pop package table off the stack
	lua_pop(L, 1); 

	free(temp);
	free(binpath);
	free(path);
}
Exemple #12
0
/*=export_func  optionMakePath
 * private:
 *
 * what:  translate and construct a path
 * arg:   + char*       + pzBuf      + The result buffer +
 * arg:   + int         + bufSize    + The size of this buffer +
 * arg:   + char const* + pzName     + The input name +
 * arg:   + char const* + pzProgPath + The full path of the current program +
 *
 * ret-type: ag_bool
 * ret-desc: AG_TRUE if the name was handled, otherwise AG_FALSE.
 *           If the name does not start with ``$'', then it is handled
 *           simply by copying the input name to the output buffer and
 *           resolving the name with either
 *           @code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}.
 *
 * doc:
 *
 *  This routine will copy the @code{pzName} input name into the @code{pzBuf}
 *  output buffer, carefully not exceeding @code{bufSize} bytes.  If the
 *  first character of the input name is a @code{'$'} character, then there
 *  is special handling:
 *  @*
 *  @code{$$} is replaced with the directory name of the @code{pzProgPath},
 *  searching @code{$PATH} if necessary.
 *  @*
 *  @code{$@} is replaced with the AutoGen package data installation directory
 *  (aka @code{pkgdatadir}).
 *  @*
 *  @code{$NAME} is replaced by the contents of the @code{NAME} environment
 *  variable.  If not found, the search fails.
 *
 *  Please note: both @code{$$} and @code{$NAME} must be at the start of the
 *     @code{pzName} string and must either be the entire string or be followed
 *     by the @code{'/'} (backslash on windows) character.
 *
 * err:  @code{AG_FALSE} is returned if:
 *       @*
 *       @bullet{} The input name exceeds @code{bufSize} bytes.
 *       @*
 *       @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string
 *                 and the next character is not '/'.
 *       @*
 *       @bullet{} libopts was built without PKGDATADIR defined and @code{$@@}
 *                 was specified.
 *       @*
 *       @bullet{} @code{NAME} is not a known environment variable
 *       @*
 *       @bullet{} @code{canonicalize_file_name} or @code{realpath} return
 *                 errors (cannot resolve the resulting path).
=*/
ag_bool
optionMakePath(
    char*   pzBuf,
    size_t  bufSize,
    tCC*    pzName,
    tCC*    pzProgPath )
{
    size_t  name_len = strlen( pzName );

#   ifndef PKGDATADIR
#     define PKGDATADIR ""
#   endif

    tSCC    pkgdatadir[] = PKGDATADIR;

    ag_bool res = AG_TRUE;

    if (bufSize <= name_len)
        return AG_FALSE;

    /*
     *  IF not an environment variable, just copy the data
     */
    if (*pzName != '$') {
        tCC*  pzS = pzName;
        char* pzD = pzBuf;
        int   ct  = bufSize;

        for (;;) {
            if ( (*(pzD++) = *(pzS++)) == NUL)
                break;
            if (--ct <= 0)
                return AG_FALSE;
        }
    }

    /*
     *  IF the name starts with "$$", then it must be "$$" or
     *  it must start with "$$/".  In either event, replace the "$$"
     *  with the path to the executable and append a "/" character.
     */
    else switch (pzName[1]) {
    case NUL:
        return AG_FALSE;

    case '$':
        res = insertProgramPath( pzBuf, bufSize, pzName, pzProgPath );
        break;

    case '@':
        if (pkgdatadir[0] == NUL)
            return AG_FALSE;

        if (name_len + sizeof (pkgdatadir) > bufSize)
            return AG_FALSE;

        strcpy(pzBuf, pkgdatadir);
        strcpy(pzBuf + sizeof(pkgdatadir) - 1, pzName + 2);
        break;

    default:
        res = insertEnvVal( pzBuf, bufSize, pzName, pzProgPath );
    }

    if (! res)
        return AG_FALSE;

#if defined(HAVE_CANONICALIZE_FILE_NAME)
    {
        char* pz = canonicalize_file_name(pzBuf);
        if (pz == NULL)
            return AG_FALSE;
        if (strlen(pz) < bufSize)
            strcpy(pzBuf, pz);
        free(pz);
    }

#elif defined(HAVE_REALPATH)
    {
        char z[ PATH_MAX+1 ];

        if (realpath( pzBuf, z ) == NULL)
            return AG_FALSE;

        if (strlen(z) < bufSize)
            strcpy( pzBuf, z );
    }
#endif

    return AG_TRUE;
}
Exemple #13
0
static void doSyslogd(void)
{
	struct sockaddr_un sunx;
	socklen_t addrLength;

	int sock_fd;
	fd_set fds;

	/* Set up signal handlers. */
	signal(SIGINT, quit_signal);
	signal(SIGTERM, quit_signal);
	signal(SIGQUIT, quit_signal);
	signal(SIGHUP, SIG_IGN);
	signal(SIGCHLD, SIG_IGN);
#ifdef SIGCLD
	signal(SIGCLD, SIG_IGN);
#endif
	signal(SIGALRM, domark);
	alarm(MarkInterval);

	/* Create the syslog file so realpath() can work. */
	if (realpath(_PATH_LOG, lfile) != NULL) {
		unlink(lfile);
	}

	memset(&sunx, 0, sizeof(sunx));
	sunx.sun_family = AF_UNIX;
	strncpy(sunx.sun_path, lfile, sizeof(sunx.sun_path));
	if ((sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
		bb_perror_msg_and_die("Couldn't get file descriptor for socket "
						   _PATH_LOG);
	}

	addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
	if (bind(sock_fd, (struct sockaddr *) &sunx, addrLength) < 0) {
		bb_perror_msg_and_die("Could not connect to socket " _PATH_LOG);
	}

	if (chmod(lfile, 0666) < 0) {
		bb_perror_msg_and_die("Could not set permission on " _PATH_LOG);
	}
#ifdef CONFIG_FEATURE_IPC_SYSLOG
	if (circular_logging == TRUE) {
		ipcsyslog_init();
	}
#endif

#ifdef CONFIG_FEATURE_REMOTE_LOG
	if (doRemoteLog == TRUE) {
		init_RemoteLog();
	}
#endif

	logMessage(LOG_SYSLOG | LOG_INFO, "syslogd started: " BB_BANNER);

	for (;;) {

		FD_ZERO(&fds);
		FD_SET(sock_fd, &fds);

		if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
			if (errno == EINTR) {
				/* alarm may have happened. */
				continue;
			}
			bb_perror_msg_and_die("select error");
		}

		if (FD_ISSET(sock_fd, &fds)) {
			int i;
#if MAXLINE > BUFSIZ
# define TMP_BUF_SZ BUFSIZ
#else
# define TMP_BUF_SZ MAXLINE
#endif
#define tmpbuf bb_common_bufsiz1

			if ((i = recv(sock_fd, tmpbuf, TMP_BUF_SZ, 0)) > 0) {
				tmpbuf[i] = '\0';
				serveConnection(tmpbuf, i);
			} else {
				bb_perror_msg_and_die("UNIX socket error");
			}
		}				/* FD_ISSET() */
	}					/* for main loop */
}
Exemple #14
0
int main( int argc, char *argv[] )
{
	int i ;
	int ret ;

	Alignments alignments ;
	Alignments clippedAlignments ;
	Blocks blocks ;
	Genome genome ;
	char *genomeFile = NULL ;
	
	if ( argc < 2 )
	{
		printf( "%s", usage ) ;
		exit( 0 ) ;
	}

	minimumSupport = 2 ;
	minimumEffectiveLength = 200 ;
	kmerSize = 23 ;
	breakN = 1 ;
	minContigSize = 200 ;
	prefix = NULL ;
	VERBOSE = false ;
	outputConnectionSequence = false ;
	aggressiveMode = false ;

	for ( i = 1 ; i < argc ; ++i )
	{
		if ( !strcmp( "-b", argv[i] ) )
		{
			alignments.Open( argv[i + 1]) ;
			++i ;
		}
		else if ( !strcmp( "-o", argv[i] ) )
		{
			prefix = argv[i + 1] ;
			++i ;
		}
		else if ( !strcmp( "-f", argv[i] ) )
		{
			genomeFile = argv[i + 1] ;
			++i ;
		}
		else if ( !strcmp( "-ms", argv[i] ) )
		{
			minimumSupport = atoi( argv[i + 1] ) ;
			++i ;
		}
		else if ( !strcmp( "-ml", argv[i] ) )
		{
			minimumEffectiveLength = atoi( argv[i + 1] ) ;
			++i ;
		}
		else if ( !strcmp( "-k", argv[i] ) )
		{
			kmerSize = atoi( argv[i + 1] ) ;
			++i ;
		}
		else if ( !strcmp( "-breakN", argv[i] ) )
		{
			breakN = atoi( argv[i + 1] ) ;
			++i ;
		}
		else if ( !strcmp( "-minContigSize", argv[i] ) )
		{
			minContigSize = atoi( argv[i + 1] ) ;
			++i ;
		}
		else if ( !strcmp( "-v", argv[i] ) )
		{
			VERBOSE = true ;
		}
		else if ( !strcmp( "-cs", argv[i] ) )
		{
			outputConnectionSequence = true ;
		}
		/*else if ( !strcmp( "-aggressive", argv[i] ) )
		{
			aggressiveMode = true ;
		}*/
		else if ( !strcmp( "-bc", argv[i] ) )
		{
			// So far, assume the input is from BWA mem
			clippedAlignments.Open( argv[i + 1] ) ;
			clippedAlignments.SetAllowSupplementary( true ) ;
			++i ;
		}
		else
		{
			fprintf( stderr, "Unknown parameter: %s\n", argv[i] ) ;
			exit( 1 ) ;
		}
	}

	if ( !alignments.IsOpened() )
	{
		printf( "Must use -b to specify the bam file." ) ;
		return 0 ;
	}

	if ( prefix != NULL )
	{
		char buffer[255] ;
		sprintf( buffer, "%s.out", prefix ) ;
		fpOut = fopen( buffer, "w" ) ;
	}
	else
	{
		char buffer[255] ;
		prefix = strdup( "rascaf" ) ;
		sprintf( buffer, "%s.out", prefix ) ;
		fpOut = fopen( buffer, "w" ) ;
	}
	
	if ( genomeFile != NULL )
	{
		genome.Open( alignments, genomeFile ) ;
		alignments.Rewind() ;
	}

	if ( outputConnectionSequence == true && genomeFile == NULL )
	{
		fprintf( stderr, "Must use -f to specify assembly file when using -cs\n" ) ;	
		exit( EXIT_FAILURE ) ;
	}
	// 74619
	//printf( "%c\n", genome.GetNucleotide( 74619, 4 ) ) ;
	//exit(0) ;
	// Build the graph
	ret = blocks.BuildExonBlocks( alignments, genome ) ;
	alignments.Rewind() ;
	fprintf( stderr, "Found %d exon blocks.\n", ret ) ;
	if ( clippedAlignments.IsOpened() )
	{
		fprintf( stderr, "Extend exon blocks with clipped alignments.\n" ) ;
		Blocks extendBlocks ;
		extendBlocks.BuildExonBlocks( clippedAlignments, genome ) ;
		clippedAlignments.Rewind() ;

		ret = blocks.ExtendExonBlocks( extendBlocks ) ;
		fprintf( stderr, "Found %d exon blocks after extension.\n", ret ) ;
	}

	blocks.GetAlignmentsInfo( alignments ) ;
	alignments.Rewind() ;

	ret = blocks.BuildGeneBlocks( alignments, genome ) ;
	alignments.Rewind() ;
	fprintf( stderr, "Found %d gene blocks.\n", ret ) ;
	
	blocks.BuildGeneBlockGraph( alignments ) ;
	if ( clippedAlignments.IsOpened() )
	{
		blocks.AddGeneBlockGraphByClippedAlignments( clippedAlignments ) ; 
	}
	
	// Cleaning
	blocks.CleanGeneBlockGraph( alignments, genome ) ;

	// Scaffolding
	Scaffold scaffold( blocks, genome ) ;
	//scaffold.Init( blocks ) ;
	int componentCnt = scaffold.BuildComponent() ;
	fprintf( stderr, "Found %d non-trivial gene block components.\n", componentCnt ) ;
	// Possible for parallelization
	for ( i = 0 ; i < componentCnt ; ++i )
	{
		scaffold.ScaffoldComponent( i ) ;
	}
	
	scaffold.ScaffoldGenome() ;
	
	// Output the command line
	fprintf( fpOut, "command line: " ) ;
	char *fullpath = (char *)malloc( sizeof( char ) * 4096 ) ;
	for ( i = 0 ; i < argc ; ++i )
	{
		char c = ' ' ;
		if ( i == argc - 1 )
			c = '\n' ;
		if ( i > 0 && !strcmp( argv[i - 1], "-b" ) )
		{
			if ( realpath( argv[i], fullpath ) == NULL )
			{
				fprintf( stderr, "Failed to resolve the path of file %s.\n", argv[i] ) ;
				exit( 1 ) ;
			}
			fprintf( fpOut, "%s%c", fullpath, c ) ;
		}
		else if ( i > 0 && !strcmp( argv[i - 1], "-f" ) )
		{
			if ( realpath( argv[i], fullpath ) == NULL )
			{
				fprintf( stderr, "Failed to resolve the path of file %s.\n", argv[i] ) ;
				exit( 1 ) ;
			}
			fprintf( fpOut, "%s%c", fullpath, c ) ;
		}
		else
			fprintf( fpOut, "%s%c", argv[i], c ) ;
	}
	free( fullpath ) ;
	scaffold.Output( fpOut, alignments ) ;
	return 0 ;
}
Exemple #15
0
/*-
 * main --
 *	The main function, for obvious reasons. Initializes variables
 *	and a few modules, then parses the arguments give it in the
 *	environment and on the command line. Reads the system makefile
 *	followed by either Makefile, makefile or the file given by the
 *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
 *	flags it has received by then uses either the Make or the Compat
 *	module to create the initial list of targets.
 *
 * Results:
 *	If -q was given, exits -1 if anything was out-of-date. Else it exits
 *	0.
 *
 * Side Effects:
 *	The program exits when done. Targets are created. etc. etc. etc.
 */
int
main(int argc, char **argv)
{
	Lst targs;	/* target nodes to create -- passed to Make_Init */
	Boolean outOfDate = FALSE; 	/* FALSE if all targets up to date */
	struct stat sb, sa;
	char *p1, *path, *pwd;
	char mdpath[MAXPATHLEN];
#ifdef FORCE_MACHINE
	const char *machine = FORCE_MACHINE;
#else
    	const char *machine = getenv("MACHINE");
#endif
	const char *machine_arch = getenv("MACHINE_ARCH");
	char *syspath = getenv("MAKESYSPATH");
	Lst sysMkPath;			/* Path of sys.mk */
	char *cp = NULL, *start;
					/* avoid faults on read-only strings */
	static char defsyspath[] = _PATH_DEFSYSPATH;
	char found_path[MAXPATHLEN + 1];	/* for searching for sys.mk */
	struct timeval rightnow;		/* to initialize random seed */
	struct utsname utsname;

	/* default to writing debug to stderr */
	debug_file = stderr;

#ifdef SIGINFO
	(void)bmake_signal(SIGINFO, siginfo);
#endif
	/*
	 * Set the seed to produce a different random sequence
	 * on each program execution.
	 */
	gettimeofday(&rightnow, NULL);
	srandom(rightnow.tv_sec + rightnow.tv_usec);
	
	if ((progname = strrchr(argv[0], '/')) != NULL)
		progname++;
	else
		progname = argv[0];
#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
	/*
	 * get rid of resource limit on file descriptors
	 */
	{
		struct rlimit rl;
		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
		    rl.rlim_cur != rl.rlim_max) {
			rl.rlim_cur = rl.rlim_max;
			(void)setrlimit(RLIMIT_NOFILE, &rl);
		}
	}
#endif

	if (uname(&utsname) == -1) {
	    (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
		strerror(errno));
	    exit(2);
	}

	/*
	 * Get the name of this type of MACHINE from utsname
	 * so we can share an executable for similar machines.
	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
	 *
	 * Note that both MACHINE and MACHINE_ARCH are decided at
	 * run-time.
	 */
	if (!machine) {
#ifdef MAKE_NATIVE
	    machine = utsname.machine;
#else
#ifdef MAKE_MACHINE
	    machine = MAKE_MACHINE;
#else
	    machine = "unknown";
#endif
#endif
	}

	if (!machine_arch) {
#ifndef MACHINE_ARCH
#ifdef MAKE_MACHINE_ARCH
            machine_arch = MAKE_MACHINE_ARCH;
#else
	    machine_arch = "unknown";
#endif
#else
	    machine_arch = MACHINE_ARCH;
#endif
	}

	myPid = getpid();		/* remember this for vFork() */

	/*
	 * Just in case MAKEOBJDIR wants us to do something tricky.
	 */
	Var_Init();		/* Initialize the lists of variables for
				 * parsing arguments */
	Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0);
	Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
#ifdef MAKE_VERSION
	Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
#endif
	Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
	/*
	 * This is the traditional preference for makefiles.
	 */
#ifndef MAKEFILE_PREFERENCE_LIST
# define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
#endif
	Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
		VAR_GLOBAL, 0);
	Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0);

	create = Lst_Init(FALSE);
	makefiles = Lst_Init(FALSE);
	printVars = FALSE;
	debugVflag = FALSE;
	variables = Lst_Init(FALSE);
	beSilent = FALSE;		/* Print commands as executed */
	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
	noExecute = FALSE;		/* Execute all commands */
	noRecursiveExecute = FALSE;	/* Execute all .MAKE targets */
	keepgoing = FALSE;		/* Stop on error */
	allPrecious = FALSE;		/* Remove targets when interrupted */
	queryFlag = FALSE;		/* This is not just a check-run */
	noBuiltins = FALSE;		/* Read the built-in rules */
	touchFlag = FALSE;		/* Actually update targets */
	debug = 0;			/* No debug verbosity, please. */
	jobsRunning = FALSE;

	maxJobs = DEFMAXLOCAL;		/* Set default local max concurrency */
	maxJobTokens = maxJobs;
	compatMake = FALSE;		/* No compat mode */
	ignorePWD = FALSE;

	/*
	 * Initialize the parsing, directory and variable modules to prepare
	 * for the reading of inclusion paths and variable settings on the
	 * command line
	 */

	/*
	 * Initialize various variables.
	 *	MAKE also gets this name, for compatibility
	 *	.MAKEFLAGS gets set to the empty string just in case.
	 *	MFLAGS also gets initialized empty, for compatibility.
	 */
	Parse_Init();
	if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) {
	    /*
	     * Leave alone if it is an absolute path, or if it does
	     * not contain a '/' in which case we need to find it in
	     * the path, like execvp(3) and the shells do.
	     */
	    p1 = argv[0];
	} else {
	    /*
	     * A relative path, canonicalize it.
	     */
	    p1 = realpath(argv[0], mdpath);
	    if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
		p1 = argv[0];		/* realpath failed */
	    }
	}
	Var_Set("MAKE", p1, VAR_GLOBAL, 0);
	Var_Set(".MAKE", p1, VAR_GLOBAL, 0);
	Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
	Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
	Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
	Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);

	/*
	 * Set some other useful macros
	 */
	{
	    char tmp[64];
	    const char *ep;

	    if (!(ep = getenv(MAKE_LEVEL))) {
#ifdef MAKE_LEVEL_SAFE
		if (!(ep = getenv(MAKE_LEVEL_SAFE)))
#endif
		    ep = "0";
	    }
	    Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
	    snprintf(tmp, sizeof(tmp), "%u", myPid);
	    Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
	    snprintf(tmp, sizeof(tmp), "%u", getppid());
	    Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
	}
	Job_SetPrefix();

#ifdef USE_META
	meta_init();
#endif
	/*
	 * First snag any flags out of the MAKE environment variable.
	 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
	 * in a different format).
	 */
#ifdef POSIX
	Main_ParseArgLine(getenv("MAKEFLAGS"));
#else
	Main_ParseArgLine(getenv("MAKE"));
#endif

	/*
	 * Find where we are (now).
	 * We take care of PWD for the automounter below...
	 */
	if (getcwd(curdir, MAXPATHLEN) == NULL) {
		(void)fprintf(stderr, "%s: getcwd: %s.\n",
		    progname, strerror(errno));
		exit(2);
	}

	MainParseArgs(argc, argv);

	/*
	 * Verify that cwd is sane.
	 */
	if (stat(curdir, &sa) == -1) {
	    (void)fprintf(stderr, "%s: %s: %s.\n",
		 progname, curdir, strerror(errno));
	    exit(2);
	}

	/*
	 * All this code is so that we know where we are when we start up
	 * on a different machine with pmake.
	 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
	 * since the value of curdir can vary depending on how we got
	 * here.  Ie sitting at a shell prompt (shell that provides $PWD)
	 * or via subdir.mk in which case its likely a shell which does
	 * not provide it.
	 * So, to stop it breaking this case only, we ignore PWD if
	 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
	 */
#ifndef NO_PWD_OVERRIDE
	if (!ignorePWD &&
	    (pwd = getenv("PWD")) != NULL &&
	    getenv("MAKEOBJDIRPREFIX") == NULL) {
		const char *makeobjdir = getenv("MAKEOBJDIR");

		if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
			if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
			    sa.st_dev == sb.st_dev)
				(void)strncpy(curdir, pwd, MAXPATHLEN);
		}
	}
#endif
	Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);

	/*
	 * Find the .OBJDIR.  If MAKEOBJDIRPREFIX, or failing that,
	 * MAKEOBJDIR is set in the environment, try only that value
	 * and fall back to .CURDIR if it does not exist.
	 *
	 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
	 * finally _PATH_OBJDIRPREFIX`pwd`, in that order.  If none
	 * of these paths exist, just use .CURDIR.
	 */
	Dir_Init(curdir);
	(void)Main_SetObjdir(curdir);

	if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
		(void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
		(void)Main_SetObjdir(mdpath);
	} else if ((path = getenv("MAKEOBJDIR")) != NULL) {
		(void)Main_SetObjdir(path);
	} else {
		(void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
		if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
			(void)snprintf(mdpath, MAXPATHLEN, "%s%s", 
					_PATH_OBJDIRPREFIX, curdir);
			(void)Main_SetObjdir(mdpath);
		}
	}

	/*
	 * Be compatible if user did not specify -j and did not explicitly
	 * turned compatibility on
	 */
	if (!compatMake && !forceJobs) {
		compatMake = TRUE;
	}
	
	/*
	 * Initialize archive, target and suffix modules in preparation for
	 * parsing the makefile(s)
	 */
	Arch_Init();
	Targ_Init();
	Suff_Init();
	Trace_Init(tracefile);

	DEFAULT = NULL;
	(void)time(&now);

	Trace_Log(MAKESTART, NULL);
	
	/*
	 * Set up the .TARGETS variable to contain the list of targets to be
	 * created. If none specified, make the variable empty -- the parser
	 * will fill the thing in with the default or .MAIN target.
	 */
	if (!Lst_IsEmpty(create)) {
		LstNode ln;

		for (ln = Lst_First(create); ln != NULL;
		    ln = Lst_Succ(ln)) {
			char *name = (char *)Lst_Datum(ln);

			Var_Append(".TARGETS", name, VAR_GLOBAL);
		}
	} else
		Var_Set(".TARGETS", "", VAR_GLOBAL, 0);


	/*
	 * If no user-supplied system path was given (through the -m option)
	 * add the directories from the DEFSYSPATH (more than one may be given
	 * as dir1:...:dirn) to the system include path.
	 */
	if (syspath == NULL || *syspath == '\0')
		syspath = defsyspath;
	else
		syspath = bmake_strdup(syspath);

	for (start = syspath; *start != '\0'; start = cp) {
		for (cp = start; *cp != '\0' && *cp != ':'; cp++)
			continue;
		if (*cp == ':') {
			*cp++ = '\0';
		}
		/* look for magic parent directory search string */
		if (strncmp(".../", start, 4) != 0) {
			(void)Dir_AddDir(defIncPath, start);
		} else {
			if (Dir_FindHereOrAbove(curdir, start+4, 
			    found_path, sizeof(found_path))) {
				(void)Dir_AddDir(defIncPath, found_path);
			}
		}
	}
	if (syspath != defsyspath)
		free(syspath);

	/*
	 * Read in the built-in rules first, followed by the specified
	 * makefile, if it was (makefile != NULL), or the default
	 * makefile and Makefile, in that order, if it wasn't.
	 */
	if (!noBuiltins) {
		LstNode ln;

		sysMkPath = Lst_Init(FALSE);
		Dir_Expand(_PATH_DEFSYSMK,
			   Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
			   sysMkPath);
		if (Lst_IsEmpty(sysMkPath))
			Fatal("%s: no system rules (%s).", progname,
			    _PATH_DEFSYSMK);
		ln = Lst_Find(sysMkPath, NULL, ReadMakefile);
		if (ln == NULL)
			Fatal("%s: cannot open %s.", progname,
			    (char *)Lst_Datum(ln));
	}

	if (!Lst_IsEmpty(makefiles)) {
		LstNode ln;

		ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
		if (ln != NULL)
			Fatal("%s: cannot open %s.", progname, 
			    (char *)Lst_Datum(ln));
	} else {
	    p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
		VAR_CMD, 0);
	    if (p1) {
		(void)str2Lst_Append(makefiles, p1, NULL);
		(void)Lst_Find(makefiles, NULL, ReadMakefile);
		free(p1);
	    }
	}

	/* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
	if (!noBuiltins || !printVars) {
	    makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
		VAR_CMD, 0);
	    doing_depend = TRUE;
	    (void)ReadMakefile(makeDependfile, NULL);
	    doing_depend = FALSE;
	}

	MakeMode(NULL);

	Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
	if (p1)
	    free(p1);

	if (!compatMake)
	    Job_ServerStart(maxJobTokens, jp_0, jp_1);
	if (DEBUG(JOB))
	    fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
		jp_0, jp_1, maxJobs, maxJobTokens, compatMake);

	Main_ExportMAKEFLAGS(TRUE);	/* initial export */

	/*
	 * For compatibility, look at the directories in the VPATH variable
	 * and add them to the search path, if the variable is defined. The
	 * variable's value is in the same format as the PATH envariable, i.e.
	 * <directory>:<directory>:<directory>...
	 */
	if (Var_Exists("VPATH", VAR_CMD)) {
		char *vpath, savec;
		/*
		 * GCC stores string constants in read-only memory, but
		 * Var_Subst will want to write this thing, so store it
		 * in an array
		 */
		static char VPATH[] = "${VPATH}";

		vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
		path = vpath;
		do {
			/* skip to end of directory */
			for (cp = path; *cp != ':' && *cp != '\0'; cp++)
				continue;
			/* Save terminator character so know when to stop */
			savec = *cp;
			*cp = '\0';
			/* Add directory to search path */
			(void)Dir_AddDir(dirSearchPath, path);
			*cp = savec;
			path = cp + 1;
		} while (savec == ':');
		free(vpath);
	}

	/*
	 * Now that all search paths have been read for suffixes et al, it's
	 * time to add the default search path to their lists...
	 */
	Suff_DoPaths();

	/*
	 * Propagate attributes through :: dependency lists.
	 */
	Targ_Propagate();

	/* print the initial graph, if the user requested it */
	if (DEBUG(GRAPH1))
		Targ_PrintGraph(1);

	/* print the values of any variables requested by the user */
	if (printVars) {
		LstNode ln;
		Boolean expandVars;

		if (debugVflag)
			expandVars = FALSE;
		else
			expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
		for (ln = Lst_First(variables); ln != NULL;
		    ln = Lst_Succ(ln)) {
			char *var = (char *)Lst_Datum(ln);
			char *value;
			
			if (strchr(var, '$')) {
				value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0);
			} else if (expandVars) {
				char tmp[128];
								
				if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp)))
					Fatal("%s: variable name too big: %s",
					      progname, var);
				value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
			} else {
				value = Var_Value(var, VAR_GLOBAL, &p1);
			}
			printf("%s\n", value ? value : "");
			if (p1)
				free(p1);
		}
	} else {
		/*
		 * Have now read the entire graph and need to make a list of
		 * targets to create. If none was given on the command line,
		 * we consult the parsing module to find the main target(s)
		 * to create.
		 */
		if (Lst_IsEmpty(create))
			targs = Parse_MainName();
		else
			targs = Targ_FindList(create, TARG_CREATE);

		if (!compatMake) {
			/*
			 * Initialize job module before traversing the graph
			 * now that any .BEGIN and .END targets have been read.
			 * This is done only if the -q flag wasn't given
			 * (to prevent the .BEGIN from being executed should
			 * it exist).
			 */
			if (!queryFlag) {
				Job_Init();
				jobsRunning = TRUE;
			}

			/* Traverse the graph, checking on all the targets */
			outOfDate = Make_Run(targs);
		} else {
			/*
			 * Compat_Init will take care of creating all the
			 * targets as well as initializing the module.
			 */
			Compat_Run(targs);
		}
	}

#ifdef CLEANUP
	Lst_Destroy(targs, NULL);
	Lst_Destroy(variables, NULL);
	Lst_Destroy(makefiles, NULL);
	Lst_Destroy(create, (FreeProc *)free);
#endif

	/* print the graph now it's been processed if the user requested it */
	if (DEBUG(GRAPH2))
		Targ_PrintGraph(2);

	Trace_Log(MAKEEND, 0);

	Suff_End();
        Targ_End();
	Arch_End();
	Var_End();
	Parse_End();
	Dir_End();
	Job_End();
	Trace_End();

	return outOfDate ? 1 : 0;
}
Exemple #16
0
int
main (int argc, char *argv[])
{
  inp_t input_params;
  mdl_t source_mdl;
  net_t network;
  int cell_index;

  int verbose = 1;
  char *input_file;

  /* Parse options and command line arguments. Diplay help
     message if no (or more than one) argument is given. */

    {
      int opt;

      static struct option longopts[] = {
          {"help", no_argument, NULL, 'h'},
          {"version", no_argument, NULL, 'V'},
          {"verbose", no_argument, NULL, 'v'},
          {"quiet", no_argument, NULL, 'q'},
          {0, 0, 0, 0}
      };

      while ((opt = getopt_long (argc, argv, "hVvq", longopts, NULL)) != -1)
        {
          switch (opt)
            {
            case 'h':
              usage ();
              return EXIT_SUCCESS;
              break;
            case 'V':
              version ();
              return EXIT_SUCCESS;
              break;
            case 'v':
              verbose = 2;
              break;
            case 'q':
              verbose = 0;
              break;
            default:
              usage ();
              return EXIT_FAILURE;
            }
        };
      argc -= optind;
      argv += optind;
      if (argc != 1)
        {
          usage ();
          return EXIT_FAILURE;
        }
      input_file = argv[0];
    }

  /* Read the input file */
  if( read_input_file_names (input_file, &input_params.files, verbose) != EXIT_SUCCESS )
    {
      return EXIT_FAILURE;
    }

  /* Read the chemical network file */
  if( read_network (input_params.files.chem_file, &network, verbose) != EXIT_SUCCESS )
    {
      return EXIT_FAILURE;
    }

  /* Read the input file */
  if( read_input (input_file, &input_params, &network, verbose) != EXIT_SUCCESS )
    {
      return EXIT_FAILURE;
    }

  /* Read the source model file */
  if( read_source (input_params.files.source_file, &source_mdl, &input_params,
               verbose) != EXIT_SUCCESS )
    {
      return EXIT_FAILURE;
    }

  // Hdf5 files, datatype and dataspace
  hid_t       fid, datatype, dataspace, dataset, tsDataset, tsDataspace,  speciesDataset, speciesDataspace, speciesType;
  datatype = H5Tcopy(H5T_NATIVE_DOUBLE);

  hsize_t     dimsf[ ROUTE_DATASET_RANK ]={  source_mdl.n_cells, source_mdl.ts.n_time_steps, input_params.output.n_output_species, N_OUTPUT_ROUTES };
  fid = H5Fcreate( "astrochem_output.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 
  dataspace = H5Screate_simple( ABUNDANCE_DATASET_RANK, dimsf, NULL);

  // Add Atributes
  hid_t simpleDataspace = H5Screate(H5S_SCALAR);
  hid_t attrType = H5Tcopy(H5T_C_S1);
  H5Tset_size ( attrType, MAX_CHAR_FILENAME );
  H5Tset_strpad(attrType,H5T_STR_NULLTERM);
  hid_t attrNetwork = H5Acreate( fid, "chem_file", attrType, simpleDataspace, H5P_DEFAULT, H5P_DEFAULT);
  H5Awrite( attrNetwork, attrType, realpath( input_params.files.chem_file, NULL ) );
  H5Aclose( attrNetwork );
  hid_t attrModel = H5Acreate( fid, "source_file", attrType, simpleDataspace, H5P_DEFAULT, H5P_DEFAULT);
  H5Awrite( attrModel, attrType, realpath( input_params.files.source_file, NULL ) );
  H5Aclose( attrModel );

  H5Tclose( attrType );
  H5Sclose( simpleDataspace );

  // Define chunk property
  hsize_t     chunk_dims[ ROUTE_DATASET_RANK ] = { 1, 1, input_params.output.n_output_species, N_OUTPUT_ROUTES };
  hid_t prop_id = H5Pcreate(H5P_DATASET_CREATE);
  H5Pset_chunk(prop_id, ABUNDANCE_DATASET_RANK , chunk_dims);

  // Create dataset
  dataset = H5Dcreate(fid, "Abundances", datatype, dataspace, H5P_DEFAULT, prop_id, H5P_DEFAULT);

  int i;
  hid_t dataspaceRoute, route_t_datatype, r_t_datatype, route_prop_id, routeGroup;
  hid_t routeDatasets[ input_params.output.n_output_species ];
  if (input_params.output.trace_routes)
    {

      // Create route dataspace
      dataspaceRoute = H5Screate_simple( ROUTE_DATASET_RANK, dimsf, NULL);

      // Create route datatype
      r_t_datatype = H5Tcreate (H5T_COMPOUND, sizeof(r_t));
      H5Tinsert( r_t_datatype, "reaction_number", HOFFSET(r_t, reaction_no ), H5T_NATIVE_INT);
      H5Tinsert( r_t_datatype, "reaction_rate", HOFFSET(r_t, rate), H5T_NATIVE_DOUBLE);

      route_t_datatype = H5Tcreate (H5T_COMPOUND, sizeof(rout_t));
      H5Tinsert( route_t_datatype, "formation_rate", HOFFSET(rout_t, formation ), r_t_datatype );
      H5Tinsert( route_t_datatype, "destruction_rate", HOFFSET(rout_t, destruction ), r_t_datatype );

      // Define route chunk property
      route_prop_id = H5Pcreate(H5P_DATASET_CREATE);
      H5Pset_chunk( route_prop_id, ROUTE_DATASET_RANK, chunk_dims);


      // Create each named route dataset
      routeGroup = H5Gcreate( fid, "Routes", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
      char routeName[6] = "route_";
      char tempName[ MAX_CHAR_SPECIES + sizeof( routeName ) ];
      for( i = 0; i < input_params.output.n_output_species ; i++ )
        {
          strcpy( tempName, routeName );
          strcat( tempName, network.species[input_params.output.output_species_idx[i]].name );
          routeDatasets[i] = H5Dcreate( routeGroup, tempName, route_t_datatype, dataspaceRoute, H5P_DEFAULT, route_prop_id, H5P_DEFAULT);
        }
    }
  // Timesteps and species
  hsize_t n_ts = source_mdl.ts.n_time_steps;
  hsize_t n_species =  input_params.output.n_output_species ;
  tsDataspace = H5Screate_simple( 1, &n_ts, NULL);
  speciesDataspace = H5Screate_simple( 1, &n_species, NULL);
  speciesType = H5Tcopy (H5T_C_S1);
  H5Tset_size (speciesType, MAX_CHAR_SPECIES );
  H5Tset_strpad(speciesType,H5T_STR_NULLTERM);

  // Create ts and species datasets
  tsDataset = H5Dcreate(fid, "TimeSteps", datatype, tsDataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  speciesDataset = H5Dcreate(fid, "Species", speciesType, speciesDataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  double* convTs = (double*) malloc( sizeof(double)* source_mdl.ts.n_time_steps );
  for( i=0; i< source_mdl.ts.n_time_steps; i++ )
    {
      convTs[i] = source_mdl.ts.time_steps[i] / CONST_MKSA_YEAR;
    }

  H5Dwrite( tsDataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, convTs );


  char speciesName [ input_params.output.n_output_species ][ MAX_CHAR_SPECIES ];
  for( i = 0; i < input_params.output.n_output_species ; i++ )
    {
      strcpy( speciesName[i], network.species[input_params.output.output_species_idx[i]].name );
    }

  H5Dwrite( speciesDataset, speciesType, H5S_ALL, H5S_ALL, H5P_DEFAULT, speciesName );

  free( convTs );
  H5Dclose( tsDataset );
  H5Dclose( speciesDataset );
  H5Tclose( speciesType );
  H5Sclose( tsDataspace );
  H5Sclose( speciesDataspace );


#ifdef HAVE_OPENMP
  /*Initialize lock*/
  omp_init_lock(&lock);


  /* Solve the ODE system for each cell. */
    {
#pragma omp parallel for schedule (dynamic, 1)
#endif
      for (cell_index = 0; cell_index < source_mdl.n_cells; cell_index++)
        {
          if (verbose >= 1)
            fprintf (stdout, "Computing abundances in cell %d...\n",
                     cell_index);
          if( full_solve ( fid, dataset, routeDatasets, dataspace, dataspaceRoute, datatype, route_t_datatype, cell_index, &input_params, source_mdl.mode,
                       &source_mdl.cell[cell_index], &network, &source_mdl.ts, verbose) != EXIT_SUCCESS )
            {
	      exit (EXIT_FAILURE);
            }
          if (verbose >= 1)
            fprintf (stdout, "Done with cell %d.\n", cell_index);
        }
#ifdef HAVE_OPENMP
    }


  /*Finished lock mechanism, destroy it*/
  omp_destroy_lock(&lock);
#endif

  /*
   * Close/release hdf5 resources.
   */
  if (input_params.output.trace_routes)
    {


      for( i = 0; i <  input_params.output.n_output_species ; i++ )
        {
          H5Dclose(routeDatasets[i] );
        }
      H5Sclose(dataspaceRoute);
      H5Gclose(routeGroup);
      H5Pclose(route_prop_id);
      H5Tclose(r_t_datatype);
      H5Tclose(route_t_datatype);
    }
  H5Dclose(dataset);
  H5Pclose(prop_id);
  H5Sclose(dataspace);
  H5Tclose(datatype);

  H5Fclose(fid);

  free_input (&input_params);
  free_mdl (&source_mdl);
  free_network (&network);
  return (EXIT_SUCCESS);
}
Exemple #17
0
int main(int argc, char **argv)
{
	struct alias *alias;
	bool nofork = false;
	char *port;
	int opt, ch;
	int cur_fd;
	int bound = 0;
#ifdef HAVE_TLS
	struct no_tls_redirect *no_tls_redirect;
	int n_tls = 0;
	const char *tls_key = NULL, *tls_crt = NULL;
#endif

	BUILD_BUG_ON(sizeof(uh_buf) < PATH_MAX);

	uh_dispatch_add(&cgi_dispatch);
	init_defaults_pre();
	signal(SIGPIPE, SIG_IGN);

	while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:p:qQ:Rr:Ss:T:t:U:u:Xx:y:")) != -1) {
		switch(ch) {
#ifdef HAVE_TLS
		case 'C':
			tls_crt = optarg;
			break;

		case 'K':
			tls_key = optarg;
			break;

		case 'q':
			conf.tls_redirect = 1;
			break;

		case 'Q':
			no_tls_redirect = calloc(1, sizeof(*no_tls_redirect));
			if (!no_tls_redirect) {
				fprintf(stderr, "Error: failed to allocate no_tls_redirect\n");
				exit(1);
			}
			no_tls_redirect->path = strdup(optarg);
			list_add(&no_tls_redirect->list, &conf.no_tls_redirect);
			break;

		case 's':
			n_tls++;
			/* fall through */
#else
		case 'C':
		case 'K':
		case 'q':
		case 'Q':
		case 's':
			fprintf(stderr, "uhttpd: TLS support not compiled, "
			                "ignoring -%c\n", ch);
			break;
#endif
		case 'p':
			optarg = strdup(optarg);
			bound += add_listener_arg(optarg, (ch == 's'));
			break;

		case 'h':
			if (!realpath(optarg, uh_buf)) {
				fprintf(stderr, "Error: Invalid directory %s: %s\n",
						optarg, strerror(errno));
				exit(1);
			}
			conf.docroot = strdup(uh_buf);
			break;

		case 'H':
			if (uh_handler_add(optarg)) {
				fprintf(stderr, "Error: Failed to load handler script %s\n",
					optarg);
				exit(1);
			}
			break;

		case 'E':
			if (optarg[0] != '/') {
				fprintf(stderr, "Error: Invalid error handler: %s\n",
						optarg);
				exit(1);
			}
			conf.error_handler = optarg;
			break;

		case 'I':
			if (optarg[0] == '/') {
				fprintf(stderr, "Error: Invalid index page: %s\n",
						optarg);
				exit(1);
			}
			uh_index_add(optarg);
			break;

		case 'S':
			conf.no_symlinks = 1;
			break;

		case 'D':
			conf.no_dirlists = 1;
			break;

		case 'R':
			conf.rfc1918_filter = 1;
			break;

		case 'n':
			conf.max_script_requests = atoi(optarg);
			break;

		case 'N':
			conf.max_connections = atoi(optarg);
			break;

		case 'x':
			fixup_prefix(optarg);
			conf.cgi_prefix = optarg;
			break;

		case 'y':
			alias = calloc(1, sizeof(*alias));
			if (!alias) {
				fprintf(stderr, "Error: failed to allocate alias\n");
				exit(1);
			}
			alias->alias = strdup(optarg);
			alias->path = strchr(alias->alias, '=');
			if (alias->path)
				*alias->path++ = 0;
			list_add(&alias->list, &conf.cgi_alias);
			break;

		case 'i':
			optarg = strdup(optarg);
			port = strchr(optarg, '=');
			if (optarg[0] != '.' || !port) {
				fprintf(stderr, "Error: Invalid interpreter: %s\n",
						optarg);
				exit(1);
			}

			*port++ = 0;
			uh_interpreter_add(optarg, port);
			break;

		case 't':
			conf.script_timeout = atoi(optarg);
			break;

		case 'T':
			conf.network_timeout = atoi(optarg);
			break;

		case 'k':
			conf.http_keepalive = atoi(optarg);
			break;

		case 'A':
			conf.tcp_keepalive = atoi(optarg);
			break;

		case 'f':
			nofork = 1;
			break;

		case 'd':
			optarg = strdup(optarg);
			port = alloca(strlen(optarg) + 1);
			if (!port)
				return -1;

			/* "decode" plus to space to retain compat */
			for (opt = 0; optarg[opt]; opt++)
				if (optarg[opt] == '+')
					optarg[opt] = ' ';

			/* opt now contains strlen(optarg) -- no need to re-scan */
			if (uh_urldecode(port, opt, optarg, opt) < 0) {
				fprintf(stderr, "uhttpd: invalid encoding\n");
				return -1;
			}

			printf("%s", port);
			return 0;
			break;

		/* basic auth realm */
		case 'r':
			conf.realm = optarg;
			break;

		/* md5 crypt */
		case 'm':
			printf("%s\n", crypt(optarg, "$1$"));
			return 0;
			break;

		/* config file */
		case 'c':
			conf.file = optarg;
			break;

#ifdef HAVE_LUA
		case 'l':
			conf.lua_prefix = optarg;
			break;

		case 'L':
			conf.lua_handler = optarg;
			break;
#else
		case 'l':
		case 'L':
			fprintf(stderr, "uhttpd: Lua support not compiled, "
			                "ignoring -%c\n", ch);
			break;
#endif
#ifdef HAVE_UBUS
		case 'a':
			conf.ubus_noauth = 1;
			break;

		case 'u':
			conf.ubus_prefix = optarg;
			break;

		case 'U':
			conf.ubus_socket = optarg;
			break;

		case 'X':
			conf.ubus_cors = 1;
			break;
#else
		case 'a':
		case 'u':
		case 'U':
		case 'X':
			fprintf(stderr, "uhttpd: UBUS support not compiled, "
			                "ignoring -%c\n", ch);
			break;
#endif
		default:
			return usage(argv[0]);
		}
	}

	uh_config_parse();

	if (!conf.docroot) {
		if (!realpath(".", uh_buf)) {
			fprintf(stderr, "Error: Unable to determine work dir\n");
			return 1;
		}
		conf.docroot = strdup(uh_buf);
	}

	init_defaults_post();

	if (!bound) {
		fprintf(stderr, "Error: No sockets bound, unable to continue\n");
		return 1;
	}

#ifdef HAVE_TLS
	if (n_tls) {
		if (!tls_crt || !tls_key) {
			fprintf(stderr, "Please specify a certificate and "
					"a key file to enable SSL support\n");
			return 1;
		}

		if (uh_tls_init(tls_key, tls_crt))
		    return 1;
	}
#endif

#ifdef HAVE_LUA
	if (conf.lua_handler || conf.lua_prefix) {
		if (!conf.lua_handler || !conf.lua_prefix) {
			fprintf(stderr, "Need handler and prefix to enable Lua support\n");
			return 1;
		}
		if (uh_plugin_init("uhttpd_lua.so"))
			return 1;
	}
#endif
#ifdef HAVE_UBUS
	if (conf.ubus_prefix && uh_plugin_init("uhttpd_ubus.so"))
		return 1;
#endif

	/* fork (if not disabled) */
	if (!nofork) {
		switch (fork()) {
		case -1:
			perror("fork()");
			exit(1);

		case 0:
			/* daemon setup */
			if (chdir("/"))
				perror("chdir()");

			cur_fd = open("/dev/null", O_WRONLY);
			if (cur_fd > 0) {
				dup2(cur_fd, 0);
				dup2(cur_fd, 1);
				dup2(cur_fd, 2);
			}

			break;

		default:
			exit(0);
		}
	}

	return run_server();
}
//static
QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
{
    if (entry.isEmpty() || entry.isRoot())
        return entry;

#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) && !defined(Q_OS_ANDROID) && _POSIX_VERSION < 200809L
    // realpath(X,0) is not supported
    Q_UNUSED(data);
    return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else
    char *ret = 0;
# if defined(Q_OS_MACX)
    // When using -mmacosx-version-min=10.4, we get the legacy realpath implementation,
    // which does not work properly with the realpath(X,0) form. See QTBUG-28282.
    if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
        ret = (char*)malloc(PATH_MAX + 1);
        if (ret && realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) {
            const int savedErrno = errno; // errno is checked below, and free() might change it
            free(ret);
            errno = savedErrno;
            ret = 0;
        }
    } else {
        // on 10.5 we can use FSRef to resolve the file path.
        QString path = QDir::cleanPath(entry.filePath());
        FSRef fsref;
        if (FSPathMakeRef((const UInt8 *)path.toUtf8().data(), &fsref, 0) == noErr) {
            CFURLRef urlref = CFURLCreateFromFSRef(NULL, &fsref);
            CFStringRef canonicalPath = CFURLCopyFileSystemPath(urlref, kCFURLPOSIXPathStyle);
            QString ret = QCFString::toQString(canonicalPath);
            CFRelease(canonicalPath);
            CFRelease(urlref);
            return QFileSystemEntry(ret);
        }
    }
# else
#  if _POSIX_VERSION >= 200801L
    ret = realpath(entry.nativeFilePath().constData(), (char*)0);
#  else
    ret = (char*)malloc(PATH_MAX + 1);
    if (realpath(entry.nativeFilePath().constData(), (char*)ret) == 0) {
        const int savedErrno = errno; // errno is checked below, and free() might change it
        free(ret);
        errno = savedErrno;
        ret = 0;
    }
#  endif
# endif
    if (ret) {
        data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
        data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
        QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret));
        free(ret);
        return QFileSystemEntry(canonicalPath);
    } else if (errno == ENOENT) { // file doesn't exist
        data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
        data.entryFlags &= ~(QFileSystemMetaData::ExistsAttribute);
        return QFileSystemEntry();
    }
    return entry;
#endif
}
Exemple #19
0
// whitelist for /home/user directory
void fs_whitelist(void) {
	char *homedir = cfg.homedir;
	assert(homedir);
	ProfileEntry *entry = cfg.profile;
	if (!entry)
		return;
	
	// realpath function will fail with ENOENT if the file is not found
	// we need to expand the path before installing a new, empty home directory
	while (entry) {
		// handle only whitelist commands
		if (strncmp(entry->data, "whitelist ", 10)) {
			entry = entry->next;
			continue;
		}

		char *new_name = expand_home(entry->data + 10, cfg.homedir);
		assert(new_name);
		char *fname = realpath(new_name, NULL);
		free(new_name);
		if (fname) {
			// change file name in entry->data
			if (strcmp(fname, entry->data + 10) != 0) {
				char *newdata;
				if (asprintf(&newdata, "whitelist %s", fname) == -1)
					errExit("asprintf");
				entry->data = newdata;
				if (arg_debug)
					printf("Replaced whitelist path: %s\n", entry->data);
			}
						
			free(fname);
		}
		else {
			// file not found, blank the entry in the list
			if (arg_debug)
				printf("Removed whitelist path: %s\n", entry->data);
			*entry->data = '\0';
		}
		entry = entry->next;
	}
		
	// create /tmp/firejail/mnt/whome directory
	fs_build_mnt_dir();
	int rv = mkdir(WHITELIST_HOME_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
	if (rv == -1)
		errExit("mkdir");
	if (chown(WHITELIST_HOME_DIR, getuid(), getgid()) < 0)
		errExit("chown");
	if (chmod(WHITELIST_HOME_DIR, 0755) < 0)
		errExit("chmod");

	// keep a copy of real home dir in /tmp/firejail/mnt/whome
	if (mount(cfg.homedir, WHITELIST_HOME_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
		errExit("mount bind");

	// start building the new home directory by mounting a tmpfs fielsystem
	 fs_private();

	// go through profile rules again, and interpret whitelist commands
	entry = cfg.profile;
	while (entry) {
		// handle only whitelist commands
		if (strncmp(entry->data, "whitelist ", 10)) {
			entry = entry->next;
			continue;
		}

		whitelist_path(entry->data + 10);

		entry = entry->next;
	}

	// mask the real home directory, currently mounted on /tmp/firejail/mnt/whome
	if (mount("tmpfs", WHITELIST_HOME_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
		errExit("mount tmpfs");
}
Exemple #20
0
// whitelist for /home/user directory
void fs_whitelist(void) {
    char *homedir = cfg.homedir;
    assert(homedir);
    ProfileEntry *entry = cfg.profile;
    if (!entry)
        return;

    char *new_name = NULL;
    int home_dir = 0;	// /home/user directory flag
    int tmp_dir = 0;	// /tmp directory flag
    int media_dir = 0;	// /media directory flag
    int mnt_dir = 0;	// /mnt directory flag
    int var_dir = 0;		// /var directory flag
    int dev_dir = 0;		// /dev directory flag
    int opt_dir = 0;		// /opt directory flag
    int srv_dir = 0;                // /srv directory flag
    // verify whitelist files, extract symbolic links, etc.
    while (entry) {
        // handle only whitelist commands
        if (strncmp(entry->data, "whitelist ", 10)) {
            entry = entry->next;
            continue;
        }

        // resolve ${DOWNLOADS}
        if (strcmp(entry->data + 10, "${DOWNLOADS}") == 0) {
            char *tmp = resolve_downloads();
            if (tmp)
                entry->data = tmp;
            else {
                *entry->data = '\0';
                fprintf(stderr, "***\n");
                fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n");
                fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
                fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n");
                fprintf(stderr, "***\n");
                continue;
            }
        }

        // replace ~/ or ${HOME} into /home/username
//		if (new_name)
//			free(new_name);
        new_name = expand_home(entry->data + 10, cfg.homedir);
        assert(new_name);
        if (arg_debug)
            fprintf(stderr, "Debug %d: new_name #%s#\n", __LINE__, new_name);

        // valid path referenced to filesystem root
        if (*new_name != '/') {
            if (arg_debug)
                fprintf(stderr, "Debug %d: \n", __LINE__);
            goto errexit;
        }


        // extract the absolute path of the file
        // realpath function will fail with ENOENT if the file is not found
        char *fname = realpath(new_name, NULL);
        if (!fname) {
            // file not found, blank the entry in the list and continue
            if (arg_debug || arg_debug_whitelists) {
                printf("Removed whitelist path: %s\n", entry->data);
                printf("\texpanded: %s\n", new_name);
                printf("\treal path: (null)\n");
                printf("\t");
                fflush(0);
                perror("realpath");
            }
            *entry->data = '\0';

            // if 1 the file was not found; mount an empty directory
            if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
                if(!arg_private)
                    home_dir = 1;
            }
            else if (strncmp(new_name, "/tmp/", 5) == 0)
                tmp_dir = 1;
            else if (strncmp(new_name, "/media/", 7) == 0)
                media_dir = 1;
            else if (strncmp(new_name, "/mnt/", 5) == 0)
                mnt_dir = 1;
            else if (strncmp(new_name, "/var/", 5) == 0)
                var_dir = 1;
            else if (strncmp(new_name, "/dev/", 5) == 0)
                dev_dir = 1;
            else if (strncmp(new_name, "/opt/", 5) == 0)
                opt_dir = 1;
            else if (strncmp(new_name, "/srv/", 5) == 0)
                opt_dir = 1;

            continue;
        }

        // check for supported directories
        if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
            // whitelisting home directory is disabled if --private option is present
            if (arg_private) {
                if (arg_debug || arg_debug_whitelists)
                    printf("Removed whitelist path %s, --private option is present\n", entry->data);

                *entry->data = '\0';
                continue;
            }

            entry->home_dir = 1;
            home_dir = 1;
            if (arg_debug || arg_debug_whitelists)
                fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n",
                        __LINE__, fname, cfg.homedir);

            // both path and absolute path are under /home
            if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) {
                // check if the file is owned by the user
                struct stat s;
                if (stat(fname, &s) == 0 && s.st_uid != getuid())
                    goto errexit;
            }
        }
        else if (strncmp(new_name, "/tmp/", 5) == 0) {
            entry->tmp_dir = 1;
            tmp_dir = 1;
            // both path and absolute path are under /tmp
            if (strncmp(fname, "/tmp/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/media/", 7) == 0) {
            entry->media_dir = 1;
            media_dir = 1;
            // both path and absolute path are under /media
            if (strncmp(fname, "/media/", 7) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/mnt/", 5) == 0) {
            entry->mnt_dir = 1;
            mnt_dir = 1;
            // both path and absolute path are under /mnt
            if (strncmp(fname, "/mnt/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/var/", 5) == 0) {
            entry->var_dir = 1;
            var_dir = 1;
            // both path and absolute path are under /var
            // exceptions: /var/run and /var/lock
            if (strcmp(new_name, "/var/run")== 0)
                ;
            else if (strcmp(new_name, "/var/lock")== 0)
                ;
            else if (strncmp(fname, "/var/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/dev/", 5) == 0) {
            entry->dev_dir = 1;
            dev_dir = 1;
            // both path and absolute path are under /dev
            if (strncmp(fname, "/dev/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/opt/", 5) == 0) {
            entry->opt_dir = 1;
            opt_dir = 1;
            // both path and absolute path are under /dev
            if (strncmp(fname, "/opt/", 5) != 0) {
                goto errexit;
            }
        }
        else if (strncmp(new_name, "/srv/", 5) == 0) {
            entry->srv_dir = 1;
            srv_dir = 1;
            // both path and absolute path are under /srv
            if (strncmp(fname, "/srv/", 5) != 0) {
                goto errexit;
            }
        }
        else {
            goto errexit;
        }

        // mark symbolic links
        if (is_link(new_name))
            entry->link = new_name;
        else {
            free(new_name);
            new_name = NULL;
        }

        // change file name in entry->data
        if (strcmp(fname, entry->data + 10) != 0) {
            char *newdata;
            if (asprintf(&newdata, "whitelist %s", fname) == -1)
                errExit("asprintf");
            entry->data = newdata;
            if (arg_debug || arg_debug_whitelists)
                printf("Replaced whitelist path: %s\n", entry->data);
        }
        free(fname);
        entry = entry->next;
    }

    // /home/user
    if (home_dir) {
        // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR
        mkdir_attr(RUN_WHITELIST_HOME_USER_DIR, 0755, getuid(), getgid());
        if (mount(cfg.homedir, RUN_WHITELIST_HOME_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount a tmpfs and initialize /home/user
        fs_private();
    }

    // /tmp mountpoint
    if (tmp_dir) {
        // keep a copy of real /tmp directory in
        mkdir_attr(RUN_WHITELIST_TMP_DIR, 1777, 0, 0);
        if (mount("/tmp", RUN_WHITELIST_TMP_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount tmpfs on /tmp
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /tmp directory\n");
        if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=1777,gid=0") < 0)
            errExit("mounting tmpfs on /tmp");
        fs_logger("tmpfs /tmp");
    }

    // /media mountpoint
    if (media_dir) {
        // some distros don't have a /media directory
        struct stat s;
        if (stat("/media", &s) == 0) {
            // keep a copy of real /media directory in RUN_WHITELIST_MEDIA_DIR
            mkdir_attr(RUN_WHITELIST_MEDIA_DIR, 0755, 0, 0);
            if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
                errExit("mount bind");

            // mount tmpfs on /media
            if (arg_debug || arg_debug_whitelists)
                printf("Mounting tmpfs on /media directory\n");
            if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
                errExit("mounting tmpfs on /media");
            fs_logger("tmpfs /media");
        }
        else
            media_dir = 0;
    }

    // /mnt mountpoint
    if (mnt_dir) {
        // check if /mnt directory exists
        struct stat s;
        if (stat("/mnt", &s) == 0) {
            // keep a copy of real /mnt directory in RUN_WHITELIST_MNT_DIR
            mkdir_attr(RUN_WHITELIST_MNT_DIR, 0755, 0, 0);
            if (mount("/mnt", RUN_WHITELIST_MNT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
                errExit("mount bind");

            // mount tmpfs on /mnt
            if (arg_debug || arg_debug_whitelists)
                printf("Mounting tmpfs on /mnt directory\n");
            if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
                errExit("mounting tmpfs on /mnt");
            fs_logger("tmpfs /mnt");
        }
        else
            mnt_dir = 0;
    }


    // /var mountpoint
    if (var_dir) {
        // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR
        mkdir_attr(RUN_WHITELIST_VAR_DIR, 0755, 0, 0);
        if (mount("/var", RUN_WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount tmpfs on /var
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /var directory\n");
        if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mounting tmpfs on /var");
        fs_logger("tmpfs /var");
    }

    // /dev mountpoint
    if (dev_dir) {
        // keep a copy of real /dev directory in RUN_WHITELIST_DEV_DIR
        mkdir_attr(RUN_WHITELIST_DEV_DIR, 0755, 0, 0);
        if (mount("/dev", RUN_WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount bind");

        // mount tmpfs on /dev
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /dev directory\n");
        if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mounting tmpfs on /dev");
        fs_logger("tmpfs /dev");
    }

    // /opt mountpoint
    if (opt_dir) {
        // keep a copy of real /opt directory in RUN_WHITELIST_OPT_DIR
        mkdir_attr(RUN_WHITELIST_OPT_DIR, 0755, 0, 0);
        if (mount("/opt", RUN_WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
            errExit("mount bind");

        // mount tmpfs on /opt
        if (arg_debug || arg_debug_whitelists)
            printf("Mounting tmpfs on /opt directory\n");
        if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mounting tmpfs on /opt");
        fs_logger("tmpfs /opt");
    }

    // /srv mountpoint
    if (srv_dir) {
        // check if /srv directory exists
        struct stat s;
        if (stat("/srv", &s) == 0) {
            // keep a copy of real /srv directory in RUN_WHITELIST_SRV_DIR
            mkdir_attr(RUN_WHITELIST_SRV_DIR, 0755, 0, 0);
            if (mount("/srv", RUN_WHITELIST_SRV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
                errExit("mount bind");

            // mount tmpfs on /srv
            if (arg_debug || arg_debug_whitelists)
                printf("Mounting tmpfs on /srv directory\n");
            if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
                errExit("mounting tmpfs on /srv");
            fs_logger("tmpfs /srv");
        }
        else
            srv_dir = 0;
    }



    // go through profile rules again, and interpret whitelist commands
    entry = cfg.profile;
    while (entry) {
        // handle only whitelist commands
        if (strncmp(entry->data, "whitelist ", 10)) {
            entry = entry->next;
            continue;
        }

//printf("here %d#%s#\n", __LINE__, entry->data);
        // whitelist the real file
        if (strcmp(entry->data, "whitelist /run") == 0 &&
                (strcmp(entry->link, "/var/run") == 0 || strcmp(entry->link, "/var/lock") == 0)) {
            int rv = symlink(entry->data + 10, entry->link);
            if (rv)
                fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link);
            else if (arg_debug || arg_debug_whitelists)
                printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10);
        }
        else {
            whitelist_path(entry);

            // create the link if any
            if (entry->link) {
                // if the link is already there, do not bother
                struct stat s;
                if (stat(entry->link, &s) != 0) {
                    // create the path if necessary
                    mkpath(entry->link, s.st_mode);

                    int rv = symlink(entry->data + 10, entry->link);
                    if (rv)
                        fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link);
                    else if (arg_debug || arg_debug_whitelists)
                        printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10);
                }
            }
        }

        entry = entry->next;
    }

    // mask the real home directory, currently mounted on RUN_WHITELIST_HOME_DIR
    if (home_dir) {
        if (mount("tmpfs", RUN_WHITELIST_HOME_USER_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_HOME_USER_DIR);
    }

    // mask the real /tmp directory, currently mounted on RUN_WHITELIST_TMP_DIR
    if (tmp_dir) {
        if (mount("tmpfs", RUN_WHITELIST_TMP_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_TMP_DIR);
    }

    // mask the real /var directory, currently mounted on RUN_WHITELIST_VAR_DIR
    if (var_dir) {
        if (mount("tmpfs", RUN_WHITELIST_VAR_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_VAR_DIR);
    }

    // mask the real /opt directory, currently mounted on RUN_WHITELIST_OPT_DIR
    if (opt_dir) {
        if (mount("tmpfs", RUN_WHITELIST_OPT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_OPT_DIR);
    }

    // mask the real /dev directory, currently mounted on RUN_WHITELIST_DEV_DIR
    if (dev_dir) {
        if (mount("tmpfs", RUN_WHITELIST_DEV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_DEV_DIR);
    }

    // mask the real /media directory, currently mounted on RUN_WHITELIST_MEDIA_DIR
    if (media_dir) {
        if (mount("tmpfs", RUN_WHITELIST_MEDIA_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR);
    }

    // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR
    if (mnt_dir) {
        if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR);
    }

    // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR
    if (srv_dir) {
        if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
            errExit("mount tmpfs");
        fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR);
    }

    if (new_name)
        free(new_name);

    return;

errexit:
    fprintf(stderr, "Error: invalid whitelist path %s\n", new_name);
    exit(1);
}
Exemple #21
0
// this function executes server-side commands only
// must be called only from within server
// -1 error, program must exit with error code -1
//  0 proceed normally as nothing happened
//  1 no error, but program must exit with error code 0
//  2 don't load playlist on startup
//  when executed in remote server -- error code will be ignored
int
server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsize) {
    if (sendback) {
        sendback[0] = 0;
    }
    const uint8_t *parg = (const uint8_t *)cmdline;
    const uint8_t *pend = cmdline + len;
    int queue = 0;
    while (parg < pend) {
        const char *parg_c = parg;
        if (strlen (parg) >= 2 && parg[0] == '-' && parg[1] != '-') {
            parg += strlen (parg);
            parg++;
            return 0; // running under osx debugger?
        }
        else if (!strcmp (parg, "--nowplaying")) {
            parg += strlen (parg);
            parg++;
            if (parg >= pend) {
                if (sendback) {
                    snprintf (sendback, sbsize, "error --nowplaying expects format argument\n");
                    return 0;
                }
                else {
                    fprintf (stderr, "--nowplaying expects format argument\n");
                    return -1;
                }
            }
            if (sendback) {
                playItem_t *curr = streamer_get_playing_track ();
                DB_fileinfo_t *dec = streamer_get_current_fileinfo ();
                if (curr && dec) {
                    const char np[] = "nowplaying ";
                    memcpy (sendback, np, sizeof (np)-1);
                    pl_format_title (curr, -1, sendback+sizeof(np)-1, sbsize-sizeof(np)+1, -1, parg);
                }
                else {
                    strcpy (sendback, "nowplaying nothing");
                }
                if (curr) {
                    pl_item_unref (curr);
                }
            }
            else {
                char out[2048];
                playItem_t *curr = streamer_get_playing_track ();
                DB_fileinfo_t *dec = streamer_get_current_fileinfo();
                if (curr && dec) {
                    pl_format_title (curr, -1, out, sizeof (out), -1, parg);
                }
                else {
                    strcpy (out, "nothing");
                }
                if (curr) {
                    pl_item_unref (curr);
                }
                fwrite (out, 1, strlen (out), stdout);
                return 1; // exit
            }
        }
        else if (!strcmp (parg, "--next")) {
            messagepump_push (DB_EV_NEXT, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--prev")) {
            messagepump_push (DB_EV_PREV, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--play")) {
            messagepump_push (DB_EV_PLAY_CURRENT, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--stop")) {
            messagepump_push (DB_EV_STOP, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--pause")) {
            messagepump_push (DB_EV_PAUSE, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--toggle-pause")) {
            messagepump_push (DB_EV_TOGGLE_PAUSE, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--play-pause")) {
            int state = deadbeef->get_output ()->state ();
            if (state == OUTPUT_STATE_PLAYING) {
                deadbeef->sendmessage (DB_EV_PAUSE, 0, 0, 0);
            }
            else {
                deadbeef->sendmessage (DB_EV_PLAY_CURRENT, 0, 0, 0);
            }
            return 0;
        }
        else if (!strcmp (parg, "--random")) {
            messagepump_push (DB_EV_PLAY_RANDOM, 0, 0, 0);
            return 0;
        }
        else if (!strcmp (parg, "--queue")) {
            queue = 1;
        }
        else if (!strcmp (parg, "--quit")) {
            messagepump_push (DB_EV_TERMINATE, 0, 0, 0);
        }
        else if (!strcmp (parg, "--sm-client-id")) {
            parg += strlen (parg);
            parg++;
            if (parg < pend) {
                parg += strlen (parg);
                parg++;
            }
            continue;
        }
        else if (!strcmp (parg, "--gui")) {
            // need to skip --gui here, it is handled in the client cmdline
            parg += strlen (parg);
            parg++;
            if (parg >= pend) {
                break;
            }
            parg += strlen (parg);
            parg++;
            continue;
        }
        else if (parg[0] != '-') {
            break; // unknown option is filename
        }
        parg += strlen (parg);
        parg++;
    }
    if (parg < pend) {
        if (conf_get_int ("cli_add_to_specific_playlist", 1)) {
            char str[200];
            conf_get_str ("cli_add_playlist_name", "Default", str, sizeof (str));
            int idx = plt_find (str);
            if (idx < 0) {
                idx = plt_add (plt_get_count (), str);
            }
            if (idx >= 0) {
                plt_set_curr_idx (idx);
            }
        }
        playlist_t *curr_plt = plt_get_curr ();
        if (plt_add_files_begin (curr_plt, 0) != 0) {
            plt_unref (curr_plt);
            snprintf (sendback, sbsize, "it's not allowed to add files to playlist right now, because another file adding operation is in progress. please try again later.");
            return 0;
        }
        // add files
        if (!queue) {
            plt_clear (curr_plt);
            messagepump_push (DB_EV_PLAYLISTCHANGED, 0, 0, 0);
            plt_reset_cursor (curr_plt);
        }
        while (parg < pend) {
            char resolved[PATH_MAX];
            const char *pname;
            if (realpath (parg, resolved)) {
                pname = resolved;
            }
            else {
                pname = parg;
            }
            if (deadbeef->plt_add_dir2 (0, (ddb_playlist_t*)curr_plt, pname, NULL, NULL) < 0) {
                if (deadbeef->plt_add_file2 (0, (ddb_playlist_t*)curr_plt, pname, NULL, NULL) < 0) {
                    int ab = 0;
                    playItem_t *it = plt_load2 (0, curr_plt, NULL, pname, &ab, NULL, NULL);
                    if (!it) {
                        fprintf (stderr, "failed to add file or folder %s\n", pname);
                    }
                }
            }
            parg += strlen (parg);
            parg++;
        }
        messagepump_push (DB_EV_PLAYLIST_REFRESH, 0, 0, 0);
        plt_add_files_end (curr_plt, 0);
        plt_unref (curr_plt);
        if (!queue) {
            messagepump_push (DB_EV_PLAY_NUM, 0, 0, 0);
            return 2; // don't reload playlist at startup
        }
    }
    return 0;
}
Exemple #22
0
const char *sbncGetExePath(void) {
	static char *ExePath;

	if (ExePath != NULL) {
		return ExePath;
	}

#ifndef _WIN32
	char Buf[MAXPATHLEN], Cwd[MAXPATHLEN];
	char *PathEnv, *Directory, PathTest[MAXPATHLEN], FullExePath[MAXPATHLEN];
	bool FoundPath;

	if (getcwd(Cwd, sizeof(Cwd)) == NULL) {
		perror("getcwd() failed");
		exit(EXIT_FAILURE);
	}

	if (g_ArgV[0][0] != '/') {
		snprintf(FullExePath, sizeof(FullExePath), "%s/%s", Cwd, g_ArgV[0]);
	} else {
		strmcpy(FullExePath, g_ArgV[0], sizeof(FullExePath));
	}

	if (strchr(g_ArgV[0], '/') == NULL) {
		PathEnv = getenv("PATH");

		if (PathEnv != NULL) {
			PathEnv = strdup(PathEnv);

			if (PathEnv == NULL) {
				perror("strdup() failed");
				exit(EXIT_FAILURE);
			}

			FoundPath = false;

			for (Directory = strtok(PathEnv, ":"); Directory != NULL; Directory = strtok(NULL, ":")) {
				if (snprintf(PathTest, sizeof(PathTest), "%s/%s", Directory, g_ArgV[0]) < 0) {
					perror("snprintf() failed");
					exit(EXIT_FAILURE);
				}

				if (access(PathTest, X_OK) == 0) {
					strmcpy(FullExePath, PathTest, sizeof(FullExePath));

					FoundPath = true;

					break;
				}
			}

			free(PathEnv);

			if (!FoundPath) {
				printf("Could not determine executable path.\n");
				exit(EXIT_FAILURE);
			}
		}
	}

	if (realpath(FullExePath, Buf) == NULL) {
		perror("realpath() failed");
		exit(EXIT_FAILURE);
	}

	// remove filename
	char *LastSlash = strrchr(Buf, '/');
	if (LastSlash != NULL) {
		*LastSlash = '\0';
	}

	ExePath = strdup(Buf);

	if (ExePath == NULL) {
		perror("strdup() failed");
		exit(EXIT_FAILURE);
	}
#else /* _WIN32 */
	ExePath = (char *)malloc(MAXPATHLEN);

	if (ExePath == NULL) {
		perror("strdup failed");

		exit(EXIT_FAILURE);
	}

	GetModuleFileName(NULL, ExePath, MAXPATHLEN);

	PathRemoveFileSpec(ExePath);
#endif /* _WIN32 */

	return ExePath;
}
Exemple #23
0
size_t printXMLStatInfo(FILE *out, int indent, const char* tag, const char* id,
                        const StatInfo* info, int includeData, int useCDATA) {
    char *real = NULL;

    /* sanity check */
    if (info->source == IS_INVALID) {
        return 0;
    }

    /* start main tag */
    fprintf(out, "%*s<%s error=\"%d\"", indent, "", tag, info->error);
    if (id != NULL) {
        fprintf(out, " id=\"%s\"", id);
    }
    if (info->lfn != NULL) {
        fprintf(out, " lfn=\"%s\"", info->lfn);
    }
    fprintf(out, ">\n");

    /* NEW: ignore "file not found" error for "kickstart" */
    if (id != NULL && info->error == 2 && strcmp(id, "kickstart") == 0) {
        fprintf(out, "%*s<!-- ignore above error -->\n", indent+2, "");
    }

    /* either a <name> or <descriptor> sub element */
    switch (info->source) {
        case IS_TEMP:   /* preparation for <temporary> element */
            /* late update for temp files */
            errno = 0;
            if (fstat(info->file.descriptor, (struct stat*) &info->info) != -1 &&
                (((StatInfo*) info)->error = errno) == 0) {

                /* obtain header of file */
                int fd = dup(info->file.descriptor);
                if (fd != -1) {
                    if (lseek(fd, 0, SEEK_SET) != -1) {
                        read(fd, (char*) info->client.header, sizeof(info->client.header));
                    }
                    close(fd);
                }
            }

            fprintf(out, "%*s<temporary name=\"%s\" descriptor=\"%d\"/>\n",
                    indent+2, "", info->file.name, info->file.descriptor);
            break;

        case IS_FIFO: /* <fifo> element */
            fprintf(out, "%*s<fifo name=\"%s\" descriptor=\"%d\" count=\"%zu\" rsize=\"%zu\" wsize=\"%zu\"/>\n",
                    indent+2, "", info->file.name, info->file.descriptor,
                    info->client.fifo.count, info->client.fifo.rsize,
                    info->client.fifo.wsize);
            break;

        case IS_FILE: /* <file> element */
            real = realpath(info->file.name, NULL);
            fprintf(out, "%*s<file name=\"%s\"", indent+2, "", real ? real : info->file.name);
            if (real) {
                free((void*) real);
            }

            if (info->error == 0 &&
                S_ISREG(info->info.st_mode) &&
                info->info.st_size > 0) {

                /* optional hex information */
                size_t i, end = sizeof(info->client.header);
                if (info->info.st_size < end) end = info->info.st_size;

                fprintf(out, ">");
                for (i=0; i<end; ++i) {
                    fprintf(out, "%02X", info->client.header[i]);
                }
                fprintf(out, "</file>\n");
            } else {
                fprintf(out, "/>\n");
            }
            break;

        case IS_HANDLE: /* <descriptor> element */
            fprintf(out, "%*s<descriptor number=\"%u\"/>\n", indent+2, "",
                    info->file.descriptor);
            break;

        default: /* this must not happen! */
            fprintf(out, "%*s<!-- ERROR: No valid file info available -->\n",
                    indent+2, "");
            break;
    }

    if (info->error == 0 && info->source != IS_INVALID) {
        /* <stat> subrecord */
        char my[32];
        struct passwd* user = getpwuid(info->info.st_uid);
        struct group* group = getgrgid(info->info.st_gid);

        fprintf(out, "%*s<statinfo mode=\"0%o\"", indent+2, "",
                info->info.st_mode);

        /* Grmblftz, are we in 32bit, 64bit LFS on 32bit, or 64bit on 64 */
        sizer(my, sizeof(my), sizeof(info->info.st_size), &info->info.st_size);
        fprintf(out, " size=\"%s\"", my);

        sizer(my, sizeof(my), sizeof(info->info.st_ino), &info->info.st_ino);
        fprintf(out, " inode=\"%s\"", my);

        sizer(my, sizeof(my), sizeof(info->info.st_nlink), &info->info.st_nlink);
        fprintf(out, " nlink=\"%s\"", my);

        sizer(my, sizeof(my), sizeof(info->info.st_blksize), &info->info.st_blksize);
        fprintf(out, " blksize=\"%s\"", my);

        /* st_blocks is new in iv-1.8 */
        sizer(my, sizeof(my), sizeof(info->info.st_blocks), &info->info.st_blocks);
        fprintf(out, " blocks=\"%s\"", my);

        fprintf(out, " mtime=\"%s\"", fmtisodate(info->info.st_mtime, -1));
        fprintf(out, " atime=\"%s\"", fmtisodate(info->info.st_atime, -1));
        fprintf(out, " ctime=\"%s\"", fmtisodate(info->info.st_ctime, -1));

        fprintf(out, " uid=\"%d\"", info->info.st_uid);
        if (user) {
            fprintf(out, " user=\"%s\"", user->pw_name);
        }
        fprintf(out, " gid=\"%d\"", info->info.st_gid);
        if (group) {
            fprintf(out, " group=\"%s\"", group->gr_name);
        }

        fprintf(out, "/>\n");
    }

    /* data section from stdout and stderr of application */
    if (includeData &&
        info->source == IS_TEMP &&
        info->error == 0 &&
        info->info.st_size && data_section_size > 0) {

        size_t dsize = data_section_size;
        size_t fsize = info->info.st_size;
        fprintf(out, "%*s<data%s", indent+2, "",
                (fsize > dsize ? " truncated=\"true\"" : ""));
        if (fsize > 0) {
            char buf [BUFSIZ];
            int fd = dup(info->file.descriptor);

            fprintf(out, ">");
            if (fd != -1) {

                if (useCDATA) {
                    fprintf(out, "<![CDATA[");
                }

                /* Get the last dsize bytes of the file */
                size_t offset = 0;
                if (fsize > dsize) {
                    offset = fsize - dsize;
                }
                if (lseek(fd, offset, SEEK_SET) != -1) {
                    ssize_t total = 0;
                    while (total < dsize) {
                        ssize_t rsize = read(fd, buf, BUFSIZ);
                        if (rsize == 0) {
                            break;
                        } else if (rsize < 0) {
                            printerr("ERROR reading %s: %s",
                                    info->file.name, strerror(errno));
                            break;
                        }
                        if (useCDATA) {
                            fwrite(buf, rsize, 1, out);
                        } else {
                            xmlquote(out, buf, rsize);
                        }
                        total += rsize;
                    }
                }
                close(fd);

                if (useCDATA) {
                    fprintf(out, "]]>");
                }
            }

            fprintf(out, "</data>\n");
        } else {
            fprintf(out, "/>\n");
        }
    }

    fprintf(out, "%*s</%s>\n", indent, "", tag);

    return 0;
}
Exemple #24
0
static DB_playItem_t *
cda_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *path)
{
    trace("CDA insert: %s\n", path);
    cdio_close_tray(NULL, NULL);

    /* Deal with any NRG files and get them out of the way */
    const char *ext = strrchr(path, '.');
    if (ext && !strcasecmp(ext, ".nrg")) {
        if (!deadbeef->conf_get_int("cdda.enable_nrg", 0)) {
            trace("cda: NRG found but disabled in preferences\n");
            return NULL;
        }
        CdIo_t* cdio = cdio_open(path, DRIVER_NRG);
        if (!cdio) {
            trace("not an NRG image, or file not found (%s)\n", path);
            return NULL;
        }
        DB_playItem_t *inserted = insert_disc(plt, after, path, 0, cdio);
        cdio_destroy(cdio);
        return inserted;
    }

    /* Get a list of all devices containing CD audio */
    driver_id_t driver_id;
    char **device_list = cdio_get_devices_with_cap_ret(NULL, CDIO_FS_AUDIO, false, &driver_id);
    if (!device_list) {
        trace("cda: no audio drives found\n");
        return NULL;
    }

    /* Match the device name for the requested insert (invalid devices may crash cdio) */
    const char *sep = strrchr(path, '/');
    char *drive_device = NULL;
    if (sep) {
        char *real_path = realpath(path, NULL);
        if (!real_path) {
            const size_t device_length = sep - path;
            char device_path[device_length+1];
            strncpy(device_path, path, device_length);
            device_path[device_length] = '\0';
            real_path = realpath(device_path, NULL);
        }
        if (real_path) {
            for (size_t i = 0; device_list[i] && !drive_device; i++) {
                char *real_device = realpath(device_list[i], NULL);
                if (real_device) {
                    if (!strcmp(real_device, real_path)) {
                        drive_device = device_list[i];
                    }
                    free(real_device);
                }
            }
            free(real_path);
        }
    }
    else {
        drive_device = device_list[0];
    }

    /* Open the device and insert the requested track(s) */
    DB_playItem_t *inserted = NULL;
    if (drive_device) {
        trace("cda: try to open device %s\n", drive_device);
        CdIo_t* cdio = cdio_open(drive_device, driver_id);
        if (cdio) {
            char *track_end;
            const unsigned long track_nr = strtoul(sep ? sep + 1 : path, &track_end, 10);
            const track_t single_track = strcmp(track_end, ".cda") || track_nr > CDIO_CD_MAX_TRACKS ? 0 : track_nr;
            inserted = insert_disc(plt, after, drive_device, single_track, cdio);
            cdio_destroy(cdio);
        }
    }
    cdio_free_device_list(device_list);
    return inserted;
}
Exemple #25
0
static int
efi_get_info(int fd, struct dk_cinfo *dki_info)
{
#if defined(__linux__)
	char *path;
	char *dev_path;
	int rval = 0;

	memset(dki_info, 0, sizeof (*dki_info));

	path = calloc(PATH_MAX, 1);
	if (path == NULL)
		goto error;

	/*
	 * The simplest way to get the partition number under linux is
	 * to parse it out of the /dev/<disk><parition> block device name.
	 * The kernel creates this using the partition number when it
	 * populates /dev/ so it may be trusted.  The tricky bit here is
	 * that the naming convention is based on the block device type.
	 * So we need to take this in to account when parsing out the
	 * partition information.  Another issue is that the libefi API
	 * API only provides the open fd and not the file path.  To handle
	 * this realpath(3) is used to resolve the block device name from
	 * /proc/self/fd/<fd>.  Aside from the partition number we collect
	 * some additional device info.
	 */
	(void) sprintf(path, "/proc/self/fd/%d", fd);
	dev_path = realpath(path, NULL);
	free(path);

	if (dev_path == NULL)
		goto error;

	if ((strncmp(dev_path, "/dev/sd", 7) == 0)) {
		strcpy(dki_info->dki_cname, "sd");
		dki_info->dki_ctype = DKC_SCSI_CCS;
		rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
		    dki_info->dki_dname,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/hd", 7) == 0)) {
		strcpy(dki_info->dki_cname, "hd");
		dki_info->dki_ctype = DKC_DIRECT;
		rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
		    dki_info->dki_dname,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/md", 7) == 0)) {
		strcpy(dki_info->dki_cname, "pseudo");
		dki_info->dki_ctype = DKC_MD;
		strcpy(dki_info->dki_dname, "md");
		rval = sscanf(dev_path, "/dev/md%[0-9]p%hu",
		    dki_info->dki_dname + 2,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/vd", 7) == 0)) {
		strcpy(dki_info->dki_cname, "vd");
		dki_info->dki_ctype = DKC_MD;
		rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
		    dki_info->dki_dname,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/xvd", 8) == 0)) {
		strcpy(dki_info->dki_cname, "xvd");
		dki_info->dki_ctype = DKC_MD;
		rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
		    dki_info->dki_dname,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/zd", 7) == 0)) {
		strcpy(dki_info->dki_cname, "zd");
		dki_info->dki_ctype = DKC_MD;
		rval = sscanf(dev_path, "/dev/%[a-zA-Z]%hu",
		    dki_info->dki_dname,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/dm-", 8) == 0)) {
		strcpy(dki_info->dki_cname, "pseudo");
		dki_info->dki_ctype = DKC_VBD;
		strcpy(dki_info->dki_dname, "dm-");
		rval = sscanf(dev_path, "/dev/dm-%[0-9]p%hu",
		    dki_info->dki_dname + 3,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/ram", 8) == 0)) {
		strcpy(dki_info->dki_cname, "pseudo");
		dki_info->dki_ctype = DKC_PCMCIA_MEM;
		strcpy(dki_info->dki_dname, "ram");
		rval = sscanf(dev_path, "/dev/ram%[0-9]p%hu",
		    dki_info->dki_dname + 3,
		    &dki_info->dki_partition);
	} else if ((strncmp(dev_path, "/dev/loop", 9) == 0)) {
		strcpy(dki_info->dki_cname, "pseudo");
		dki_info->dki_ctype = DKC_VBD;
		strcpy(dki_info->dki_dname, "loop");
		rval = sscanf(dev_path, "/dev/loop%[0-9]p%hu",
		    dki_info->dki_dname + 4,
		    &dki_info->dki_partition);
	} else {
		strcpy(dki_info->dki_dname, "unknown");
		strcpy(dki_info->dki_cname, "unknown");
		dki_info->dki_ctype = DKC_UNKNOWN;
	}

	switch (rval) {
	case 0:
		errno = EINVAL;
		goto error;
	case 1:
		dki_info->dki_partition = 0;
	}

	free(dev_path);
#else
	if (ioctl(fd, DKIOCINFO, (caddr_t)dki_info) == -1)
		goto error;
#endif
	return (0);
error:
	if (efi_debug)
		(void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno);

	switch (errno) {
	case EIO:
		return (VT_EIO);
	case EINVAL:
		return (VT_EINVAL);
	default:
		return (VT_ERROR);
	}
}
Exemple #26
0
int     main            (int argc, char * argv [])
{
    int     x;
    uchar   *buf = (uchar*) malloc (65536);
    char    *pc;

    assert (buf != 0);

    rc = libusb_init (NULL);
    assert (rc == 0);

    if (NULL == (realpath (argv [0], szBasePath)))
      {
        printf ("Can't get realpath\n");
        return (1);
      }
    for (pc = strchr (szBasePath, '\0'); *pc != '/'; pc--) *pc = '\0';

    FN = &FN_sun7i;                             // A20 by default.

    while (argc > 1)
      {
        if (strcmp (argv [1], (char *) "-t") == 0)
          {
            USBTests (buf);
            goto bye;
          }
        if (strcmp (argv [1], (char *) "-H") == 0)
          {
            H3_Tests (buf);
            goto bye;
          }
        if (strcmp (argv [1], (char *) "-l") == 0)
          {
            Lime_Tests (buf);
            goto bye;
          }
        if (strcmp (argv [1], (char *) "-a") == 0)
          {
            A20_Tests (buf);
            goto bye;
          }
        if (strcmp (argv [1], (char *) "-h") == 0)
          {
            printf ("no flags = update boot0 and boot1.\n");
            printf ("-x = allow force continue when error.\n");
            printf ("-e = erase chip before boot update.\n");
            printf ("-r = read all NAND, save to NAND.DAT.\n");
            printf ("-w = write NAND.DAT to device NAND.\n");
            printf ("-t = USB tests.\n");
            printf ("-i <file list> = create NAND MBR, write MBR and files to NAND,\n");
            printf ("  each file is a partition to write, the file name is used as\n");
            printf ("  the partition name in the MBR.\n");
            printf ("  Each file entry consists of a name and start and size enclosed in quotes.\n");
            printf ("  The start is the sector key (0 = use next available sector).\n");
            printf ("  The size is the partition size in sectors (0 = use file size).\n");
            printf ("  e.g. bootfix -i \"/data/boot 2048 0\" \"/data/rootfs 0 0\" \"/data/extra 0 0\"\n");
            goto bye;
          }
        if (strcmp (argv [1], (char *) "-x") == 0)
            forceable = 1;
        else if (strcmp (argv [1], (char *) "-e") == 0)
            bEraseReqd = 1;
        else if (strcmp (argv [1], (char *) "-r") == 0)
          {
            readNAND = 1;
            if (argc > 2)
                strcpy (NAND_FID, argv [2]);
            break;
          }  
        else if (strcmp (argv [1], (char *) "-w") == 0)
          {
            writeNAND = 1;
            if (argc > 2)
                strcpy (NAND_FID, argv [2]);
            break;
          }
        else if (strcmp (argv [1], (char *) "-i") == 0)
          {
            loadNAND = 1;
            part_cnt = argc - 2;
            if (part_cnt > 16)
                part_cnt = 16;
            BOJLoadNANDCheck (part_cnt, &argv [2], part_start, part_secs);
            bEraseReqd = true;
            break;
          }
        argc--;
        argv++;
      }

    handle = open_usb ();                               // stage 1
    stage_1 (handle, buf);
    handle = close_usb (handle);

    printf ("Re-opening");                              // stage 2
    fflush (stdout);
    for (x = 0; !handle; x++)
      {
        usleep (1000000);                               // wait 1 sec
        printf (".");
        fflush (stdout);
        handle = open_usb (x < 10);                     // try to open
      }
    printf ("done\n");
    stage_2 (handle, buf);
    handle = close_usb (handle);

    printf ("All done\n");

bye:
    libusb_exit (NULL);

    return 0;
}
Exemple #27
0
int
main(int argc, char **argv)
{
  nsresult rv;
  char *lastSlash;

  char iniPath[MAXPATHLEN];
  char tmpPath[MAXPATHLEN];
  char greDir[MAXPATHLEN];
  PRBool greFound = PR_FALSE;

#if defined(XP_MACOSX)
  CFBundleRef appBundle = CFBundleGetMainBundle();
  if (!appBundle)
    return 1;

  CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(appBundle);
  if (!resourcesURL)
    return 1;

  CFURLRef absResourcesURL = CFURLCopyAbsoluteURL(resourcesURL);
  CFRelease(resourcesURL);
  if (!absResourcesURL)
    return 1;

  CFURLRef iniFileURL =
    CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
                                          absResourcesURL,
                                          CFSTR("application.ini"),
                                          false);
  CFRelease(absResourcesURL);
  if (!iniFileURL)
    return 1;

  CFStringRef iniPathStr =
    CFURLCopyFileSystemPath(iniFileURL, kCFURLPOSIXPathStyle);
  CFRelease(iniFileURL);
  if (!iniPathStr)
    return 1;

  CFStringGetCString(iniPathStr, iniPath, sizeof(iniPath),
                     kCFStringEncodingUTF8);
  CFRelease(iniPathStr);

#else

#ifdef XP_WIN
  wchar_t wide_path[MAX_PATH];
  if (!::GetModuleFileNameW(NULL, wide_path, MAX_PATH))
    return 1;

  WideCharToMultiByte(CP_UTF8, 0, wide_path,-1,
		      iniPath, MAX_PATH, NULL, NULL);

#elif defined(XP_OS2)
   PPIB ppib;
   PTIB ptib;

   DosGetInfoBlocks(&ptib, &ppib);
   DosQueryModuleName(ppib->pib_hmte, sizeof(iniPath), iniPath);

#elif defined(XP_BEOS)
   BEntry e((const char *)argv[0], true); // traverse symlink
   BPath p;
   status_t err;
   err = e.GetPath(&p);
   NS_ASSERTION(err == B_OK, "realpath failed");

   if (err == B_OK)
     // p.Path returns a pointer, so use strcpy to store path in iniPath
     strcpy(iniPath, p.Path());

#else
  // on unix, there is no official way to get the path of the current binary.
  // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to
  // multiple applications, we will try a series of techniques:
  //
  // 1) use realpath() on argv[0], which works unless we're loaded from the
  //    PATH
  // 2) manually walk through the PATH and look for ourself
  // 3) give up

  struct stat fileStat;

  if (!realpath(argv[0], iniPath) || stat(iniPath, &fileStat)) {
    const char *path = getenv("PATH");
    if (!path)
      return 1;

    char *pathdup = strdup(path);
    if (!pathdup)
      return 1;

    PRBool found = PR_FALSE;
    char *token = strtok(pathdup, ":");
    while (token) {
      sprintf(tmpPath, "%s/%s", token, argv[0]);
      if (realpath(tmpPath, iniPath) && stat(iniPath, &fileStat) == 0) {
        found = PR_TRUE;
        break;
      }
      token = strtok(NULL, ":");
    }
    free (pathdup);
    if (!found)
      return 1;
  }
#endif

  lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR);
  if (!lastSlash)
    return 1;

  *(++lastSlash) = '\0';

  // On Linux/Win, look for XULRunner in appdir/xulrunner

  snprintf(greDir, sizeof(greDir),
           "%sxulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL,
           iniPath);

  greFound = FolderExists(greDir);

  strncpy(lastSlash, "application.ini", sizeof(iniPath) - (lastSlash - iniPath));

#endif

  // If -app parameter was passed in, it is now time to take it under 
  // consideration.
  const char *appDataFile;
  appDataFile = getenv("XUL_APP_FILE");
  if (!appDataFile || !*appDataFile) 
    if (argc > 1 && IsArg(argv[1], "app")) {
      if (argc == 2) {
        Output(PR_FALSE, "specify APP-FILE (optional)\n");
        return 1;
      }
      argv[1] = argv[0];
      ++argv;
      --argc;

      appDataFile = argv[1];
      argv[1] = argv[0];
      ++argv;
      --argc;

      char kAppEnv[MAXPATHLEN];
      snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile);
      if (putenv(kAppEnv)) 
        Output(PR_FALSE, "Couldn't set %s.\n", kAppEnv);

      char *result = (char*) calloc(sizeof(char), MAXPATHLEN);
      if (NS_FAILED(GetRealPath(appDataFile, &result))) {
        Output(PR_TRUE, "Invalid application.ini path.\n");
        return 1;
      }
      
      // We have a valid application.ini path passed in to the -app parameter 
      // but not yet a valid greDir, so lets look for it also on the same folder
      // as the stub.
      if (!greFound) {
        lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR);
        if (!lastSlash)
          return 1;

        *(++lastSlash) = '\0';

        snprintf(greDir, sizeof(greDir), "%s" XPCOM_DLL, iniPath);
        greFound = FolderExists(greDir);
      }
      
      // copy it back.
      strcpy(iniPath, result);
    }
  
  nsINIParser parser;
  rv = parser.Init(iniPath);
  if (NS_FAILED(rv)) {
    fprintf(stderr, "Could not read application.ini\n");
    return 1;
  }

#ifdef WINCE
  // On Windows Mobile and WinCE, we can save a lot of time by not
  // waiting for XUL and XPCOM to load up.  Let's see if we can find
  // an existing app window to forward our command-line to now.

  // Shouldn't attempt this if the -no-remote parameter has been provided.
  bool noRemote = false;
  for (int i = 1; i < argc; i++) {
    if (IsArg(argv[i], "no-remote")) {
      noRemote = true;
      break;
    }
  }

  if (!noRemote) {
    char windowName[512];  // Is there a const for appname like VERSION_MAXLEN?
    rv = parser.GetString("App", "Name", windowName, sizeof(windowName));
    if (NS_FAILED(rv)) {
      fprintf(stderr, "Couldn't figure out the application name\n");
      return 1;
    }

    // Lookup the hidden message window created by nsNativeAppSupport
    strncat(windowName, "MessageWindow", sizeof(windowName) - strlen(windowName));
    WCHAR wWindowName[512];
    MultiByteToWideChar(CP_UTF8, 0, windowName, -1, wWindowName, sizeof(wWindowName));
    HWND wnd = ::FindWindowW(wWindowName, NULL);
    if (wnd) {
      // Forward the command-line and bail out
      ForwardToWindow(wnd);
      return 0;
    }
  }
#endif

  if (!greFound) {
    char minVersion[VERSION_MAXLEN];

    // If a gecko maxVersion is not specified, we assume that the app uses only
    // frozen APIs, and is therefore compatible with any xulrunner 1.x.
    char maxVersion[VERSION_MAXLEN] = "1.*";

    GREVersionRange range = {
      minVersion,
      PR_TRUE,
      maxVersion,
      PR_TRUE
    };

    rv = parser.GetString("Gecko", "MinVersion", minVersion, sizeof(minVersion));
    if (NS_FAILED(rv)) {
      fprintf(stderr,
              "The application.ini does not specify a [Gecko] MinVersion\n");
      return 1;
    }

    rv = parser.GetString("Gecko", "MaxVersion", maxVersion, sizeof(maxVersion));
    if (NS_SUCCEEDED(rv))
      range.upperInclusive = PR_TRUE;

    static const GREProperty kProperties[] = {
      { "xulrunner", "true" }
    };

    rv = GRE_GetGREPathWithProperties(&range, 1,
                                      kProperties, NS_ARRAY_LENGTH(kProperties),
                                      greDir, sizeof(greDir));
    if (NS_FAILED(rv)) {
      // XXXbsmedberg: Do something much smarter here: notify the
      // user/offer to download/?

      Output(PR_FALSE,
             "Could not find compatible GRE between version %s and %s.\n",
             range.lower, range.upper);
      return 1;
    }
#ifdef XP_UNIX
    // Using a symlinked greDir will fail during startup. Not sure why, but if
    // we resolve the symlink, everything works as expected.
    char resolved_greDir[MAXPATHLEN] = "";  
    if (realpath(greDir, resolved_greDir) && *resolved_greDir) {
      strncpy(greDir, resolved_greDir, MAXPATHLEN);
    }
#endif
  }

#ifdef XP_OS2
  // On OS/2 we need to set BEGINLIBPATH to be able to find XULRunner DLLs
  strcpy(tmpPath, greDir);
  lastSlash = strrchr(tmpPath, PATH_SEPARATOR_CHAR);
  if (lastSlash) {
    *lastSlash = '\0';
  }
  DosSetExtLIBPATH(tmpPath, BEGIN_LIBPATH);
#endif

  rv = XPCOMGlueStartup(greDir);
  if (NS_FAILED(rv)) {
    if (rv == NS_ERROR_OUT_OF_MEMORY) {
      char applicationName[2000] = "this application";
      parser.GetString("App", "Name", applicationName, sizeof(applicationName));
      Output(PR_TRUE, "Not enough memory available to start %s.\n",
             applicationName);
    } else {
      Output(PR_TRUE, "Couldn't load XPCOM.\n");
    }
    return 1;
  }

  static const nsDynamicFunctionLoad kXULFuncs[] = {
    { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
    { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
    { "XRE_main", (NSFuncPtr*) &XRE_main },
    { nsnull, nsnull }
  };

  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
  if (NS_FAILED(rv)) {
    Output(PR_TRUE, "Couldn't load XRE functions.\n");
    return 1;
  }

  NS_LogInit();

  int retval;

  { // Scope COMPtr and AutoAppData
    nsCOMPtr<nsILocalFile> iniFile;
#ifdef XP_WIN
    // On Windows and Windows CE, iniPath is UTF-8 encoded,
    // so we need to convert it.
    rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(iniPath), PR_FALSE,
                         getter_AddRefs(iniFile));
#else
    rv = NS_NewNativeLocalFile(nsDependentCString(iniPath), PR_FALSE,
                               getter_AddRefs(iniFile));
#endif
    if (NS_FAILED(rv)) {
      Output(PR_TRUE, "Couldn't find application.ini file.\n");
      return 1;
    }

    AutoAppData appData(iniFile);
    if (!appData) {
      Output(PR_TRUE, "Error: couldn't parse application.ini.\n");
      return 1;
    }

    NS_ASSERTION(appData->directory, "Failed to get app directory.");

    if (!appData->xreDirectory) {
      // chop "libxul.so" off the GRE path
      lastSlash = strrchr(greDir, PATH_SEPARATOR_CHAR);
      if (lastSlash) {
        *lastSlash = '\0';
      }
#ifdef XP_WIN
      // same as iniPath.
      NS_NewLocalFile(NS_ConvertUTF8toUTF16(greDir), PR_FALSE,
                      &appData->xreDirectory);
#else
      NS_NewNativeLocalFile(nsDependentCString(greDir), PR_FALSE,
                            &appData->xreDirectory);
#endif
    }

    retval = XRE_main(argc, argv, appData);
  }

  NS_LogTerm();

  XPCOMGlueShutdown();

  return retval;
}
Exemple #28
0
int main(int argc, char **argv) {
    prompt_read_history();

    mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4));

    pre_process_options(argc, argv);

#if MICROPY_ENABLE_GC
    char *heap = malloc(heap_size);
    gc_init(heap, heap + heap_size);
#endif

    mp_init();

    #ifndef _WIN32
    // create keyboard interrupt object
    MP_STATE_VM(keyboard_interrupt_obj) = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
    #endif

    char *home = getenv("HOME");
    char *path = getenv("MICROPYPATH");
    if (path == NULL) {
        path = "~/.micropython/lib:/usr/lib/micropython";
    }
    mp_uint_t path_num = 1; // [0] is for current dir (or base dir of the script)
    for (char *p = path; p != NULL; p = strchr(p, PATHLIST_SEP_CHAR)) {
        path_num++;
        if (p != NULL) {
            p++;
        }
    }
    mp_obj_list_init(mp_sys_path, path_num);
    mp_obj_t *path_items;
    mp_obj_list_get(mp_sys_path, &path_num, &path_items);
    path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_);
    {
    char *p = path;
    for (mp_uint_t i = 1; i < path_num; i++) {
        char *p1 = strchr(p, PATHLIST_SEP_CHAR);
        if (p1 == NULL) {
            p1 = p + strlen(p);
        }
        if (p[0] == '~' && p[1] == '/' && home != NULL) {
            // Expand standalone ~ to $HOME
            CHECKBUF(buf, PATH_MAX);
            CHECKBUF_APPEND(buf, home, strlen(home));
            CHECKBUF_APPEND(buf, p + 1, (size_t)(p1 - p - 1));
            path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(buf, CHECKBUF_LEN(buf)));
        } else {
            path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p));
        }
        p = p1 + 1;
    }
    }

    mp_obj_list_init(mp_sys_argv, 0);

    #if defined(MICROPY_UNIX_COVERAGE)
    {
        MP_DECLARE_CONST_FUN_OBJ(extra_coverage_obj);
        mp_store_global(QSTR_FROM_STR_STATIC("extra_coverage"), (mp_obj_t)&extra_coverage_obj);
    }
    #endif

    // Here is some example code to create a class and instance of that class.
    // First is the Python, then the C code.
    //
    // class TestClass:
    //     pass
    // test_obj = TestClass()
    // test_obj.attr = 42
    //
    // mp_obj_t test_class_type, test_class_instance;
    // test_class_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0));
    // mp_store_name(QSTR_FROM_STR_STATIC("test_obj"), test_class_instance = mp_call_function_0(test_class_type));
    // mp_store_attr(test_class_instance, QSTR_FROM_STR_STATIC("attr"), mp_obj_new_int(42));

    /*
    printf("bytes:\n");
    printf("    total %d\n", m_get_total_bytes_allocated());
    printf("    cur   %d\n", m_get_current_bytes_allocated());
    printf("    peak  %d\n", m_get_peak_bytes_allocated());
    */

    const int NOTHING_EXECUTED = -2;
    int ret = NOTHING_EXECUTED;
    for (int a = 1; a < argc; a++) {
        if (argv[a][0] == '-') {
            if (strcmp(argv[a], "-c") == 0) {
                if (a + 1 >= argc) {
                    return usage(argv);
                }
                ret = do_str(argv[a + 1]);
                if (ret & FORCED_EXIT) {
                    break;
                }
                a += 1;
            } else if (strcmp(argv[a], "-m") == 0) {
                if (a + 1 >= argc) {
                    return usage(argv);
                }
                mp_obj_t import_args[4];
                import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1]), false);
                import_args[1] = import_args[2] = mp_const_none;
                // Ask __import__ to handle imported module specially - set its __name__
                // to __main__, and also return this leaf module, not top-level package
                // containing it.
                import_args[3] = mp_const_false;
                // TODO: https://docs.python.org/3/using/cmdline.html#cmdoption-m :
                // "the first element of sys.argv will be the full path to
                // the module file (while the module file is being located,
                // the first element will be set to "-m")."
                set_sys_argv(argv, argc, a + 1);

                mp_obj_t mod;
                nlr_buf_t nlr;
                if (nlr_push(&nlr) == 0) {
                    mod = mp_builtin___import__(MP_ARRAY_SIZE(import_args), import_args);
                    nlr_pop();
                } else {
                    // uncaught exception
                    return handle_uncaught_exception((mp_obj_t)nlr.ret_val) & 0xff;
                }

                if (mp_obj_is_package(mod)) {
                    // TODO
                    fprintf(stderr, "%s: -m for packages not yet implemented\n", argv[0]);
                    exit(1);
                }
                ret = 0;
                break;
            } else if (strcmp(argv[a], "-X") == 0) {
                a += 1;
            } else if (strcmp(argv[a], "-v") == 0) {
                mp_verbose_flag++;
            } else if (strncmp(argv[a], "-O", 2) == 0) {
                if (isdigit(argv[a][2])) {
                    MP_STATE_VM(mp_optimise_value) = argv[a][2] & 0xf;
                } else {
                    MP_STATE_VM(mp_optimise_value) = 0;
                    for (char *p = argv[a] + 1; *p && *p == 'O'; p++, MP_STATE_VM(mp_optimise_value)++);
                }
            } else {
                return usage(argv);
            }
        } else {
            char *pathbuf = malloc(PATH_MAX);
            char *basedir = realpath(argv[a], pathbuf);
            if (basedir == NULL) {
                fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[a], errno);
                perror("");
                // CPython exits with 2 in such case
                ret = 2;
                break;
            }

            // Set base dir of the script as first entry in sys.path
            char *p = strrchr(basedir, '/');
            path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir));
            free(pathbuf);

            set_sys_argv(argv, argc, a);
            ret = do_file(argv[a]);
            break;
        }
    }

    if (ret == NOTHING_EXECUTED) {
        ret = do_repl();
    }

    #if MICROPY_PY_MICROPYTHON_MEM_INFO
    if (mp_verbose_flag) {
        mp_micropython_mem_info(0, NULL);
    }
    #endif

    mp_deinit();

#if MICROPY_ENABLE_GC && !defined(NDEBUG)
    // We don't really need to free memory since we are about to exit the
    // process, but doing so helps to find memory leaks.
    free(heap);
#endif

    //printf("total bytes = %d\n", m_get_total_bytes_allocated());
    prompt_write_history();
    return ret & 0xff;
}
Exemple #29
0
gboolean
x_realpath (const gchar *item, gchar *rpath)
{
	return !!realpath (item, rpath);
}
Exemple #30
0
TEST(stdlib, realpath__empty_filename) {
  errno = 0;
  char* p = realpath("", NULL);
  ASSERT_TRUE(p == NULL);
  ASSERT_EQ(ENOENT, errno);
}