📄 rdesktop.c
字号:
{ /* -r disk:h:=/mnt/floppy */ disk_enum_devices(&g_num_devices, optarg + 4); } else if (strncmp("comport", optarg, 7) == 0) { serial_enum_devices(&g_num_devices, optarg + 7); } else if (strncmp("lptport", optarg, 7) == 0) { parallel_enum_devices(&g_num_devices, optarg + 7); } else if (strncmp("printer", optarg, 7) == 0) { printer_enum_devices(&g_num_devices, optarg + 7); } else if (strncmp("clientname", optarg, 7) == 0) { g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1); strcpy(g_rdpdr_clientname, optarg + 11); } else { warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound\n"); } break; case '0': g_console_session = True; break; case '4': g_use_rdp5 = False; break; case '5': g_use_rdp5 = True; break; case 'h': case '?': default: usage(argv[0]); return 1; } } if (argc - optind != 1) { usage(argv[0]); return 1; } STRNCPY(server, argv[optind], sizeof(server)); parse_server_and_port(server); if (!username_option) { pw = getpwuid(getuid()); if ((pw == NULL) || (pw->pw_name == NULL)) { error("could not determine username, use -u\n"); return 1; } STRNCPY(g_username, pw->pw_name, sizeof(g_username)); }#ifdef HAVE_ICONV if (g_codepage[0] == 0) { if (setlocale(LC_CTYPE, "")) { STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage)); } else { STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage)); } }#endif if (g_hostname[0] == 0) { if (gethostname(fullhostname, sizeof(fullhostname)) == -1) { error("could not determine local hostname, use -n\n"); return 1; } p = strchr(fullhostname, '.'); if (p != NULL) *p = 0; STRNCPY(g_hostname, fullhostname, sizeof(g_hostname)); } if (prompt_password && read_password(password, sizeof(password))) flags |= RDP_LOGON_AUTO; if (g_title[0] == 0) { strcpy(g_title, "rdesktop - "); strncat(g_title, server, sizeof(g_title) - sizeof("rdesktop - ")); }#ifdef RDP2VNC rdp2vnc_connect(server, flags, domain, password, shell, directory); return 0;#else if (!ui_init()) return 1;#ifdef WITH_RDPSND if (g_rdpsnd) rdpsnd_init();#endif rdpdr_init(); if (!rdp_connect(server, flags, domain, password, shell, directory)) return 1; /* By setting encryption to False here, we have an encrypted login packet but unencrypted transfer of other packets */ if (!packet_encryption) g_encryption = False; DEBUG(("Connection successful.\n")); memset(password, 0, sizeof(password)); if (ui_create_window()) { rdp_main_loop(&deactivated, &ext_disc_reason); ui_destroy_window(); } DEBUG(("Disconnecting...\n")); rdp_disconnect(); cache_save_state(); ui_deinit(); if (ext_disc_reason >= 2) print_disconnect_reason(ext_disc_reason); if (deactivated) { /* clean disconnect */ return 0; } else { if (ext_disc_reason == exDiscReasonAPIInitiatedDisconnect || ext_disc_reason == exDiscReasonAPIInitiatedLogoff) { /* not so clean disconnect, but nothing to worry about */ return 0; } else { /* return error */ return 2; } }#endif}#ifdef EGD_SOCKET/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */static BOOLgenerate_random_egd(uint8 * buf){ struct sockaddr_un addr; BOOL ret = False; int fd; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) return False; addr.sun_family = AF_UNIX; memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET)); if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) goto err; /* PRNGD and EGD use a simple communications protocol */ buf[0] = 1; /* Non-blocking (similar to /dev/urandom) */ buf[1] = 32; /* Number of requested random bytes */ if (write(fd, buf, 2) != 2) goto err; if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */ goto err; if (read(fd, buf, 32) != 32) goto err; ret = True; err: close(fd); return ret;}#endif/* Generate a 32-byte random for the secure transport code. */voidgenerate_random(uint8 * random){ struct stat st; struct tms tmsbuf; MD5_CTX md5; uint32 *r; int fd, n; /* If we have a kernel random device, try that first */ if (((fd = open("/dev/urandom", O_RDONLY)) != -1) || ((fd = open("/dev/random", O_RDONLY)) != -1)) { n = read(fd, random, 32); close(fd); if (n == 32) return; }#ifdef EGD_SOCKET /* As a second preference use an EGD */ if (generate_random_egd(random)) return;#endif /* Otherwise use whatever entropy we can gather - ideas welcome. */ r = (uint32 *) random; r[0] = (getpid()) | (getppid() << 16); r[1] = (getuid()) | (getgid() << 16); r[2] = times(&tmsbuf); /* system uptime (clocks) */ gettimeofday((struct timeval *) &r[3], NULL); /* sec and usec */ stat("/tmp", &st); r[5] = st.st_atime; r[6] = st.st_mtime; r[7] = st.st_ctime; /* Hash both halves with MD5 to obscure possible patterns */ MD5_Init(&md5); MD5_Update(&md5, random, 16); MD5_Final(random, &md5); MD5_Update(&md5, random + 16, 16); MD5_Final(random + 16, &md5);}/* malloc; exit if out of memory */void *xmalloc(int size){ void *mem = malloc(size); if (mem == NULL) { error("xmalloc %d\n", size); exit(1); } return mem;}/* realloc; exit if out of memory */void *xrealloc(void *oldmem, int size){ void *mem; if (size < 1) size = 1; mem = realloc(oldmem, size); if (mem == NULL) { error("xrealloc %d\n", size); exit(1); } return mem;}/* free */voidxfree(void *mem){ free(mem);}/* report an error */voiderror(char *format, ...){ va_list ap; fprintf(stderr, "ERROR: "); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);}/* report a warning */voidwarning(char *format, ...){ va_list ap; fprintf(stderr, "WARNING: "); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);}/* report an unimplemented protocol feature */voidunimpl(char *format, ...){ va_list ap; fprintf(stderr, "NOT IMPLEMENTED: "); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);}/* produce a hex dump */voidhexdump(unsigned char *p, unsigned int len){ unsigned char *line = p; int i, thisline, offset = 0; while (offset < len) { printf("%04x ", offset); thisline = len - offset; if (thisline > 16) thisline = 16; for (i = 0; i < thisline; i++) printf("%02x ", line[i]); for (; i < 16; i++) printf(" "); for (i = 0; i < thisline; i++) printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); printf("\n"); offset += thisline; line += thisline; }}/* input: src is the string we look in for needle. Needle may be escaped by a backslash, in that case we ignore that particular needle. return value: returns next src pointer, for succesive executions, like in a while loop if retval is 0, then there are no more args. pitfalls: src is modified. 0x00 chars are inserted to terminate strings. return val, points on the next val chr after ins 0x00 example usage: while( (pos = next_arg( optarg, ',')) ){ printf("%s\n",optarg); optarg=pos; }*/char *next_arg(char *src, char needle){ char *nextval; char *p; char *mvp = 0; /* EOS */ if (*src == (char) 0x00) return 0; p = src; /* skip escaped needles */ while ((nextval = strchr(p, needle))) { mvp = nextval - 1; /* found backslashed needle */ if (*mvp == '\\' && (mvp > src)) { /* move string one to the left */ while (*(mvp + 1) != (char) 0x00) { *mvp = *(mvp + 1); *mvp++; } *mvp = (char) 0x00; p = nextval; } else { p = nextval + 1; break; } } /* more args available */ if (nextval) { *nextval = (char) 0x00; return ++nextval; } /* no more args after this, jump to EOS */ nextval = src + strlen(src); return nextval;}voidtoupper_str(char *p){ while (*p) { if ((*p >= 'a') && (*p <= 'z')) *p = toupper((int) *p); p++; }}/* not all clibs got ltoa */#define LTOA_BUFSIZE (sizeof(long) * 8 + 1)char *l_to_a(long N, int base){ static char ret[LTOA_BUFSIZE]; char *head = ret, buf[LTOA_BUFSIZE], *tail = buf + sizeof(buf); register int divrem; if (base < 36 || 2 > base) base = 10; if (N < 0) { *head++ = '-'; N = -N; } tail = buf + sizeof(buf); *--tail = 0; do { divrem = N % base; *--tail = (divrem <= 9) ? divrem + '0' : divrem + 'a' - 10; N /= base; } while (N); strcpy(head, tail); return ret;}intload_licence(unsigned char **data){ char *home, *path; struct stat st; int fd, length; home = getenv("HOME"); if (home == NULL) return -1; path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence.")); sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname); fd = open(path, O_RDONLY); if (fd == -1) return -1; if (fstat(fd, &st)) return -1; *data = (uint8 *) xmalloc(st.st_size); length = read(fd, *data, st.st_size); close(fd); xfree(path); return length;}voidsave_licence(unsigned char *data, int length){ char *home, *path, *tmppath; int fd; home = getenv("HOME"); if (home == NULL) return; path = (char *) xmalloc(strlen(home) + strlen(g_hostname) + sizeof("/.rdesktop/licence.")); sprintf(path, "%s/.rdesktop", home); if ((mkdir(path, 0700) == -1) && errno != EEXIST) { perror(path); return; } /* write licence to licence.hostname.new, then atomically rename to licence.hostname */ sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname); tmppath = (char *) xmalloc(strlen(path) + sizeof(".new")); strcpy(tmppath, path); strcat(tmppath, ".new"); fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd == -1) { perror(tmppath); return; } if (write(fd, data, length) != length) { perror(tmppath); unlink(tmppath); } else if (rename(tmppath, path) == -1) { perror(path); unlink(tmppath); } close(fd); xfree(tmppath); xfree(path);}/* Create the bitmap cache directory */BOOLrd_pstcache_mkdir(void){ char *home; char bmpcache_dir[256]; home = getenv("HOME"); if (home == NULL) return False; sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop"); if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST) { perror(bmpcache_dir); return False; } sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache"); if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST) { perror(bmpcache_dir); return False; } return True;}/* open a file in the .rdesktop directory */intrd_open_file(char *filename){ char *home; char fn[256]; int fd; home = getenv("HOME"); if (home == NULL) return -1; sprintf(fn, "%s/.rdesktop/%s", home, filename); fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) perror(fn); return fd;}/* close file */voidrd_close_file(int fd){ close(fd);}/* read from file*/intrd_read_file(int fd, void *ptr, int len){ return read(fd, ptr, len);}/* write to file */intrd_write_file(int fd, void *ptr, int len){ return write(fd, ptr, len);}/* move file pointer */intrd_lseek_file(int fd, int offset){ return lseek(fd, offset, SEEK_SET);}/* do a write lock on a file */BOOLrd_lock_file(int fd, int start, int len){ struct flock lock; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = start; lock.l_len = len; if (fcntl(fd, F_SETLK, &lock) == -1) return False; return True;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -