VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.3/lspci.c@ 55121

Last change on this file since 55121 was 55121, checked in by vboxsync, 10 years ago

rdesktop 1.8.3 unmodified

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.4 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 3 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, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "rdesktop.h"
21#include <sys/types.h>
22#include <unistd.h>
23
24static VCHANNEL *lspci_channel;
25
26typedef struct _pci_device
27{
28 uint16 klass;
29 uint16 vendor;
30 uint16 device;
31 uint16 subvendor;
32 uint16 subdevice;
33 uint8 revision;
34 uint8 progif;
35} pci_device;
36
37static pci_device current_device;
38
39static void lspci_send(const char *output);
40
41
42/* Handle one line of output from the lspci subprocess */
43static RD_BOOL
44handle_child_line(const char *line, void *data)
45{
46 const char *val;
47 char buf[1024];
48
49 if (str_startswith(line, "Class:"))
50 {
51 val = line + sizeof("Class:");
52 /* Skip whitespace and second Class: occurance */
53 val += strspn(val, " \t") + sizeof("Class");
54 current_device.klass = strtol(val, NULL, 16);
55 }
56 else if (str_startswith(line, "Vendor:"))
57 {
58 val = line + sizeof("Vendor:");
59 current_device.vendor = strtol(val, NULL, 16);
60 }
61 else if (str_startswith(line, "Device:"))
62 {
63 val = line + sizeof("Device:");
64 /* Sigh, there are *two* lines tagged as Device:. We
65 are not interested in the domain/bus/slot/func */
66 if (!strchr(val, ':'))
67 current_device.device = strtol(val, NULL, 16);
68 }
69 else if (str_startswith(line, "SVendor:"))
70 {
71 val = line + sizeof("SVendor:");
72 current_device.subvendor = strtol(val, NULL, 16);
73 }
74 else if (str_startswith(line, "SDevice:"))
75 {
76 val = line + sizeof("SDevice:");
77 current_device.subdevice = strtol(val, NULL, 16);
78 }
79 else if (str_startswith(line, "Rev:"))
80 {
81 val = line + sizeof("Rev:");
82 current_device.revision = strtol(val, NULL, 16);
83 }
84 else if (str_startswith(line, "ProgIf:"))
85 {
86 val = line + sizeof("ProgIf:");
87 current_device.progif = strtol(val, NULL, 16);
88 }
89 else if (strspn(line, " \t") == strlen(line))
90 {
91 /* Blank line. Send collected information over channel */
92 snprintf(buf, sizeof(buf), "%04x,%04x,%04x,%04x,%04x,%02x,%02x\n",
93 current_device.klass, current_device.vendor,
94 current_device.device, current_device.subvendor,
95 current_device.subdevice, current_device.revision, current_device.progif);
96 lspci_send(buf);
97 memset(&current_device, 0, sizeof(current_device));
98 }
99 else
100 {
101 warning("lspci: Unrecoqnized line '%s'\n", line);
102 }
103 return True;
104}
105
106
107/* Process one line of input from virtual channel */
108static RD_BOOL
109lspci_process_line(const char *line, void *data)
110{
111 char *lspci_command[5] = { "lspci", "-m", "-n", "-v", NULL };
112
113 if (!strcmp(line, "LSPCI"))
114 {
115 memset(&current_device, 0, sizeof(current_device));
116 subprocess(lspci_command, handle_child_line, NULL);
117 /* Send single dot to indicate end of enumeration */
118 lspci_send(".\n");
119 }
120 else
121 {
122 error("lspci protocol error: Invalid line '%s'\n", line);
123 }
124 return True;
125}
126
127
128/* Process new data from the virtual channel */
129static void
130lspci_process(STREAM s)
131{
132 unsigned int pkglen;
133 static char *rest = NULL;
134 char *buf;
135
136 pkglen = s->end - s->p;
137 /* str_handle_lines requires null terminated strings */
138 buf = xmalloc(pkglen + 1);
139 STRNCPY(buf, (char *) s->p, pkglen + 1);
140#if 0
141 printf("lspci recv:\n");
142 hexdump(s->p, pkglen);
143#endif
144
145 str_handle_lines(buf, &rest, lspci_process_line, NULL);
146 xfree(buf);
147}
148
149/* Initialize this module: Register the lspci channel */
150RD_BOOL
151lspci_init(void)
152{
153 lspci_channel =
154 channel_register("lspci", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
155 lspci_process);
156 return (lspci_channel != NULL);
157}
158
159/* Send data to channel */
160static void
161lspci_send(const char *output)
162{
163 STREAM s;
164 size_t len;
165
166 len = strlen(output);
167 s = channel_init(lspci_channel, len);
168 out_uint8p(s, output, len) s_mark_end(s);
169
170#if 0
171 printf("lspci send:\n");
172 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
173#endif
174
175 channel_send(s, lspci_channel);
176}
Note: See TracBrowser for help on using the repository browser.

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