Esempio n. 1
0
File: VFS.cpp Progetto: ss23/rpcs3
void VFS::Mount(const std::string& ps3_path, const std::string& local_path, vfsDevice* device)
{
	std::string simpl_ps3_path = simplify_path(ps3_path, true, true);

	UnMount(simpl_ps3_path);

	device->SetPath(simpl_ps3_path, simplify_path(local_path, true, false));
	m_devices.push_back(device);

	if (m_devices.size() > 1)
	{
		std::sort(m_devices.begin(), m_devices.end(), [](vfsDevice *a, vfsDevice *b) { return b->GetPs3Path().length() < a->GetPs3Path().length(); });
	}
}
/*

** note: it modifies it's first argument
*/
void simplify_path(char **buf)
{
	unsigned int last1slash = 0;
	unsigned int last2slash = 0;

	while (!strncmp(*buf, "/../", 4))
		memmove(*buf, *buf + 3, strlen(*buf + 3) + 1);

	for (unsigned int i = 0; i < strlen(*buf) - 2; i++)
		while (!strncmp(*buf + i, "/./", 3))
			memmove(*buf + i, *buf + i + 2, strlen(*buf + i + 2) + 1);

	for (unsigned int i = 0; i < strlen(*buf) - 3; i++)
	{
		if (*(*buf + i) == '/')
		{
			last2slash = last1slash;
			last1slash = i;
		}

		if (!strncmp(*buf + i, "/../", 4))
		{
			memmove(*buf + last2slash, *buf + i + 3, strlen(*buf + i + 3) + 1);

			return simplify_path(buf);
		}
	}
}
Esempio n. 3
0
void BackupSystem::create_new_version(const OpaqueTimestamp &start_time){
	{
		auto version = this->versions.back();
		ArchiveReader archive(this->get_version_path(version), &this->get_aux_fso_path(version), this->keypair.get());
		auto manifest = archive.read_manifest();
		this->old_objects = this->get_old_objects(archive, version);
		this->next_stream_id = manifest->next_stream_id;
		this->next_differential_chain_id = manifest->next_differential_chain_id;
	}
	this->set_old_objects_map();
	this->set_base_objects();
	for (auto &base_object : this->base_objects){
		for (auto &fso : base_object->get_iterator()){
			auto search_path = simplify_path(fso->get_mapped_path().wstring());
			auto it = this->old_objects_map.find(search_path);
			FileSystemObject *found = nullptr;
			if (it == this->old_objects_map.end()){
				for (auto &fso2 : this->old_objects){
					if (!fso2->get_is_encrypted())
						continue;
					found = fso2->find(search_path);
					if (found)
						break;
				}
			}else
				found = it->second;
			if (!found)
				continue;
			fso->set_stream_id(found->get_stream_id());
			break;
		}
	}
	this->generate_archive(start_time, &BackupSystem::check_and_maybe_add, this->get_new_version_number());
}
Esempio n. 4
0
File: VFS.cpp Progetto: ss23/rpcs3
vfsDevice* VFS::GetDevice(const std::string& ps3_path, std::string& path) const
{
	auto try_get_device = [this, &path](const std::string& ps3_path) -> vfsDevice*
	{
		std::vector<std::string> ps3_path_blocks = simplify_path_blocks(ps3_path);
		size_t max_eq = 0;
		int max_i = -1;

		for (u32 i = 0; i < m_devices.size(); ++i)
		{
			std::vector<std::string> dev_ps3_path_blocks = simplify_path_blocks(m_devices[i]->GetPs3Path());

			if (ps3_path_blocks.size() < dev_ps3_path_blocks.size())
				continue;

			size_t eq = 0;
			for (; eq < dev_ps3_path_blocks.size(); ++eq)
			{
				if (strcmp(ps3_path_blocks[eq].c_str(), dev_ps3_path_blocks[eq].c_str()))
				{
					break;
				}
			}

			if (eq > max_eq)
			{
				max_eq = eq;
				max_i = i;
			}
		}

		if (max_i < 0)
			return nullptr;

		path = m_devices[max_i]->GetLocalPath();

		for (size_t i = max_eq; i < ps3_path_blocks.size(); i++)
		{
			path += "/" + ps3_path_blocks[i];
		}

		path = simplify_path(path, false, false);
		
		return m_devices[max_i];
	};

	if (!ps3_path.size() || ps3_path[0] != '/')
	{
		return nullptr;
	}

	return try_get_device(GetLinked(ps3_path));

	// What is it? cwd is real path, ps3_path is ps3 path, but GetLinked accepts ps3 path
	//if (auto res = try_get_device(GetLinked(cwd + ps3_path))) 
	//	return res;
}
Esempio n. 5
0
void BackupSystem::set_old_objects_map(){
	this->old_objects_map.clear();
	for (auto &old_object : this->old_objects){
		if (old_object->get_is_encrypted())
			continue;
		for (auto &fso : old_object->get_iterator())
			this->old_objects_map[simplify_path(fso->get_mapped_path().wstring())] = fso;
	}
}
void __TIMM_OSAL_TraceFunction(const __TIMM_OSAL_TRACE_LOCATION * loc,
    const char *fmt, ...)
{
	if (trace_level == -1)
	{
		char *val = getenv("TIMM_OSAL_DEBUG_TRACE_LEVEL");
		trace_level =
		    val ? strtol(val, NULL, 0) : DEFAULT_TRACE_LEVEL;
	}

	if (trace_level >= loc->level)
	{
		va_list ap;

		va_start(ap, fmt);	/* make ap point to first arg after 'fmt' */

#ifdef _Android

#if ( TIMM_OSAL_DEBUG_TRACE_DETAIL > 1 )
		LOGD("%s:%d\t%s()\t", simplify_path(loc->file), loc->line,
		    loc->function);
#endif
		char string[1000];
		vsprintf(string, fmt, ap);
		LOGD("%s",string);

#else

#if ( TIMM_OSAL_DEBUG_TRACE_DETAIL > 1 )
		printf("%s:%d\t%s()\t", simplify_path(loc->file), loc->line,
		    loc->function);
#endif
		vprintf(fmt, ap);

#endif
		va_end(ap);
	}
}
/**
        \fn ADM_PathCanonize
        \brief Canonize the path, returns a copy of the absolute path given as parameter
*/
char *ADM_PathCanonize(const char *tmpname)
{
	char path[300];
	char *out;

	if (!getcwd(path, 300))
	{
		fprintf(stderr, "\ngetcwd() failed with: %s (%u)\n", strerror(errno), errno);
		path[0] = '\0';
	}

	if (!tmpname || tmpname[0] == 0)
	{
		out = new char[strlen(path) + 2];
		strcpy(out, path);
#ifndef __WIN32
		strcat(out, "/");
#else
		strcat(out, "\\");
#endif
		printf("\n Canonizing null string ??? (%s)\n", out);
	}
	else if (tmpname[0] == '/'
#if defined(__WIN32)
		|| tmpname[1] == ':'
#endif
		)
	{
		out = new char[strlen(tmpname) + 1];
		strcpy(out, tmpname);

		return out;
	}
	else
	{
		out = new char[strlen(path) + strlen(tmpname) + 6];
		strcpy(out, path);
#ifndef __WIN32
		strcat(out, "/");
#else
		strcat(out, "\\");
#endif
		strcat(out, tmpname);
	}

	simplify_path(&out);

	return out;
}
Esempio n. 8
0
File: VFS.cpp Progetto: ss23/rpcs3
void VFS::UnMount(const std::string& ps3_path)
{
	std::string simpl_ps3_path = simplify_path(ps3_path, true, true);

	for (u32 i = 0; i < m_devices.size(); ++i)
	{
		if (!strcmp(m_devices[i]->GetPs3Path().c_str(), simpl_ps3_path.c_str()))
		{
			delete m_devices[i];

			m_devices.erase(m_devices.begin() +i);

			return;
		}
	}
}
Esempio n. 9
0
bool vfsDir::Open(const std::string& path)
{
	Close();

	m_stream.reset(Emu.GetVFS().OpenDir(path));

	DirEntryInfo info;

	m_cwd = simplify_path(Emu.GetVFS().GetLinked(0 && m_stream && m_stream->IsOpened() ? m_stream->GetPath() : path), true, true);

	auto blocks = simplify_path_blocks(GetPath());

	for (auto dev : Emu.GetVFS().m_devices)
	{
		auto dev_blocks = simplify_path_blocks(dev->GetPs3Path());

		if (dev_blocks.size() < (blocks.size() + 1))
		{
			continue;
		}

		bool is_ok = true;

		for (size_t i = 0; i < blocks.size(); ++i)
		{
			if (strcmp(dev_blocks[i].c_str(), blocks[i].c_str()))
			{
				is_ok = false;
				break;
			}
		}

		if (is_ok)
		{
			info.name = dev_blocks[blocks.size()];
			m_entries.push_back(info);
		}
	}

	if (m_stream && m_stream->IsOpened())
	{
		m_entries.insert(m_entries.begin(), m_stream->GetEntries().begin(), m_stream->GetEntries().end());
	}

	return !m_entries.empty();
}
Esempio n. 10
0
char *
single_path_relocation(const char *from, const char *to)
{
#if defined(__MINGW32__)
  char exe_path[PATH_MAX];
  get_executable_path (NULL, &exe_path[0], sizeof(exe_path)/sizeof(exe_path[0]));
  if (strrchr (exe_path, '/') != NULL)
  {
     strrchr (exe_path, '/')[1] = '\0';
  }
  char * rel_to_datadir = get_relative_path (from, to);
  strcat (exe_path, rel_to_datadir);
  simplify_path (&exe_path[0]);
  return malloc_copy_string(exe_path);
#else
  return malloc_copy_string(to);
#endif
}
Esempio n. 11
0
File: VFS.cpp Progetto: ss23/rpcs3
vfsDevice* VFS::GetDeviceLocal(const std::string& local_path, std::string& path) const
{
	int max_eq = -1;
	int max_i = -1;

	std::vector<std::string> local_path_blocks = simplify_path_blocks(local_path);

	for (u32 i = 0; i < m_devices.size(); ++i)
	{
		std::vector<std::string> dev_local_path_blocks = simplify_path_blocks(m_devices[i]->GetLocalPath());

		if (local_path_blocks.size() < dev_local_path_blocks.size())
			continue;

		int dev_blocks = dev_local_path_blocks.size();

		bool prefix_equal = std::equal(
			std::begin(dev_local_path_blocks),
			std::end(dev_local_path_blocks),
			std::begin(local_path_blocks),
			[](const std::string& a, const std::string& b){ return strcmp(a.c_str(), b.c_str()) == 0; }
		);
		
		if (prefix_equal && dev_blocks > max_eq)
		{
			max_eq = dev_blocks;
			max_i = i;
		}
	}

	if (max_i < 0)
		return nullptr;

	path = m_devices[max_i]->GetPs3Path();

	for (size_t i = max_eq; i < local_path_blocks.size(); i++)
	{
		path += "/" + local_path_blocks[i];
	}

	path = simplify_path(path, false, true);

	return m_devices[max_i];
}
Esempio n. 12
0
File: VFS.cpp Progetto: ss23/rpcs3
void VFS::Init(const std::string& path)
{
	cwd = simplify_path(path, true, false);

	UnMountAll();

	std::vector<VFSManagerEntry> entries;
	SaveLoadDevices(entries, true);

	for(const VFSManagerEntry& entry : entries)
	{
		vfsDevice* dev;

		switch(entry.device)
		{
		case vfsDevice_LocalFile:
			dev = new vfsDeviceLocalFile();
		break;

		case vfsDevice_HDD:
			dev = new vfsDeviceHDD(entry.device_path);
		break;

		default:
			continue;
		}
		
		std::string mpath = entry.path;
		// TODO: This shouldn't use current dir
		// If no value assigned to SysEmulationDirPath in INI, use the path that with executable.
		if (rpcs3::config.system.emulation_dir_path_enable.value())
		{
			fmt::Replace(mpath, "$(EmulatorDir)", rpcs3::config.system.emulation_dir_path.value());
		}
		else
		{
			fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath());
		}
		fmt::Replace(mpath, "$(GameDir)", cwd);
		Mount(entry.mount, mpath, dev);
	}

	Link("/app_home/", "/host_root/" + cwd);
}
Esempio n. 13
0
int
main(void)
{
	int	rv;
	char	*cp, cdpath[256], pwd[256], file[256], result[256];

	printf("enter CDPATH: "); gets(cdpath);
	printf("enter PWD: "); gets(pwd);
	while (1) {
		if (printf("Enter file: "), gets(file) == 0)
			return (0);
		cp = cdpath;
		do {
			rv = make_path(pwd, file, &cp, result, sizeof(result));
			printf("make_path returns (%d), \"%s\" ", rv, result);
			simplify_path(result);
			printf("(simpifies to \"%s\")\n", result);
		} while (cp);
	}
}
Esempio n. 14
0
void
simplify_path_debug (const char * input, const char * expected)
{
  char * input_copy = malloc_copy_string (input);
  if ( input_copy == NULL )
  {
    _exit(1);
  }
  simplify_path (input_copy);
  int ok = (strcmp(input_copy, expected) == 0) ? 1 : 0;
  if (ok)
  {
    printf ("PASS: %s simplifies to %s\n", input, input_copy);
  }
  else
  {
    printf ("FAIL: %s simplifies to %s, should be %s\n", input, input_copy, expected);
    _exit(1);
  }
  free ((void *)input_copy);
}
Esempio n. 15
0
int
c_cd(const char **wp)
{
	int optc, rv, phys_path;
	bool physical = tobool(Flag(FPHYSICAL));
	/* was a node from cdpath added in? */
	int cdnode;
	/* show where we went?, error for $PWD */
	bool printpath = false, eflag = false;
	struct tbl *pwd_s, *oldpwd_s;
	XString xs;
	char *dir, *allocd = NULL, *tryp, *pwd, *cdpath;

	while ((optc = ksh_getopt(wp, &builtin_opt, "eLP")) != -1)
		switch (optc) {
		case 'e':
			eflag = true;
			break;
		case 'L':
			physical = false;
			break;
		case 'P':
			physical = true;
			break;
		case '?':
			return (2);
		}
	wp += builtin_opt.optind;

	if (Flag(FRESTRICTED)) {
		bi_errorf("restricted shell - can't cd");
		return (2);
	}

	pwd_s = global("PWD");
	oldpwd_s = global("OLDPWD");

	if (!wp[0]) {
		/* No arguments - go home */
		if ((dir = str_val(global("HOME"))) == null) {
			bi_errorf("no home directory (HOME not set)");
			return (2);
		}
	} else if (!wp[1]) {
		/* One argument: - or dir */
		strdupx(allocd, wp[0], ATEMP);
		if (ksh_isdash((dir = allocd))) {
			afree(allocd, ATEMP);
			allocd = NULL;
			dir = str_val(oldpwd_s);
			if (dir == null) {
				bi_errorf("no OLDPWD");
				return (2);
			}
			printpath = true;
		}
	} else if (!wp[2]) {
		/* Two arguments - substitute arg1 in PWD for arg2 */
		size_t ilen, olen, nlen, elen;
		char *cp;

		if (!current_wd[0]) {
			bi_errorf("can't determine current directory");
			return (2);
		}
		/*
		 * substitute arg1 for arg2 in current path.
		 * if the first substitution fails because the cd fails
		 * we could try to find another substitution. For now
		 * we don't
		 */
		if ((cp = strstr(current_wd, wp[0])) == NULL) {
			bi_errorf("bad substitution");
			return (2);
		}
		/*-
		 * ilen = part of current_wd before wp[0]
		 * elen = part of current_wd after wp[0]
		 * because current_wd and wp[1] need to be in memory at the
		 * same time beforehand the addition can stay unchecked
		 */
		ilen = cp - current_wd;
		olen = strlen(wp[0]);
		nlen = strlen(wp[1]);
		elen = strlen(current_wd + ilen + olen) + 1;
		dir = allocd = alloc(ilen + nlen + elen, ATEMP);
		memcpy(dir, current_wd, ilen);
		memcpy(dir + ilen, wp[1], nlen);
		memcpy(dir + ilen + nlen, current_wd + ilen + olen, elen);
		printpath = true;
	} else {
		bi_errorf("too many arguments");
		return (2);
	}

#ifdef MKSH__NO_PATH_MAX
	/* only a first guess; make_path will enlarge xs if necessary */
	XinitN(xs, 1024, ATEMP);
#else
	XinitN(xs, PATH_MAX, ATEMP);
#endif

	cdpath = str_val(global("CDPATH"));
	do {
		cdnode = make_path(current_wd, dir, &cdpath, &xs, &phys_path);
		if (physical)
			rv = chdir(tryp = Xstring(xs, xp) + phys_path);
		else {
			simplify_path(Xstring(xs, xp));
			rv = chdir(tryp = Xstring(xs, xp));
		}
	} while (rv < 0 && cdpath != NULL);

	if (rv < 0) {
		if (cdnode)
			bi_errorf("%s: %s", dir, "bad directory");
		else
			bi_errorf("%s: %s", tryp, cstrerror(errno));
		afree(allocd, ATEMP);
		Xfree(xs, xp);
		return (2);
	}

	rv = 0;

	/* allocd (above) => dir, which is no longer used */
	afree(allocd, ATEMP);
	allocd = NULL;

	/* Clear out tracked aliases with relative paths */
	flushcom(false);

	/*
	 * Set OLDPWD (note: unsetting OLDPWD does not disable this
	 * setting in AT&T ksh)
	 */
	if (current_wd[0])
		/* Ignore failure (happens if readonly or integer) */
		setstr(oldpwd_s, current_wd, KSH_RETURN_ERROR);

	if (!mksh_abspath(Xstring(xs, xp))) {
		pwd = NULL;
	} else if (!physical) {
		goto norealpath_PWD;
	} else if ((pwd = allocd = do_realpath(Xstring(xs, xp))) == NULL) {
		if (eflag)
			rv = 1;
 norealpath_PWD:
		pwd = Xstring(xs, xp);
	}

	/* Set PWD */
	if (pwd) {
		char *ptmp = pwd;

		set_current_wd(ptmp);
		/* Ignore failure (happens if readonly or integer) */
		setstr(pwd_s, ptmp, KSH_RETURN_ERROR);
	} else {
		set_current_wd(null);
		pwd = Xstring(xs, xp);
		/* XXX unset $PWD? */
		if (eflag)
			rv = 1;
	}
	if (printpath || cdnode)
		shprintf("%s\n", pwd);

	afree(allocd, ATEMP);
	Xfree(xs, xp);
	return (rv);
}
Esempio n. 16
0
extern int mount_main(int argc, char **argv)
{
	struct stat statbuf;
	char *string_flags = xstrdup("");
	char *extra_opts;
	int flags = 0;
	char *filesystemType = "auto";
	int got_filesystemType = 0;
	char *device = xmalloc(PATH_MAX);
	char *directory = xmalloc(PATH_MAX);
	struct mntent *m = NULL;
	int all = FALSE;
	int fakeIt = FALSE;
	int useMtab = TRUE;
	int rc = EXIT_FAILURE;
	FILE *f = 0;
	int opt;

	/* Parse options */
	while ((opt = getopt(argc, argv, "o:rt:wafnv")) > 0) {
		switch (opt) {
		case 'o':
			parse_mount_options(optarg, &flags, &string_flags);
			break;
		case 'r':
			flags |= MS_RDONLY;
			break;
		case 't':
			filesystemType = optarg;
			got_filesystemType = 1;
			break;
		case 'w':
			flags &= ~MS_RDONLY;
			break;
		case 'a':
			all = TRUE;
			break;
		case 'f':
			fakeIt = TRUE;
			break;
#ifdef BB_FEATURE_MTAB_SUPPORT
		case 'n':
			useMtab = FALSE;
			break;
#endif
		case 'v':
			break; /* ignore -v */
		}
	}

	if (!all && optind == argc)
		show_mounts(got_filesystemType ? filesystemType : 0);

	if (optind < argc) {
		/* if device is a filename get its real path */
		if (stat(argv[optind], &statbuf) == 0) {
			char *tmp = simplify_path(argv[optind]);
			safe_strncpy(device, tmp, PATH_MAX);
		} else {
			safe_strncpy(device, argv[optind], PATH_MAX);
		}
	}

	if (optind + 1 < argc)
		directory = simplify_path(argv[optind + 1]);

	if (all || optind + 1 == argc) {
		f = setmntent("/etc/fstab", "r");

		if (f == NULL)
			perror_msg_and_die( "\nCannot read /etc/fstab");

		while ((m = getmntent(f)) != NULL) {
			if (! all && optind + 1 == argc && (
				(strcmp(device, m->mnt_fsname) != 0) &&
				(strcmp(device, m->mnt_dir) != 0) ) ) {
				continue;
			}
			
			if (all && (							// If we're mounting 'all'
				(strstr(m->mnt_opts, "noauto")) ||	// and the file system isn't noauto,
				(strstr(m->mnt_type, "swap")) ||	// and isn't swap or nfs, then mount it
				(strstr(m->mnt_type, "nfs")) ) ) {
				continue;
			}
			
			if (all || flags == 0) {	// Allow single mount to override fstab flags
				flags = 0;
				string_flags[0] = 0;
				parse_mount_options(m->mnt_opts, &flags, &string_flags);
			}
			
			strcpy(device, m->mnt_fsname);
			strcpy(directory, m->mnt_dir);
			filesystemType = xstrdup(m->mnt_type);
singlemount:			
			extra_opts = string_flags;
			rc = EXIT_SUCCESS;
#ifdef BB_NFSMOUNT
			if (strchr(device, ':') != NULL) {
				filesystemType = "nfs";
				if (nfsmount (device, directory, &flags, &extra_opts,
							&string_flags, 1)) {
					perror_msg("nfsmount failed");
					rc = EXIT_FAILURE;
				}
			}
#endif
			if (!mount_one(device, directory, filesystemType, flags,
					string_flags, useMtab, fakeIt, extra_opts, TRUE, all))
				rc = EXIT_FAILURE;
				
			if (! all)
				break;
		}
		if (f)
			endmntent(f);
			
		if (! all && f && m == NULL)
			fprintf(stderr, "Can't find %s in /etc/fstab\n", device);
	
		return rc;
	}
	
	goto singlemount;
}
Esempio n. 17
0
// This function is called once, from main.c.
void maze_solve()
{
	// Loop until we have solved the maze.
	while(1)
	{
		// FIRST MAIN LOOP BODY  
		follow_segment();

		// Drive straight a bit.  This helps us in case we entered the
		// intersection at an angle.
		// Note that we are slowing down - this prevents the robot
		// from tipping forward too much.
		set_motors(50,50);
		delay_ms(50);

		// These variables record whether the robot has seen a line to the
		// left, straight ahead, and right, whil examining the current
		// intersection.
		unsigned char found_left=0;
		unsigned char found_straight=0;
		unsigned char found_right=0;

		// Now read the sensors and check the intersection type.
		unsigned int sensors[5];
		read_line(sensors,IR_EMITTERS_ON);

		// Check for left and right exits.
		if(sensors[0] > 100)
			found_left = 1;
		if(sensors[4] > 100)
			found_right = 1;

		// Drive straight a bit more - this is enough to line up our
		// wheels with the intersection.
		set_motors(40,40);
		delay_ms(200);

		// Check for a straight exit.
		read_line(sensors,IR_EMITTERS_ON);
		if(sensors[1] > 200 || sensors[2] > 200 || sensors[3] > 200)
			found_straight = 1;

		// Check for the ending spot.
		// If all three middle sensors are on dark black, we have
		// solved the maze.
		if(sensors[1] > 600 && sensors[2] > 600 && sensors[3] > 600)
			break;

		// Intersection identification is complete.
		// If the maze has been solved, we can follow the existing
		// path.  Otherwise, we need to learn the solution.
		unsigned char dir = select_turn(found_left, found_straight, found_right);

		// Make the turn indicated by the path.
		turn(dir);

		// Store the intersection in the path variable.
		path[path_length] = dir;
		path_length ++;

		// You should check to make sure that the path_length does not
		// exceed the bounds of the array.  We'll ignore that in this
		// example.

		// Simplify the learned path.
		simplify_path();

		// Display the path on the LCD.
		display_path();
	}

	// Solved the maze!

	// Now enter an infinite loop - we can re-run the maze as many
	// times as we want to.
	while(1)
	{
		// Beep to show that we finished the maze.
		set_motors(0,0);
		play(">>a32");

		// Wait for the user to press a button, while displaying
		// the solution.
		while(!button_is_pressed(BUTTON_B))
		{
			if(get_ms() % 2000 < 1000)
			{
				clear();
				print("Solved!");
				lcd_goto_xy(0,1);
				print("Press B");
			}
			else
				display_path();
			delay_ms(30);
		}
		while(button_is_pressed(BUTTON_B));
	
		delay_ms(1000);

		// Re-run the maze.  It's not necessary to identify the
		// intersections, so this loop is really simple.
		int i;
		for(i=0;i<path_length;i++)
		{
			// SECOND MAIN LOOP BODY  
			follow_segment();

			// Drive straight while slowing down, as before.
			set_motors(50,50);
			delay_ms(50);
			set_motors(40,40);
			delay_ms(200);

			// Make a turn according to the instruction stored in
			// path[i].
			turn(path[i]);
		}
		
		// Follow the last segment up to the finish.
		follow_segment();

		// Now we should be at the finish!  Restart the loop.
	}
}
Esempio n. 18
0
char *
get_relocated_path_list(char const * from, char const * to_path_list)
{
  char exe_path[MAX_PATH];
  char * temp;
  get_executable_path (NULL, &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0]));
  if ((temp = strrchr (exe_path, '/')) != NULL)
  {
    temp[1] = '\0';
  }

  char **arr = NULL;
  /* Ask Alexey why he added this. Are we not 100% sure
     that we're dealing with unix paths here? */
  char split_char = ':';
  if (strchr (to_path_list, ';'))
  {
    split_char = ';';
  }
  size_t count = split_path_list (to_path_list, split_char, &arr);
  int result_size = 1 + (count - 1); /* count - 1 is for ; delim. */
  size_t exe_path_size = strlen (exe_path);
  size_t i;
  /* Space required is:
     count * (exe_path_size + strlen (rel_to_datadir))
     rel_to_datadir upper bound is:
     (count * strlen (from)) + (3 * num_slashes (from))
     + strlen(arr[i]) + 1.
     .. pathalogically num_slashes (from) is strlen (from)
     (from = ////////) */
  size_t space_required = (count * (exe_path_size + 4 * strlen (from))) + count - 1;
  for (i = 0; i < count; ++i)
  {
    space_required += strlen (arr[i]);
  }
  char * scratch = (char *) alloca (space_required);
  if (scratch == NULL)
    return NULL;
  for (i = 0; i < count; ++i)
  {
    char * rel_to_datadir = get_relative_path (from, arr[i]);
    scratch[0] = '\0';
    arr[i] = scratch;
    strcat (scratch, exe_path);
    strcat (scratch, rel_to_datadir);
    simplify_path (arr[i]);
    size_t arr_i_size = strlen (arr[i]);
    result_size += arr_i_size;
    scratch = arr[i] + arr_i_size + 1;
  }
  char * result = (char *) malloc (result_size);
  if (result == NULL)
  {
    return NULL;
  }
  result[0] = '\0';
  for (i = 0; i < count; ++i)
  {
    strcat (result, arr[i]);
    if (i != count-1)
    {
#if defined(_WIN32)
      strcat (result, ";");
#else
      strcat (result, ":");
#endif
    }
  }
  free ((void*)arr);
  return result;
}
Esempio n. 19
0
char *
get_relative_path(char const * from_in, char const * to_in)
{
  size_t from_size = (from_in == NULL) ? 0 : strlen (from_in);
  size_t to_size = (to_in == NULL) ? 0 : strlen (to_in);
  size_t max_size = (from_size + to_size) * 2 + 4;
  char * scratch_space = (char *) alloca (from_size + 1 + to_size + 1 + max_size + max_size);
  char * from;
  char * to;
  char * common_part;
  char * result;
  size_t count;

  /* No to, return "./" */
  if (to_in == NULL)
  {
    return malloc_copy_string ("./");
  }

  /* If alloca failed or no from was given return a copy of to */
  if (   from_in == NULL
      || scratch_space == NULL )
  {
    return malloc_copy_string (to_in);
  }

  from = scratch_space;
  strcpy (from, from_in);
  to = from + from_size + 1;
  strcpy (to, to_in);
  common_part = to + to_size + 1;
  result = common_part + max_size;
  simplify_path (from);
  simplify_path (to);

  result[0] = '\0';

  size_t match_size_dirsep = 0;  /* The match size up to the last /. Always wind back to this - 1 */
  size_t match_size = 0;         /* The running (and final) match size. */
  size_t largest_size = (from_size > to_size) ? from_size : to_size;
  int to_final_is_slash = (to[to_size-1] == '/') ? 1 : 0;
  char from_c;
  char to_c;
  for (match_size = 0; match_size < largest_size; ++match_size)
  {
    /* To simplify the logic, always pretend the strings end with '/' */
    from_c = (match_size < from_size) ? from[match_size] : '/';
    to_c =   (match_size <   to_size) ?   to[match_size] : '/';

    if (from_c != to_c)
    {
      if (from_c != '\0' || to_c != '\0')
      {
        match_size = match_size_dirsep;
      }
      break;
    }
    else if (from_c == '/')
    {
      match_size_dirsep = match_size;
    }
  }
  strncpy (common_part, from, match_size);
  common_part[match_size] = '\0';
  from += match_size;
  to += match_size;
  size_t ndotdots = 0;
  char const* from_last = from + strlen(from) - 1;
  while ((from = strchr (from, '/')) && from != from_last)
  {
    ++ndotdots;
    ++from;
  }
  for (count = 0; count < ndotdots; ++count)
  {
    strcat(result, "../");
  }
  if (strlen(to) > 0)
  {
    strcat(result, to+1);
  }
  /* Make sure that if to ends with '/' result does the same, and
     vice-versa. */
  size_t size_result = strlen(result);
  if ((to_final_is_slash == 1)
      && (!size_result || result[size_result-1] != '/'))
  {
    strcat (result, "/");
  }
  else if (!to_final_is_slash
           && size_result && result[size_result-1] == '/')
  {
    result[size_result-1] = '\0';
  }

  return malloc_copy_string (result);
}
Esempio n. 20
0
static int
main_init(int argc, const char *argv[], Source **sp, struct block **lp)
{
	int argi, i;
	Source *s = NULL;
	struct block *l;
	unsigned char restricted_shell, errexit, utf_flag;
	char *cp;
	const char *ccp, **wp;
	struct tbl *vp;
	struct stat s_stdin;
#if !defined(_PATH_DEFPATH) && defined(_CS_PATH)
	ssize_t k;
#endif

#if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC)
	ebcdic_init();
#endif
	set_ifs(TC_IFSWS);

#ifdef __OS2__
	os2_init(&argc, &argv);
#endif

	/* do things like getpgrp() et al. */
	chvt_reinit();

	/* make sure argv[] is sane, for weird OSes */
	if (!*argv) {
		argv = empty_argv;
		argc = 1;
	}
	kshname = argv[0];

	/* initialise permanent Area */
	ainit(&aperm);
	/* max. name length: -2147483648 = 11 (+ NUL) */
	vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM);

	/* set up base environment */
	env.type = E_NONE;
	ainit(&env.area);
	/* set up global l->vars and l->funs */
	newblock();

	/* Do this first so output routines (eg, errorf, shellf) can work */
	initio();

	/* determine the basename (without '-' or path) of the executable */
	ccp = kshname;
	goto begin_parsing_kshname;
	while ((i = ccp[argi++])) {
		if (mksh_cdirsep(i)) {
			ccp += argi;
 begin_parsing_kshname:
			argi = 0;
			if (*ccp == '-')
				++ccp;
		}
	}
	if (!*ccp)
		ccp = empty_argv[0];

	/*
	 * Turn on nohup by default. (AT&T ksh does not have a nohup
	 * option - it always sends the hup).
	 */
	Flag(FNOHUP) = 1;

	/*
	 * Turn on brace expansion by default. AT&T kshs that have
	 * alternation always have it on.
	 */
	Flag(FBRACEEXPAND) = 1;

	/*
	 * Turn on "set -x" inheritance by default.
	 */
	Flag(FXTRACEREC) = 1;

	/* define built-in commands and see if we were called as one */
	ktinit(APERM, &builtins,
	    /* currently up to 54 builtins: 75% of 128 = 2^7 */
	    7);
	for (i = 0; mkshbuiltins[i].name != NULL; i++)
		if (!strcmp(ccp, builtin(mkshbuiltins[i].name,
		    mkshbuiltins[i].func)))
			Flag(FAS_BUILTIN) = 1;

	if (!Flag(FAS_BUILTIN)) {
		/* check for -T option early */
		argi = parse_args(argv, OF_FIRSTTIME, NULL);
		if (argi < 0)
			return (1);

#if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED)
		/* are we called as -sh or /bin/sh or so? */
		if (!strcmp(ccp, "sh" MKSH_EXE_EXT)) {
			/* either also turns off braceexpand */
#ifdef MKSH_BINSHPOSIX
			/* enable better POSIX conformance */
			change_flag(FPOSIX, OF_FIRSTTIME, true);
#endif
#ifdef MKSH_BINSHREDUCED
			/* enable kludge/compat mode */
			change_flag(FSH, OF_FIRSTTIME, true);
#endif
		}
#endif
	}

	initvar();

	inittraps();

	coproc_init();

	/* set up variable and command dictionaries */
	ktinit(APERM, &taliases, 0);
	ktinit(APERM, &aliases, 0);
#ifndef MKSH_NOPWNAM
	ktinit(APERM, &homedirs, 0);
#endif

	/* define shell keywords */
	initkeywords();

	init_histvec();

	/* initialise tty size before importing environment */
	change_winsz();

#ifdef _PATH_DEFPATH
	def_path = _PATH_DEFPATH;
#else
#ifdef _CS_PATH
	if ((k = confstr(_CS_PATH, NULL, 0)) > 0 &&
	    confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1)
		def_path = cp;
	else
#endif
		/*
		 * this is uniform across all OSes unless it
		 * breaks somewhere hard; don't try to optimise,
		 * e.g. add stuff for Interix or remove /usr
		 * for HURD, because e.g. Debian GNU/HURD is
		 * "keeping a regular /usr"; this is supposed
		 * to be a sane 'basic' default PATH
		 */
		def_path = MKSH_UNIXROOT "/bin" MKSH_PATHSEPS
		    MKSH_UNIXROOT "/usr/bin" MKSH_PATHSEPS
		    MKSH_UNIXROOT "/sbin" MKSH_PATHSEPS
		    MKSH_UNIXROOT "/usr/sbin";
#endif

	/*
	 * Set PATH to def_path (will set the path global variable).
	 * (import of environment below will probably change this setting).
	 */
	vp = global(TPATH);
	/* setstr can't fail here */
	setstr(vp, def_path, KSH_RETURN_ERROR);

#ifndef MKSH_NO_CMDLINE_EDITING
	/*
	 * Set edit mode to emacs by default, may be overridden
	 * by the environment or the user. Also, we want tab completion
	 * on in vi by default.
	 */
	change_flag(FEMACS, OF_SPECIAL, true);
#if !MKSH_S_NOVI
	Flag(FVITABCOMPLETE) = 1;
#endif
#endif

	/* import environment */
	init_environ();

	/* override default PATH regardless of environment */
#ifdef MKSH_DEFPATH_OVERRIDE
	vp = global(TPATH);
	setstr(vp, MKSH_DEFPATH_OVERRIDE, KSH_RETURN_ERROR);
#endif

	/* for security */
	typeset(TinitIFS, 0, 0, 0, 0);

	/* assign default shell variable values */
	typeset("PATHSEP=" MKSH_PATHSEPS, 0, 0, 0, 0);
	substitute(initsubs, 0);

	/* Figure out the current working directory and set $PWD */
	vp = global(TPWD);
	cp = str_val(vp);
	/* Try to use existing $PWD if it is valid */
	set_current_wd((mksh_abspath(cp) && test_eval(NULL, TO_FILEQ, cp,
	    Tdot, true)) ? cp : NULL);
	if (current_wd[0])
		simplify_path(current_wd);
	/* Only set pwd if we know where we are or if it had a bogus value */
	if (current_wd[0] || *cp)
		/* setstr can't fail here */
		setstr(vp, current_wd, KSH_RETURN_ERROR);

	for (wp = initcoms; *wp != NULL; wp++) {
		c_builtin(wp);
		while (*wp != NULL)
			wp++;
	}
	setint_n(global("OPTIND"), 1, 10);

	kshuid = getuid();
	kshgid = getgid();
	kshegid = getegid();

	safe_prompt = ksheuid ? "$ " : "# ";
	vp = global("PS1");
	/* Set PS1 if unset or we are root and prompt doesn't contain a # */
	if (!(vp->flag & ISSET) ||
	    (!ksheuid && !strchr(str_val(vp), '#')))
		/* setstr can't fail here */
		setstr(vp, safe_prompt, KSH_RETURN_ERROR);
	setint_n((vp = global("BASHPID")), 0, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10);
	vp->flag |= INT_U;
	setint_n((vp = global("RANDOM")), rndsetup(), 10);
	vp->flag |= INT_U;
	setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);

	/* Set this before parsing arguments */
	Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;

	/* this to note if monitor is set on command line (see below) */
#ifndef MKSH_UNEMPLOYED
	Flag(FMONITOR) = 127;
#endif
	/* this to note if utf-8 mode is set on command line (see below) */
	UTFMODE = 2;

	if (!Flag(FAS_BUILTIN)) {
		argi = parse_args(argv, OF_CMDLINE, NULL);
		if (argi < 0)
			return (1);
	}

	/* process this later only, default to off (hysterical raisins) */
	utf_flag = UTFMODE;
	UTFMODE = 0;

	if (Flag(FAS_BUILTIN)) {
		/* auto-detect from environment variables, always */
		utf_flag = 3;
	} else if (Flag(FCOMMAND)) {
		s = pushs(SSTRINGCMDLINE, ATEMP);
		if (!(s->start = s->str = argv[argi++]))
			errorf(Tf_optfoo, "", "", 'c', Treq_arg);
		while (*s->str) {
			if (ctype(*s->str, C_QUOTE))
				break;
			s->str++;
		}
		if (!*s->str)
			s->flags |= SF_MAYEXEC;
		s->str = s->start;
#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT
		/* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */
		if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--"))
			++argi;
#endif
		if (argv[argi])
			kshname = argv[argi++];
	} else if (argi < argc && !Flag(FSTDIN)) {
		s = pushs(SFILE, ATEMP);
#ifdef __OS2__
		/*
		 * A bug in OS/2 extproc (like shebang) handling makes
		 * it not pass the full pathname of a script, so we need
		 * to search for it. This changes the behaviour of a
		 * simple "mksh foo", but can't be helped.
		 */
		s->file = argv[argi++];
		if (search_access(s->file, X_OK) != 0)
			s->file = search_path(s->file, path, X_OK, NULL);
		if (!s->file || !*s->file)
			s->file = argv[argi - 1];
#else
		s->file = argv[argi++];
#endif
		s->u.shf = shf_open(s->file, O_RDONLY, 0,
		    SHF_MAPHI | SHF_CLEXEC);
		if (s->u.shf == NULL) {
			shl_stdout_ok = false;
			warningf(true, Tf_sD_s, s->file, cstrerror(errno));
			/* mandated by SUSv4 */
			exstat = 127;
			unwind(LERROR);
		}
		kshname = s->file;
	} else {
		Flag(FSTDIN) = 1;
		s = pushs(SSTDIN, ATEMP);
		s->file = "<stdin>";
		s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0),
		    NULL);
		if (isatty(0) && isatty(2)) {
			Flag(FTALKING) = Flag(FTALKING_I) = 1;
			/* The following only if isatty(0) */
			s->flags |= SF_TTY;
			s->u.shf->flags |= SHF_INTERRUPT;
			s->file = NULL;
		}
	}

	/* this bizarreness is mandated by POSIX */
	if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) &&
	    Flag(FTALKING))
		reset_nonblock(0);

	/* initialise job control */
	j_init();
	/* do this after j_init() which calls tty_init_state() */
	if (Flag(FTALKING)) {
		if (utf_flag == 2) {
#ifndef MKSH_ASSUME_UTF8
			/* auto-detect from locale or environment */
			utf_flag = 4;
#else /* this may not be an #elif */
#if MKSH_ASSUME_UTF8
			utf_flag = 1;
#else
			/* always disable UTF-8 (for interactive) */
			utf_flag = 0;
#endif
#endif
		}
#ifndef MKSH_NO_CMDLINE_EDITING
		x_init();
#endif
	}

#ifdef SIGWINCH
	sigtraps[SIGWINCH].flags |= TF_SHELL_USES;
	setsig(&sigtraps[SIGWINCH], x_sigwinch,
	    SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
#endif

	l = e->loc;
	if (Flag(FAS_BUILTIN)) {
		l->argc = argc;
		l->argv = argv;
		l->argv[0] = ccp;
	} else {
		l->argc = argc - argi;
		/*
		 * allocate a new array because otherwise, when we modify
		 * it in-place, ps(1) output changes; the meaning of argc
		 * here is slightly different as it excludes kshname, and
		 * we add a trailing NULL sentinel as well
		 */
		l->argv = alloc2(l->argc + 2, sizeof(void *), APERM);
		l->argv[0] = kshname;
		memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *));
		l->argv[l->argc + 1] = NULL;
		getopts_reset(1);
	}

	/* divine the initial state of the utf8-mode Flag */
	ccp = null;
	switch (utf_flag) {

	/* auto-detect from locale or environment */
	case 4:
#if HAVE_SETLOCALE_CTYPE
		ccp = setlocale(LC_CTYPE, "");
#if HAVE_LANGINFO_CODESET
		if (!isuc(ccp))
			ccp = nl_langinfo(CODESET);
#endif
		if (!isuc(ccp))
			ccp = null;
#endif
		/* FALLTHROUGH */

	/* auto-detect from environment */
	case 3:
		/* these were imported from environ earlier */
		if (ccp == null)
			ccp = str_val(global("LC_ALL"));
		if (ccp == null)
			ccp = str_val(global("LC_CTYPE"));
		if (ccp == null)
			ccp = str_val(global("LANG"));
		UTFMODE = isuc(ccp);
		break;

	/* not set on command line, not FTALKING */
	case 2:
	/* unknown values */
	default:
		utf_flag = 0;
		/* FALLTHROUGH */

	/* known values */
	case 1:
	case 0:
		UTFMODE = utf_flag;
		break;
	}

	/* Disable during .profile/ENV reading */
	restricted_shell = Flag(FRESTRICTED);
	Flag(FRESTRICTED) = 0;
	errexit = Flag(FERREXIT);
	Flag(FERREXIT) = 0;

	/*
	 * Do this before profile/$ENV so that if it causes problems in them,
	 * user will know why things broke.
	 */
	if (!current_wd[0] && Flag(FTALKING))
		warningf(false, "can't determine current directory");

	if (Flag(FLOGIN))
		include(MKSH_SYSTEM_PROFILE, 0, NULL, true);
	if (!Flag(FPRIVILEGED)) {
		if (Flag(FLOGIN))
			include(substitute("$HOME/.profile", 0), 0, NULL, true);
		if (Flag(FTALKING)) {
			cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE);
			if (cp[0] != '\0')
				include(cp, 0, NULL, true);
		}
	} else {
		include(MKSH_SUID_PROFILE, 0, NULL, true);
		/* turn off -p if not set explicitly */
		if (Flag(FPRIVILEGED) != 1)
			change_flag(FPRIVILEGED, OF_INTERNAL, false);
	}

	if (restricted_shell) {
		c_builtin(restr_com);
		/* After typeset command... */
		Flag(FRESTRICTED) = 1;
	}
	Flag(FERREXIT) = errexit;

	if (Flag(FTALKING) && s)
		hist_init(s);
	else
		/* set after ENV */
		Flag(FTRACKALL) = 1;

	alarm_init();

	*sp = s;
	*lp = l;
	return (0);
}
Esempio n. 21
0
int main(int argc, char *argv[])
{
#define BINDIR  "/mingw64/bin"
#define DATADIR "/mingw64/share"

  char exe_path[PATH_MAX];
  get_executable_path (argv[0], &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0]));
  printf ("executable path is %s\n", exe_path);

  char * rel_to_datadir = get_relative_path (BINDIR, DATADIR);
  if (strrchr (exe_path, '/') != NULL)
  {
     strrchr (exe_path, '/')[1] = '\0';
  }
  strcat (exe_path, rel_to_datadir);
  simplify_path (&exe_path[0]);
  printf("real path of DATADIR is %s\n", exe_path);

  if (argc >= 2)
  {
    get_relative_path_debug (argv[argc-2], argv[argc-1], 0);
  }
  get_relative_path_debug (NULL,                      NULL,                              "./");
  get_relative_path_debug ("/mingw64/bin",            "/mingw64/etc/pkcs11/pkcs11.conf", "../etc/pkcs11/pkcs11.conf");
  get_relative_path_debug ("/a/b/c/d",                "/a/b/c",                          "..");
  get_relative_path_debug ("/a/b/c/d/",               "/a/b/c/",                         "../");
  get_relative_path_debug ("/",                       "/",                               "/");
  get_relative_path_debug ("/a/testone/c/d",          "/a/testtwo/c",                    "../../../testtwo/c");
  get_relative_path_debug ("/a/testone/c/d/",         "/a/testtwo/c/",                   "../../../testtwo/c/");
  get_relative_path_debug ("/home/part2/part3/part4", "/work/proj1/proj2",               "../../../../work/proj1/proj2");

  simplify_path_debug ("a/b/..", "a");
  simplify_path_debug ("a/b/c/../../", "a/");
  simplify_path_debug ("a/../a/..",    "");
  simplify_path_debug ("../a/../a/",   "../a/");

  simplify_path_debug ("./././",     "./");
  simplify_path_debug ("/test/",     "/test/");
  simplify_path_debug (".",          ".");
  simplify_path_debug ("..",         "..");
  simplify_path_debug ("../",        "../");
  simplify_path_debug ("././.",      ".");
  simplify_path_debug ("../..",      "../..");
  simplify_path_debug ("/",          "/");
  simplify_path_debug ("./test/",    "./test/");
  simplify_path_debug ("./test",     "./test");
  simplify_path_debug ("/test",      "/test");
  simplify_path_debug ("../test",    "../test");
  simplify_path_debug ("../../test", "../../test");
  simplify_path_debug ("../test/..", "..");
  simplify_path_debug (".././../",   "../../");

  sanitise_path_debug ("C:\\windows\\path", "C:/windows/path");
  sanitise_path_debug ("", "");
  sanitise_path_debug ("\\\\", "/");

  char const * win_path = X509_get_default_private_dir ();
  printf ("%s -> %s\n", X509_PRIVATE_DIR, win_path);

  char * trusts = msys2_get_relocated_path_list (TRUST_PATHS);
  printf ("%s -> %s\n", TRUST_PATHS, trusts);
  free ((void*)trusts);

  char * single = msys2_get_relocated_path_list (SINGLE_PATH_LIST);
  printf ("%s -> %s\n", SINGLE_PATH_LIST, single);
  free ((void*)single);
  
  char *multi = get_relocated_path_list(BINDIR, TRUST_PATHS);
  printf ("Source pathlist: %s \n", TRUST_PATHS);
  printf ("Real pathlist: %s\n", multi);
  free ((void*)multi);
  return 0;
}
Esempio n. 22
0
// This function is called once, from main.c.
void maze_solve() {
   // Loop until we have record the maze.
   while(1) {
      // FIRST MAIN LOOP BODY  
      follow_segment();

      // Drive straight a bit.  This helps us in case we entered the
      // intersection at an angle.
      // Note that we are slowing down - this prevents the robot
      // from tipping forward too much.
      set_motors(50,50);
      delay_ms(50);

      // These variables record whether the robot has seen a line to the
      // left, straight ahead, and right, while examining the current
      // intersection.
      unsigned char found_left=0;
      unsigned char found_straight=0;
      unsigned char found_right=0;

      // Now read the sensors and check the intersection type.
      unsigned int sensors[5];
      read_line_white(sensors,IR_EMITTERS_ON);

      // Check for left and right exits.
      if(sensors[0] < 200){
         found_left = 1;
      }
      if(sensors[4] < 200){
         found_right = 1;
      }

      // Drive straight a bit more - this is enough to line up our
      // wheels with the intersection.
      set_motors(40,40);
      delay_ms(200);

      // Check for a straight exit.
      read_line_white(sensors,IR_EMITTERS_ON);
      if(sensors[1] < 200 || sensors[2] < 200 || sensors[3] < 200) {
         found_straight = 1;
      }

      // Check for the ending spot.
      // If all 3 center sensors are on white, we have solved the maze.
      if(sensors[1] < 200 && sensors[2] < 200 && sensors[3] < 200) {
         break;
      }

      // Intersection identification is complete.
      // If the maze has been solved, we can follow the existing
      // path.  Otherwise, we need to learn the solution.
      unsigned char dir = select_turn(found_left, found_straight, found_right);
        
      int recint = record_intersec(found_left, found_straight, found_right);
      // Make the turn indicated by the path.
      turn(dir);

      // Store the intersection in the path variable.
      path[path_length] = dir;
      intersection[path_length] = recint;
      path_length ++;

      // You should check to make sure that the path_length does not
      // exceed the bounds of the array.  We'll ignore that in this
      // example.  
   }

   // Maze Recorded!
   while(1) {
      
      // Beep to show that we finished the maze.
      paths_length=0;
      set_motors(0,0);
      play(">>a32");

      // Wait for the user to press a button.
      while(!button_is_pressed(BUTTON_B)) {
         clear();
         print("Recorded!");
         lcd_goto_xy(0,1);
         print("Press B");
         delay_ms(30);
      }
      
      while(button_is_pressed(BUTTON_B)) {
         clear();
         print("Here we");
         lcd_goto_xy(0,1);
         print("Go!");
         delay_ms(1000);
      }
         
      int i=0;   
      while (i<4) {
         follow_segment();
         // Drive straight a bit.  This helps us in case we entered the
         // intersection at an angle.
         // Note that we are slowing down - this prevents the robot
         // from tipping forward too much.
         set_motors(50,50);
         delay_ms(50);

         // These variables record whether the robot has seen a line to the
         // left, straight ahead, and right, while examining the current
         // intersection.
         unsigned char found_left=0;
         unsigned char found_straight=0;
         unsigned char found_right=0;

         // Now read the sensors and check the intersection type.
         unsigned int sensors[5];
         read_line_white(sensors,IR_EMITTERS_ON);

         // Check for left and right exits.
         if(sensors[0] < 200) {
            found_left = 1;
         }
         if(sensors[4] < 200) {
            found_right = 1;
         }

         // Drive straight a bit more - this is enough to line up our
         // wheels with the intersection.
         set_motors(40,40);
         delay_ms(200);

         // Check for a straight exit.
         read_line_white(sensors,IR_EMITTERS_ON);
         if(sensors[1] < 200 || sensors[2] < 200 || sensors[3] < 200) {
            found_straight = 1;
         }

         unsigned char dir = select_turn(found_left, found_straight, found_right);
        
         int recint = record_intersec(found_left, found_straight, found_right);
         // Make the turn indicated by the path.
         turn(dir);

         // Store the intersection in the path variable.
         paths[paths_length] = dir;
         intersections[paths_length] = recint;
         if (paths[paths_length] != 'B') {
            i++;
            paths_length ++;
         } else {
            paths_length ++;
         }
      
      }
        // Find the robot location with respect to the end.
      // The Robot location code can be simplified more. 
      // Its Possible to modify this code, so we start by running the robot two steps, 
      // then we check how many values of m we have, if we have more than one value we add another step and so on until we have one m value. 
      int i2;
      int c2;

      for (i=0;i<100;i++) {
         if (i<(100-paths_length)) {
            i2=0;
            while (i2<paths_length) {
               c2=0;
               if (paths[i2]==path[i+i2] && intersections[i2]==intersection[i+i2]) {
                  c2=1;
                  i2++;
               }
               if (c2!=1) {
                  i2=100;
               }
               if (i2 == paths_length ) {
                  m=i+paths_length;
               }
            }
         }
      }

      // We found the Robot location, now find the shortest way to the end.
      for(i=0;i<(100-m);i++) {
         pathsol[pathsol_length]=path[i+m];
         pathsol_length ++;
         simplify_path();
      }

      // Go to the end.
      i=0;
      while(i<pathsol_length) {
         // Re-run the maze.  It's not necessary to identify the
         // intersections, so this loop is really simple.
            follow_segment();

            // Drive straight while slowing down, as before.
            set_motors(50,50);
            delay_ms(50);
            set_motors(40,40);
            delay_ms(200);

            // Make a turn according to the instruction stored in
            // pathsol[i].
            turn(pathsol[i]);
            i+=1;
            unsigned int sensors[5];
            read_line_white(sensors,IR_EMITTERS_ON);
            // The end is reached.
            if(sensors[1] < 200 && sensors[2] < 200 && sensors[3] < 200) {
               pathsol_length=0;
            }
      }
      // Now we should be at the finish!  Restart the loop.
   }
}
void GUI_FileSel(const char *label, SELFILE_CB * cb, int rw,char **rname)
{   /* Create the selector */

    GtkWidget *dialog;
    char *name=NULL;
    char *tmpname;
    gchar *selected_filename;
    uint8_t res;


    if(rname)
        *rname=NULL;

    if(rw)
    {
        dialog=dialog = gtk_file_chooser_dialog_new ("Save",
                        NULL,
                        GTK_FILE_CHOOSER_ACTION_SAVE,
                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                        NULL);

    }
    else
    {
        dialog=dialog = gtk_file_chooser_dialog_new ("Open File",
                        NULL,
                        GTK_FILE_CHOOSER_ACTION_OPEN,
                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                        NULL);
    }
    /**********/
    initFileSelector();
    setFilter(dialog);
    /**********/
    gtk_window_set_title (GTK_WINDOW (dialog),label);
    gtk_register_dialog(dialog);
    if(rw)
        res=prefs->get(LASTDIR_WRITE,&tmpname);
    else
        res=prefs->get(LASTDIR_READ,&tmpname);
    if(res)
    {
        DIR *dir;
        char *str=PathCanonize(tmpname);
        PathStripName(str);

        /* LASTDIR may have gone; then do nothing and use current dir instead (implied) */
        if( (dir=opendir(str)) )
        {
            closedir(dir);
            gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),(gchar *)str);
        }
        delete [] str;
    }
    if(gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT)
    {

        selected_filename= (gchar *) 	gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
#ifdef CYG_MANGLING
        if (*(selected_filename + strlen(selected_filename) - 1) == '\\') {
#else
        if (*(selected_filename + strlen(selected_filename) - 1) == '/') {
#endif
            GUI_Error_HIG("Cannot open directory as a file", NULL);
        }
        else
        {
            name=ADM_strdup(selected_filename);

            char *str=PathCanonize(name);
            PathStripName(str);
            if(rw)
                prefs->set(LASTDIR_WRITE,str);
            else
                prefs->set(LASTDIR_READ,str);
            delete [] str;

        }
    }
    gtk_unregister_dialog(dialog);
    gtk_widget_destroy(dialog);

// CYB 2005.02.23
    if(cb)
    {
        fileReadWrite(cb, rw, name);
    }
    else
    {
        *rname=name;
    }
}


//------------------------------------------------------------------

/*

** note: it modifies it's first argument
*/
void simplify_path(char **buf) {
    unsigned int last1slash = 0;
    unsigned int last2slash = 0;
    while( !strncmp(*buf,"/../",4) )
        memmove(*buf,*buf+3,strlen(*buf+3)+1);
    for(unsigned int i=0; i<strlen(*buf)-2; i++)
        while( !strncmp(*buf+i,"/./",3) )
            memmove(*buf+i,*buf+i+2,strlen(*buf+i+2)+1);
    for(unsigned int i=0; i<strlen(*buf)-3; i++) {
        if( *(*buf+i) == '/' ) {
            last2slash = last1slash;
            last1slash = i;
        }
        if( !strncmp(*buf+i,"/../",4) ) {
            memmove(*buf+last2slash,*buf+i+3,strlen(*buf+i+3)+1);
            return simplify_path(buf);
        }
    }
}