VirtualBox

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

Last change on this file since 34346 was 33656, checked in by vboxsync, 14 years ago

*: rebrand Sun (L)GPL disclaimers

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