Ejemplo n.º 1
0
unsigned int
freerdp_kbd_init(unsigned int keyboard_layout_id)
{
	char xkbfile[256];
	keyboard_layout_id = detect_keyboard(keyboard_layout_id, xkbfile, sizeof(xkbfile));

	printf("Using keyboard layout 0x%X with xkb name %s and xkbfile %s\n",
			keyboard_layout_id, get_layout_name(keyboard_layout_id), xkbfile);

	load_keyboard_map(xkbfile);
	return keyboard_layout_id;
}
Ejemplo n.º 2
0
unsigned int freerdp_kbd_init(void* dpy, unsigned int keyboard_layout_id)
{
	memset(x_keycode_to_rdp_scancode, 0, sizeof(x_keycode_to_rdp_scancode));
	memset(rdp_scancode_to_x_keycode, '\0', sizeof(rdp_scancode_to_x_keycode));

#ifdef WITH_XKBFILE
	if (!init_xkb(dpy))
	{
		DEBUG_KBD("Error initializing xkb");
		return 0;
	}
	if (keyboard_layout_id == 0)
	{
		keyboard_layout_id = detect_keyboard_layout_from_xkb(dpy);
		DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboard_layout_id);
	}
	init_keycodes_from_xkb(dpy, x_keycode_to_rdp_scancode, rdp_scancode_to_x_keycode);
#else
	int vkcode;
	int keycode;
	char xkbfile[256];
	KeycodeToVkcode keycodeToVkcode;

	if (keyboard_layout_id == 0)
		keyboard_layout_id = detect_keyboard(dpy, keyboard_layout_id, xkbfile, sizeof(xkbfile));

	DEBUG_KBD("Using keyboard layout 0x%X with xkb name %s and xkbfile %s",
			keyboard_layout_id, get_layout_name(keyboard_layout_id), xkbfile);

	load_keyboard_map(keycodeToVkcode, xkbfile);

	for (keycode = 0; keycode < 256; keycode++)
	{
		vkcode = keycodeToVkcode[keycode];

		DEBUG_KBD("X keycode %3d VK %3d %-19s-> RDP scancode %d/%d",
				keycode, vkcode, virtualKeyboard[vkcode].name,
				virtualKeyboard[vkcode].extended, virtualKeyboard[vkcode].scancode);

		x_keycode_to_rdp_scancode[keycode].keycode = virtualKeyboard[vkcode].scancode;
		x_keycode_to_rdp_scancode[keycode].extended = virtualKeyboard[vkcode].extended;
		x_keycode_to_rdp_scancode[keycode].keyname = virtualKeyboard[vkcode].name;

		if (x_keycode_to_rdp_scancode[keycode].extended)
			rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][1] = keycode;
		else
			rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][0] = keycode;
	}
#endif

	return keyboard_layout_id;
}
Ejemplo n.º 3
0
/*
 * Main function for doing the copying of bits
 */
int
TM_perform_transfer(nvlist_t *targs, void(*prog)(int))
{
	char *logfile = NULL, *buf = NULL, *cprefix;
	char *buf1 = NULL, *layout = NULL, *dbg;
	FILE *cpipe = NULL, *kbd_file;
	float ipercent, rem_percent, cpfiles;
	float calc_factor;
	int kbd = -1, kbd_layout;
	int rv = 0, i;
	struct file_list flist, *cflist;
	clock_t tm;
	struct stat st;
	char zerolist[PATH_MAX];

	if (pthread_mutex_lock(&tran_mutex) != 0) {
		Perror("Unable to acquire Transfer lock ");
		return (1);
	}

	if (nvlist_lookup_string(targs, "mountpoint", &mntpt) != 0) {
		Perror("Alternate root mountpoint not provided. Bailing. ");
		return (1);
	}

	if (prog == NULL) {
		progress = log_progress;
	} else {
		progress = prog;
	}

	logfile = malloc(PATH_MAX);
	if (logfile == NULL) {
		Perror("Malloc failed ");
		return (1);
	}

	(void) snprintf(logfile, PATH_MAX, "%s/%s", mntpt,
	    TM_LOGFILE_NAME);

	lof = fopen(logfile, "w+");
	if (lof == NULL) {
		Perror("Unable to open logfile ");
		goto error_done;
	}

	buf = malloc(BUF_SIZE);
	if (buf == NULL) {
		Perror("Malloc failed ");
		goto error_done;
	}

	buf1 = malloc(BUF_SIZE);
	if (buf1 == NULL) {
		Perror("Malloc failed ");
		goto error_done;
	}

	dbg = getenv("TM_DEBUG");
	if (dbg != NULL && strcmp(dbg, "1") == 0) {
		TM_enable_debug();
	}

	/*
	 * Set TMPDIR to avoid cpio depleting ramdisk space
	 */
	if (putenv(tmpenv) != 0) {
		Perror(tmpenv);
		goto error_done;
	}

	/*
	 * Zero length file list.
	 */
	(void) strlcpy(zerolist, mntpt, PATH_MAX);
	(void) strlcat(zerolist, "/flist.0length", PATH_MAX);
	if ((zerolength = fopen(zerolist, "w+")) == NULL) {
		Perror(zerolist);
		goto error_done;
	}

	tm = time(NULL);
	(void) strftime(buf, PATH_MAX, (char *)0, localtime(&tm));
	INFO_MSG2("-- Starting transfer process, %s --", buf);
	(void) chdir("/");
	CHECK_ABORT;

	(*progress)(0);
	percent = 0;
	opercent = 0;
	total_find_percent = (NUM_PREFIXES - 1) * FIND_PERCENT;

	/*
	 * Get the optimized libc overlay out of the way.
	 */
	if (umount("/lib/libc.so.1") != 0) {
		if (errno != EINVAL) {
			Perror("Can't unmount /lib/libc.so.1 ");
			goto error_done;
		}
	}
	CHECK_ABORT;
	INFO_MSG1("Building file lists for cpio");

	/*
	 * Do a file tree walk of all the mountpoints provided and
	 * build up pathname lists. Pathname lists of all mountpoints
	 * under the same prefix are aggregated in the same file to
	 * reduce the number of cpio invocations.
	 *
	 * This loop builds a linked list where each entry points to
	 * a file containing a pathname list and mentions other info
	 * like the mountpoint from which to copy etc.
	 */
	cprefix = "";
	flist.next = NULL;
	cflist = &flist;
	for (i = 0; cpio_prefixes[i].chdir_prefix != NULL; i++) {
		char *patt;
		regex_t re;

		CHECK_ABORT;
		DBG_MSG3("Cpio dir: %s, Chdir to: %s",
		    cpio_prefixes[i].cpio_dir,
		    cpio_prefixes[i].chdir_prefix);
		patt = cpio_prefixes[i].match_pattern;
		if (strcmp(cprefix,
		    cpio_prefixes[i].chdir_prefix) != 0 ||
		    patt != NULL ||
		    cpio_prefixes[i].clobber_files == 1 ||
		    cpio_prefixes[i].cpio_args != NULL) {

			cprefix = cpio_prefixes[i].chdir_prefix;
			cflist->next = (struct file_list *)
			    malloc(sizeof (struct file_list));
			cflist = cflist->next;
			cflist->next = NULL;
			(void) snprintf(cflist->name, PATH_MAX, "%s/flist%d",
			    mntpt, i);
			DBG_MSG2(" File list tempfile: %s", cflist->name);

			cflist->handle = fopen(cflist->name, "w+");
			if (cflist->handle == NULL) {
				Perror("Unable to open file list ");
				goto error_done;
			}

			cflist->chdir_prefix =
			    cpio_prefixes[i].chdir_prefix;
			if (patt != NULL) {
				DBG_MSG2(" Compiling regexp: %s", patt);
				if (patt[0] == '!') {
					negate = 1;
					patt++;
				} else {
					negate = 0;
				}
				if (regcomp(&re, patt,
				    REG_EXTENDED|REG_NOSUB) != 0) {
					Perror("Regexp error ");
					goto error_done;
				}
				mre = &re;
			} else {
				mre = NULL;
			}

			listfile = cflist->handle;
			cflist->clobber_files =
			    cpio_prefixes[i].clobber_files;
			if (cpio_prefixes[i].cpio_args != NULL) {
				cflist->cpio_args =
				    cpio_prefixes[i].cpio_args;
			} else {
				cflist->cpio_args = DEFAULT_CPIO_ARGS;
			}
		}

		INFO_MSG3("Scanning %s/%s", cflist->chdir_prefix,
		    cpio_prefixes[i].cpio_dir);
		(void) chdir(cflist->chdir_prefix);
		if (nftw(cpio_prefixes[i].cpio_dir, add_files, 10,
		    FTW_MOUNT|FTW_PHYS) < 0) {
			Perror("Nftw failed ");
			goto error_done;
		}
		(void) fflush(cflist->handle);
	}
	(void) fflush(zerolength);

	/*
	 * Now process each entry in the list. cpio is executed with the
	 * -V option where it prints a dot for each pathname processed.
	 * Since we already know the number of files we can show accurate
	 * percentage completion.
	 */
	INFO_MSG1("Beginning cpio actions ...");

	rem_percent = 95 - percent;
	ipercent = percent;
	cflist = flist.next;
	cpfiles = 0;
	opercent = 0;
	percent = 0;
	calc_factor = rem_percent / nfiles;
	while (cflist != NULL) {
		(void) fclose(cflist->handle);
		cflist->handle = NULL;
		CHECK_ABORT;
		if (cflist->clobber_files) {
			if (do_clobber_files(cflist->name) != 0) {
				goto error_done;
			}
		}

		(void) chdir(cflist->chdir_prefix);
		(void) snprintf(buf, PATH_MAX, "%s -%sV %s < %s",
		    CPIO, cflist->cpio_args, mntpt, cflist->name);
		DBG_MSG3("Executing: %s, CWD: %s", buf,
		    cflist->chdir_prefix);

		cpipe = popen(buf, "r");
		if (cpipe == NULL) {
			Perror("Unable to cpio files ");
			goto error_done;
		}

		while (!feof(cpipe)) {
			int ch = fgetc(cpipe);
			if (ch == '.') {
				cpfiles++;
				percent = (int)(cpfiles * calc_factor +
				    ipercent);
				if (percent - opercent >= 1) {
					if (progress != NULL) {
						(*progress)(percent);
					}
					opercent = percent;
				}
			}
			CHECK_ABORT;
		}
		if (ferror(cpipe)) {
			Perror(CPIO);
			goto error_done;
		}

		(void) fclose(cpipe);
		cpipe = NULL;

		(void) unlink(cflist->name);
		cflist->name[0] = '\0';
		cflist = cflist->next;
	}
	(*progress)(percent);
	cpipe = NULL;

	/*
	 * Process zero-length files if any.
	 */
	INFO_MSG1("Creating zero-length files");
	rewind(zerolength);
	while (fgets(buf, BUF_SIZE, zerolength) != NULL) {
		int fd;
		mode_t mod;
		uid_t st_uid, st_gid;
		char *token, *lasts;

		/* Get the newline out of the way */
		buf[strlen(buf) - 1] = '\0';

		/* Parse out ownership and perms */
		GET_TOKEN(token, lasts, buf, ",");
		mod = atoi(token);
		GET_TOKEN(token, lasts, NULL, ",");
		st_uid = atoi(token);
		GET_TOKEN(token, lasts, NULL, ",");
		st_gid = atoi(token);

		GET_TOKEN(token, lasts, NULL, ",");
		(void) snprintf(buf1, PATH_MAX, "%s/%s", mntpt, token);

		fd = open(buf1, O_WRONLY | O_CREAT | O_TRUNC, mod);
		if (fd != -1) {
			(void) fchown(fd, st_uid, st_gid);
			(void) close(fd);
			DBG_MSG2("Created file %s", buf1);
		} else {
			INFO_MSG1("Unable to create file:");
			Perror(buf1);
		}
	}
	(*progress)(97);

	CHECK_ABORT;
	INFO_MSG1("Extracting archive");
	(void) chdir(mntpt);
	(void) snprintf(buf, PATH_MAX, "%s e -so %s | %s -idum",
	    SZIP, ARCHIVE, CPIO);
	DBG_MSG3("Executing: %s, CWD: %s", buf, mntpt);
	if (system(buf) != 0) {
		Perror("Extracting archive failed ");
		goto error_done;
	}
	(*progress)(98);
	CHECK_ABORT;

	/*
	 * Check for the presence of skeleton.cpio before extracting it.
	 * This file may not be present in a Distro Constructor image.
	 */
	if (lstat(SKELETON, &st) == 0 && (S_ISREG(st.st_mode) ||
	    S_ISLNK(st.st_mode))) {
		INFO_MSG1("Extracting skeleton archive");
		(void) snprintf(buf, PATH_MAX, "%s -imu < %s", CPIO,
		    SKELETON, mntpt);
		DBG_MSG3("Executing: %s, CWD: %s", buf, mntpt);
		if (system(buf) != 0) {
			Perror("Skeleton cpio failed ");
			goto error_done;
		}
	}
	(*progress)(99);

	CHECK_ABORT;
	INFO_MSG1("Performing file operations");
	for (i = 0; i < NUM_FILEOPS_LIST; i++) {
		int rv;

		CHECK_ABORT;
		expand_symbols(fileops_list[i].src, buf, PATH_MAX);

		switch (fileops_list[i].op) {
			int op;

		case FILE_OP_UNLINK:
			DBG_MSG2("Unlink: %s", buf);
			(void) unlink(buf);
			rv = 0; /* unlink errors are non-fatal */
			break;

		case FILE_OP_RMDIR:
			DBG_MSG2("Rmdir: %s", buf);
			(void) rmdir(buf);
			rv = 0; /* Ignore rmdir errors for now */
			break;

		case FILE_OP_MKDIR:

			DBG_MSG2("Mkdir: %s", buf);
			rv = 0;
			if (lstat(buf, &st) == 0) {
				op = 0;
				if ((st.st_mode & S_IFMT)
				    != S_IFDIR) {
					rv = unlink(buf);
					op = 1;
				}
				if (rv == 0 && op) {
					rv = mkdir(buf,
					    fileops_list[i].perms);
				}
			} else {
				rv = mkdir(buf,
				    fileops_list[i].perms);
			}
			break;

		case FILE_OP_COPY:
			expand_symbols(fileops_list[i].dst, buf1,
			    PATH_MAX);
			rv = copyfile(buf, buf1);
			break;
		case FILE_OP_CHMOD:
			expand_symbols(fileops_list[i].dst, buf1,
			    PATH_MAX);
			rv = chmod(buf, fileops_list[i].perms);
			break;
		default:
			Perror("Unsupported file operation ");
			rv = 1;
			break;
		}
		if (rv != 0) {
			Perror("File ops error ");
			Perror(buf);
			goto error_done;
		}
	}

	CHECK_ABORT;
	INFO_MSG1("Fetching and updating keyboard layout");
	(void) chdir(mntpt);

	DBG_MSG2("Opening keyboard device: %s", KBD_DEVICE);
	kbd = open(KBD_DEVICE, O_RDWR);
	if (kbd < 0) {
		Perror("Error opening keyboard");
		goto error_done;
	}

	if (ioctl(kbd, KIOCLAYOUT, &kbd_layout)) {
		Perror("ioctl keyboard layout");
		goto error_done;
	}

	CHECK_ABORT;
	if ((layout = get_layout_name(kbd_layout)) == NULL) {
		goto error_done;
	}

	kbd_file = fopen(KBD_DEFAULTS_FILE, "a+");
	if (kbd_file == NULL) {
		Perror("Unable to open kbd defaults file ");
		goto error_done;
	}

	(void) fprintf(kbd_file, "LAYOUT=%s\n", layout);
	(void) fclose(kbd_file);
	DBG_MSG3("Updated keyboard defaults file: %s/%s", mntpt,
	    KBD_DEFAULTS_FILE);

	INFO_MSG2("Detected %s keyboard layout", layout);
	tm = time(NULL);
	(void) strftime(buf, PATH_MAX, (char *)0, localtime(&tm));
	INFO_MSG2("-- Completed transfer process, %s --", buf);

	(*progress)(100);

	goto done;
error_done:
	rv = 1;

done:
	if (lof != NULL)
		(void) fclose(lof);

	if (cpipe != NULL)
		(void) fclose(cpipe);

	free_flist(flist.next);

	if (logfile != NULL)
		free(logfile);

	if (kbd > 0)
		(void) close(kbd);

	if (buf != NULL)
		free(buf);

	if (buf1 != NULL)
		free(buf1);

	if (layout != NULL)
		free(layout);

	if (zerolength != NULL) {
		(void) fclose(zerolength);
		(void) unlink(zerolist);
	}

	do_abort = 0;
	(void) pthread_mutex_unlock(&tran_mutex);

	return (rv);
}