int main (int argc, char *argv[]) { static const struct option options[] = { {"help", no_argument, NULL, 'h'}, {} }; int fd = 0; char *device; struct v4l2_capability v2cap; char cap_str[4097]; memset (cap_str, 0, 4097); for (;;) { int option; option = getopt_long (argc, argv, "h", options, NULL); if (option == -1) { break; } switch (option) { case 'h': printf ("%s [-h,--help] <device file>\n\n" "Video4Linux device identification.\n\n" " -h Print this message\n", argv[0]); return 0; default: return 1; } } device = argv[optind]; if (device == NULL) { return 2; } fd = open (device, O_RDONLY); if (fd < 0) { return 3; } if (ioctl (fd, VIDIOC_QUERYCAP, &v2cap) == 0) { vdev_property_add ("VDEV_V4L_VERSION", "2"); vdev_property_add ("VDEV_V4L_PRODUCT", (char *) v2cap.card); strcat (cap_str, ":"); if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0) { strcat (cap_str, "capture:"); } if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0) { strcat (cap_str, "video_output:"); } if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0) { strcat (cap_str, "video_overlay:"); } if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0) { strcat (cap_str, "audio:"); } if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0) { strcat (cap_str, "tuner:"); } if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0) { strcat (cap_str, "radio:"); } vdev_property_add ("VDEV_V4L_CAPABILITIES", cap_str); } close (fd); vdev_property_print (); vdev_property_free_all (); return 0; }
int main( int argc, char** argv ) { if( argc != 2 ) { usage( argv[0] ); } char* next_bus = NULL; char subsystem_list[ 4097 ]; char subsystem_list_uniq[ 4097 ]; char* delim = NULL; char* subsystem_buf = (char*)calloc( strlen(argv[1]) + strlen("/subsystem") + 1, 1 ); char readlink_buf[ 4097 ]; int rc = 0; struct stat sb; if( subsystem_buf == NULL ) { exit(1); } next_bus = argv[1]; memset( subsystem_list, 0, 4097 ); memset( subsystem_list_uniq, 0, 4097 ); // directory must exist rc = stat( next_bus, &sb ); if( rc != 0 ) { exit(1); } while( 1 ) { // what's the subsystem here? sprintf( subsystem_buf, "%s/subsystem", next_bus ); rc = lstat( subsystem_buf, &sb ); if( rc != 0 ) { rc = remove_child( next_bus ); if( rc != 0 ) { break; } else { continue; } } if( !S_ISLNK( sb.st_mode ) ) { rc = remove_child( next_bus ); if( rc != 0 ) { break; } else { continue; } } memset( readlink_buf, 0, 4097 ); rc = readlink( subsystem_buf, readlink_buf, 4096 ); if( rc < 0 ) { rc = remove_child( next_bus ); if( rc != 0 ) { break; } else { continue; } } delim = strrchr( readlink_buf, '/' ); if( delim == NULL ) { rc = remove_child( next_bus ); if( rc != 0 ) { break; } else { continue; } } // delim + 1 is the subsystem name if( subsystem_list[0] != 0 ) { strncat( subsystem_list, ",", 4096 - strlen(subsystem_list) - 1 ); } strncat( subsystem_list, delim + 1, 4096 - strlen(subsystem_list) - 1 ); if( strstr( subsystem_list_uniq, delim + 1 ) == NULL ) { // haven't seen this subsystem name before... if( subsystem_list_uniq[0] != 0 ) { strncat( subsystem_list_uniq, ",", 4096 - strlen(subsystem_list_uniq) - 1 ); } strncat( subsystem_list_uniq, delim + 1, 4096 - strlen(subsystem_list_uniq) - 1 ); } rc = remove_child( next_bus ); if( rc != 0 ) { break; } else { continue; } } free( subsystem_buf ); vdev_property_add( "VDEV_BUS_SUBSYSTEMS", subsystem_list ); vdev_property_add( "VDEV_BUS_SUBSYSTEMS_UNIQ", subsystem_list_uniq ); vdev_property_print(); vdev_property_free_all(); exit(0); }