1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
|
/*
* Copyright (C) 2000-2011 the xine project
*
* This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
* Xine Health Check:
*
* Overview: Checking the setup of the user's system is the task of
* xine-check.sh for now. At present this is intended to replace
* xine_check to provide a more robust way of informing users new
* to xine of the setup of their system.
*
* Interface: The function xine_health_check is the starting point
* to check the user's system. It is expected that the values for
* hc->cdrom_dev and hc->dvd_dev will be defined. For example,
* hc->cdrom_dev = /dev/cdrom and hc->/dev/dvd. If at any point a
* step fails the function returns with a failed status,
* XINE_HEALTH_CHECK_FAIL, and an error message contained in hc->msg.
*
* Author: Stephen Torri <storri@users.sourceforge.net>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <xine/xineutils.h>
#ifndef O_CLOEXEC
# define O_CLOEXEC 0
#endif
#if defined(__linux__)
#include <dlfcn.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <linux/major.h>
#include <linux/hdreg.h>
#ifdef HAVE_X11
# include <X11/Xlib.h>
# ifdef HAVE_XV
# include <X11/extensions/Xvlib.h>
# endif
#endif
#ifndef SCSI_BLK_MAJOR
#define SCSI_BLK_MAJOR(m) \
(((m) == SCSI_DISK0_MAJOR || \
((m) >= SCSI_DISK1_MAJOR && (m) <= SCSI_DISK7_MAJOR)) || \
((m) == SCSI_CDROM_MAJOR))
#endif
#endif /* !__linux__ */
static void XINE_FORMAT_PRINTF(3, 4)
set_hc_result(xine_health_check_t* hc, int state, const char *format, ...)
{
va_list args;
char *buf = NULL;
if (!hc) {
printf ("xine_check: GASP, hc is NULL\n");
_x_abort();
}
if (!format) {
printf ("xine_check: GASP, format is NULL\n");
_x_abort();
}
va_start(args, format);
if (vasprintf (&buf, format, args) < 0)
buf = NULL;
va_end(args);
if (!buf)
_x_abort();
hc->msg = buf;
hc->status = state;
}
#if defined(__linux__)
static xine_health_check_t* _x_health_check_kernel (xine_health_check_t* hc) {
struct utsname kernel;
hc->title = "Check for kernel version";
hc->explanation = "Probably you're not running a Linux-Like system.";
if (uname (&kernel) == 0) {
fprintf (stdout," sysname: %s\n", kernel.sysname);
fprintf (stdout," release: %s\n", kernel.release);
fprintf (stdout," machine: %s\n", kernel.machine);
hc->status = XINE_HEALTH_CHECK_OK;
}
else {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL,
"FAILED - Could not get kernel information.");
}
return hc;
}
#if defined(ARCH_X86) || defined(ARCH_X86_64)
static xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
FILE *fd;
hc->title = "Check for MTRR support";
hc->explanation = "Make sure your kernel has MTRR support compiled in.";
fd = fopen("/proc/mtrr", "r");
if (!fd) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL,
"FAILED: mtrr is not enabled.");
} else {
hc->status = XINE_HEALTH_CHECK_OK;
fclose (fd);
}
return hc;
}
#else
static xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
hc->title = "Check for MTRR support";
hc->explanation = "Don't worry about this one";
set_hc_result (hc, XINE_HEALTH_CHECK_OK,
"mtrr does not apply on this hw platform.");
return hc;
}
#endif
static xine_health_check_t* _x_health_check_cdrom (xine_health_check_t* hc) {
struct stat cdrom_st;
int fd;
hc->title = "Check for CDROM drive";
hc->explanation = "Either create a symbolic link /dev/cdrom pointing to "
"your cdrom device or set your cdrom device in the "
"preferences dialog.";
if (stat (hc->cdrom_dev,&cdrom_st) < 0) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - could not access cdrom: %s\n", hc->cdrom_dev);
return hc;
}
if ((cdrom_st.st_mode & S_IFMT) != S_IFBLK) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s is not a block device.\n", hc->cdrom_dev);
return hc;
}
if ( (fd = open(hc->cdrom_dev, O_RDWR | O_CLOEXEC)) < 0) {
switch (errno) {
case EACCES:
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s permissions are not sufficient\n.", hc->cdrom_dev);
return hc;
case ENXIO:
case ENODEV:
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - there is no device behind %s\n.", hc->cdrom_dev);
return hc;
}
} else
close(fd);
hc->status = XINE_HEALTH_CHECK_OK;
return hc;
}
static xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t* hc) {
struct stat dvdrom_st;
int fd;
hc->title = "Check for DVD drive";
hc->explanation = "Either create a symbolic link /dev/dvd pointing to "
"your cdrom device or set your cdrom device in the "
"preferences dialog.";
if (stat (hc->dvd_dev,&dvdrom_st) < 0) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - could not access dvdrom: %s\n", hc->dvd_dev);
return hc;
}
if ((dvdrom_st.st_mode & S_IFMT) != S_IFBLK) {
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s is not a block device.\n", hc->dvd_dev);
return hc;
}
if ( (fd = open(hc->dvd_dev, O_RDWR | O_CLOEXEC)) < 0) {
switch (errno) {
case EACCES:
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s permissions are not sufficient\n.", hc->dvd_dev);
return hc;
case ENXIO:
case ENODEV:
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - there is no device behind %s\n.", hc->dvd_dev);
return hc;
}
} else
close(fd);
hc->status = XINE_HEALTH_CHECK_OK;
return hc;
}
static xine_health_check_t* _x_health_check_dma (xine_health_check_t* hc) {
int is_scsi_dev = 0;
int fd = 0;
static long param = 0;
struct stat st;
hc->title = "Check for DMA mode on DVD drive";
hc->explanation = "If you are using the ide-cd module ensure\n"
"that you have the following entry in /etc/modules.conf:\n"
"options ide-cd dma=1\n Reload ide-cd module.\n"
"otherwise run hdparm -d 1 on your dvd-device.";
/* If /dev/dvd points to /dev/scd0 but the drive is IDE (e.g. /dev/hdc)
* and not scsi how do we detect the correct one */
if (stat (hc->dvd_dev, &st)) {
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - Could not read stats for %s.\n", hc->dvd_dev);
return hc;
}
if (SCSI_BLK_MAJOR(major(st.st_rdev))) {
is_scsi_dev = 1;
set_hc_result(hc, XINE_HEALTH_CHECK_OK, "SKIPPED - Operation not supported on SCSI drives or drives that use the ide-scsi module.");
return hc;
}
fd = open (hc->dvd_dev, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
if (fd < 0) {
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - Could not open %s.\n", hc->dvd_dev);
return hc;
}
if (!is_scsi_dev) {
if(ioctl (fd, HDIO_GET_DMA, ¶m)) {
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL,
"FAILED - HDIO_GET_DMA failed. Ensure the permissions for %s are 0664.\n",
hc->dvd_dev);
return hc;
}
if (param != 1) {
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL,
"FAILED - DMA not turned on for %s.",
hc->dvd_dev);
return hc;
}
}
close (fd);
hc->status = XINE_HEALTH_CHECK_OK;
return hc;
}
static xine_health_check_t* _x_health_check_x (xine_health_check_t* hc) {
char* env_display = getenv("DISPLAY");
hc->title = "Check for X11 environment";
hc->explanation = "Make sure you're running X11, if this is an ssh connection,\n"
"make sure you have X11 forwarding enabled (ssh -X ...)";
if (strlen (env_display) == 0) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - DISPLAY environment variable not set.");
}
else {
hc->status = XINE_HEALTH_CHECK_OK;
}
return hc;
}
static xine_health_check_t* _x_health_check_xv (xine_health_check_t* hc) {
#ifdef HAVE_X11
#ifdef HAVE_XV
Display *dpy;
unsigned int ver, rev, eventB, reqB, errorB;
char *disname = NULL;
void *x11_handle;
void *xv_handle;
Display *(*xopendisplay)(char*);
char *(*xdisplayname)(char*);
int (*xvqueryextension)(Display*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*);
int (*xvqueryadaptors)(Display*, Window, int*, XvAdaptorInfo**);
XvImageFormatValues *(*xvlistimageformats)(Display*, XvPortID, int*);
char *err = NULL;
int formats, adaptors, i;
XvImageFormatValues *img_formats;
XvAdaptorInfo *adaptor_info;
hc->title = "Check for MIT Xv extension";
hc->explanation = "You can improve performance by installing an X11\n"
"driver that supports the Xv protocol extension.";
/* Majority of thi code was taken from or inspired by the xvinfo.c file of XFree86 */
dlerror(); /* clear error code */
x11_handle = dlopen(LIBX11_SO, RTLD_LAZY);
if(!x11_handle) {
hc->msg = dlerror();
hc->status = XINE_HEALTH_CHECK_FAIL;
return hc;
}
/* Get reference to XOpenDisplay */
xopendisplay = dlsym(x11_handle,"XOpenDisplay");
if((err = dlerror()) != NULL) {
hc->msg = err;
hc->status = XINE_HEALTH_CHECK_FAIL;
dlclose(x11_handle);
return hc;
}
/* Get reference to XDisplayName */
xdisplayname = dlsym(x11_handle,"XDisplayName");
if((err = dlerror()) != NULL) {
hc->msg = err;
hc->status = XINE_HEALTH_CHECK_FAIL;
dlclose(x11_handle);
return hc;
}
dlerror(); /* clear error code */
xv_handle = dlopen(LIBXV_SO, RTLD_LAZY);
if(!xv_handle) {
hc->msg = dlerror();
/* Xv might still work when linked statically into the output plugin,
* so reporting FAIL would be wrong here */
hc->status = XINE_HEALTH_CHECK_UNSUPPORTED;
dlclose(x11_handle);
return hc;
}
/* Get reference to XvQueryExtension */
xvqueryextension = dlsym(xv_handle,"XvQueryExtension");
if((err = dlerror()) != NULL) {
hc->msg = err;
hc->status = XINE_HEALTH_CHECK_FAIL;
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
/* Get reference to XvQueryAdaptors */
xvqueryadaptors = dlsym(xv_handle,"XvQueryAdaptors");
if((err = dlerror()) != NULL) {
hc->msg = err;
hc->status = XINE_HEALTH_CHECK_FAIL;
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
/* Get reference to XvListImageFormats */
xvlistimageformats = dlsym(xv_handle,"XvListImageFormats");
if((err = dlerror()) != NULL) {
hc->msg = err;
hc->status = XINE_HEALTH_CHECK_FAIL;
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
if(!(dpy = (*xopendisplay)(disname))) {
if (!disname) {
disname = (*xdisplayname)(NULL);
}
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "Unable to open display: %s\n", disname);
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
if((Success != xvqueryextension(dpy, &ver, &rev, &reqB, &eventB, &errorB))) {
if (!disname) {
disname = xdisplayname(NULL);
}
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "Unable to open display: %s\n",disname);
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
else {
printf("X-Video Extension version %d.%d\n", ver, rev);
}
/*
* check adaptors, search for one that supports (at least) yuv12
*/
if (Success != xvqueryadaptors(dpy,DefaultRootWindow(dpy),
&adaptors,&adaptor_info)) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "video_out_xv: XvQueryAdaptors failed.\n");
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
if (!adaptor_info) {
set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "video_out_xv: No adaptors found.\n");
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
}
img_formats = xvlistimageformats (dpy, adaptor_info->base_id, &formats);
for(i = 0; i < formats; i++) {
printf ("video_out_xv: Xv image format: 0x%x (%4.4s) %s\n",
img_formats[i].id, (char*)&img_formats[i].id,
(img_formats[i].format == XvPacked) ? "packed" : "planar");
if (img_formats[i].id == XINE_IMGFMT_YV12) {
printf("video_out_xv: this adaptor supports the yv12 format.\n");
set_hc_result (hc, XINE_HEALTH_CHECK_OK, "video_out_xv: this adaptor supports the yv12 format.\n");
} else if (img_formats[i].id == XINE_IMGFMT_YUY2) {
printf("video_out_xv: this adaptor supports the yuy2 format.\n");
set_hc_result (hc, XINE_HEALTH_CHECK_OK, "video_out_xv: this adaptor supports the yuy2 format.\n");
}
}
dlclose(x11_handle);
dlclose(xv_handle);
return hc;
#else
hc->title = "Check for MIT Xv extension";
hc->explanation = "You can improve performance by installing an X11\n"
"driver that supports the Xv protocol extension.";
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "No X-Video Extension was present at compile time");
return hc;
#endif /* ! HAVE_HV */
#else
hc->title = "Check for MIT Xv extension";
hc->explanation = "You can improve performance by installing an X11\n"
"driver that supports the Xv protocol extension.";
set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "No X11 windowing system was present at compile time");
return hc;
#endif /* ! HAVE_X11 */
}
xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) {
switch(check_num) {
case CHECK_KERNEL:
hc = _x_health_check_kernel (hc);
break;
case CHECK_MTRR:
hc = _x_health_check_mtrr (hc);
break;
case CHECK_CDROM:
hc = _x_health_check_cdrom (hc);
break;
case CHECK_DVDROM:
hc = _x_health_check_dvdrom (hc);
break;
case CHECK_DMA:
hc = _x_health_check_dma (hc);
break;
case CHECK_X:
hc = _x_health_check_x (hc);
break;
case CHECK_XV:
hc = _x_health_check_xv (hc);
break;
default:
hc->status = XINE_HEALTH_CHECK_NO_SUCH_CHECK;
}
return hc;
}
#else /* !__linux__ */
xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) {
hc->title = "xine health check not supported on this platform";
hc->explanation = "contact the xine-devel mailing list if you'd like to\n"
"contribute code for your platform.";
set_hc_result(hc, XINE_HEALTH_CHECK_NO_SUCH_CHECK,
"xine health check not supported on the OS.\n");
return hc;
}
#endif /* !__linux__ */
|