VirtualBox

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

Last change on this file since 40654 was 37224, checked in by vboxsync, 13 years ago

RDP/client: fix OSE

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