VirtualBox

source: vbox/trunk/src/VBox/RDP/client/lspci.c@ 10076

Last change on this file since 10076 was 9902, checked in by vboxsync, 16 years ago

Added rdesktop 1.6.0.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2+ rdesktop: A Remote Desktop Protocol client.
3+ Support for the Matrox "lspci" channel
4+ Copyright (C) 2005 Matrox Graphics Inc.
5+
6+ This program is free software; you can redistribute it and/or modify
7+ it under the terms of the GNU General Public License as published by
8+ the Free Software Foundation; either version 2 of the License, or
9+ (at your option) any later version.
10+
11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+
16+ You should have received a copy of the GNU General Public License
17+ along with this program; if not, write to the Free Software
18+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19+*/
20
21#include "rdesktop.h"
22#include <sys/types.h>
23#include <unistd.h>
24
25static VCHANNEL *lspci_channel;
26
27typedef struct _pci_device
28{
29 uint16 klass;
30 uint16 vendor;
31 uint16 device;
32 uint16 subvendor;
33 uint16 subdevice;
34 uint8 revision;
35 uint8 progif;
36} pci_device;
37
38static pci_device current_device;
39
40static void lspci_send(const char *output);
41
42
43/* Handle one line of output from the lspci subprocess */
44static RD_BOOL
45handle_child_line(const char *line, void *data)
46{
47 const char *val;
48 char buf[1024];
49
50 if (str_startswith(line, "Class:"))
51 {
52 val = line + sizeof("Class:");
53 /* Skip whitespace and second Class: occurance */
54 val += strspn(val, " \t") + sizeof("Class");
55 current_device.klass = strtol(val, NULL, 16);
56 }
57 else if (str_startswith(line, "Vendor:"))
58 {
59 val = line + sizeof("Vendor:");
60 current_device.vendor = strtol(val, NULL, 16);
61 }
62 else if (str_startswith(line, "Device:"))
63 {
64 val = line + sizeof("Device:");
65 /* Sigh, there are *two* lines tagged as Device:. We
66 are not interested in the domain/bus/slot/func */
67 if (!strchr(val, ':'))
68 current_device.device = strtol(val, NULL, 16);
69 }
70 else if (str_startswith(line, "SVendor:"))
71 {
72 val = line + sizeof("SVendor:");
73 current_device.subvendor = strtol(val, NULL, 16);
74 }
75 else if (str_startswith(line, "SDevice:"))
76 {
77 val = line + sizeof("SDevice:");
78 current_device.subdevice = strtol(val, NULL, 16);
79 }
80 else if (str_startswith(line, "Rev:"))
81 {
82 val = line + sizeof("Rev:");
83 current_device.revision = strtol(val, NULL, 16);
84 }
85 else if (str_startswith(line, "ProgIf:"))
86 {
87 val = line + sizeof("ProgIf:");
88 current_device.progif = strtol(val, NULL, 16);
89 }
90 else if (strspn(line, " \t") == strlen(line))
91 {
92 /* Blank line. Send collected information over channel */
93 snprintf(buf, sizeof(buf), "%04x,%04x,%04x,%04x,%04x,%02x,%02x\n",
94 current_device.klass, current_device.vendor,
95 current_device.device, current_device.subvendor,
96 current_device.subdevice, current_device.revision, current_device.progif);
97 lspci_send(buf);
98 memset(&current_device, 0, sizeof(current_device));
99 }
100 else
101 {
102 warning("lspci: Unrecoqnized line '%s'\n", line);
103 }
104 return True;
105}
106
107
108/* Process one line of input from virtual channel */
109static RD_BOOL
110lspci_process_line(const char *line, void *data)
111{
112 char *lspci_command[5] = { "lspci", "-m", "-n", "-v", NULL };
113
114 if (!strcmp(line, "LSPCI"))
115 {
116 memset(&current_device, 0, sizeof(current_device));
117 subprocess(lspci_command, handle_child_line, NULL);
118 /* Send single dot to indicate end of enumeration */
119 lspci_send(".\n");
120 }
121 else
122 {
123 error("lspci protocol error: Invalid line '%s'\n", line);
124 }
125 return True;
126}
127
128
129/* Process new data from the virtual channel */
130static void
131lspci_process(STREAM s)
132{
133 unsigned int pkglen;
134 static char *rest = NULL;
135 char *buf;
136
137 pkglen = s->end - s->p;
138 /* str_handle_lines requires null terminated strings */
139 buf = xmalloc(pkglen + 1);
140 STRNCPY(buf, (char *) s->p, pkglen + 1);
141#if 0
142 printf("lspci recv:\n");
143 hexdump(s->p, pkglen);
144#endif
145
146 str_handle_lines(buf, &rest, lspci_process_line, NULL);
147 xfree(buf);
148}
149
150/* Initialize this module: Register the lspci channel */
151RD_BOOL
152lspci_init(void)
153{
154 lspci_channel =
155 channel_register("lspci", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
156 lspci_process);
157 return (lspci_channel != NULL);
158}
159
160/* Send data to channel */
161static void
162lspci_send(const char *output)
163{
164 STREAM s;
165 size_t len;
166
167 len = strlen(output);
168 s = channel_init(lspci_channel, len);
169 out_uint8p(s, output, len) s_mark_end(s);
170
171#if 0
172 printf("lspci send:\n");
173 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
174#endif
175
176 channel_send(s, lspci_channel);
177}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette