CVS: rdesktop constants.h,1.36,1.37 disk.c,1.39,1.40 proto.h,1.68,1.69 rdpdr.c,1.37,1.38 serial.c,1.20,1.21 types.h,1.21,1.22 xwin.c,1.178,1.179
Michael Gernoth <[email protected]>
| Newsgroups | gmane.network.rdesktop.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/rdesktop/rdesktop In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12687 Modified Files: constants.h disk.c proto.h rdpdr.c serial.c types.h xwin.c Log Message: Big serial- and disk-redirection update from Andreas Flick <[email protected]> Index: constants.h =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/constants.h,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** constants.h 27 Jun 2004 18:53:08 -0000 1.36 --- constants.h 3 Nov 2004 13:56:44 -0000 1.37 *************** *** 341,344 **** --- 341,345 ---- /* NT status codes for RDPDR */ #define STATUS_SUCCESS 0x00000000 + #define STATUS_NOT_IMPLEMENTED 0x00000001 #define STATUS_PENDING 0x00000103 *************** *** 359,362 **** --- 360,364 ---- #define STATUS_NOT_SUPPORTED 0xc00000bb #define STATUS_TIMEOUT 0xc0000102 + #define STATUS_NOTIFY_ENUM_DIR 0xc000010c #define STATUS_CANCELLED 0xc0000120 *************** *** 372,375 **** --- 374,379 ---- #define FILE_DIRECTORY_FILE 0x00000001 #define FILE_NON_DIRECTORY_FILE 0x00000040 + #define FILE_COMPLETE_IF_OPLOCKED 0x00000100 + #define FILE_DELETE_ON_CLOSE 0x00001000 #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 Index: disk.c =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/disk.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** disk.c 28 Oct 2004 07:46:39 -0000 1.39 --- disk.c 3 Nov 2004 13:56:44 -0000 1.40 *************** *** 82,85 **** --- 82,86 ---- FILEINFO g_fileinfo[MAX_OPEN_FILES]; + BOOL g_notify_stamp = False; typedef struct *************** *** 91,94 **** --- 92,96 ---- } FsInfoType; + static NTSTATUS NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p); static time_t *************** *** 329,333 **** } ! //printf("Open: \"%s\" flags: %u, accessmask: %u sharemode: %u create disp: %u\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); // Get information about file and set that flag ourselfs --- 331,335 ---- } ! //printf("Open: \"%s\" flags: %X, accessmask: %X sharemode: %X create disp: %X\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); // Get information about file and set that flag ourselfs *************** *** 425,431 **** --- 427,439 ---- if (dirp) g_fileinfo[handle].pdir = dirp; + else + g_fileinfo[handle].pdir = NULL; + g_fileinfo[handle].device_id = device_id; g_fileinfo[handle].flags_and_attributes = flags_and_attributes; + g_fileinfo[handle].accessmask = accessmask; strncpy(g_fileinfo[handle].path, path, 255); + g_fileinfo[handle].delete_on_close = False; + g_notify_stamp = True; *phandle = handle; *************** *** 440,451 **** pfinfo = &(g_fileinfo[handle]); ! if (pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE) { ! closedir(pfinfo->pdir); ! //FIXME: Should check exit code } else { ! close(handle); } --- 448,486 ---- pfinfo = &(g_fileinfo[handle]); ! g_notify_stamp = True; ! ! rdpdr_abort_io(handle, 0, STATUS_CANCELLED); ! ! if (pfinfo->pdir) { ! if (closedir(pfinfo->pdir) < 0) ! { ! perror("closedir"); ! return STATUS_INVALID_HANDLE; ! } ! ! if (pfinfo->delete_on_close) ! if (rmdir(pfinfo->path) < 0) ! { ! perror(pfinfo->path); ! return STATUS_ACCESS_DENIED; ! } ! pfinfo->delete_on_close = False; } else { ! if (close(handle) < 0) ! { ! perror("close"); ! return STATUS_INVALID_HANDLE; ! } ! if (pfinfo->delete_on_close) ! if (unlink(pfinfo->path) < 0) ! { ! perror(pfinfo->path); ! return STATUS_ACCESS_DENIED; ! } ! ! pfinfo->delete_on_close = False; } *************** *** 478,482 **** { case EISDIR: ! return STATUS_FILE_IS_A_DIRECTORY; default: perror("read"); --- 513,520 ---- { case EISDIR: ! /* Implement 24 Byte directory read ?? ! with STATUS_NOT_IMPLEMENTED server doesn't read again */ ! /* return STATUS_FILE_IS_A_DIRECTORY; */ ! return STATUS_NOT_IMPLEMENTED; default: perror("read"); *************** *** 601,608 **** disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out) { ! uint32 length, file_attributes, ft_high, ft_low; char newname[256], fullpath[256]; struct fileinfo *pfinfo; - int mode; struct stat filestat; --- 639,645 ---- disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out) { ! uint32 length, file_attributes, ft_high, ft_low, delete_on_close; char newname[256], fullpath[256]; struct fileinfo *pfinfo; int mode; struct stat filestat; *************** *** 612,615 **** --- 649,653 ---- pfinfo = &(g_fileinfo[handle]); + g_notify_stamp = True; switch (info_class) *************** *** 671,675 **** ctime(&tvs.modtime)); #endif ! if (utime(pfinfo->path, &tvs)) return STATUS_ACCESS_DENIED; } --- 709,713 ---- ctime(&tvs.modtime)); #endif ! if (utime(pfinfo->path, &tvs) && errno != EPERM) return STATUS_ACCESS_DENIED; } *************** *** 729,751 **** DeleteFile set to FALSE should unschedule the delete. See ! http://www.osronline.com/article.cfm?article=245. Currently, ! we are deleting the file immediately. I ! guess this is a FIXME. */ ! ! //in_uint32_le(in, delete_on_close); ! /* Make sure we close the file before ! unlinking it. Not doing so would trigger ! silly-delete if using NFS, which might fail ! on FAT floppies, for example. */ ! disk_close(handle); ! if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE)) // remove a directory { ! if (rmdir(pfinfo->path) < 0) ! return STATUS_ACCESS_DENIED; } - else if (unlink(pfinfo->path) < 0) // unlink a file - return STATUS_ACCESS_DENIED; break; --- 767,780 ---- DeleteFile set to FALSE should unschedule the delete. See ! http://www.osronline.com/article.cfm?article=245. */ ! in_uint32_le(in, delete_on_close); ! if (delete_on_close || ! (pfinfo-> ! accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED))) { ! pfinfo->delete_on_close = True; } break; *************** *** 764,768 **** /* prevents start of writing if not enough space left on device */ if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0) ! if (stat_fs.f_bsize * stat_fs.f_bfree < length) return STATUS_DISK_FULL; --- 793,797 ---- /* prevents start of writing if not enough space left on device */ if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0) ! if (stat_fs.f_bfree * stat_fs.f_bsize < length) return STATUS_DISK_FULL; *************** *** 781,792 **** } static FsInfoType * FsVolumeInfo(char *fpath) { - #ifdef HAVE_MNTENT_H FILE *fdfs; - struct mntent *e; static FsInfoType info; /* initialize */ --- 810,929 ---- } + NTSTATUS + disk_check_notify(NTHANDLE handle) + { + struct fileinfo *pfinfo; + NTSTATUS status = STATUS_PENDING; + + NOTIFY notify; + + pfinfo = &(g_fileinfo[handle]); + if (!pfinfo->pdir) + return STATUS_INVALID_DEVICE_REQUEST; + + + + status = NotifyInfo(handle, pfinfo->info_class, ¬ify); + + if (status != STATUS_PENDING) + return status; + + if (memcmp(&pfinfo->notify, ¬ify, sizeof(NOTIFY))) + { + //printf("disk_check_notify found changed event\n"); + memcpy(&pfinfo->notify, ¬ify, sizeof(NOTIFY)); + status = STATUS_NOTIFY_ENUM_DIR; + } + + return status; + + + } + + NTSTATUS + disk_create_notify(NTHANDLE handle, uint32 info_class) + { + + struct fileinfo *pfinfo; + NTSTATUS ret = STATUS_PENDING; + + /* printf("start disk_create_notify info_class %X\n", info_class); */ + + pfinfo = &(g_fileinfo[handle]); + pfinfo->info_class = info_class; + + ret = NotifyInfo(handle, info_class, &pfinfo->notify); + + if (info_class & 0x1000) + { /* ???? */ + if (ret == STATUS_PENDING) + return STATUS_SUCCESS; + } + + /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */ + + + return ret; + + } + + static NTSTATUS + NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p) + { + struct fileinfo *pfinfo; + struct stat buf; + struct dirent *dp; + char *fullname; + DIR *dpr; + + pfinfo = &(g_fileinfo[handle]); + if (fstat(handle, &buf) < 0) + { + perror("NotifyInfo"); + return STATUS_ACCESS_DENIED; + } + p->modify_time = buf.st_mtime; + p->status_time = buf.st_ctime; + p->num_entries = 0; + p->total_time = 0; + + + dpr = opendir(pfinfo->path); + if (!dpr) + { + perror("NotifyInfo"); + return STATUS_ACCESS_DENIED; + } + + + while ((dp = readdir(dpr))) + { + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + p->num_entries++; + fullname = xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2); + sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name); + + if (!stat(fullname, &buf)) + { + p->total_time += (buf.st_mtime + buf.st_ctime); + } + + xfree(fullname); + } + closedir(dpr); + + return STATUS_PENDING; + } + static FsInfoType * FsVolumeInfo(char *fpath) { FILE *fdfs; static FsInfoType info; + #ifdef HAVE_MNTENT_H + struct mntent *e; + #endif /* initialize */ *************** *** 795,798 **** --- 932,936 ---- strcpy(info.type, "RDPFS"); + #ifdef HAVE_MNTENT_H fdfs = setmntent(MNTENT_PATH, "r"); if (!fdfs) *************** *** 837,842 **** endmntent(fdfs); #else - static FsInfoType info; - /* initialize */ memset(&info, 0, sizeof(info)); --- 975,978 ---- Index: proto.h =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** proto.h 2 Oct 2004 01:30:32 -0000 1.68 --- proto.h 3 Nov 2004 13:56:44 -0000 1.69 *************** *** 33,36 **** --- 33,38 ---- NTSTATUS disk_query_volume_information(NTHANDLE handle, uint32 info_class, STREAM out); NTSTATUS disk_query_directory(NTHANDLE handle, uint32 info_class, char *pattern, STREAM out); + NTSTATUS disk_create_notify(NTHANDLE handle, uint32 info_class); + NTSTATUS disk_check_notify(NTHANDLE handle); /* mppc.c */ int mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen); *************** *** 145,148 **** --- 147,151 ---- int serial_enum_devices(uint32 * id, char *optarg); BOOL serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout); + BOOL serial_get_event(NTHANDLE handle, uint32 * result); /* tcp.c */ STREAM tcp_init(uint32 maxlen); Index: rdpdr.c =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/rdpdr.c,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** rdpdr.c 2 Oct 2004 01:30:32 -0000 1.37 --- rdpdr.c 3 Nov 2004 13:56:51 -0000 1.38 *************** *** 62,65 **** --- 62,66 ---- extern DEVICE_FNS disk_fns; extern FILEINFO g_fileinfo[]; + extern BOOL g_notify_stamp; static VCHANNEL *rdpdr_channel; *************** *** 324,329 **** out_uint8p(s, buffer, length); s_mark_end(s); ! /* JIF ! hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); */ channel_send(s, rdpdr_channel); } --- 325,333 ---- out_uint8p(s, buffer, length); s_mark_end(s); ! /* JIF */ ! #ifdef WITH_DEBUG_RDP5 ! printf("--> rdpdr_send_completion\n"); ! //hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); ! #endif channel_send(s, rdpdr_channel); } *************** *** 624,629 **** /* JIF ! unimpl("IRP major=0x%x minor=0x%x: IRP_MN_NOTIFY_CHANGE_DIRECTORY\n", major, minor); */ ! status = STATUS_PENDING; // Don't send completion packet break; --- 628,643 ---- /* JIF ! unimpl("IRP major=0x%x minor=0x%x: IRP_MN_NOTIFY_CHANGE_DIRECTORY\n", major, minor); */ ! ! in_uint32_le(s, info_level); // notify mask ! ! g_notify_stamp = True; ! ! status = disk_create_notify(file, info_level); ! result = 0; ! ! if (status == STATUS_PENDING) ! add_async_iorequest(device, file, id, major, length, ! fns, 0, 0, NULL, 0); break; *************** *** 631,636 **** status = STATUS_INVALID_PARAMETER; ! /* JIF ! unimpl("IRP major=0x%x minor=0x%x\n", major, minor); */ } break; --- 645,650 ---- status = STATUS_INVALID_PARAMETER; ! /* JIF */ ! unimpl("IRP major=0x%x minor=0x%x\n", major, minor); } break; *************** *** 660,663 **** --- 674,688 ---- status = fns->device_control(file, request, s, &out); result = buffer_len = out.p - out.data; + + /* Serial SERIAL_WAIT_ON_MASK */ + if (status == STATUS_PENDING) + { + if (add_async_iorequest + (device, file, id, major, length, fns, 0, 0, NULL, 0)) + { + status = STATUS_PENDING; + break; + } + } break; *************** *** 828,843 **** support for reconnects. */ - if ((read(iorq->fd, &c, 0) != 0) && (errno == EBADF)) - break; - FD_SET(iorq->fd, rfds); *n = MAX(*n, iorq->fd); ! // Check if io request timeout is smaller than current (but not 0). if (iorq->timeout && (select_timeout == 0 || iorq->timeout < select_timeout)) { ! // Set new timeout select_timeout = iorq->timeout; g_min_timeout_fd = iorq->fd; /* Remember fd */ --- 853,865 ---- support for reconnects. */ FD_SET(iorq->fd, rfds); *n = MAX(*n, iorq->fd); ! /* Check if io request timeout is smaller than current (but not 0). */ if (iorq->timeout && (select_timeout == 0 || iorq->timeout < select_timeout)) { ! /* Set new timeout */ select_timeout = iorq->timeout; g_min_timeout_fd = iorq->fd; /* Remember fd */ *************** *** 845,850 **** tv->tv_usec = (select_timeout % 1000) * 1000; *timeout = True; } - break; --- 867,884 ---- tv->tv_usec = (select_timeout % 1000) * 1000; *timeout = True; + break; + } + if (iorq->itv_timeout && iorq->partial_len > 0 + && (select_timeout == 0 + || iorq->itv_timeout < select_timeout)) + { + /* Set new timeout */ + select_timeout = iorq->itv_timeout; + g_min_timeout_fd = iorq->fd; /* Remember fd */ + tv->tv_sec = select_timeout / 1000; + tv->tv_usec = (select_timeout % 1000) * 1000; + *timeout = True; + break; } break; *************** *** 858,861 **** --- 892,900 ---- break; + case IRP_MJ_DEVICE_CONTROL: + if (select_timeout > 5) + select_timeout = 5; /* serial event queue */ + break; + } *************** *** 892,896 **** /* Check if select() returned with one of the rdpdr file descriptors, and complete io if it did */ void ! rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out) { NTSTATUS status; --- 931,935 ---- /* Check if select() returned with one of the rdpdr file descriptors, and complete io if it did */ void ! _rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out) { NTSTATUS status; *************** *** 900,906 **** --- 939,989 ---- struct async_iorequest *prev; uint32 req_size = 0; + uint32 buffer_len; + struct stream out; + uint8 *buffer = NULL; + if (timed_out) { + /* check serial iv_timeout */ + + iorq = g_iorequest; + prev = NULL; + while (iorq != NULL) + { + if (iorq->fd == g_min_timeout_fd) + { + if ((iorq->partial_len > 0) && + (g_rdpdr_device[iorq->device].device_type == + DEVICE_TYPE_SERIAL)) + { + + /* iv_timeout between 2 chars, send partial_len */ + //printf("RDPDR: IVT total %u bytes read of %u\n", iorq->partial_len, iorq->length); + rdpdr_send_completion(iorq->device, + iorq->id, STATUS_SUCCESS, + iorq->partial_len, + iorq->buffer, iorq->partial_len); + iorq = rdpdr_remove_iorequest(prev, iorq); + return; + } + else + { + break; + } + + } + else + { + break; + } + + + prev = iorq; + if (iorq) + iorq = iorq->next; + + } + rdpdr_abort_io(g_min_timeout_fd, 0, STATUS_TIMEOUT); return; *************** *** 930,934 **** req_size, iorq->offset, &result); ! if (result > 0) { iorq->partial_len += result; --- 1013,1017 ---- req_size, iorq->offset, &result); ! if ((long) result > 0) { iorq->partial_len += result; *************** *** 941,946 **** /* or if result was 0 and status success - EOF */ if ((iorq->partial_len == iorq->length) || ! (g_rdpdr_device[iorq->device].device_type == ! DEVICE_TYPE_SERIAL) || (result == 0)) { #if WITH_DEBUG_RDP5 --- 1024,1028 ---- /* or if result was 0 and status success - EOF */ if ((iorq->partial_len == iorq->length) || ! (result == 0)) { #if WITH_DEBUG_RDP5 *************** *** 973,977 **** iorq->offset, &result); ! if (result > 0) { iorq->partial_len += result; --- 1055,1059 ---- iorq->offset, &result); ! if ((long) result > 0) { iorq->partial_len += result; *************** *** 1000,1003 **** --- 1082,1102 ---- } break; + case IRP_MJ_DEVICE_CONTROL: + if (serial_get_event(iorq->fd, &result)) + { + buffer = (uint8 *) xrealloc((void *) buffer, 0x14); + out.data = out.p = buffer; + out.size = sizeof(buffer); + out_uint32_le(&out, result); + result = buffer_len = out.p - out.data; + status = STATUS_SUCCESS; + rdpdr_send_completion(iorq->device, iorq->id, + status, result, buffer, + buffer_len); + xfree(buffer); + iorq = rdpdr_remove_iorequest(prev, iorq); + } + + break; } *************** *** 1008,1013 **** --- 1107,1172 ---- } + /* Check notify */ + iorq = g_iorequest; + prev = NULL; + while (iorq != NULL) + { + if (iorq->fd != 0) + { + switch (iorq->major) + { + + case IRP_MJ_DIRECTORY_CONTROL: + if (g_rdpdr_device[iorq->device].device_type == + DEVICE_TYPE_DISK) + { + + if (g_notify_stamp) + { + g_notify_stamp = False; + status = disk_check_notify(iorq->fd); + if (status != STATUS_PENDING) + { + rdpdr_send_completion(iorq->device, + iorq->id, + status, 0, + NULL, 0); + iorq = rdpdr_remove_iorequest(prev, + iorq); + } + } + } + break; + + + + } + } + + prev = iorq; + if (iorq) + iorq = iorq->next; + } + + } + + void + rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out) + { + fd_set dummy; + + + FD_ZERO(&dummy); + + + /* fist check event queue only, + any serial wait event must be done before read block will be sent + */ + + _rdpdr_check_fds(&dummy, &dummy, False); + _rdpdr_check_fds(rfds, wfds, timed_out); } + /* Abort a pending io request for a given handle and major */ BOOL Index: serial.c =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/serial.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** serial.c 7 Oct 2004 13:00:28 -0000 1.20 --- serial.c 3 Nov 2004 13:56:51 -0000 1.21 *************** *** 6,9 **** --- 6,15 ---- #include "rdesktop.h" + #ifdef WITH_DEBUG_SERIAL + #define DEBUG_SERIAL(args) printf args; + #else + #define DEBUG_SERIAL(args) + #endif + #define FILE_DEVICE_SERIAL_PORT 0x1b *************** *** 76,79 **** --- 82,87 ---- /* Modem Status */ + #define SERIAL_MS_DTR 0x01 + #define SERIAL_MS_RTS 0x02 #define SERIAL_MS_CTS 0x10 #define SERIAL_MS_DSR 0x20 *************** *** 81,88 **** --- 89,118 ---- #define SERIAL_MS_CAR 0x80 + /* Handflow */ + #define SERIAL_DTR_CONTROL 0x01 + #define SERIAL_CTS_HANDSHAKE 0x08 + #define SERIAL_ERROR_ABORT 0x80000000 + + #define SERIAL_XON_HANDSHAKE 0x01 + #define SERIAL_XOFF_HANDSHAKE 0x02 + #define SERIAL_DSR_SENSITIVITY 0x40 + + #define SERIAL_CHAR_EOF 0 + #define SERIAL_CHAR_ERROR 1 + #define SERIAL_CHAR_BREAK 2 + #define SERIAL_CHAR_EVENT 3 + #define SERIAL_CHAR_XON 4 + #define SERIAL_CHAR_XOFF 5 + #ifndef CRTSCTS #define CRTSCTS 0 #endif + /* FIONREAD should really do the same thing as TIOCINQ, where it is + * not available */ + #ifndef TIOCINQ + #include <sys/filio.h> + #define TIOCINQ FIONREAD + #endif extern RDPDR_DEVICE g_rdpdr_device[]; *************** *** 190,195 **** break; #endif default: ! pser_inf->baud_rate = 0; break; } --- 220,235 ---- break; #endif + #ifdef B230400 + case B230400: + pser_inf->baud_rate = 230400; + break; + #endif + #ifdef B460800 + case B460800: + pser_inf->baud_rate = 460800; + break; + #endif default: ! pser_inf->baud_rate = 9600; break; } *************** *** 219,223 **** } ! pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0; return True; --- 259,283 ---- } ! if (ptermios->c_cflag & CRTSCTS) ! { ! pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE | SERIAL_ERROR_ABORT; ! } ! else ! { ! pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_ERROR_ABORT; ! } ! ! pser_inf->xonoff = SERIAL_DSR_SENSITIVITY; ! if (ptermios->c_iflag & IXON) ! pser_inf->xonoff |= SERIAL_XON_HANDSHAKE; ! ! if (ptermios->c_iflag & IXOFF) ! pser_inf->xonoff |= SERIAL_XOFF_HANDSHAKE; ! ! pser_inf->chars[SERIAL_CHAR_XON] = ptermios->c_cc[VSTART]; ! pser_inf->chars[SERIAL_CHAR_XOFF] = ptermios->c_cc[VSTOP]; ! pser_inf->chars[SERIAL_CHAR_EOF] = ptermios->c_cc[VEOF]; ! pser_inf->chars[SERIAL_CHAR_BREAK] = ptermios->c_cc[VINTR]; ! pser_inf->chars[SERIAL_CHAR_ERROR] = ptermios->c_cc[VKILL]; return True; *************** *** 311,323 **** break; #endif default: ! speed = B0; break; } /* on systems with separate ispeed and ospeed, we can remember the speed in ispeed while changing DTR with ospeed */ cfsetispeed(pser_inf->ptermios, speed); cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0); ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS); --- 371,398 ---- break; #endif + #ifdef B230400 + case 230400: + speed = B115200; + break; + #endif + #ifdef B460800 + case 460800: + speed = B115200; + break; + #endif default: ! speed = B9600; break; } + #if 0 /* on systems with separate ispeed and ospeed, we can remember the speed in ispeed while changing DTR with ospeed */ cfsetispeed(pser_inf->ptermios, speed); cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0); + #endif + + ptermios->c_cflag &= ~CBAUD; + ptermios->c_cflag |= speed; ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS); *************** *** 327,330 **** --- 402,408 ---- ptermios->c_cflag |= CSTOPB; break; + default: + ptermios->c_cflag &= ~CSTOPB; + break; } *************** *** 337,340 **** --- 415,421 ---- ptermios->c_cflag |= PARENB | PARODD; break; + case NO_PARITY: + ptermios->c_cflag &= ~(PARENB | PARODD); + break; } *************** *** 355,360 **** --- 436,476 ---- } + #if 0 if (pser_inf->rts) ptermios->c_cflag |= CRTSCTS; + else + ptermios->c_cflag &= ~CRTSCTS; + #endif + + if (pser_inf->control & SERIAL_CTS_HANDSHAKE) + { + ptermios->c_cflag |= CRTSCTS; + } + else + { + ptermios->c_cflag &= ~CRTSCTS; + } + + + if (pser_inf->xonoff & SERIAL_XON_HANDSHAKE) + { + ptermios->c_iflag |= IXON | IMAXBEL; + } + if (pser_inf->xonoff & SERIAL_XOFF_HANDSHAKE) + { + ptermios->c_iflag |= IXOFF | IMAXBEL; + } + + if ((pser_inf->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0) + { + ptermios->c_iflag &= ~IXON; + ptermios->c_iflag &= ~IXOFF; + } + + ptermios->c_cc[VSTART] = pser_inf->chars[SERIAL_CHAR_XON]; + ptermios->c_cc[VSTOP] = pser_inf->chars[SERIAL_CHAR_XOFF]; + ptermios->c_cc[VEOF] = pser_inf->chars[SERIAL_CHAR_EOF]; + ptermios->c_cc[VINTR] = pser_inf->chars[SERIAL_CHAR_BREAK]; + ptermios->c_cc[VKILL] = pser_inf->chars[SERIAL_CHAR_ERROR]; tcsetattr(serial_fd, TCSANOW, ptermios); *************** *** 435,457 **** /* some sane information */ ! printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u, rts %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr, pser_inf->rts); ! ! printf("INFO: use stty to change settings\n"); ! ! /* ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD; ! ptermios->c_cflag |= CREAD; ! ptermios->c_lflag |= ICANON; ! ptermios->c_iflag = IGNPAR | ICRNL; - tcsetattr(serial_fd, TCSANOW, ptermios); - */ pser_inf->ptermios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); pser_inf->ptermios->c_oflag &= ~OPOST; ! pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB); pser_inf->ptermios->c_cflag |= CS8; tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios); *handle = serial_fd; --- 551,571 ---- /* some sane information */ ! DEBUG_SERIAL(("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u, rts %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr, pser_inf->rts)); pser_inf->ptermios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); pser_inf->ptermios->c_oflag &= ~OPOST; ! pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN | XCASE); pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB); pser_inf->ptermios->c_cflag |= CS8; + tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios); + pser_inf->event_txempty = 0; + pser_inf->event_cts = 0; + pser_inf->event_dsr = 0; + pser_inf->event_rlsd = 0; + pser_inf->event_pending = 0; + *handle = serial_fd; *************** *** 460,463 **** --- 574,579 ---- perror("fcntl"); + pser_inf->read_total_timeout_constant = 5; + return STATUS_SUCCESS; } *************** *** 469,472 **** --- 585,590 ---- if (i >= 0) g_rdpdr_device[i].handle = 0; + + rdpdr_abort_io(handle, 0, STATUS_TIMEOUT); close(handle); return STATUS_SUCCESS; *************** *** 479,482 **** --- 597,604 ---- SERIAL_DEVICE *pser_inf; struct termios *ptermios; + #ifdef WITH_DEBUG_SERIAL + int bytes_inqueue; + #endif + timeout = 90; *************** *** 512,519 **** tcsetattr(handle, TCSANOW, ptermios); *result = read(handle, data, length); ! //hexdump(data, *read); return STATUS_SUCCESS; --- 634,649 ---- tcsetattr(handle, TCSANOW, ptermios); + #ifdef WITH_DEBUG_SERIAL + ioctl(handle, TIOCINQ, &bytes_inqueue); + DEBUG_SERIAL(("serial_read inqueue: %d expected %d\n", bytes_inqueue, length)); + #endif *result = read(handle, data, length); ! #ifdef WITH_DEBUG_SERIAL ! DEBUG_SERIAL(("serial_read Bytes %d\n", *result)); ! if (*result > 0) ! hexdump(data, *result); ! #endif return STATUS_SUCCESS; *************** *** 523,527 **** --- 653,667 ---- serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) { + SERIAL_DEVICE *pser_inf; + + pser_inf = get_serial_info(handle); + *result = write(handle, data, length); + + if (*result > 0) + pser_inf->event_txempty = *result; + + DEBUG_SERIAL(("serial_write length %d, offset %d result %d\n", length, offset, *result)); + return STATUS_SUCCESS; } *************** *** 530,536 **** serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out) { - #if 0 int flush_mask, purge_mask; - #endif uint32 result, modemstate; uint8 immediate; --- 670,674 ---- *************** *** 548,553 **** request &= 0xfff; - printf("SERIAL IOCTL %d\n", request); - switch (request) { --- 686,689 ---- *************** *** 555,565 **** --- 691,705 ---- in_uint32_le(in, pser_inf->baud_rate); set_termios(pser_inf, handle); + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BAUD_RATE %d\n", pser_inf->baud_rate)); break; case SERIAL_GET_BAUD_RATE: out_uint32_le(out, pser_inf->baud_rate); + DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_BAUD_RATE %d\n", pser_inf->baud_rate)); break; case SERIAL_SET_QUEUE_SIZE: in_uint32_le(in, pser_inf->queue_in_size); in_uint32_le(in, pser_inf->queue_out_size); + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d\n", + pser_inf->queue_in_size, pser_inf->queue_out_size)); break; case SERIAL_SET_LINE_CONTROL: *************** *** 568,573 **** --- 708,716 ---- in_uint8(in, pser_inf->word_length); set_termios(pser_inf, handle); + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d\n", + pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length)); break; case SERIAL_GET_LINE_CONTROL: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n")); out_uint8(out, pser_inf->stop_bits); out_uint8(out, pser_inf->parity); *************** *** 575,626 **** break; case SERIAL_IMMEDIATE_CHAR: in_uint8(in, immediate); serial_write(handle, &immediate, 1, 0, &result); break; case SERIAL_CONFIG_SIZE: out_uint32_le(out, 0); break; case SERIAL_GET_CHARS: ! out_uint8s(out, 6); break; case SERIAL_SET_CHARS: ! in_uint8s(in, 6); break; case SERIAL_GET_HANDFLOW: ! out_uint32_le(out, 0); ! out_uint32_le(out, 3); /* Xon/Xoff */ ! out_uint32_le(out, 0); ! out_uint32_le(out, 0); break; case SERIAL_SET_HANDFLOW: ! in_uint8s(in, 16); break; case SERIAL_SET_TIMEOUTS: ! in_uint8s(in, 20); break; case SERIAL_GET_TIMEOUTS: ! out_uint8s(out, 20); break; case SERIAL_GET_WAIT_MASK: ! out_uint32(out, pser_inf->wait_mask); break; case SERIAL_SET_WAIT_MASK: in_uint32(in, pser_inf->wait_mask); break; case SERIAL_SET_DTR: pser_inf->dtr = 1; - set_termios(pser_inf, handle); break; case SERIAL_CLR_DTR: pser_inf->dtr = 0; - set_termios(pser_inf, handle); break; case SERIAL_SET_RTS: pser_inf->rts = 1; - set_termios(pser_inf, handle); break; case SERIAL_CLR_RTS: pser_inf->rts = 0; - set_termios(pser_inf, handle); break; case SERIAL_GET_MODEMSTATUS: --- 718,817 ---- break; case SERIAL_IMMEDIATE_CHAR: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_IMMEDIATE_CHAR\n")); in_uint8(in, immediate); serial_write(handle, &immediate, 1, 0, &result); break; case SERIAL_CONFIG_SIZE: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_CONFIG_SIZE\n")); out_uint32_le(out, 0); break; case SERIAL_GET_CHARS: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_CHARS\n")); ! out_uint8a(out, pser_inf->chars, 6); break; case SERIAL_SET_CHARS: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_CHARS\n")); ! in_uint8a(in, pser_inf->chars, 6); ! #ifdef WITH_DEBUG_SERIAL ! hexdump(pser_inf->chars, 6); ! #endif ! set_termios(pser_inf, handle); break; case SERIAL_GET_HANDFLOW: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_HANDFLOW\n")); ! get_termios(pser_inf, handle); ! out_uint32_le(out, pser_inf->control); ! out_uint32_le(out, pser_inf->xonoff); /* Xon/Xoff */ ! out_uint32_le(out, pser_inf->onlimit); ! out_uint32_le(out, pser_inf->offlimit); break; case SERIAL_SET_HANDFLOW: ! in_uint32_le(in, pser_inf->control); ! in_uint32_le(in, pser_inf->xonoff); ! in_uint32_le(in, pser_inf->onlimit); ! in_uint32_le(in, pser_inf->offlimit); ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_HANDFLOW %x %x %x %x\n", ! pser_inf->control, pser_inf->xonoff, pser_inf->onlimit, ! pser_inf->onlimit)); ! set_termios(pser_inf, handle); break; case SERIAL_SET_TIMEOUTS: ! in_uint32(in, pser_inf->read_interval_timeout); ! in_uint32(in, pser_inf->read_total_timeout_multiplier); ! in_uint32(in, pser_inf->read_total_timeout_constant); ! in_uint32(in, pser_inf->write_total_timeout_multiplier); ! in_uint32(in, pser_inf->write_total_timeout_constant); ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d\n", ! pser_inf->read_interval_timeout, ! pser_inf->read_total_timeout_multiplier, ! pser_inf->read_total_timeout_constant)); break; case SERIAL_GET_TIMEOUTS: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d\n", ! pser_inf->read_interval_timeout, ! pser_inf->read_total_timeout_multiplier, ! pser_inf->read_total_timeout_constant)); ! ! out_uint32(out, pser_inf->read_interval_timeout); ! out_uint32(out, pser_inf->read_total_timeout_multiplier); ! out_uint32(out, pser_inf->read_total_timeout_constant); ! out_uint32(out, pser_inf->write_total_timeout_multiplier); ! out_uint32(out, pser_inf->write_total_timeout_constant); break; case SERIAL_GET_WAIT_MASK: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n", pser_inf->wait_mask); ! out_uint32(out, pser_inf->wait_mask)); break; case SERIAL_SET_WAIT_MASK: in_uint32(in, pser_inf->wait_mask); + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n", pser_inf->wait_mask)); break; case SERIAL_SET_DTR: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n")); + ioctl(handle, TIOCMGET, &result); + result |= TIOCM_DTR; + ioctl(handle, TIOCMSET, &result); pser_inf->dtr = 1; break; case SERIAL_CLR_DTR: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n")); + ioctl(handle, TIOCMGET, &result); + result &= ~TIOCM_DTR; + ioctl(handle, TIOCMSET, &result); pser_inf->dtr = 0; break; case SERIAL_SET_RTS: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n")); + ioctl(handle, TIOCMGET, &result); + result |= TIOCM_RTS; + ioctl(handle, TIOCMSET, &result); pser_inf->rts = 1; break; case SERIAL_CLR_RTS: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n")); + ioctl(handle, TIOCMGET, &result); + result &= ~TIOCM_RTS; + ioctl(handle, TIOCMSET, &result); pser_inf->rts = 0; break; case SERIAL_GET_MODEMSTATUS: *************** *** 636,640 **** --- 827,836 ---- if (result & TIOCM_CAR) modemstate |= SERIAL_MS_CAR; + if (result & TIOCM_DTR) + modemstate |= SERIAL_MS_DTR; + if (result & TIOCM_RTS) + modemstate |= SERIAL_MS_RTS; #endif + DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate)); out_uint32_le(out, modemstate); break; *************** *** 642,679 **** out_uint32_le(out, 0); /* Errors */ out_uint32_le(out, 0); /* Hold reasons */ ! out_uint32_le(out, 0); /* Amount in in queue */ ! out_uint32_le(out, 0); /* Amount in out queue */ out_uint8(out, 0); /* EofReceived */ out_uint8(out, 0); /* WaitForImmediate */ break; - #if 0 case SERIAL_PURGE: - printf("SERIAL_PURGE\n"); in_uint32(in, purge_mask); ! if (purge_mask & 0x04) flush_mask |= TCOFLUSH; ! if (purge_mask & 0x08) flush_mask |= TCIFLUSH; if (flush_mask != 0) tcflush(handle, flush_mask); ! if (purge_mask & 0x01) rdpdr_abort_io(handle, 4, STATUS_CANCELLED); ! if (purge_mask & 0x02) rdpdr_abort_io(handle, 3, STATUS_CANCELLED); break; case SERIAL_WAIT_ON_MASK: ! /* XXX implement me */ ! out_uint32_le(out, pser_inf->wait_mask); break; case SERIAL_SET_BREAK_ON: ! tcsendbreak(serial_fd, 0); break; case SERIAL_RESET_DEVICE: case SERIAL_SET_BREAK_OFF: case SERIAL_SET_XOFF: case SERIAL_SET_XON: ! /* ignore */ break; - #endif default: unimpl("SERIAL IOCTL %d\n", request); --- 838,900 ---- out_uint32_le(out, 0); /* Errors */ out_uint32_le(out, 0); /* Hold reasons */ ! ! result = 0; ! ioctl(handle, TIOCINQ, &result); ! out_uint32_le(out, result); /* Amount in in queue */ ! if (result) ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n", result)); ! ! result = 0; ! ioctl(handle, TIOCOUTQ, &result); ! out_uint32_le(out, result); /* Amount in out queue */ ! if (result) ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result)); ! out_uint8(out, 0); /* EofReceived */ out_uint8(out, 0); /* WaitForImmediate */ break; case SERIAL_PURGE: in_uint32(in, purge_mask); ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask)); ! flush_mask = 0; ! if (purge_mask & SERIAL_PURGE_TXCLEAR) flush_mask |= TCOFLUSH; ! if (purge_mask & SERIAL_PURGE_RXCLEAR) flush_mask |= TCIFLUSH; if (flush_mask != 0) tcflush(handle, flush_mask); ! if (purge_mask & SERIAL_PURGE_TXABORT) rdpdr_abort_io(handle, 4, STATUS_CANCELLED); ! if (purge_mask & SERIAL_PURGE_RXABORT) rdpdr_abort_io(handle, 3, STATUS_CANCELLED); break; case SERIAL_WAIT_ON_MASK: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n", pser_inf->wait_mask)); ! pser_inf->event_pending = 1; ! if (serial_get_event(handle, &result)) ! { ! DEBUG_SERIAL(("WAIT end event = %x\n", result)); ! out_uint32_le(out, result); ! break; ! } ! return STATUS_PENDING; break; case SERIAL_SET_BREAK_ON: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n")); ! tcsendbreak(handle, 0); break; case SERIAL_RESET_DEVICE: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n")); + break; case SERIAL_SET_BREAK_OFF: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n")); + break; case SERIAL_SET_XOFF: + DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n")); + break; case SERIAL_SET_XON: ! DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n")); ! tcflow(handle, TCION); break; default: unimpl("SERIAL IOCTL %d\n", request); *************** *** 684,687 **** --- 905,1002 ---- } + BOOL + serial_get_event(NTHANDLE handle, uint32 * result) + { + int index; + SERIAL_DEVICE *pser_inf; + int bytes; + BOOL ret = False; + + *result = 0; + index = get_device_index(handle); + if (index < 0) + return False; + + pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data; + + + ioctl(handle, TIOCINQ, &bytes); + + if (bytes > 0) + { + DEBUG_SERIAL(("serial_get_event Bytes %d\n", bytes)); + if (bytes > pser_inf->event_rlsd) + { + pser_inf->event_rlsd = bytes; + if (pser_inf->wait_mask & SERIAL_EV_RLSD) + { + DEBUG_SERIAL(("Event -> SERIAL_EV_RLSD \n")); + *result |= SERIAL_EV_RLSD; + ret = True; + } + + } + + if ((bytes > 1) && (pser_inf->wait_mask & SERIAL_EV_RXFLAG)) + { + DEBUG_SERIAL(("Event -> SERIAL_EV_RXFLAG Bytes %d\n", bytes)); + *result |= SERIAL_EV_RXFLAG; + ret = True; + } + if ((pser_inf->wait_mask & SERIAL_EV_RXCHAR)) + { + DEBUG_SERIAL(("Event -> SERIAL_EV_RXCHAR Bytes %d\n", bytes)); + *result |= SERIAL_EV_RXCHAR; + ret = True; + } + + } + else + { + pser_inf->event_rlsd = 0; + } + + + ioctl(handle, TIOCOUTQ, &bytes); + if ((bytes == 0) + && (pser_inf->event_txempty > 0) && (pser_inf->wait_mask & SERIAL_EV_TXEMPTY)) + { + + DEBUG_SERIAL(("Event -> SERIAL_EV_TXEMPTY\n")); + *result |= SERIAL_EV_TXEMPTY; + ret = True; + } + pser_inf->event_txempty = bytes; + + + ioctl(handle, TIOCMGET, &bytes); + if ((bytes & TIOCM_DSR) != pser_inf->event_dsr) + { + pser_inf->event_dsr = bytes & TIOCM_DSR; + if (pser_inf->wait_mask & SERIAL_EV_DSR) + { + DEBUG_SERIAL(("event -> SERIAL_EV_DSR %s\n", (bytes & TIOCM_DSR) ? "ON" : "OFF")); + *result |= SERIAL_EV_DSR; + ret = True; + } + } + + if ((bytes & TIOCM_CTS) != pser_inf->event_cts) + { + pser_inf->event_cts = bytes & TIOCM_CTS; + if (pser_inf->wait_mask & SERIAL_EV_CTS) + { + DEBUG_SERIAL((" EVENT-> SERIAL_EV_CTS %s\n", (bytes & TIOCM_CTS) ? "ON" : "OFF")); + *result |= SERIAL_EV_CTS; + ret = True; + } + } + + if (ret) + pser_inf->event_pending = 0; + + return ret; + } + /* Read timeout for a given file descripter (device) when adding fd's to select() */ BOOL Index: types.h =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/types.h,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** types.h 2 Oct 2004 01:30:32 -0000 1.21 --- types.h 3 Nov 2004 13:56:52 -0000 1.22 *************** *** 198,201 **** --- 198,202 ---- int dtr; int rts; + uint32 control, xonoff, onlimit, offlimit; uint32 baud_rate, queue_in_size, *************** *** 207,211 **** --- 208,214 ---- write_total_timeout_multiplier, write_total_timeout_constant, posix_wait_mask; uint8 stop_bits, parity, word_length; + uint8 chars[6]; struct termios *ptermios, *pold_termios; + int event_txempty, event_cts, event_dsr, event_rlsd, event_pending; } SERIAL_DEVICE; *************** *** 236,242 **** PRINTER; typedef struct fileinfo { ! uint32 device_id, flags_and_attributes; char path[256]; DIR *pdir; --- 239,254 ---- PRINTER; + typedef struct notify_data + { + time_t modify_time; + time_t status_time; + time_t total_time; + unsigned int num_entries; + } + NOTIFY; + typedef struct fileinfo { ! uint32 device_id, flags_and_attributes, accessmask; char path[256]; DIR *pdir; *************** *** 244,247 **** --- 256,261 ---- char pattern[64]; BOOL delete_on_close; + NOTIFY notify; + uint32 info_class; } FILEINFO; Index: xwin.c =================================================================== RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v retrieving revision 1.178 retrieving revision 1.179 diff -C2 -d -r1.178 -r1.179 *** xwin.c 21 Oct 2004 08:43:22 -0000 1.178 --- xwin.c 3 Nov 2004 13:56:52 -0000 1.179 *************** *** 1436,1445 **** case 0: ! /* TODO: if tv.tv_sec just times out ! * we will segfault. ! * FIXME: ! */ ! //s_timeout = True; ! //rdpdr_check_fds(&rfds, &wfds, (BOOL) True); continue; } --- 1436,1442 ---- case 0: ! /* Abort serial read calls */ ! if (s_timeout) ! rdpdr_check_fds(&rfds, &wfds, (BOOL) True); continue; } ------------------------------------------------------- This SF.Net email is sponsored by: Sybase ASE Linux Express Edition - download now for FREE LinuxWorld Reader's Choice Award Winner for best database on Linux. http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click