Exemplo n.º 1
0
int
pseudo_client_shutdown(void) {
	pseudo_msg_t msg;
	pseudo_msg_t *ack;
	char *pseudo_path;

	pseudo_path = pseudo_prefix_path(NULL);
	if (pseudo_prefix_dir_fd == -1) {
		if (pseudo_path) {
			pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
			/* directory is missing? */
			if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
				pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
				mkdir_p(pseudo_path);
				pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
			}
			pseudo_prefix_dir_fd = pseudo_fd(pseudo_prefix_dir_fd, COPY_FD);
			free(pseudo_path);
		} else {
			pseudo_diag("No prefix available to to find server.\n");
			exit(1);
		}
		if (pseudo_prefix_dir_fd == -1) {
			pseudo_diag("Can't open prefix path (%s) for server. (%s)\n",
				pseudo_prefix_path(NULL),
				strerror(errno));
			exit(1);
		}
	}
	pseudo_path = pseudo_localstatedir_path(NULL);
	mkdir_p(pseudo_path);
	if (pseudo_localstate_dir_fd == -1) {
		if (pseudo_path) {
			pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
			/* directory is missing? */
			if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
				pseudo_debug(1, "local state dir doesn't exist, trying to create\n");
				mkdir_p(pseudo_path);
				pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
			}
			pseudo_localstate_dir_fd = pseudo_fd(pseudo_localstate_dir_fd, COPY_FD);
			free(pseudo_path);
		} else {
			pseudo_diag("No prefix available to to find server.\n");
			exit(1);
		}
		if (pseudo_localstate_dir_fd == -1) {
			pseudo_diag("Can't open local state path (%s) for server. (%s)\n",
				pseudo_localstatedir_path(NULL),
				strerror(errno));
			exit(1);
		}
	}
	if (client_connect()) {
		pseudo_diag("Pseudo server seems to be already offline.\n");
		return 0;
	}
	memset(&msg, 0, sizeof(pseudo_msg_t));
	msg.type = PSEUDO_MSG_SHUTDOWN;
	msg.op = OP_NONE;
	msg.client = getpid();
	pseudo_debug(2, "sending shutdown request\n");
	if (pseudo_msg_send(connect_fd, &msg, 0, NULL)) {
		pseudo_debug(1, "error requesting shutdown: %s\n", strerror(errno));
		return 1;
	}
	ack = pseudo_msg_receive(connect_fd);
	if (!ack) {
		pseudo_diag("server did not respond to shutdown query.\n");
		return 1;
	}
	if (ack->type == PSEUDO_MSG_ACK) {
		return 0;
	}
	pseudo_diag("Server refused shutdown.  Remaining client fds: %d\n", ack->fd);
	pseudo_diag("Client pids: %s\n", ack->path);
	pseudo_diag("Server will shut down after all clients exit.\n");
	return 0;
}
Exemplo n.º 2
0
/**
 *  Hauptfunktion von Siedler II.5 Return to the Roots
 *
 *  @param[in] argc Anzahl übergebener Argumente
 *  @param[in] argv Array der übergebenen Argumente
 *
 *  @return Exit Status, 0 bei Erfolg, > 0 bei Fehler
 *
 *  @author FloSoft
 *  @author OLiver
 */
int main(int argc, char* argv[])
{
#if defined _WIN32 && defined _DEBUG && defined _MSC_VER && !defined NOHWETRANS
    _set_se_translator(ExceptionHandler);
#endif // _WIN32 && _DEBUG && !NOHWETRANS

#if defined _WIN32 && defined _DEBUG && defined _MSC_VER && !defined NOCRTDBG
    // Enable Memory-Leak-Detection
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF /*| _CRTDBG_CHECK_CRT_DF*/);
#endif // _WIN32 && _DEBUG && !NOCRTDBG

    // Signal-Handler setzen
#ifdef _WIN32
    SetConsoleCtrlHandler(HandlerRoutine, TRUE);

    // set console window icon
    SendMessage(GetConsoleWindow(), WM_SETICON, (WPARAM)TRUE, (LPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SYMBOL)));

    // Set UTF-8 console charset
    SetConsoleOutputCP(CP_UTF8);

#ifndef _MSC_VER
    signal(SIGSEGV, WinExceptionHandler);
#else
    SetUnhandledExceptionFilter(WinExceptionHandler);
#endif
    //AddVectoredExceptionHandler(1, WinExceptionHandler);
#else
    struct sigaction sa;
    sa.sa_handler = HandlerRoutine;
    sa.sa_flags = 0; //SA_RESTART would not allow to interrupt connect call;
    sigemptyset(&sa.sa_mask);

    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);
    sigaction(SIGALRM, &sa, NULL);

    signal(SIGSEGV, LinExceptionHandler);
#endif // _WIN32

    // diverse dirs anlegen
    const unsigned int dir_count = 7;
    unsigned int dirs[dir_count] = { 94, 47, 48, 51, 85, 98, 99 }; // settingsdir muss zuerst angelegt werden (94)

#ifdef _WIN32
    if(IsDir(GetFilePath("~/Siedler II.5 RttR")))
        MoveFileA(GetFilePath("~/Siedler II.5 RttR").c_str(), GetFilePath(FILE_PATHS[94]).c_str());
#endif

#ifdef __APPLE__
    if(IsDir(GetFilePath("~/.s25rttr")))
        rename(GetFilePath("~/.s25rttr").c_str(), GetFilePath(FILE_PATHS[94]).c_str());
#endif

    for(unsigned int i = 0; i < dir_count; ++i)
    {
        std::string dir = GetFilePath(FILE_PATHS[dirs[i]]);

        if(mkdir_p(dir) < 0)
        {
            error("Verzeichnis %s konnte nicht erstellt werden: ", dir.c_str());
            error("Das Spiel konnte nicht gestartet werden");
            return 1;
        }
    }

    libsiedler2::setTextureFormat(libsiedler2::FORMAT_RGBA);
    libsiedler2::setAllocator(glAllocator);

    // Zufallsgenerator initialisieren (Achtung: nur für Animationens-Offsets interessant, für alles andere (spielentscheidende) wird unser Generator verwendet)
    srand(static_cast<unsigned int>(std::time(NULL)));

    // Exit-Handler initialisieren
    atexit(&ExitHandler);

    // Socketzeug initialisieren
    if(!Socket::Initialize())
    {
        error("Konnte Sockets nicht initialisieren!");
        return 1;
    }

    // Spiel starten
    if(!GAMEMANAGER.Start())
    {
        error("Das Spiel konnte nicht gestartet werden");
        return 1;
    }

#ifndef NDEBUG
    if (argc > 1)
    {
        CreateServerInfo csi;
        csi.gamename = _("Unlimited Play");
        csi.password = "******";
        csi.port = 3665;
        csi.type = NP_LOCAL;
        csi.ipv6 = false;
        csi.use_upnp = false;

        printf("loading game!\n");

        WindowManager::inst().Switch(new dskSelectMap(csi));

        if(!GAMESERVER.TryToStart(csi, argv[1], MAPTYPE_SAVEGAME))
        {
            if(!GAMESERVER.TryToStart(csi, argv[1], MAPTYPE_OLDMAP))
            {
                GameWorldViewer* gwv;
                unsigned int error = GAMECLIENT.StartReplay(argv[1], gwv);

                std::string replay_errors[] =
                {
                    _("Error while playing replay!"),
                    _("Error while opening file!"),
                    _("Invalid Replay!"),
                    _("Error: Replay is too old!"),
                    _("Program version is too old to play that replay!"),
                    "",
                    _("Temporary map file was not found!")
                };

                if (error)
                {
                    printf("ERROR: %s\n", replay_errors[error].c_str());
                }
                else
                {
                    WindowManager::inst().Switch(new dskGameLoader(gwv));
                }
            }
            else
            {
                WindowManager::inst().Draw();
                WindowManager::inst().Show(new iwPleaseWait);
            }
        }
        else
        {
            WindowManager::inst().Draw();
            WindowManager::inst().Show(new iwPleaseWait);
        }
    }
#endif

    // Hauptschleife
    while(GAMEMANAGER.Run())
    {
#ifndef _WIN32
        extern bool killme;
        killme = false;
#endif // !_WIN32
    }

    // Spiel beenden
    GAMEMANAGER.Stop();

    return 0;
}
Exemplo n.º 3
0
void
pseudo_init_client(void) {
	char *env;

	pseudo_antimagic();
	pseudo_new_pid();
	if (connect_fd != -1) {
		close(connect_fd);
		connect_fd = -1;
	}

	/* in child processes, PSEUDO_DISABLED may have become set to
	 * some truthy value, in which case we'd disable pseudo,
	 * or it may have gone away, in which case we'd enable
	 * pseudo (and cause it to reinit the defaults).
	 */
	env = getenv("PSEUDO_DISABLED");
	if (!env) {
		env = pseudo_get_value("PSEUDO_DISABLED");
	}
	if (env) {
		int actually_disabled = 1;
		switch (*env) {
		case '0':
		case 'f':
		case 'F':
		case 'n':
		case 'N':
			actually_disabled = 0;
			break;
		case 's':
		case 'S':
			actually_disabled = 0;
			pseudo_local_only = 1;
			break;
		}
		if (actually_disabled) {
			if (!pseudo_disabled) {
				pseudo_antimagic();
				pseudo_disabled = 1;
			}
			pseudo_set_value("PSEUDO_DISABLED", "1");
		} else {
			if (pseudo_disabled) {
				pseudo_magic();
				pseudo_disabled = 0;
				pseudo_inited = 0; /* Re-read the initial values! */
			}
			pseudo_set_value("PSEUDO_DISABLED", "0");
		}
	} else {
		pseudo_set_value("PSEUDO_DISABLED", "0");
	}

	/* Setup global items needed for pseudo to function... */
	if (!pseudo_inited) {
		/* Ensure that all of the values are reset */
		server_pid = 0;
		pseudo_prefix_dir_fd = -1;
		pseudo_localstate_dir_fd = -1;
		pseudo_pwd_fd = -1;
		pseudo_pwd_lck_fd = -1;
		pseudo_pwd_lck_name = NULL;
		pseudo_pwd = NULL;
		pseudo_grp_fd = -1;
		pseudo_grp = NULL;
		pseudo_cwd = NULL;
		pseudo_cwd_len = 0;
		pseudo_chroot = NULL;
		pseudo_passwd = NULL;
		pseudo_chroot_len = 0;
		pseudo_cwd_rel = NULL;
		pseudo_nosymlinkexp = 0;
	}

	if (!pseudo_disabled && !pseudo_inited) {
		char *pseudo_path = 0;

		pseudo_path = pseudo_prefix_path(NULL);
		if (pseudo_prefix_dir_fd == -1) {
			if (pseudo_path) {
				pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
				/* directory is missing? */
				if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
					pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
					mkdir_p(pseudo_path);
					pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
				}
				pseudo_prefix_dir_fd = pseudo_fd(pseudo_prefix_dir_fd, MOVE_FD);
			} else {
				pseudo_diag("No prefix available to to find server.\n");
				exit(1);
			}
			if (pseudo_prefix_dir_fd == -1) {
				pseudo_diag("Can't open prefix path (%s) for server: %s\n",
					pseudo_path,
					strerror(errno));
				exit(1);
			}
		}
		free(pseudo_path);
		pseudo_path = pseudo_localstatedir_path(NULL);
		if (pseudo_localstate_dir_fd == -1) {
			if (pseudo_path) {
				pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
				/* directory is missing? */
				if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
					pseudo_debug(1, "local state directory doesn't exist, trying to create\n");
					mkdir_p(pseudo_path);
					pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
				}
				pseudo_localstate_dir_fd = pseudo_fd(pseudo_localstate_dir_fd, MOVE_FD);
			} else {
				pseudo_diag("No prefix available to to find server.\n");
				exit(1);
			}
			if (pseudo_localstate_dir_fd == -1) {
				pseudo_diag("Can't open local state path (%s) for server: %s\n",
					pseudo_path,
					strerror(errno));
				exit(1);
			}
		}
		free(pseudo_path);

		env = pseudo_get_value("PSEUDO_NOSYMLINKEXP");
		if (env) {
			char *endptr;
			/* if the environment variable is not an empty string,
			 * parse it; "0" means turn NOSYMLINKEXP off, "1" means
			 * turn it on (disabling the feature).  An empty string
			 * or something we can't parse means to set the flag; this
			 * is a safe default because if you didn't want the flag
			 * set, you normally wouldn't set the environment variable
			 * at all.
			 */
			if (*env) {
				pseudo_nosymlinkexp = strtol(env, &endptr, 10);
				if (*endptr)
					pseudo_nosymlinkexp = 1;
			} else {
				pseudo_nosymlinkexp = 1;
			}
		} else {
			pseudo_nosymlinkexp = 0;
		}
		free(env);
		env = pseudo_get_value("PSEUDO_UIDS");
		if (env)
			sscanf(env, "%d,%d,%d,%d",
				&pseudo_ruid, &pseudo_euid,
				&pseudo_suid, &pseudo_fuid);
		free(env);

		env = pseudo_get_value("PSEUDO_GIDS");
		if (env)
			sscanf(env, "%d,%d,%d,%d",
				&pseudo_rgid, &pseudo_egid,
				&pseudo_sgid, &pseudo_fuid);
		free(env);

		env = pseudo_get_value("PSEUDO_CHROOT");
		if (env) {
			pseudo_chroot = strdup(env);
			if (pseudo_chroot) {
				pseudo_chroot_len = strlen(pseudo_chroot);
			} else {
				pseudo_diag("can't store chroot path (%s)\n", env);
			}
		}
		free(env);

		env = pseudo_get_value("PSEUDO_PASSWD");
		if (env) {
			pseudo_passwd = strdup(env);
		}
		free(env);

		pseudo_inited = 1;
	}
	if (!pseudo_disabled)
		pseudo_client_getcwd();

	pseudo_magic();
}
Exemplo n.º 4
0
static int scrub_start(int argc, char **argv, int resume)
{
	int fdmnt;
	int prg_fd = -1;
	int fdres = -1;
	int ret;
	pid_t pid;
	int c;
	int i;
	int err = 0;
	int e_uncorrectable = 0;
	int e_correctable = 0;
	int print_raw = 0;
	char *path;
	int do_background = 1;
	int do_wait = 0;
	int do_print = 0;
	int do_quiet = 0;
	int do_record = 1;
	int readonly = 0;
	int do_stats_per_dev = 0;
	int ioprio_class = IOPRIO_CLASS_IDLE;
	int ioprio_classdata = 0;
	int n_start = 0;
	int n_skip = 0;
	int n_resume = 0;
	struct btrfs_ioctl_fs_info_args fi_args;
	struct btrfs_ioctl_dev_info_args *di_args = NULL;
	struct scrub_progress *sp = NULL;
	struct scrub_fs_stat fs_stat;
	struct timeval tv;
	struct sockaddr_un addr = {
		.sun_family = AF_UNIX,
	};
	pthread_t *t_devs = NULL;
	pthread_t t_prog;
	struct scrub_file_record **past_scrubs = NULL;
	struct scrub_file_record *last_scrub = NULL;
	char *datafile = strdup(SCRUB_DATA_FILE);
	char fsid[BTRFS_UUID_UNPARSED_SIZE];
	char sock_path[PATH_MAX] = "";
	struct scrub_progress_cycle spc;
	pthread_mutex_t spc_write_mutex = PTHREAD_MUTEX_INITIALIZER;
	void *terr;
	u64 devid;
	DIR *dirstream = NULL;
	int force = 0;
	int nothing_to_resume = 0;

	while ((c = getopt(argc, argv, "BdqrRc:n:f")) != -1) {
		switch (c) {
		case 'B':
			do_background = 0;
			do_wait = 1;
			do_print = 1;
			break;
		case 'd':
			do_stats_per_dev = 1;
			break;
		case 'q':
			do_quiet = 1;
			break;
		case 'r':
			readonly = 1;
			break;
		case 'R':
			print_raw = 1;
			break;
		case 'c':
			ioprio_class = (int)strtol(optarg, NULL, 10);
			break;
		case 'n':
			ioprio_classdata = (int)strtol(optarg, NULL, 10);
			break;
		case 'f':
			force = 1;
			break;
		case '?':
		default:
			usage(resume ? cmd_scrub_resume_usage :
						cmd_scrub_start_usage);
		}
	}

	/* try to catch most error cases before forking */

	if (check_argc_exact(argc - optind, 1)) {
		usage(resume ? cmd_scrub_resume_usage :
					cmd_scrub_start_usage);
	}

	spc.progress = NULL;
	if (do_quiet && do_print)
		do_print = 0;

	if (mkdir_p(datafile)) {
		warning_on(!do_quiet,
    "cannot create scrub data file, mkdir %s failed: %s. Status recording disabled",
			datafile, strerror(errno));
		do_record = 0;
	}
	free(datafile);

	path = argv[optind];

	fdmnt = open_path_or_dev_mnt(path, &dirstream, !do_quiet);
	if (fdmnt < 0)
		return 1;

	ret = get_fs_info(path, &fi_args, &di_args);
	if (ret) {
		error_on(!do_quiet,
			"getting dev info for scrub failed: %s",
			 strerror(-ret));
		err = 1;
		goto out;
	}
	if (!fi_args.num_devices) {
		error_on(!do_quiet, "no devices found");
		err = 1;
		goto out;
	}

	uuid_unparse(fi_args.fsid, fsid);
	fdres = scrub_open_file_r(SCRUB_DATA_FILE, fsid);
	if (fdres < 0 && fdres != -ENOENT) {
		warning_on(!do_quiet, "failed to open status file: %s",
			strerror(-fdres));
	} else if (fdres >= 0) {
		past_scrubs = scrub_read_file(fdres, !do_quiet);
		if (IS_ERR(past_scrubs))
			warning_on(!do_quiet, "failed to read status file: %s",
				strerror(-PTR_ERR(past_scrubs)));
		close(fdres);
	}

	/*
	 * Check for stale information in the status file, ie. if it's
	 * canceled=0, finished=0 but no scrub is running.
	 */
	if (!is_scrub_running_in_kernel(fdmnt, di_args, fi_args.num_devices))
		force = 1;

	/*
	 * check whether any involved device is already busy running a
	 * scrub. This would cause damaged status messages and the state
	 * "aborted" without the explanation that a scrub was already
	 * running. Therefore check it first, prevent it and give some
	 * feedback to the user if scrub is already running.
	 * Note that if scrub is started with a block device as the
	 * parameter, only that particular block device is checked. It
	 * is a normal mode of operation to start scrub on multiple
	 * single devices, there is no reason to prevent this.
	 */
	if (!force && is_scrub_running_on_fs(&fi_args, di_args, past_scrubs)) {
		error_on(!do_quiet,
			"Scrub is already running.\n"
			"To cancel use 'btrfs scrub cancel %s'.\n"
			"To see the status use 'btrfs scrub status [-d] %s'",
			path, path);
		err = 1;
		goto out;
	}

	t_devs = malloc(fi_args.num_devices * sizeof(*t_devs));
	sp = calloc(fi_args.num_devices, sizeof(*sp));
	spc.progress = calloc(fi_args.num_devices * 2, sizeof(*spc.progress));

	if (!t_devs || !sp || !spc.progress) {
		error_on(!do_quiet, "scrub failed: %s", strerror(errno));
		err = 1;
		goto out;
	}

	for (i = 0; i < fi_args.num_devices; ++i) {
		devid = di_args[i].devid;
		ret = pthread_mutex_init(&sp[i].progress_mutex, NULL);
		if (ret) {
			error_on(!do_quiet, "pthread_mutex_init failed: %s",
				strerror(ret));
			err = 1;
			goto out;
		}
		last_scrub = last_dev_scrub(past_scrubs, devid);
		sp[i].scrub_args.devid = devid;
		sp[i].fd = fdmnt;
		if (resume && last_scrub && (last_scrub->stats.canceled ||
					     !last_scrub->stats.finished)) {
			++n_resume;
			sp[i].scrub_args.start = last_scrub->p.last_physical;
			sp[i].resumed = last_scrub;
		} else if (resume) {
			++n_skip;
			sp[i].skip = 1;
			sp[i].resumed = last_scrub;
			continue;
		} else {
			++n_start;
			sp[i].scrub_args.start = 0ll;
			sp[i].resumed = NULL;
		}
		sp[i].skip = 0;
		sp[i].scrub_args.end = (u64)-1ll;
		sp[i].scrub_args.flags = readonly ? BTRFS_SCRUB_READONLY : 0;
		sp[i].ioprio_class = ioprio_class;
		sp[i].ioprio_classdata = ioprio_classdata;
	}

	if (!n_start && !n_resume) {
		if (!do_quiet)
			printf("scrub: nothing to resume for %s, fsid %s\n",
			       path, fsid);
		nothing_to_resume = 1;
		goto out;
	}

	ret = prg_fd = socket(AF_UNIX, SOCK_STREAM, 0);
	while (ret != -1) {
		ret = scrub_datafile(SCRUB_PROGRESS_SOCKET_PATH, fsid, NULL,
					sock_path, sizeof(sock_path));
		/* ignore EOVERFLOW, try using a shorter path for the socket */
		addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
		strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1);
		ret = bind(prg_fd, (struct sockaddr *)&addr, sizeof(addr));
		if (ret != -1 || errno != EADDRINUSE)
			break;
		/*
		 * bind failed with EADDRINUSE. so let's see if anyone answers
		 * when we make a call to the socket ...
		 */
		ret = connect(prg_fd, (struct sockaddr *)&addr, sizeof(addr));
		if (!ret || errno != ECONNREFUSED) {
			/* ... yes, so scrub must be running. error out */
			error("scrub already running");
			close(prg_fd);
			prg_fd = -1;
			goto out;
		}
		/*
		 * ... no, this means someone left us alone with an unused
		 * socket in the file system. remove it and try again.
		 */
		ret = unlink(sock_path);
	}
	if (ret != -1)
		ret = listen(prg_fd, 100);
	if (ret == -1) {
		warning_on(!do_quiet,
   "failed to open the progress status socket at %s: %s. Progress cannot be queried",
			sock_path[0] ? sock_path :
			SCRUB_PROGRESS_SOCKET_PATH, strerror(errno));
		if (prg_fd != -1) {
			close(prg_fd);
			prg_fd = -1;
			if (sock_path[0])
				unlink(sock_path);
		}
	}

	if (do_record) {
		/* write all-zero progress file for a start */
		ret = scrub_write_progress(&spc_write_mutex, fsid, sp,
					   fi_args.num_devices);
		if (ret) {
			warning_on(!do_quiet,
   "failed to write the progress status file: %s. Status recording disabled",
				strerror(-ret));
			do_record = 0;
		}
	}

	if (do_background) {
		pid = fork();
		if (pid == -1) {
			error_on(!do_quiet, "cannot scrub, fork failed: %s",
				strerror(errno));
			err = 1;
			goto out;
		}

		if (pid) {
			int stat;
			scrub_handle_sigint_parent();
			if (!do_quiet)
				printf("scrub %s on %s, fsid %s (pid=%d)\n",
				       n_start ? "started" : "resumed",
				       path, fsid, pid);
			if (!do_wait) {
				err = 0;
				goto out;
			}
			ret = wait(&stat);
			if (ret != pid) {
				error_on(!do_quiet, "wait failed (ret=%d): %s",
					ret, strerror(errno));
				err = 1;
				goto out;
			}
			if (!WIFEXITED(stat) || WEXITSTATUS(stat)) {
				error_on(!do_quiet, "scrub process failed");
				err = WIFEXITED(stat) ? WEXITSTATUS(stat) : -1;
				goto out;
			}
			err = 0;
			goto out;
		}
	}

	scrub_handle_sigint_child(fdmnt);

	for (i = 0; i < fi_args.num_devices; ++i) {
		if (sp[i].skip) {
			sp[i].scrub_args.progress = sp[i].resumed->p;
			sp[i].stats = sp[i].resumed->stats;
			sp[i].ret = 0;
			sp[i].stats.finished = 1;
			continue;
		}
		devid = di_args[i].devid;
		gettimeofday(&tv, NULL);
		sp[i].stats.t_start = tv.tv_sec;
		ret = pthread_create(&t_devs[i], NULL,
					scrub_one_dev, &sp[i]);
		if (ret) {
			if (do_print)
			error("creating scrub_one_dev[%llu] thread failed: %s",
				devid, strerror(ret));
			err = 1;
			goto out;
		}
	}

	spc.fdmnt = fdmnt;
	spc.prg_fd = prg_fd;
	spc.do_record = do_record;
	spc.write_mutex = &spc_write_mutex;
	spc.shared_progress = sp;
	spc.fi = &fi_args;
	ret = pthread_create(&t_prog, NULL, scrub_progress_cycle, &spc);
	if (ret) {
		if (do_print)
			error("creating progress thread failed: %s",
				strerror(ret));
		err = 1;
		goto out;
	}

	err = 0;
	for (i = 0; i < fi_args.num_devices; ++i) {
		if (sp[i].skip)
			continue;
		devid = di_args[i].devid;
		ret = pthread_join(t_devs[i], NULL);
		if (ret) {
			if (do_print)
			  error("pthread_join failed for scrub_one_dev[%llu]: %s",
				devid, strerror(ret));
			++err;
			continue;
		}
		if (sp[i].ret) {
			switch (sp[i].ioctl_errno) {
			case ENODEV:
				if (do_print)
					warning("device %lld not present",
						devid);
				continue;
			case ECANCELED:
				++err;
				break;
			default:
				if (do_print)
		error("scrubbing %s failed for device id %lld: ret=%d, errno=%d (%s)",
					path, devid,
					sp[i].ret, sp[i].ioctl_errno,
					strerror(sp[i].ioctl_errno));
				++err;
				continue;
			}
		}
		if (sp[i].scrub_args.progress.uncorrectable_errors > 0)
			e_uncorrectable++;
		if (sp[i].scrub_args.progress.corrected_errors > 0
		    || sp[i].scrub_args.progress.unverified_errors > 0)
			e_correctable++;
	}

	if (do_print) {
		const char *append = "done";
		if (!do_stats_per_dev)
			init_fs_stat(&fs_stat);
		for (i = 0; i < fi_args.num_devices; ++i) {
			if (do_stats_per_dev) {
				print_scrub_dev(&di_args[i],
						&sp[i].scrub_args.progress,
						print_raw,
						sp[i].ret ? "canceled" : "done",
						&sp[i].stats);
			} else {
				if (sp[i].ret)
					append = "canceled";
				add_to_fs_stat(&sp[i].scrub_args.progress,
						&sp[i].stats, &fs_stat);
			}
		}
		if (!do_stats_per_dev) {
			printf("scrub %s for %s\n", append, fsid);
			print_fs_stat(&fs_stat, print_raw);
		}
	}

	ret = pthread_cancel(t_prog);
	if (!ret)
		ret = pthread_join(t_prog, &terr);

	/* check for errors from the handling of the progress thread */
	if (do_print && ret) {
		error("progress thread handling failed: %s",
			strerror(ret));
	}

	/* check for errors returned from the progress thread itself */
	if (do_print && terr && terr != PTHREAD_CANCELED)
		error("recording progress failed: %s",
			strerror(-PTR_ERR(terr)));

	if (do_record) {
		ret = scrub_write_progress(&spc_write_mutex, fsid, sp,
					   fi_args.num_devices);
		if (ret && do_print)
			error("failed to record the result: %s",
				strerror(-ret));
	}

	scrub_handle_sigint_child(-1);

out:
	free_history(past_scrubs);
	free(di_args);
	free(t_devs);
	free(sp);
	free(spc.progress);
	if (prg_fd > -1) {
		close(prg_fd);
		if (sock_path[0])
			unlink(sock_path);
	}
	close_file_or_dir(fdmnt, dirstream);

	if (err)
		return 1;
	if (nothing_to_resume)
		return 2;
	if (e_uncorrectable) {
		error_on(!do_quiet, "there are uncorrectable errors");
		return 3;
	}
	if (e_correctable)
		warning_on(!do_quiet,
			"errors detected during scrubbing, corrected");

	return 0;
}
Exemplo n.º 5
0
static int stdout_stream_save(StdoutStream *s) {
        _cleanup_free_ char *temp_path = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(s);

        if (s->state != STDOUT_STREAM_RUNNING)
                return 0;

        if (!s->state_file) {
                struct stat st;

                r = fstat(s->fd, &st);
                if (r < 0)
                        return log_warning_errno(errno, "Failed to stat connected stream: %m");

                /* We use device and inode numbers as identifier for the stream */
                if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
                        return log_oom();
        }

        mkdir_p("/run/systemd/journal/streams", 0755);

        r = fopen_temporary(s->state_file, &f, &temp_path);
        if (r < 0)
                goto fail;

        fprintf(f,
                "# This is private data. Do not parse\n"
                "PRIORITY=%i\n"
                "LEVEL_PREFIX=%i\n"
                "FORWARD_TO_SYSLOG=%i\n"
                "FORWARD_TO_KMSG=%i\n"
                "FORWARD_TO_CONSOLE=%i\n"
                "STREAM_ID=%s\n",
                s->priority,
                s->level_prefix,
                s->forward_to_syslog,
                s->forward_to_kmsg,
                s->forward_to_console,
                s->id_field + strlen("_STREAM_ID="));

        if (!isempty(s->identifier)) {
                _cleanup_free_ char *escaped;

                escaped = cescape(s->identifier);
                if (!escaped) {
                        r = -ENOMEM;
                        goto fail;
                }

                fprintf(f, "IDENTIFIER=%s\n", escaped);
        }

        if (!isempty(s->unit_id)) {
                _cleanup_free_ char *escaped;

                escaped = cescape(s->unit_id);
                if (!escaped) {
                        r = -ENOMEM;
                        goto fail;
                }

                fprintf(f, "UNIT=%s\n", escaped);
        }

        r = fflush_and_check(f);
        if (r < 0)
                goto fail;

        if (rename(temp_path, s->state_file) < 0) {
                r = -errno;
                goto fail;
        }

        if (!s->fdstore && !s->in_notify_queue) {
                LIST_PREPEND(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
                s->in_notify_queue = true;

                if (s->server->notify_event_source) {
                        r = sd_event_source_set_enabled(s->server->notify_event_source, SD_EVENT_ON);
                        if (r < 0)
                                log_warning_errno(r, "Failed to enable notify event source: %m");
                }
        }

        return 0;

fail:
        (void) unlink(s->state_file);

        if (temp_path)
                (void) unlink(temp_path);

        return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
}
Exemplo n.º 6
0
Arquivo: main.c Projeto: heyLu/planck
int main(int argc, char **argv) {
	struct option long_options[] = {
		{"help", no_argument, NULL, 'h'},
		{"legal", no_argument, NULL, 'l'},
		{"verbose", no_argument, NULL, 'v'},
		{"quiet", no_argument, NULL, 'q'},
		{"repl", no_argument, NULL, 'r'},
		{"static-fns", no_argument, NULL, 's'},
		{"elide-asserts", no_argument, NULL, 'a'},
		{"cache", required_argument, NULL, 'k'},
		{"eval", required_argument, NULL, 'e'},
		{"theme", required_argument, NULL, 't'},
		{"classpath", required_argument, NULL, 'c'},
		{"auto-cache", no_argument, NULL, 'K'},
		{"init", required_argument, NULL, 'i'},
		{"main", required_argument, NULL, 'm'},

		// development options
		{"javascript", no_argument, NULL, 'j'},
		{"out", required_argument, NULL, 'o'},

		{0, 0, 0, 0}
	};
	int opt, option_index;
	while ((opt = getopt_long(argc, argv, "h?lvrsak:je:t:c:o:Ki:qm:", long_options, &option_index)) != -1) {
		switch (opt) {
		case 'h':
			usage(argv[0]);
			exit(0);
		case 'l':
			legal();
			return 0;
		case 'v':
			verbose = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			repl = true;
			break;
		case 's':
			static_fns = true;
			break;
		case 'a':
			elide_asserts = true;
			break;
		case 'k':
			cache_path = argv[optind - 1];
			break;
		case 'K':
			cache_path = ".planck_cache";
			{
				char *path_copy = strdup(cache_path);
				char *dir = dirname(path_copy);
				if (mkdir_p(dir) < 0) {
					fprintf(stderr, "Could not create %s: %s\n", cache_path, strerror(errno));
				}
				free(path_copy);
			}
			break;
		case 'j':
			javascript = true;
			break;
		case 'e':
			num_scripts += 1;
			scripts = realloc(scripts, num_scripts * sizeof(struct script));
			scripts[num_scripts - 1].type = "text";
			scripts[num_scripts - 1].expression = true;
			scripts[num_scripts - 1].source = argv[optind - 1];
			break;
		case 'i':
			num_scripts += 1;
			scripts = realloc(scripts, num_scripts * sizeof(struct script));
			scripts[num_scripts - 1].type = "path";
			scripts[num_scripts - 1].expression = false;
			scripts[num_scripts - 1].source = argv[optind - 1];
			break;
		case 'm':
			main_ns_name = argv[optind - 1];
		case 't':
			theme = argv[optind - 1];
			break;
		case 'c':
			{
				char *classpath = argv[optind - 1];
				char *source = strtok(classpath, ":");
				while (source != NULL) {
					char *type = "src";
					if (str_has_suffix(source, ".jar") == 0) {
						type = "jar";
					}

					num_src_paths += 1;
					src_paths = realloc(src_paths, num_src_paths * sizeof(struct src_path));
					src_paths[num_src_paths - 1].type = type;
					src_paths[num_src_paths - 1].path = strdup(source);

					source = strtok(NULL, ":");
				}

				break;
			}
		case 'o':
			out_path = argv[optind - 1];
			break;
		case '?':
			usage(argv[0]);
			exit(1);
		default:
			printf("unhandled argument: %c\n", opt);
		}
	}

	int num_rest_args = 0;
	char **rest_args = NULL;
	if (optind < argc) {
		num_rest_args = argc - optind;
		rest_args = malloc((argc - optind) * sizeof(char*));
		int i = 0;
		while (optind < argc) {
			rest_args[i++] = argv[optind++];
		}
	}

	if (num_scripts == 0 && main_ns_name == NULL && num_rest_args == 0) {
		repl = true;
	}

	if (main_ns_name != NULL && repl) {
		printf("Only one main-opt can be specified.");
	}

	JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
	global_ctx = ctx;

	JSStringRef nameRef = JSStringCreateWithUTF8CString("planck");
	JSGlobalContextSetName(ctx, nameRef);

	evaluate_script(ctx, "var global = this;", "<init>");

	register_global_function(ctx, "AMBLY_IMPORT_SCRIPT", function_import_script);
	bootstrap(ctx, out_path);

	register_global_function(ctx, "PLANCK_CONSOLE_LOG", function_console_log);
	register_global_function(ctx, "PLANCK_CONSOLE_ERROR", function_console_error);

	evaluate_script(ctx, "var console = {};"\
			"console.log = PLANCK_CONSOLE_LOG;"\
			"console.error = PLANCK_CONSOLE_ERROR;", "<init>");

	evaluate_script(ctx, "var PLANCK_VERSION = \"" PLANCK_VERSION "\";", "<init>");

	// require app namespaces
	evaluate_script(ctx, "goog.require('planck.repl');", "<init>");

	// without this things won't work
	evaluate_script(ctx, "var window = global;", "<init>");

	register_global_function(ctx, "PLANCK_READ_FILE", function_read_file);
	register_global_function(ctx, "PLANCK_LOAD", function_load);
	register_global_function(ctx, "PLANCK_LOAD_DEPS_CLJS_FILES", function_load_deps_cljs_files);
	register_global_function(ctx, "PLANCK_CACHE", function_cache);

	register_global_function(ctx, "PLANCK_EVAL", function_eval);

	register_global_function(ctx, "PLANCK_GET_TERM_SIZE", function_get_term_size);
	register_global_function(ctx, "PLANCK_PRINT_FN", function_print_fn);
	register_global_function(ctx, "PLANCK_PRINT_ERR_FN", function_print_err_fn);

	register_global_function(ctx, "PLANCK_SET_EXIT_VALUE", function_set_exit_value);

	is_tty = isatty(STDIN_FILENO) == 1;
	register_global_function(ctx, "PLANCK_RAW_READ_STDIN", function_raw_read_stdin);
	register_global_function(ctx, "PLANCK_RAW_WRITE_STDOUT", function_raw_write_stdout);
	register_global_function(ctx, "PLANCK_RAW_FLUSH_STDOUT", function_raw_flush_stdout);
	register_global_function(ctx, "PLANCK_RAW_WRITE_STDERR", function_raw_write_stderr);
	register_global_function(ctx, "PLANCK_RAW_FLUSH_STDERR", function_raw_flush_stderr);

	register_global_function(ctx, "PLANCK_REQUEST", function_http_request);

	{
		JSValueRef arguments[num_rest_args];
		for (int i = 0; i < num_rest_args; i++) {
			arguments[i] = c_string_to_value(ctx, rest_args[i]);
		}
		JSValueRef args_ref = JSObjectMakeArray(ctx, num_rest_args, arguments, NULL);

		JSValueRef global_obj = JSContextGetGlobalObject(ctx);
		JSStringRef prop = JSStringCreateWithUTF8CString("PLANCK_INITIAL_COMMAND_LINE_ARGS");
		JSObjectSetProperty(ctx, JSValueToObject(ctx, global_obj, NULL), prop, args_ref, kJSPropertyAttributeNone, NULL);
		JSStringRelease(prop);
	}

	evaluate_script(ctx, "cljs.core.set_print_fn_BANG_.call(null,PLANCK_PRINT_FN);", "<init>");
	evaluate_script(ctx, "cljs.core.set_print_err_fn_BANG_.call(null,PLANCK_PRINT_ERR_FN);", "<init>");

	char *elide_script = str_concat("cljs.core._STAR_assert_STAR_ = ", elide_asserts ? "false" : "true");
	evaluate_script(ctx, elide_script, "<init>");
	free(elide_script);

	{
		JSValueRef arguments[4];
		arguments[0] = JSValueMakeBoolean(ctx, repl);
		arguments[1] = JSValueMakeBoolean(ctx, verbose);
		JSValueRef cache_path_ref = NULL;
		if (cache_path != NULL) {
			JSStringRef cache_path_str = JSStringCreateWithUTF8CString(cache_path);
			cache_path_ref = JSValueMakeString(ctx, cache_path_str);
		}
		arguments[2] = cache_path_ref;
		arguments[3] = JSValueMakeBoolean(ctx, static_fns);
		JSValueRef ex = NULL;
		JSObjectCallAsFunction(ctx, get_function(ctx, "planck.repl", "init"), JSContextGetGlobalObject(ctx), 4, arguments, &ex);
		debug_print_value("planck.repl/init", ctx, ex);
	}

	if (repl) {
		evaluate_source(ctx, "text", "(require '[planck.repl :refer-macros [apropos dir find-doc doc source pst]])", true, false, "cljs.user", "dumb");
	}

	evaluate_script(ctx, "goog.provide('cljs.user');", "<init>");
	evaluate_script(ctx, "goog.require('cljs.core');", "<init>");

	evaluate_script(ctx, "cljs.core._STAR_assert_STAR_ = true;", "<init>");

	// Process init arguments

	for (int i = 0; i < num_scripts; i++) {
		// TODO: exit if not successfull
		evaluate_source(ctx, scripts[i].type, scripts[i].source, scripts[i].expression, false, NULL, theme);
	}

	// Process main arguments

	if (main_ns_name != NULL) {
		run_main_in_ns(ctx, main_ns_name, num_rest_args, rest_args);
	} else if (!repl && num_rest_args > 0) {
		char *path = rest_args[0];

		struct script script;
		if (strcmp(path, "-") == 0) {
			char *source = read_all(stdin);
			script.type = "text";
			script.source = source;
			script.expression = false;
		} else {
			script.type = "path";
			script.source = path;
			script.expression = false;
		}

		evaluate_source(ctx, script.type, script.source, script.expression, false, NULL, theme);
	} else if (repl) {
		if (!quiet) {
			banner();
		}

		char *home = getenv("HOME");
		char *history_path = NULL;
		if (home != NULL) {
			char history_name[] = ".planck_history";
			int len = strlen(home) + strlen(history_name) + 2;
			history_path = malloc(len * sizeof(char));
			snprintf(history_path, len, "%s/%s", home, history_name);

			linenoiseHistoryLoad(history_path);
		}

		if (!javascript) {
			linenoiseSetCompletionCallback(completion);
		}

		char *prompt = javascript ? " > " : "cljs.user=> ";
		char *current_ns = get_current_ns(ctx);
		if (!javascript) {
			prompt = str_concat(current_ns, "=> ");
		}

		char *line;
		while ((line = linenoise(prompt, "\x1b[36m", 0)) != NULL) {
			if (javascript) {
				JSValueRef res = evaluate_script(ctx, line, "<stdin>");
				print_value("", ctx, res);
			} else {
				evaluate_source(ctx, "text", line, true, true, current_ns, theme);
				char *new_ns = get_current_ns(ctx);
				free(current_ns);
				free(prompt);
				current_ns = new_ns;
				prompt = str_concat(current_ns, "=> ");
			}
			linenoiseHistoryAdd(line);
			if (history_path != NULL) {
				linenoiseHistorySave(history_path);
			}
			free(line);
		}
	}

	return exit_value;
}
std::string FileTransferCurl::Download(FileDownloadInfo *downloadInfo)
{
    CURL *curl;
    FILE *fp;
    CURLcode result;
    std::string result_string;
    bool error = 0;
    int http_status = 0;

    const char *source = (downloadInfo->source).c_str();
    const char *target = (downloadInfo->target).c_str();

    std::string source_escaped(curl_easy_escape(curl, curl_easy_escape(curl, source, 0), 0));
    std::string target_escaped(curl_easy_escape(curl, curl_easy_escape(curl, target, 0), 0));

    const char *targetDir = downloadInfo->target.substr(0, downloadInfo->target.find_last_of('/')).c_str();

    // Check if target directory exists with write permissions
    if (access(targetDir, R_OK)) {
        if (mkdir_p(targetDir, S_IRWXU | S_IRWXG)) {
            return buildDownloadErrorString(PERMISSIONS_ERR, source_escaped, target_escaped, http_status);
        }
    }

    curl = curl_easy_init();

    if (!curl) {
        return buildDownloadErrorString(CONNECTION_ERR, source_escaped, target_escaped, http_status);
    }

    fp = fopen(target, "wb");
    curl_easy_setopt(curl, CURLOPT_URL, source);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadWriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

    // Check domain
    bool blockedDomain = false;
    const std::string parsedDomain(parseDomain(downloadInfo->source.c_str()));
    const DomainVerifyMap::iterator findDomain = m_pVerifyMap->find(parsedDomain);

    if (findDomain != m_pVerifyMap->end()) {
        if (findDomain->second) {
            curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        } else {
            blockedDomain = true;
        }
    }

    result = curl_easy_perform(curl);

    if (result == CURLE_SSL_CACERT) {
        if (!blockedDomain) {
            result = openDialog(curl, downloadInfo->windowGroup, parsedDomain);
        }
    }

    if (result == CURLE_OK) {
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);

        if (http_status >= 200 && http_status < 300) {
            result_string = buildDownloadSuccessString(true, false, downloadInfo->source.substr(downloadInfo->source.find_last_of('/')+1), downloadInfo->target);
        } else if (http_status == 404) {
            error = 1;
            result_string = buildDownloadErrorString(FILE_NOT_FOUND_ERR, source_escaped, target_escaped, http_status);
        } else if (http_status >= 400 && http_status < 500) {
            error = 1;
            result_string = buildDownloadErrorString(INVALID_URL_ERR, source_escaped, target_escaped, http_status);
        } else {
            error = 1;
            result_string = buildDownloadErrorString(CONNECTION_ERR, source_escaped, target_escaped, http_status);
        }
    } else {
        FileTransferErrorCodes error_code;

        switch (result)
        {
            case CURLE_READ_ERROR:
            case CURLE_FILE_COULDNT_READ_FILE:
                error_code = FILE_NOT_FOUND_ERR;
                break;
            case CURLE_URL_MALFORMAT:
                error_code = INVALID_URL_ERR;
                break;
            default:
                error_code = CONNECTION_ERR;
                break;
        }

        error = 1;
        result_string = buildDownloadErrorString(error_code, source_escaped, target_escaped, http_status);
    }

    fclose(fp);

    if (error) {
        remove(downloadInfo->target.c_str());
    }

    curl_easy_cleanup(curl);

    return result_string;
}
Exemplo n.º 8
0
int machine_id_setup(void) {
        int fd, r;
        bool writable;
        struct stat st;
        char id[34]; /* 32 + \n + \0 */
        mode_t m;

        m = umask(0000);

        /* We create this 0444, to indicate that this isn't really
         * something you should ever modify. Of course, since the file
         * will be owned by root it doesn't matter much, but maybe
         * people look. */

        if ((fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444)) >= 0)
                writable = true;
        else {
                if ((fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) {
                        umask(m);
                        log_error("Cannot open /etc/machine-id: %m");
                        return -errno;
                }

                writable = false;
        }

        umask(m);

        if (fstat(fd, &st) < 0) {
                log_error("fstat() failed: %m");
                r = -errno;
                goto finish;
        }

        if (S_ISREG(st.st_mode)) {
                if (loop_read(fd, id, 32, false) >= 32) {
                        r = 0;
                        goto finish;
                }
        }

        /* Hmm, so, the id currently stored is not useful, then let's
         * generate one */

        if ((r = generate(id)) < 0)
                goto finish;

        if (S_ISREG(st.st_mode) && writable) {
                lseek(fd, 0, SEEK_SET);

                if (loop_write(fd, id, 33, false) == 33) {
                        r = 0;
                        goto finish;
                }
        }

        close_nointr_nofail(fd);
        fd = -1;

        /* Hmm, we couldn't write it? So let's write it to
         * /run/systemd/machine-id as a replacement */

        mkdir_p("/run/systemd", 0755);

        if ((r = write_one_line_file("/run/systemd/machine-id", id)) < 0) {
                log_error("Cannot write /run/systemd/machine-id: %s", strerror(-r));

                unlink("/run/systemd/machine-id");
                goto finish;
        }

        /* And now, let's mount it over */
        r = mount("/run/systemd/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0;
        unlink("/run/systemd/machine-id");

        if (r < 0)
                log_error("Failed to mount /etc/machine-id: %s", strerror(-r));
        else
                log_info("Installed transient /etc/machine-id file.");

finish:

        if (fd >= 0)
                close_nointr_nofail(fd);

        return r;
}
Exemplo n.º 9
0
static void dumpPlugin_packet(u_char new_bucket, void* pluginData,
				     HashBucket* bkt,
				     u_short proto, u_char isFragment,
				     u_short numPkts, u_char tos,
				     u_short vlanId, struct ether_header *ehdr,
				     IpAddress *src, u_short sport,
				     IpAddress *dst, u_short dport,
				     u_int len, u_int8_t flags, u_int8_t icmpType,
				     u_short numMplsLabels,
				     u_char mplsLabels[MAX_NUM_MPLS_LABELS][MPLS_LABEL_LEN],
				     char *fingerprint,
				     const struct pcap_pkthdr *h, const u_char *p,
				     u_char *payload, int payloadLen) {  

  if(new_bucket) {
    PluginInformation *info;
    /* The file has not yet been created */
    char buf[32], buf1[32], filePath[PATH_LEN], dirPath[PATH_LEN];
    time_t now = time(NULL);
    FILE *fd;
    struct tm t;
    char *prefix;
    
    info = (PluginInformation*)malloc(sizeof(PluginInformation));
    if(info == NULL) {
      traceEvent(TRACE_ERROR, "Not enough memory?");
      return; /* Not enough memory */
    }

    info->pluginPtr  = (void*)&dumpPlugin;
    pluginData = info->pluginData = malloc(sizeof(struct plugin_info));
    
    if(info->pluginData == NULL) {	
      traceEvent(TRACE_ERROR, "Not enough memory?");
      free(info);
      return; /* Not enough memory */
    }

    info->next = bkt->plugin;      
    bkt->plugin = info;

#ifdef DEBUG
    traceEvent(TRACE_INFO, "dumpPlugin_create called.\n");
#endif

    strftime(dirPath, sizeof(dirPath), "/%G/%b/%e/%H/%M/", localtime_r(&now, &t));

    if(     (bkt->sport == 25)  || (bkt->dport == 25)) prefix = "smtp";
    else if((bkt->sport == 110) || (bkt->dport == 110)) prefix = "pop";
    else if((bkt->sport == 143) || (bkt->dport == 143)) prefix = "imap";
    else if((bkt->sport == 220) || (bkt->dport == 220)) prefix = "imap3";
    else prefix = "data";

    snprintf(filePath, sizeof(filePath), "%s/%s/%s:%d_%s:%d-%u.%s",
	     BASE_PATH, dirPath,
	     _intoa(bkt->src, buf, sizeof(buf)), (int)bkt->sport,
	     _intoa(bkt->dst, buf1, sizeof(buf1)), (int)bkt->dport,
	     (unsigned int)now, prefix);

    fd = fopen(filePath, "w+");

    if(fd == NULL) {
      char fullPath[256];

      /* Maybe the directory has not been created yet */
      snprintf(fullPath, sizeof(fullPath), "%s/%s", BASE_PATH, dirPath);
      mkdir_p(fullPath);

      fd = fopen(filePath, "w+");
    }

    if(fd != NULL) {
      struct plugin_info* infos = (struct plugin_info*)pluginData;

#ifdef DEBUG
      traceEvent(TRACE_INFO, "Saving flow into %s", filePath);
#endif
      infos->fd = fd;
      infos->file_path = strdup(filePath);
    }
  }
  
  if((payload == NULL) || (payloadLen == 0)) return; /* Nothing to save */

  if(pluginData != NULL)
    (void)fwrite(payload, payloadLen, 1, ((struct plugin_info *)pluginData)->fd);
}
Exemplo n.º 10
0
void mkdir_p(const std::string &dir) {
  mkdir_p(boost::filesystem::path(dir));
}
Exemplo n.º 11
0
int main(int argc, char **argv)
{
  kumy_file_t *kumy;
  miniseed_file_t *mseed[KUMY_FILE_CHANNELS];
  int32_t frame[KUMY_FILE_CHANNELS];
  uint64_t frames, l, frames_per_file, frames_total, frame_count = 0;
  int i;
  char oname[1024], folder[1024];
  uint32_t sample_rate, seconds_per_file;
  int percent = 0, old_percent = -1;
  int compression = 1, show_progress = 1;
  char *infile = 0;

  struct taia start_time; /* 1871 */
  struct taia stop_time;  /* 1951 */
  struct taia sync_time;  /* 2031 */
  struct taia skew_time;  /* 2111 */

  struct caltime ct;
  struct taia tt, dt;

  program = argv[0];
  parse_options(&argc, &argv, OPTIONS(
    FLAG('n', "no-compression", compression, 0),
    FLAG('q', "quiet", show_progress, 0),
    FLAG_CALLBACK('h', "help", usage)
  ));

  if (argc < 2) {
    usage(0, 0, 0);
  }

  infile = argv[1];
  if (!(kumy = kumy_file_open(infile))) {
    fprintf(stderr, "Invalid file: %s.\n", infile);
    return -1;
  }

  parse_text_date(&start_time, kumy->text_header[0].content + 1871);
  parse_text_date(&stop_time,  kumy->text_header[0].content + 1951);
  parse_text_date(&sync_time,  kumy->text_header[0].content + 2031);
  parse_text_date(&skew_time,  kumy->text_header[0].content + 2111);

  sample_rate = 1000000 / kumy->binary_header[0].sample_interval;

  if (sample_rate <= 250) {
    seconds_per_file = 86400;
  } else if (sample_rate <= 500) {
    seconds_per_file = 43200;
  } else if (sample_rate <= 1000) {
    seconds_per_file = 21600;
  } else if (sample_rate <= 2000) {
    seconds_per_file = 10800;
  } else {
    seconds_per_file = 5400;
  }

  frames_per_file = sample_rate * seconds_per_file;
  frames_total = kumy->binary_header[0].num_samples;

  caltime_utc(&ct, &start_time.sec, 0, 0);
  ct.hour = 0;
  ct.minute = 0;
  ct.second = 0;
  caltime_tai(&ct, &tt.sec);
  tt.nano = tt.atto = 0;

  while (!taia_less(&start_time, &tt)) {
    tt.sec.x += seconds_per_file;
  }

  taia_sub(&dt, &tt, &start_time);
  frames = taia_approx(&dt) / seconds_per_file * frames_per_file;

  l = last('.', infile);
  if (l == -1 || l >= sizeof(folder)) return -1;

  /* Create folder. */
  copy(folder, l, infile);
  folder[l] = 0;
  mkdir_p(folder);

  for (i = 0; i < KUMY_FILE_CHANNELS; ++i) {
    caltime_utc(&ct, &start_time.sec, 0, 0);
    snprintf(oname, sizeof(oname), "%s/%lld.%02lld.%02lld.%02lld.%02lld.%02lld.%s.seed",
      folder, (long long)ct.date.year, (long long)ct.date.month, (long long)ct.date.day, (long long)ct.hour, (long long)ct.minute, (long long)ct.second, channel_names[i]);

    if (!(mseed[i] = miniseed_file_create((char*)oname))) {
      fprintf(stderr, "Invalid file: %s.\n", oname);
      return -1;
    }
    miniseed_file_set_sample_rate(mseed[i], sample_rate);
    miniseed_file_set_start_time(mseed[i], &start_time);
    miniseed_file_set_info(mseed[i], "OBS", "DE", channel_names[i], "K");
    miniseed_file_set_compression(mseed[i], compression);
  }

  while (kumy_file_read_int_frame(kumy, frame) >= 0) {
    if (frames == 0) {
      /* Create new files.*/
      for (i = 0; i < KUMY_FILE_CHANNELS; ++i) {
        miniseed_file_close(mseed[i]);
        caltime_utc(&ct, &tt.sec, 0, 0);
        snprintf(oname, sizeof(oname), "%s/%lld.%02lld.%02lld.%02lld.%02lld.%02lld.%s.seed",
          folder, (long long)ct.date.year, (long long)ct.date.month, (long long)ct.date.day, (long long)ct.hour, (long long)ct.minute, (long long)ct.second, channel_names[i]);
        if (!(mseed[i] = miniseed_file_create((char*)oname))) {
          fprintf(stderr, "Invalid file: %s.\n", oname);
          return -1;
        }
        miniseed_file_set_sample_rate(mseed[i], sample_rate);
        miniseed_file_set_start_time(mseed[i], &tt);
        miniseed_file_set_info(mseed[i], "OBS", "DE", channel_names[i], "K");
        miniseed_file_set_compression(mseed[i], compression);
      }
      frames = frames_per_file;
      tt.sec.x += seconds_per_file;
    }

    for (i = 0; i < KUMY_FILE_CHANNELS; ++i) {
      miniseed_file_write_int_frame(mseed[i], frame + i);
    }
    if (show_progress && frame_count % 10000 == 0) {
      percent = 100 * frame_count / frames_total;
      if (percent != old_percent) {
        progress(percent, 0);
        old_percent = percent;
      }
    }
    --frames;
    ++frame_count;
  }
  if (show_progress) progress(100, 1);

  kumy_file_close(kumy);
  for (i = 0; i < KUMY_FILE_CHANNELS; ++i) {
    miniseed_file_close(mseed[i]);
  }

  return 0;
}
Exemplo n.º 12
0
//void do_install(opkg_conf* conf, char* pkg_name, char* install_root_name, char* link_root_name, char** version_criteria)
void do_install(opkg_conf* conf, string_map* pkgs, char* install_root_name, char* link_root_name, int is_upgrade, int overwrite_config, int overwrite_other_package_files, int force_reinstall, char* tmp_root)
{
	string_map* package_data = initialize_string_map(1);
	string_map* matching_packages = initialize_string_map(1);
	unsigned long num_destroyed;


	char* install_root_path = (char*)get_string_map_element(conf->dest_names, install_root_name);
	char* overlay_path = NULL; // no special treatment of overlay, can be reenabled  by setting this variable here if we ever need it


	char* test_dir  = dynamic_strcat(2, (overlay_path != NULL ? overlay_path : install_root_path), "/usr/lib/opkg/info");
	if(!create_dir_and_test_writable(test_dir))
	{
		fprintf(stderr, "ERROR: Specified install destination is not writable, exiting\n");
		exit(1);
	}
	free(test_dir);

	



	if(install_root_path == NULL)
	{
		printf("ERROR: No destination %s found, cannot install\n\n", install_root_name);
		exit(1);
	}
	
	char* tmp_dir = (char*)malloc(1024);
	if(create_tmp_dir(tmp_root == NULL ? "/tmp" : tmp_root, &tmp_dir) != 0)
	{
		fprintf(stderr, "ERROR: Could not create tmp dir, exiting\n");
		exit(1);
	}


	/* Determine all packages to install by first loading all package names, status & dependencies (and no other variables) */
	load_all_package_data(conf, package_data, matching_packages, NULL, LOAD_MINIMAL_PKG_VARIABLES_FOR_ALL, install_root_name, 1 );
	destroy_string_map(matching_packages, DESTROY_MODE_FREE_VALUES, &num_destroyed);

		
	/* determine list of all packiages we are about to install, including dependencies */
	string_map* install_pkgs_map = initialize_string_map(1);
	char** install_pkg_list = NULL;	
	unsigned long install_pkg_list_len = 0;
	char* unsatisfied_dep_err = NULL;
	
	
	//new string map var with all pkgs to install = pkgs, keys = version
	unsigned long num_pkg_names;
	char** pkg_names = get_string_map_keys(pkgs, &num_pkg_names);
	int pkg_name_index;
	for(pkg_name_index=0;pkg_name_index < num_pkg_names; pkg_name_index++)
	{
		char* pkg_name = pkg_names[pkg_name_index];
		char** version_criteria = get_string_map_element(pkgs, pkg_name);
		char* install_pkg_version = NULL;
		int install_pkg_is_current;

		if(path_exists(pkg_name))
		{
			//installing from file
			char* pkg_file = pkg_name;


			//extract control files
			int err = 0;
			char* tmp_control        = dynamic_strcat(2, tmp_dir, "/tmp_ctrl");
			char* tmp_control_prefix = dynamic_strcat(2, tmp_control, "/tmp.");
			char* tmp_control_name   = dynamic_strcat(2, tmp_control_prefix, "control");

			mkdir_p(tmp_control, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
			deb_extract(	pkg_file,
					stderr,
					extract_control_tar_gz | extract_all_to_fs| extract_preserve_date | extract_unconditional,
					tmp_control_prefix, 
					NULL, 
					&err);
			if(err != 0)
			{
				fprintf(stderr, "ERROR: %s is not a vailid package file, cannot install\n", pkg_file);
				rm_r(tmp_dir);
				exit(1);
			}
			string_map* tmp_control_pkg_data = initialize_string_map(1);
			matching_packages = initialize_string_map(1);
		       	load_package_data(tmp_control_name, 0, tmp_control_pkg_data, matching_packages, NULL, LOAD_ALL_PKG_VARIABLES, NULL);
			unsigned long num_ctrl_names;
			char** ctrl_name_list = get_string_map_keys(tmp_control_pkg_data, &num_ctrl_names);
			destroy_string_map(matching_packages, DESTROY_MODE_FREE_VALUES, &num_destroyed);
		

			err = 1; //set back to 0 when data successfully loaded
			if(num_ctrl_names > 0)
			{
				pkg_name = strdup(ctrl_name_list[0]);
				char* version = NULL;
				int is_current;
				string_map* pkg_info = get_package_current_or_latest(tmp_control_pkg_data, pkg_name, &is_current, &version);
				if(pkg_info != NULL)
				{
					err = 0;
					set_string_map_element(pkg_info, "Install-File-Location", strdup(pkg_file));
					set_string_map_element(pkg_info, "Version", version); //we need to save this, since we are going to set a special version to make sure data doesn't get over-written later, also no need to free version now

					char* special_version = dynamic_strcat(2, version, "@@_FILE_INSTALL_VERSION_@@");
					char** new_version_criteria = malloc(3*sizeof(char*));
					new_version_criteria[0] = strdup("=");
					new_version_criteria[1] = special_version;
					new_version_criteria[2] = NULL;
					
					string_map* all_current_versions = get_string_map_element(package_data, pkg_name);
					if(all_current_versions == NULL)
					{
						all_current_versions=initialize_string_map(1);
						set_string_map_element(package_data, pkg_name, all_current_versions);
					}
					set_string_map_element(all_current_versions, special_version, pkg_info);
					set_string_map_element(all_current_versions, LATEST_VERSION_STRING, special_version);
				
					free(pkg_names[pkg_name_index]);
					pkg_names[pkg_name_index] = strdup(pkg_name);
				
					set_string_map_element(pkgs, pkg_name, copy_null_terminated_string_array(new_version_criteria));	
				}
			}
			free_null_terminated_string_array(ctrl_name_list);
			if(err != 0)
			{
				fprintf(stderr, "ERROR: %s is not a vailid package file, cannot install\n", pkg_file);
				rm_r(tmp_dir);
				exit(1);
			}

			free_if_not_null(tmp_control);
			free_if_not_null(tmp_control_prefix);
			free_if_not_null(tmp_control_name);
			rm_r(tmp_control);
		}


		load_recursive_package_data_variables(package_data, pkg_name, 1, 0, 0); // load required-depends for package of interest only 
		string_map* install_pkg_data = get_package_current_or_latest_matching(package_data, pkg_name, version_criteria, &install_pkg_is_current, &install_pkg_version);
		char* install_status = install_pkg_data == NULL ? NULL : get_string_map_element(install_pkg_data, "Status");

	
		if(install_status != NULL)
		{
			
			char** old_el = set_string_map_element(install_pkgs_map, pkg_name, copy_null_terminated_string_array(version_criteria) );
			if(old_el != NULL){ free_null_terminated_string_array(old_el); }

			string_map* install_pkg_depend_map = get_string_map_element(install_pkg_data, "Required-Depends");
			if(install_pkg_depend_map != NULL)
			{
				unsigned long num_keys;
				char** load_detail_pkgs = get_string_map_keys(install_pkg_depend_map, &num_keys);
				int ldp_index;
				for(ldp_index=0;ldp_index < num_keys && unsatisfied_dep_err == NULL; ldp_index++)
				{
					char* dep_name = load_detail_pkgs[ldp_index];
					char** dep_def= get_string_map_element(install_pkg_depend_map, dep_name);
					if(get_string_map_element(install_pkgs_map, dep_name) != NULL)
					{
						/* 
						 * We really should check here whether old dependency def can be reconciled with the new one, and report an error if it can't 
						 * Right now we just use the heuristic that top-level (user specified, not dependency) package defs get preference, followed
						 * by first dependency encountered.
						 *
						 * Since right now versioning features aren't really being used very much other than kernel dependencies in Gargoyle/OpenWrt
						 * I'm just leaving this comment here as a reminder that this should be addressed at some point rather than messing with it now
						 *
						 */

						dep_def = get_string_map_element(install_pkgs_map, dep_name);
					}
					else
					{
						set_string_map_element(install_pkgs_map, dep_name, copy_null_terminated_string_array(dep_def));
					}
	
					//error checking, check that dependency definition exists
					char* latest_version = NULL;
					int latest_is_current = 0;
					string_map* dep_info = get_package_current_or_latest_matching(package_data, dep_name, dep_def, &latest_is_current, &latest_version);
					
					
					//check if we have a version installed different than what is required
					int have_current;
					char* current_version = NULL;
					string_map* cur_info = get_package_current_or_latest(package_data, dep_name, &have_current, &current_version);
					if(have_current && (latest_is_current == 0 || dep_info == NULL))
					{
						//should only get here if dep_def[1] is not null (version mismatch doesn't make sense if no version is specified)
						char* cur_status = get_string_map_element(cur_info, "Status");
						if(strstr(cur_status, " hold ") != NULL)
						{
							unsatisfied_dep_err = dynamic_strcat(11, "ERROR: Dependency ", dep_name, " (", dep_def[0], " ", dep_def[1], ") of package ", pkg_name, " is installed,\n\t\tbut has incompatible version ", current_version, " and is marked as 'hold'");
						}
						else
						{
							unsatisfied_dep_err = dynamic_strcat(10, "ERROR: Dependency ", dep_name, " (", dep_def[0], " ", dep_def[1], ") of package ", pkg_name, " is installed,\n\t\tbut has incompatible version ", current_version);
						}
					}
					free_if_not_null(current_version);
					free_if_not_null(latest_version);
	
					// check that dependency definition exists
					if(unsatisfied_dep_err == NULL && dep_info == NULL)
					{
						if(dep_def[1] != NULL)
						{
							unsatisfied_dep_err = dynamic_strcat(9, "ERROR: Dependency ", dep_name, " (", dep_def[0], " ", dep_def[1], ") of package ", pkg_name, " cannot be found, try updating your package lists");
						}
						else
						{
							unsatisfied_dep_err = dynamic_strcat(5, "ERROR: Dependency ", dep_name, " of package ", pkg_name, " cannot be found, try updating your package lists");
						}
					}
									
				}
				free_null_terminated_string_array(load_detail_pkgs);
			}
	
		}
		install_status = install_pkg_data == NULL ? NULL : get_string_map_element(install_pkg_data, "Status");




		/* error checking before we start install */
		if(install_pkg_data == NULL || install_status == NULL)
		{
			fprintf(stderr, "ERROR: No package named %s found, try updating your package lists\n\n", pkg_name);
			rm_r(tmp_dir);
			exit(1);
		}
		if(strstr(install_status, " installed") != NULL)
		{
			if(force_reinstall)
			{
				fprintf(stderr, "WARNING: Package %s is already installed, forcing removal and reinstallation\n\n", pkg_name);
				free_package_data(package_data);
				string_map* rm_pkg = initialize_string_map(1);
				set_string_map_element(rm_pkg, pkg_name, alloc_depend_def(NULL));
				do_remove(conf, rm_pkg, (overwrite_config ? 0 : 1), 0, 1, 0, tmp_root);
				
				//restart install
				return do_install(conf, pkgs, install_root_name, link_root_name, is_upgrade, overwrite_config, overwrite_other_package_files, force_reinstall, tmp_root);
				
			}
			else
			{
				fprintf(stderr, "WARNING: Package %s is already installed, ignoring\n", pkg_name);
				fprintf(stderr, "         Use --force-reinstall to force reinstallation\n\n");
				char** old_el = remove_string_map_element(install_pkgs_map, pkg_name);
				if(old_el != NULL){ free_null_terminated_string_array(old_el); };
			}

		}

		if(unsatisfied_dep_err != NULL)
		{
			fprintf(stderr, "%s\n", unsatisfied_dep_err);
			rm_r(tmp_dir);
			exit(1);
		}
	}


	
	
	/* load more detailed data on packages we are about to install */
	free_recursive_package_vars(package_data); /* note: whacks install_pkg_depend_map */	
	string_map* parameters = initialize_string_map(1);
	matching_packages = initialize_string_map(1);
	set_string_map_element(parameters, "package-list", install_pkgs_map);
	
	load_all_package_data(conf, package_data, matching_packages, parameters, LOAD_MINIMAL_FOR_ALL_PKGS_ALL_FOR_MATCHING, install_root_name, 0);
	install_pkg_list = get_string_map_keys(matching_packages, &install_pkg_list_len);



	
	
	destroy_string_map(matching_packages, DESTROY_MODE_FREE_VALUES, &num_destroyed);
	destroy_string_map(parameters, DESTROY_MODE_IGNORE_VALUES, &num_destroyed);
	

	char* all_pkg_list_str = join_strs(", ", install_pkg_list, install_pkg_list_len, 0, 0); 
	uint64_t combined_size = 0;
	int pkg_index;


	for(pkg_index=0; pkg_index < install_pkg_list_len; pkg_index++)
	{
		char** match_criteria = get_string_map_element(install_pkgs_map, install_pkg_list[pkg_index]);
		string_map* pkg = get_package_current_or_latest_matching(package_data, install_pkg_list[pkg_index], match_criteria, NULL, NULL);
		char* next_size_str = get_string_map_element(pkg, "Installed-Size");
		uint64_t next_size = 0;
		if(sscanf(next_size_str,  SCANFU64, &next_size) > 0)
		{	
			combined_size = combined_size + next_size; 
		} 
	}
	uint64_t root_size = destination_bytes_free(conf, install_root_name);
	if(combined_size >= root_size )
	{
		fprintf(stderr, "ERROR: Not enough space in destination %s to install specified packages:\n\t%s\n\n", install_root_name, all_pkg_list_str);
		rm_r(tmp_dir);
		exit(1);
	}


	if(all_pkg_list_str != NULL)
	{
		printf("Preparing to install the following packages, which will require " SCANFU64 " bytes:\n\t%s\n\n", combined_size, all_pkg_list_str);
	}
	else
	{
		fprintf(stderr, "No packages to install.\n\n");
	}

	/* Set status of new required packages to half-installed, set user-installed on requested package, installed time on all */
	char* install_root_status_path = dynamic_strcat(2, install_root_path, "/usr/lib/opkg/status");
	string_map* install_root_status = initialize_string_map(1);
	matching_packages = initialize_string_map(1);
	if(path_exists(install_root_status_path))
	{
		load_package_data(install_root_status_path, 0, install_root_status, matching_packages, NULL, LOAD_ALL_PKG_VARIABLES, install_root_name);
	}
	destroy_string_map(matching_packages, DESTROY_MODE_FREE_VALUES, &num_destroyed);



	time_t now = time(NULL);
	char install_time[20];
	sprintf(install_time, "%lu", now);
	for(pkg_index=0; pkg_index < install_pkg_list_len; pkg_index++)
	{
		int is_installed;
		char* install_version = NULL;
		char** match_criteria = get_string_map_element(install_pkgs_map, install_pkg_list[pkg_index]);
		string_map* pkg = get_package_current_or_latest_matching(package_data, install_pkg_list[pkg_index], match_criteria, &is_installed, &install_version);


		if(is_installed == 0) /* should never be true, but check anyway */
		{
			char* old_status = remove_string_map_element(pkg, "Status");
			free(old_status);
			char* status_parts[3] = { "install", "ok", "half-installed" };
			status_parts[1] = get_string_map_element(pkgs, install_pkg_list[pkg_index]) != NULL ? "user" : status_parts[1];
			char* new_status = dynamic_strcat(5, status_parts[0], " ", status_parts[1], " ", status_parts[2]);
			set_string_map_element(pkg, "Status", new_status);

			set_string_map_element(pkg, "Installed-Time", strdup(install_time));
			set_string_map_element(pkg, "Install-Destination", strdup(install_root_name));
			if(link_root_name != NULL)
			{
				set_string_map_element(pkg, "Link-Destination", strdup(link_root_name));
			}

			add_package_data(install_root_status, &pkg, install_pkg_list[pkg_index], install_version); 
			/* Note: we just added pkg data structure from package_data to install_root_status, Be careful on cleanup! */
		}
	}
	save_package_data_as_status_file(install_root_status, install_root_status_path);




	

	string_map* install_called_pkgs = initialize_string_map(1);

	int err = 0;
	for(pkg_name_index=0;pkg_name_index < num_pkg_names; pkg_name_index++)
	{
		char* pkg_name = pkg_names[pkg_name_index];
		if(get_string_map_element(install_pkgs_map, pkg_name) != NULL)
		{
			int install_pkg_is_current;
			char* install_pkg_version = NULL;
			char** version_criteria = get_string_map_element(pkgs, pkg_name);
			get_package_current_or_latest_matching(package_data, pkg_name, version_criteria, &install_pkg_is_current, &install_pkg_version);
			err = recursively_install(pkg_name, install_pkg_version, install_root_name, link_root_name, overlay_path, is_upgrade, overwrite_config, overwrite_other_package_files, tmp_dir, conf, package_data, install_called_pkgs);
		
			free_if_not_null(install_pkg_version);
		}
	}
	

	if(err)
	{
		fprintf(stderr, "An error occurred during Installation, removing partially installed packages.\n");
		unsigned long num_install_called_pkgs;
		char** install_called_pkg_list = get_string_map_keys(install_called_pkgs, &num_install_called_pkgs);
		int pkg_index;
		for(pkg_index=0; pkg_index < num_install_called_pkgs; pkg_index++)
		{
			remove_individual_package(install_called_pkg_list[pkg_index], conf, package_data, tmp_dir, 0, 0);
		}
		free_null_terminated_string_array(install_called_pkg_list);
		//call remove function to do cleanup of partial install
		//DO NOT EXIT HERE, fixup status file below
	}
	//remove tmp dir -- need to do this whether or not there is an error
	rm_r(tmp_dir);
	free(tmp_dir);


	//set status of new packages to installed on success, and remove on failure
	for(pkg_index=0; pkg_index < install_pkg_list_len; pkg_index++)
	{	
		/* no need to check version, should only be one installed version at a time... */
		string_map* pkg = get_package_current_or_latest(install_root_status, install_pkg_list[pkg_index], NULL, NULL); 
		if(pkg != NULL)
		{
			if(!err)
			{
				char* status = get_string_map_element(pkg, "Status");
				if(strstr(status, " half-installed") != NULL)
				{
					char* status_parts[3] = { "install", "ok", "installed" };
					status_parts[1] = get_string_map_element(pkgs, install_pkg_list[pkg_index]) != NULL ? "user" : status_parts[1];
					char* new_status = dynamic_strcat(5, status_parts[0], " ", status_parts[1], " ", status_parts[2]);
					char* old_status = set_string_map_element(pkg, "Status", new_status);
					free_if_not_null(old_status);
				}
			}
			else
			{
				string_map* all_pkg_versions = remove_string_map_element(install_root_status, install_pkg_list[pkg_index]);
				free_all_package_versions(all_pkg_versions);
			}
		}
	}
	save_package_data_as_status_file(install_root_status, install_root_status_path);
	if(!err)
	{
		if(all_pkg_list_str != NULL)
		{
			printf("Installation of packages successful.\n\n");
		}
	}
	else
	{
		printf("Finished removing partially installed packages.\n\n");
	}
}
Exemplo n.º 13
0
int recursively_install(char* pkg_name, char* pkg_version, char* install_root_name, char* link_to_root, char* overlay_path, int is_upgrade, int overwrite_config, int overwrite_other_package_files, char* tmp_dir, opkg_conf* conf, string_map* package_data, string_map* install_called_pkgs)
{
	int err=0;
	
	/* variables not allocated in this function, do not need to be freed */
	string_map* install_pkg_data    = get_package_with_version(package_data, pkg_name, pkg_version);
	char* src_file_path             = get_string_map_element(install_pkg_data, "Install-File-Location");
	char* src_id                    = get_string_map_element(install_pkg_data, "Source-ID");
	char* pkg_filename              = get_string_map_element(install_pkg_data, "Filename");
	string_map* pkg_dependencies    = get_string_map_element(install_pkg_data, "Required-Depends");
	char* install_root_path         = get_string_map_element(conf->dest_names, install_root_name);
	char* link_root_path            = link_to_root != NULL && safe_strcmp(link_to_root, install_root_name) != 0 ? get_string_map_element(conf->dest_names, link_to_root) : NULL;
	char* base_url = NULL;
	
	/* variables that may need to be freed */
	char* pkg_dest = NULL;
	string_map* files_to_link = NULL;
	char* info_dir            = NULL;
	char* control_name_prefix = NULL;
	char* list_file_name      = NULL;
	string_map* conf_files    = NULL;
	string_map* copied_conf_files = NULL;

	int install_root_len = strlen(install_root_path);
	char* fs_terminated_install_root = install_root_path[install_root_len-1] == '/' ? strdup(install_root_path) : dynamic_strcat(2, install_root_path, "/");
	
	int overlay_root_len;
	char* fs_terminated_overlay_root = NULL;
	if(overlay_path != NULL)
	{
		overlay_root_len = strlen(overlay_path);
		fs_terminated_overlay_root = overlay_path[overlay_root_len-1] == '/' ? strdup(overlay_path) : dynamic_strcat(2, overlay_path, "/");
	}
	else
	{
		fs_terminated_overlay_root = strdup(fs_terminated_install_root);
	}

	int link_root_len;
	char* fs_terminated_link_root = NULL;
	if(link_root_path != NULL)
	{
		link_root_len = strlen(link_root_path);
		fs_terminated_link_root = link_root_path[link_root_len-1] == '/' ? strdup(link_root_path) : dynamic_strcat(2, link_root_path, "/");
	}
	set_string_map_element(install_called_pkgs, pkg_name, strdup("D"));



	if(pkg_dependencies != NULL)
	{
		//recurse
		unsigned long num_deps;
		char** deps = get_string_map_keys(pkg_dependencies, &num_deps);
		int dep_index;
		for(dep_index=0; err == 0 && dep_index < num_deps ; dep_index++)
		{
			if(get_string_map_element(install_called_pkgs, deps[dep_index]) == NULL )
			{
				char** dep_def = get_string_map_element(pkg_dependencies, deps[dep_index]);
				int is_current;
				char* matching_version;
				string_map* dep_pkg = get_package_current_or_latest_matching(package_data, deps[dep_index], dep_def, &is_current, &matching_version);

				if(dep_pkg != NULL)
				{
					char* dep_status = get_string_map_element(dep_pkg, "Status");
					if(strstr(dep_status, " half-installed") != NULL)
					{
						err = recursively_install(deps[dep_index], matching_version, install_root_name, link_to_root, overlay_path, is_upgrade, overwrite_config, overwrite_other_package_files, tmp_dir, conf, package_data, install_called_pkgs);
						
					}
				}
				else
				{
					err = 1;
				}
			}
		}
	}
	
	if(install_root_path == NULL || ( src_id == NULL && install_pkg_data == NULL) || (pkg_filename == NULL && install_pkg_data == NULL) )
	{
		//sanity check
		err = 1;
	}
	if(err == 0)
	{
		printf("Preparing to install package %s...\n", pkg_name);
	}
	if(err == 0 && src_file_path == NULL)
	{
		//determine source url
		string_map* src_lists[2] = { conf->gzip_sources, conf->plain_sources };
		int src_list_index;
		for(src_list_index=0; src_list_index < 2 && base_url == NULL; src_list_index++)
		{
			base_url = (char*)get_string_map_element(src_lists[src_list_index], src_id);
		}
		err = base_url == NULL ? 1 : err;
		if(err == 1)
		{
			fprintf(stderr, "ERROR: Could determine download  URL for package %s\n", pkg_name);
		}
	}
	if(err == 0 && src_file_path == NULL)
	{
		
		//download package
		printf("\tDownloading...\n");
		char* src_url  = dynamic_strcat(3, base_url, "/", pkg_filename);
		pkg_dest = dynamic_strcat(3, tmp_dir, "/", pkg_name);
		FILE* package_file = fopen(pkg_dest, "w");
		if(package_file != NULL)
		{
			err = write_url_to_stream(src_url, "gpkg", NULL, package_file, NULL);
			fclose(package_file);
		}
		else
		{
			err = 1;
		}
		if(err == 1)
		{
			fprintf(stderr, "ERROR: Could not download package %s\n", pkg_name);
		}
		free(src_url);
	}
	if(err == 0 && src_file_path != NULL)
	{
		pkg_dest = strdup(src_file_path);
	}
	if(err == 0 && src_file_path == NULL)
	{
		//check md5sum
		char* md5sum = file_md5sum_alloc(pkg_dest);
		char* expected_md5sum = (char*)get_string_map_element(install_pkg_data, "MD5Sum");
		
		//printf("md5sum         = %s\n", md5sum);
		//printf("package md5sum = %s\n", (char*)get_string_map_element(install_pkg_data, "MD5Sum"));

		if(md5sum == NULL || expected_md5sum == NULL)
		{
			fprintf(stderr, "ERROR: Expected MD5Sum for %s not specified, cannot verify package\n", pkg_name);
			err = 1;
		}
		else if (safe_strcmp(md5sum, expected_md5sum) != 0)
		{
			fprintf(stderr, "ERROR: MD5Sum mismatch for %s package\n", pkg_name);
			fprintf(stderr, "       Expected:   %s\n", expected_md5sum);
			fprintf(stderr, "       Downloaded: %s\n\n", md5sum);
			err = 1;
		}
		else
		{
			printf("\tDownloaded %s successfully.\n\tInstalling %s...\n", pkg_name, pkg_name);
		}
		
		if(md5sum != NULL) { free(md5sum); }
		
	}
	if(err == 0)
	{
		// Extract list file contaiing list of files to install
		info_dir            = dynamic_strcat(2, fs_terminated_overlay_root, "usr/lib/opkg/info");
		control_name_prefix = dynamic_strcat(4, info_dir, "/", pkg_name, ".");
		list_file_name      = dynamic_strcat(4, info_dir, "/", pkg_name, ".list");
		
		mkdir_p(info_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
		FILE* list_file = fopen(list_file_name, "w");
		deb_extract(	pkg_dest,
				list_file,
				extract_quiet | extract_data_tar_gz | extract_list,
				NULL,
				NULL, 
				&err);
		fclose(list_file);
		if(err)
		{
			rm_r(list_file_name);
			fprintf(stderr, "ERROR: could not extract file list from packge %s.\n", pkg_name);
			fprintf(stderr, "       package file may be corrupt\n\n");
		}
	}
	if(err == 0)
	{
		//extract control files
		deb_extract(	pkg_dest,
				stderr,
				extract_control_tar_gz | extract_all_to_fs| extract_preserve_date | extract_unconditional,
				control_name_prefix, 
				NULL, 
				&err);
		if(err)
		{
			fprintf(stderr, "ERROR: could not extract control files from packge %s.\n", pkg_name);
			fprintf(stderr, "       package file may be corrupt\n\n");
		}

	}
	if(err == 0)
	{
		//check for file conflicts & correct list file to contain real root name in file paths
		unsigned long num_list_lines;
		char** list_file_lines = get_file_lines(list_file_name, &num_list_lines);


		char* conf_file_path = dynamic_strcat(4, info_dir, "/", pkg_name, ".conffiles");
		if(path_exists(conf_file_path))
		{
			unsigned long num_conf_lines;
			char** conf_file_lines =  get_file_lines(conf_file_path, &num_conf_lines);
			int conf_line_index;
			conf_files = initialize_string_map(1);
			for(conf_line_index=0; conf_line_index < num_conf_lines; conf_line_index++)
			{
				char* adjusted_conf_path = dynamic_strcat(2, fs_terminated_install_root, conf_file_lines[conf_line_index] + 1);
				set_string_map_element(conf_files, adjusted_conf_path, strdup("D"));
				free(adjusted_conf_path);
			}
			free_null_terminated_string_array(conf_file_lines);
		}
		free(conf_file_path);
	

		FILE* list_file = fopen(list_file_name, "w");
		int line_index;
		for(line_index=0; line_index < num_list_lines && (!err) ; line_index++)
		{
			int line_len = strlen( list_file_lines[line_index] );
			if(line_len > 2)
			{
				if(list_file_lines[line_index][0] == '.' && list_file_lines[line_index][1] == '/' && list_file_lines[line_index][line_len-1] != '/')
				{
					char* adjusted_file_path = dynamic_strcat(2, fs_terminated_install_root, list_file_lines[line_index] + 2);
					int is_conf_file = conf_files != NULL ? 
								(get_string_map_element(conf_files, adjusted_file_path) != NULL ? 1 : 0) : 
								0;
					if(strcmp(pkg_name, "opkg") == 0 && strcmp(list_file_lines[line_index], "./bin/opkg") == 0 && path_exists("/bin/opkg") == PATH_IS_SYMLINK)
					{
						//very special case: we're installing opkg, and here all the preliminary checks have already been passed
						//remove symlink placeholder to gpkg from /bin/opkg if it exists
						rm_r("/bin/opkg");
					}
					err = path_exists(adjusted_file_path) && is_conf_file == 0 && overwrite_other_package_files == 0 ? 1 : 0;
					if(err)
					{
						fprintf(stderr, "ERROR: file '%s'\n", adjusted_file_path);
						fprintf(stderr, "       from package %s already exists.\n\n", pkg_name);
					}
					else
					{
						fprintf(list_file, "%s\n", adjusted_file_path);
						if(link_root_path != NULL)
						{
							char* link_to_path = dynamic_strcat(2, fs_terminated_link_root, list_file_lines[line_index] + 2);
							files_to_link = files_to_link == NULL ? initialize_string_map(1) : files_to_link;
							set_string_map_element(files_to_link, adjusted_file_path, link_to_path);
							//don't free link_to_path, should be freed with files_to_link map
						}

						if(is_conf_file && path_exists(adjusted_file_path) && overwrite_config == 0)
						{
							char* tmp_conf_path = dynamic_strcat(2, tmp_dir, adjusted_file_path);
							
							cp(adjusted_file_path, tmp_conf_path);
							
							copied_conf_files = copied_conf_files == NULL ? initialize_string_map(1) : copied_conf_files;
							set_string_map_element(copied_conf_files, adjusted_file_path, tmp_conf_path);
						
							//don't free tmp_conf_path, should be freed with copied_conf_files map 
						}
					}
					free(adjusted_file_path);
	
				}
			}
		}
		fclose(list_file);
		if(list_file_lines != NULL) { free_null_terminated_string_array(list_file_lines); }
	}
	if(err == 0)
	{
		//run preinst
		err = run_script_if_exists(install_root_path, link_root_path, pkg_name, "preinst", (is_upgrade ? "upgrade" : "install") );
	}
	if(err == 0)
	{
		//extract package files
		deb_extract(	pkg_dest,
				stderr,
				extract_data_tar_gz | extract_all_to_fs| extract_preserve_date| extract_unconditional,
				fs_terminated_overlay_root, 
				NULL, 
				&err);
		if(err)
		{
			fprintf(stderr, "ERROR: could not extract application files from packge %s.\n", pkg_name);
			fprintf(stderr, "       package file may be corrupt\n\n");
		}

		//move any conf files back
		if(copied_conf_files != NULL)
		{
			unsigned long num_conf_paths;
			char** conf_paths = get_string_map_keys(copied_conf_files, &num_conf_paths);
			int conf_index;
			for(conf_index=0; conf_index < num_conf_paths; conf_index++)
			{
				char* tmp_conf_path = get_string_map_element(copied_conf_files, conf_paths[conf_index]);
				
				cp(tmp_conf_path, conf_paths[conf_index]);
			}
			destroy_string_map(copied_conf_files, DESTROY_MODE_FREE_VALUES, &num_conf_paths);
			if(conf_paths != NULL ) { free_null_terminated_string_array(conf_paths); }
			copied_conf_files = NULL;
		}
	}
	if(err == 0 && files_to_link != NULL)
	{
		unsigned long num_files;
		char** real_files = get_string_map_keys(files_to_link, &num_files);
		int file_index;
		if(num_files > 0)
		{
			char* link_file_name = dynamic_strcat(4, info_dir, "/", pkg_name, ".linked");
			FILE* link_file = fopen(link_file_name, "w");
			for(file_index=0; link_file != NULL && file_index < num_files; file_index++)
			{
				char* link_path = get_string_map_element(files_to_link, real_files[file_index]);
				if(!path_exists(link_path))
				{
					int sym_success;
					mkdir_p(link_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
					rm_r(link_path);
					sym_success = symlink(real_files[file_index], link_path);
					fprintf(link_file, "%s\n", link_path);
				}
			}
			if(link_file != NULL) { fclose(link_file); }
			free(link_file_name);
		}
		destroy_string_map(files_to_link, DESTROY_MODE_FREE_VALUES, &num_files);
		free_null_terminated_string_array(real_files);
		files_to_link = NULL;
	}
	if(err == 0)
	{
		//run postinst
		int warn = run_script_if_exists(install_root_path, link_root_path, pkg_name, "postinst", (is_upgrade ? "upgrade" : "install") );
		if(warn != 0)
		{
			fprintf(stderr, "Warning: postinstall script failed for package %s.\n", pkg_name);
		}
	}
	if(err == 0)
	{
		// remove downloaded package file in tmp dir & print success
		if(src_file_path == NULL) { rm_r(pkg_dest); }
		printf("\tSuccessfully installed %s.\n", pkg_name);
	}


	//cleanup
	unsigned long num_destroyed;
	free_if_not_null(pkg_dest);
	free_if_not_null(info_dir);
	free_if_not_null(control_name_prefix);
	free_if_not_null(list_file_name);
	free_if_not_null(fs_terminated_install_root);
	free_if_not_null(fs_terminated_overlay_root);
	free_if_not_null(fs_terminated_link_root);
	if(files_to_link != NULL)   { destroy_string_map(files_to_link,     DESTROY_MODE_FREE_VALUES, &num_destroyed); }
	if(conf_files != NULL)      { destroy_string_map(conf_files,        DESTROY_MODE_FREE_VALUES, &num_destroyed); }
	if(copied_conf_files!= NULL){ destroy_string_map(copied_conf_files, DESTROY_MODE_FREE_VALUES, &num_destroyed); }

	return err;
}
Exemplo n.º 14
0
int main(int argc, char **argv) {
	config.verbose = false;
	config.quiet = false;
	config.repl = false;
	config.javascript = false;
	config.static_fns = false;
	config.elide_asserts = false;
	config.cache_path = NULL;
	config.theme = "light";
	config.dumb_terminal = false;

	config.out_path = NULL;
	config.num_src_paths = 0;
	config.src_paths = NULL;
	config.num_scripts = 0;
	config.scripts = NULL;

	config.main_ns_name = NULL;

	struct option long_options[] = {
		{"help", no_argument, NULL, 'h'},
		{"legal", no_argument, NULL, 'l'},
		{"verbose", no_argument, NULL, 'v'},
		{"quiet", no_argument, NULL, 'q'},
		{"repl", no_argument, NULL, 'r'},
		{"static-fns", no_argument, NULL, 's'},
		{"elide-asserts", no_argument, NULL, 'a'},
		{"cache", required_argument, NULL, 'k'},
		{"eval", required_argument, NULL, 'e'},
		{"theme", required_argument, NULL, 't'},
		{"dumb-terminal", no_argument, NULL, 'd'},
		{"classpath", required_argument, NULL, 'c'},
		{"auto-cache", no_argument, NULL, 'K'},
		{"init", required_argument, NULL, 'i'},
		{"main", required_argument, NULL, 'm'},

		// development options
		{"javascript", no_argument, NULL, 'j'},
		{"out", required_argument, NULL, 'o'},

		{0, 0, 0, 0}
	};
	int opt, option_index;
	while ((opt = getopt_long(argc, argv, "h?lvrsak:je:t:dc:o:Ki:qm:", long_options, &option_index)) != -1) {
		switch (opt) {
		case 'h':
			usage(argv[0]);
			exit(0);
		case 'l':
			legal();
			return 0;
		case 'v':
			config.verbose = true;
			break;
		case 'q':
			config.quiet = true;
			break;
		case 'r':
			config.repl = true;
			break;
		case 's':
			config.static_fns = true;
			break;
		case 'a':
			config.elide_asserts = true;
			break;
		case 'k':
			config.cache_path = argv[optind - 1];
			break;
		case 'K':
			config.cache_path = ".planck_cache";
			{
				char *path_copy = strdup(config.cache_path);
				char *dir = dirname(path_copy);
				if (mkdir_p(dir) < 0) {
					fprintf(stderr, "Could not create %s: %s\n", config.cache_path, strerror(errno));
				}
				free(path_copy);
			}
			break;
		case 'j':
			config.javascript = true;
			break;
		case 'e':
			config.num_scripts += 1;
			config.scripts = realloc(config.scripts, config.num_scripts * sizeof(struct script));
			config.scripts[config.num_scripts - 1].type = "text";
			config.scripts[config.num_scripts - 1].expression = true;
			config.scripts[config.num_scripts - 1].source = argv[optind - 1];
			break;
		case 'i':
			config.num_scripts += 1;
			config.scripts = realloc(config.scripts, config.num_scripts * sizeof(struct script));
			config.scripts[config.num_scripts - 1].type = "path";
			config.scripts[config.num_scripts - 1].expression = false;
			config.scripts[config.num_scripts - 1].source = argv[optind - 1];
			break;
		case 'm':
			config.main_ns_name = argv[optind - 1];
			break;
		case 't':
			config.theme = argv[optind - 1];
			break;
		case 'd':
			config.dumb_terminal = true;
			break;
		case 'c':
			{
				char *classpath = argv[optind - 1];
				char *source = strtok(classpath, ":");
				while (source != NULL) {
					char *type = "src";
					if (str_has_suffix(source, ".jar") == 0) {
						type = "jar";
					}

					config.num_src_paths += 1;
					config.src_paths = realloc(config.src_paths, config.num_src_paths * sizeof(struct src_path));
					config.src_paths[config.num_src_paths - 1].type = type;
					config.src_paths[config.num_src_paths - 1].path = strcmp(type, "jar") == 0 ? strdup(source) : ensure_trailing_slash(source);

					source = strtok(NULL, ":");
				}

				break;
			}
		case 'o':
			config.out_path = ensure_trailing_slash(argv[optind - 1]);
			break;
		case '?':
			usage(argv[0]);
			exit(1);
		default:
			printf("unhandled argument: %c\n", opt);
		}
	}

	if (config.dumb_terminal) {
		config.theme = "dumb";
	}

	config.num_rest_args = 0;
	config.rest_args = NULL;
	if (optind < argc) {
		config.num_rest_args = argc - optind;
		config.rest_args = malloc((argc - optind) * sizeof(char*));
		int i = 0;
		while (optind < argc) {
			config.rest_args[i++] = argv[optind++];
		}
	}

	if (config.num_scripts == 0 && config.main_ns_name == NULL && config.num_rest_args == 0) {
		config.repl = true;
	}

	if (config.main_ns_name != NULL && config.repl) {
		printf("Only one main-opt can be specified.\n");
		exit(1);
	}

	config.is_tty = isatty(STDIN_FILENO) == 1;

	JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
	global_ctx = ctx;
	cljs_engine_init(ctx);

	// Process init arguments

	for (int i = 0; i < config.num_scripts; i++) {
		// TODO: exit if not successfull
		struct script script = config.scripts[i];
		evaluate_source(ctx, script.type, script.source, script.expression, false, NULL, config.theme, true);
	}

	// Process main arguments

	if (config.main_ns_name != NULL) {
		run_main_in_ns(ctx, config.main_ns_name, config.num_rest_args, config.rest_args);
	} else if (!config.repl && config.num_rest_args > 0) {
		char *path = config.rest_args[0];

		struct script script;
		if (strcmp(path, "-") == 0) {
			char *source = read_all(stdin);
			script.type = "text";
			script.source = source;
			script.expression = false;
		} else {
			script.type = "path";
			script.source = path;
			script.expression = false;
		}

		evaluate_source(ctx, script.type, script.source, script.expression, false, NULL, config.theme, true);
	} else if (config.repl) {
		if (!config.quiet) {
			banner();
		}

		run_repl(ctx);
	}

	return exit_value;
}
Exemplo n.º 15
0
int main(int argc, char** args) {
	int c;
	anbool help = FALSE;
	char* outdir = NULL;
	char* cmd;
	int i, j, f;
    int inputnum;
	int rtn;
	sl* engineargs;
	int nbeargs;
	anbool fromstdin = FALSE;
	anbool overwrite = FALSE;
	anbool cont = FALSE;
    anbool skip_solved = FALSE;
    anbool makeplots = TRUE;
	double plotscale = 1.0;
	char* inbgfn = NULL;
    char* bgfn = NULL;
    char* me;
    anbool verbose = FALSE;
    int loglvl = LOG_MSG;
    char* outbase = NULL;
	anbool usecurl = TRUE;
    bl* opts;
    augment_xylist_t theallaxy;
    augment_xylist_t* allaxy = &theallaxy;
    int nmyopts;
    char* removeopts = "ixo\x01";
    char* newfits;
    char* kmz = NULL;
    char* scamp = NULL;
    char* scampconfig = NULL;
    char* index_xyls;
	anbool just_augment = FALSE;
	anbool engine_batch = FALSE;
	bl* batchaxy = NULL;
	bl* batchsf = NULL;
	sl* outfiles;
	sl* tempfiles;
    // these are deleted after the outer loop over input files
	sl* tempfiles2;
	sl* tempdirs;
	anbool timestamp = FALSE;
    anbool tempaxy = FALSE;

    errors_print_on_exit(stderr);
    fits_use_error_system();

    me = find_executable(args[0], NULL);

	engineargs = sl_new(16);
	append_executable(engineargs, "astrometry-engine", me);

	// output filenames.
	outfiles = sl_new(16);
	tempfiles = sl_new(4);
	tempfiles2 = sl_new(4);
	tempdirs = sl_new(4);

	rtn = 0;

    nmyopts = sizeof(options)/sizeof(an_option_t);
    opts = opts_from_array(options, nmyopts, NULL);
    augment_xylist_add_options(opts);

    // remove duplicate short options.
    for (i=0; i<nmyopts; i++) {
        an_option_t* opt1 = bl_access(opts, i);
        for (j=nmyopts; j<bl_size(opts); j++) {
            an_option_t* opt2 = bl_access(opts, j);
            if (opt2->shortopt == opt1->shortopt)
                bl_remove_index(opts, j);
        }
    }

    // remove unwanted augment-xylist options.
    for (i=0; i<strlen(removeopts); i++) {
        for (j=nmyopts; j<bl_size(opts); j++) {
            an_option_t* opt2 = bl_access(opts, j);
            if (opt2->shortopt == removeopts[i])
                bl_remove_index(opts, j);
        }
    }

	// which options are left?
	/*{
		char options[256];
		memset(options, 0, 256);
		printf("options:\n");
		for (i=0; i<bl_size(opts); i++) {
			an_option_t* opt = bl_access(opts, i);
			printf("  %c (%i) %s\n", opt->shortopt, (int)opt->shortopt, opt->name);
			options[(int)((opt->shortopt + 256) % 256)] = 1;
		}
		printf("Remaining short opts:\n");
		for (i=0; i<256; i++) {
			if (!options[i])
				printf("  %c (%i, 0x%x)\n", (char)i, i, i);
		}
	 }*/

    augment_xylist_init(allaxy);

    // default output filename patterns.
    allaxy->axyfn    = "%s.axy";
    allaxy->matchfn  = "%s.match";
    allaxy->rdlsfn   = "%s.rdls";
    allaxy->solvedfn = "%s.solved";
    allaxy->wcsfn    = "%s.wcs";
    allaxy->corrfn   = "%s.corr";
    newfits          = "%s.new";
    index_xyls = "%s-indx.xyls";

	while (1) {
        int res;
		c = opts_getopt(opts, argc, args);
		//printf("option %c (%i)\n", c, (int)c);
        if (c == -1)
            break;
        switch (c) {
        case '\x91':
            allaxy->axyfn = optarg;
            break;
        case '\x90':
            tempaxy = TRUE;
            break;
		case '\x88':
			timestamp = TRUE;
			break;
		case '\x84':
			plotscale = atof(optarg);
			break;
		case '\x85':
			inbgfn = optarg;
			break;
		case '\x87':
			allaxy->assume_fits_image = TRUE;
			break;
		case '(':
			engine_batch = TRUE;
			break;
		case '@':
			just_augment = TRUE;
			break;
        case 'U':
            index_xyls = optarg;
            break;
        case 'n':
            scampconfig = optarg;
            break;
        case 'i':
            scamp = optarg;
            break;
        case 'Z':
            kmz = optarg;
            break;
        case 'N':
            newfits = optarg;
            break;
		case 'h':
			help = TRUE;
			break;
        case 'v':
            sl_append(engineargs, "--verbose");
            verbose = TRUE;
			allaxy->verbosity++;
            loglvl++;
            break;
		case 'D':
			outdir = optarg;
			break;
        case 'o':
            outbase = optarg;
            break;
		case 'b':
		case '\x89':
			sl_append(engineargs, "--config");
			append_escape(engineargs, optarg);
			break;
		case 'f':
			fromstdin = TRUE;
			break;
        case 'O':
            overwrite = TRUE;
            break;
        case 'p':
            makeplots = FALSE;
            break;
        case 'G':
            usecurl = FALSE;
            break;
        case 'K':
            cont = TRUE;
            break;
        case 'J':
            skip_solved = TRUE;
            break;
        default:
            res = augment_xylist_parse_option(c, optarg, allaxy);
            if (res) {
                rtn = -1;
                goto dohelp;
            }
        }
    }

	if ((optind == argc) && !fromstdin) {
		printf("ERROR: You didn't specify any files to process.\n");
		help = TRUE;
	}

	if (help) {
    dohelp:
		print_help(args[0], opts);
		exit(rtn);
	}
    bl_free(opts);

    // --dont-augment: advertised as just write xy file,
    // so quit after doing that.
    if (allaxy->dont_augment) {
        just_augment = TRUE;
    }

    log_init(loglvl);
	if (timestamp)
		log_set_timestamp(TRUE);

    if (kmz && starts_with(kmz, "-"))
        logmsg("Do you really want to save KMZ to the file named \"%s\" ??\n", kmz);

    if (starts_with(newfits, "-")) {
        logmsg("Do you really want to save the new FITS file to the file named \"%s\" ??\n", newfits);
    }

	if (engine_batch) {
		batchaxy = bl_new(16, sizeof(augment_xylist_t));
		batchsf  = bl_new(16, sizeof(solve_field_args_t));
	}

    // Allow (some of the) default filenames to be disabled by setting them to "none".
    allaxy->matchfn  = none_is_null(allaxy->matchfn);
    allaxy->rdlsfn   = none_is_null(allaxy->rdlsfn);
    allaxy->solvedfn = none_is_null(allaxy->solvedfn);
    allaxy->solvedinfn = none_is_null(allaxy->solvedinfn);
    allaxy->wcsfn    = none_is_null(allaxy->wcsfn);
    allaxy->corrfn   = none_is_null(allaxy->corrfn);
    newfits          = none_is_null(newfits);
    index_xyls = none_is_null(index_xyls);

	if (outdir) {
        if (mkdir_p(outdir)) {
            ERROR("Failed to create output directory %s", outdir);
            exit(-1);
        }
	}

	// number of engine args not specific to a particular file
	nbeargs = sl_size(engineargs);

	f = optind;
    inputnum = 0;
	while (1) {
		char* infile = NULL;
		anbool isxyls;
		char* reason;
		int len;
		char* base;
        char* basedir;
        char* basefile = NULL;
		char *objsfn=NULL;
		char *ppmfn=NULL;
        char* downloadfn = NULL;
        char* suffix = NULL;
		sl* cmdline;
        anbool ctrlc;
        anbool isurl;
        augment_xylist_t theaxy;
        augment_xylist_t* axy = &theaxy;
        int j;
		solve_field_args_t thesf;
		solve_field_args_t* sf = &thesf;
		anbool want_pnm = FALSE;

        // reset augment-xylist args.
        memcpy(axy, allaxy, sizeof(augment_xylist_t));

		memset(sf, 0, sizeof(solve_field_args_t));

		if (fromstdin) {
            char fnbuf[1024];
			if (!fgets(fnbuf, sizeof(fnbuf), stdin)) {
				if (ferror(stdin))
					SYSERROR("Failed to read a filename from stdin");
				break;
			}
			len = strlen(fnbuf);
			if (fnbuf[len-1] == '\n')
				fnbuf[len-1] = '\0';
			infile = fnbuf;
            logmsg("Reading input file \"%s\"...\n", infile);
		} else {
			if (f == argc)
				break;
			infile = args[f];
			f++;
            logmsg("Reading input file %i of %i: \"%s\"...\n",
                   f - optind, argc - optind, infile);
		}
        inputnum++;

        cmdline = sl_new(16);

		if (!engine_batch) {
			// Remove arguments that might have been added in previous trips through this loop
			sl_remove_from(engineargs,  nbeargs);
		}

		// Choose the base path/filename for output files.
        if (outbase)
            asprintf_safe(&basefile, outbase, inputnum, infile);
        else
			basefile = basename_safe(infile);
        //logverb("Base filename: %s\n", basefile);

        isurl = (!file_exists(infile) &&
                 (starts_with(infile, "http://") ||
                  starts_with(infile, "ftp://")));

		if (outdir)
            basedir = strdup(outdir);
		else {
            if (isurl)
                basedir = strdup(".");
            else
				basedir = dirname_safe(infile);
        }
        //logverb("Base directory: %s\n", basedir);

        asprintf_safe(&base, "%s/%s", basedir, basefile);
        //logverb("Base name for output files: %s\n", base);

        // trim .gz, .bz2
        // hmm, we drop the suffix in this case...
		len = strlen(base);
        if (ends_with(base, ".gz"))
            base[len-3] = '\0';
        else if (ends_with(base, ".bz2"))
            base[len-4] = '\0';
		len = strlen(base);
		// trim .xx / .xxx / .xxxx
		if (len >= 5) {
            for (j=3; j<=5; j++) {
                if (base[len - j] == '/')
                    break;
                if (base[len - j] == '.') {
                    base[len - j] = '\0';
                    suffix = base + len - j + 1;
                    break;
                }
            }
		}
        logverb("Base: \"%s\", basefile \"%s\", basedir \"%s\", suffix \"%s\"\n", base, basefile, basedir, suffix);

        if (tempaxy) {
            axy->axyfn = create_temp_file("axy", axy->tempdir);
            sl_append_nocopy(tempfiles2, axy->axyfn);
        } else
            axy->axyfn    = sl_appendf(outfiles, axy->axyfn,       base);
        if (axy->matchfn)
            axy->matchfn  = sl_appendf(outfiles, axy->matchfn,     base);
        if (axy->rdlsfn)
            axy->rdlsfn   = sl_appendf(outfiles, axy->rdlsfn,      base);
        if (axy->solvedfn)
            axy->solvedfn = sl_appendf(outfiles, axy->solvedfn,    base);
        if (axy->wcsfn)
            axy->wcsfn    = sl_appendf(outfiles, axy->wcsfn,       base);
        if (axy->corrfn)
            axy->corrfn   = sl_appendf(outfiles, axy->corrfn,      base);
        if (axy->cancelfn)
            axy->cancelfn  = sl_appendf(outfiles, axy->cancelfn, base);
        if (axy->keepxylsfn)
            axy->keepxylsfn  = sl_appendf(outfiles, axy->keepxylsfn, base);
        if (axy->pnmfn)
            axy->pnmfn  = sl_appendf(outfiles, axy->pnmfn, base);
        if (newfits)
            sf->newfitsfn  = sl_appendf(outfiles, newfits,  base);
		if (kmz)
			sf->kmzfn = sl_appendf(outfiles, kmz, base);
        if (index_xyls)
            sf->indxylsfn  = sl_appendf(outfiles, index_xyls, base);
		if (scamp)
			sf->scampfn = sl_appendf(outfiles, scamp, base);
		if (scampconfig)
			sf->scampconfigfn = sl_appendf(outfiles, scampconfig, base);
        if (makeplots) {
            objsfn     = sl_appendf(outfiles, "%s-objs.png",  base);
            sf->redgreenfn = sl_appendf(outfiles, "%s-indx.png",  base);
            sf->ngcfn      = sl_appendf(outfiles, "%s-ngc.png",   base);
        }
        if (isurl) {
            if (suffix)
                downloadfn = sl_appendf(outfiles, "%s.%s", base, suffix);
            else
                downloadfn = sl_appendf(outfiles, "%s", base);
        }

        if (axy->solvedinfn)
            asprintf_safe(&axy->solvedinfn, axy->solvedinfn, base);

        // Do %s replacement on --verify-wcs entries...
        if (sl_size(axy->verifywcs)) {
            sl* newlist = sl_new(4);
            for (j=0; j<sl_size(axy->verifywcs); j++)
                sl_appendf(newlist, sl_get(axy->verifywcs, j), base);
            axy->verifywcs = newlist;
        }

        // ... and plot-bg
        if (inbgfn)
            asprintf_safe(&bgfn, inbgfn, base);

        if (axy->solvedinfn && axy->solvedfn && streq(axy->solvedfn, axy->solvedinfn)) {
            // solved input and output files are the same: don't delete the input!
            sl_remove_string(outfiles, axy->solvedfn);
            free(axy->solvedfn);
            axy->solvedfn = axy->solvedinfn;
        }

        free(basedir);
        free(basefile);

        if (skip_solved) {
            char* tocheck[] = { axy->solvedinfn, axy->solvedfn };
            for (j=0; j<sizeof(tocheck)/sizeof(char*); j++) {
                if (!tocheck[j])
                    continue;
                logverb("Checking for solved file %s\n", tocheck[j]);
                if (file_exists(tocheck[j])) {
                    logmsg("Solved file exists: %s; skipping this input file.\n", tocheck[j]);
                    goto nextfile;
                } else {
                    logverb("File \"%s\" does not exist.\n", tocheck[j]);
                }
            }
        }

        // Check for overlap between input and output filenames
		for (i = 0; i < sl_size(outfiles); i++) {
			char* fn = sl_get(outfiles, i);
            if (streq(fn, infile)) {
                logmsg("Output filename \"%s\" is the same as your input file.\n"
                       "Refusing to continue.\n"
                       "You can either choose a different output filename, or\n"
                       "rename your input file to have a different extension.\n", fn);
                goto nextfile;
            }
        }

		// Check for (and possibly delete) existing output filenames.
		for (i = 0; i < sl_size(outfiles); i++) {
			char* fn = sl_get(outfiles, i);
			if (!file_exists(fn))
				continue;
            if (cont) {
            } else if (overwrite) {
				if (unlink(fn)) {
					SYSERROR("Failed to delete an already-existing output file \"%s\"", fn);
					exit(-1);
				}
			} else {
				logmsg("Output file already exists: \"%s\".\n"
				       "Use the --overwrite flag to overwrite existing files,\n"
                       " or the --continue  flag to not overwrite existing files but still try solving.\n", fn);
				logmsg("Continuing to next input file.\n");
                goto nextfile;
			}
		}

		// if we're making "redgreen" plot, we need:
		if (sf->redgreenfn) {
			// -- index xylist
			if (!sf->indxylsfn) {
				sf->indxylsfn = create_temp_file("indxyls", axy->tempdir);
				sl_append_nocopy(tempfiles, sf->indxylsfn);
			}
			// -- match file.
			if (!axy->matchfn) {
				axy->matchfn = create_temp_file("match", axy->tempdir);
				sl_append_nocopy(tempfiles, axy->matchfn);
			}
		}

		// if index xyls file is needed, we need:
		if (sf->indxylsfn) {
			// -- wcs
			if (!axy->wcsfn) {
				axy->wcsfn = create_temp_file("wcs", axy->tempdir);
				sl_append_nocopy(tempfiles, axy->wcsfn);
			}
			// -- rdls
			if (!axy->rdlsfn) {
				axy->rdlsfn = create_temp_file("rdls", axy->tempdir);
				sl_append_nocopy(tempfiles, axy->rdlsfn);
			}
		}

        // Download URL...
        if (isurl) {

            sl_append(cmdline, usecurl ? "curl" : "wget");
            if (!verbose)
                sl_append(cmdline, usecurl ? "--silent" : "--quiet");
            sl_append(cmdline, usecurl ? "--output" : "-O");
            append_escape(cmdline, downloadfn);
            append_escape(cmdline, infile);

            cmd = sl_implode(cmdline, " ");

            logmsg("Downloading...\n");
            if (run_command(cmd, &ctrlc)) {
                ERROR("%s command %s", sl_get(cmdline, 0),
                      (ctrlc ? "was cancelled" : "failed"));
                exit(-1);
            }
            sl_remove_all(cmdline);
            free(cmd);

            infile = downloadfn;
        }

		if (makeplots)
			want_pnm = TRUE;

		if (axy->assume_fits_image) {
			axy->imagefn = infile;
			if (axy->pnmfn)
				want_pnm = TRUE;
		} else {
			logverb("Checking if file \"%s\" ext %i is xylist or image: ",
                    infile, axy->extension);
			fflush(NULL);
			reason = NULL;
			isxyls = xylist_is_file_xylist(infile, axy->extension,
                                           axy->xcol, axy->ycol, &reason);
			logverb(isxyls ? "xyls\n" : "image\n");
			if (!isxyls)
				logverb("  (not xyls because: %s)\n", reason);
			free(reason);
			fflush(NULL);

			if (isxyls)
				axy->xylsfn = infile;
			else {
				axy->imagefn = infile;
				want_pnm = TRUE;
			}
		}

		if (want_pnm && !axy->pnmfn) {
            ppmfn = create_temp_file("ppm", axy->tempdir);
            sl_append_nocopy(tempfiles, ppmfn);
            axy->pnmfn = ppmfn;
            axy->force_ppm = TRUE;
		}

        axy->keep_fitsimg = (newfits || scamp);

        if (augment_xylist(axy, me)) {
            ERROR("augment-xylist failed");
            exit(-1);
        }

		if (just_augment)
			goto nextfile;

        if (makeplots) {
            // Check that the plotting executables were built...
            char* exec = find_executable("plotxy", me);
            free(exec);
            if (!exec) {
                logmsg("Couldn't find \"plotxy\" executable - maybe you didn't build the plotting programs?\n");
                logmsg("Disabling plots.\n");
                makeplots = FALSE;
            }
        }
        if (makeplots) {
            // source extraction overlay
            if (plot_source_overlay(axy, me, objsfn, plotscale, bgfn))
                makeplots = FALSE;
        }

		append_escape(engineargs, axy->axyfn);

		if (file_readable(axy->wcsfn))
			axy->wcs_last_mod = file_get_last_modified_time(axy->wcsfn);
		else
			axy->wcs_last_mod = 0;

		if (!engine_batch) {
			run_engine(engineargs);
			after_solved(axy, sf, makeplots, me, verbose,
						 axy->tempdir, tempdirs, tempfiles, plotscale, bgfn);
		} else {
			bl_append(batchaxy, axy);
			bl_append(batchsf,  sf );
		}
        fflush(NULL);

        // clean up and move on to the next file.
    nextfile:        
		free(base);
        sl_free2(cmdline);

		if (!engine_batch) {
			free(axy->fitsimgfn);
			free(axy->solvedinfn);
            free(bgfn);
			// erm.
			if (axy->verifywcs != allaxy->verifywcs)
				sl_free2(axy->verifywcs);
			sl_remove_all(outfiles);
			if (!axy->no_delete_temp)
				delete_temp_files(tempfiles, tempdirs);
		}
        errors_print_stack(stdout);
        errors_clear_stack();
        logmsg("\n");
	}

	if (engine_batch) {
		run_engine(engineargs);
		for (i=0; i<bl_size(batchaxy); i++) {
			augment_xylist_t* axy = bl_access(batchaxy, i);
			solve_field_args_t* sf = bl_access(batchsf, i);

			after_solved(axy, sf, makeplots, me, verbose,
						 axy->tempdir, tempdirs, tempfiles, plotscale, bgfn);
			errors_print_stack(stdout);
			errors_clear_stack();
			logmsg("\n");

			free(axy->fitsimgfn);
			free(axy->solvedinfn);
			// erm.
			if (axy->verifywcs != allaxy->verifywcs)
				sl_free2(axy->verifywcs);
		}
		if (!allaxy->no_delete_temp)
			delete_temp_files(tempfiles, tempdirs);
		bl_free(batchaxy);
		bl_free(batchsf);
	}

    if (!allaxy->no_delete_temp)
        delete_temp_files(tempfiles2, NULL);

	sl_free2(outfiles);
	sl_free2(tempfiles);
	sl_free2(tempfiles2);
	sl_free2(tempdirs);
	sl_free2(engineargs);
    free(me);
    augment_xylist_free_contents(allaxy);

	return 0;
}
Exemplo n.º 16
0
Arquivo: index.c Projeto: t-k-/OPMES
static LIST_IT_CALLBK(_posting_write)
{
	LIST_OBJ(struct subpath, p, ln);
	P_CAST(id, CP_ID, pa_extra);
	char  path[MAX_DIR_NAME_LEN];
	FILE *fh;
	struct posting_head hd = {0, 0};
	BOOL  wr_flag = 0;

	/* make directory first */
	sprintf(path, "col/%s", p->dir);
	mkdir_p(path);

	/* wirte posting header */
//	sprintf(path, "col/%s/head.bin", p->dir);
//
//	if(!file_exists(path)) {
//		/* the file does not exist currently. */
//		fh = fopen(path, "w");
//
//		if (fh) {
//			hd.max = *id;
//			hd.min = *id;
//
//			fwrite(&hd, sizeof(struct posting_head), 1, fh);
//			fclose(fh);
//		}
//	} else {
//		fh = fopen(path, "r+");
//		if (fh) {
//			fread(&hd, sizeof(struct posting_head), 1, fh);
//
//			if (hd.max < *id) {
//				hd.max = *id;
//				wr_flag = 1;
//			} 
//			
//			if (*id < hd.min) {
//				hd.min = *id;
//				wr_flag = 1;
//			}
//
//			if (wr_flag) {
//				/* overwrite by new numbers */
//				rewind(fh);
//				fwrite(&hd, sizeof(struct posting_head), 1, fh);
//			}
//			
//			fclose(fh);
//		}
//	}

	/* wirte posting file */
	sprintf(path, "col/%s/posting.bin", p->dir);
	fh = fopen(path, "a");

	if (fh) {
		struct posting_item it;
		it.id = *id;
		it.brw = p->brw;
		fwrite(&it, sizeof(struct posting_item), 1, fh);
		fclose(fh);
	}

	LIST_GO_OVER;
}