Репозиторий ALT Linux backports/2.4
Последнее обновление: 9 июля 2008 | Пакетов: 497 | Посещений: 1574784
 поиск   регистрация   авторизация 
 
Группа :: Система/Ядро и оборудование
Пакет: modutils

 Главная   Изменения   Спек   Патчи   Загрузить   Bugs and FR 

Патч: module-init-tools-3.1-alt-modinfo-legacy.patch


--- module-init-tools/modinfo.c.alt-modinfo-legacy	2004-08-11 05:32:18 +0400
+++ module-init-tools/modinfo.c	2005-01-06 20:27:06 +0300
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <sys/utsname.h>
 #include <sys/mman.h>
 #include "zlibsupport.h"
@@ -115,9 +116,128 @@ static const char *next_string(const cha
 	return string;
 }
 
+static const char *find_tag(const char *tag, const char *info,
+			    unsigned long size)
+{
+	unsigned int taglen = strlen(tag);
+
+	for (; info; info = next_string(info, &size))
+		if (strncmp(info, tag, taglen) == 0 && info[taglen] == '=')
+			return info;
+
+	return NULL;
+}
+
+static void print_legacy_parm(const char *parm_tag, const char *info,
+			      unsigned long size)
+{
+	const char *desc;
+	char *p, *eq, *desc_tag_name, *parm_name;
+	unsigned int name_len;
+	unsigned int min = 1, max = 1;
+
+	eq = strchr(parm_tag, '=');
+	if (!eq)
+		return;
+	if (eq - parm_tag < sizeof("parm_") - 1)
+		return;
+	parm_tag += sizeof("parm_") - 1;
+	name_len = eq - parm_tag;
+
+	desc_tag_name = alloca(name_len + sizeof("parm_desc_"));
+	strcpy(desc_tag_name, "parm_desc_");
+	parm_name = desc_tag_name + sizeof("parm_desc_") - 1;
+	memcpy(parm_name, parm_tag, name_len);
+	parm_name[name_len] = '\0';
+	printf("%s:", parm_name);
+
+	p = eq + 1;
+	if (isdigit(*p)) {
+		min = strtoul(p, &p, 10);
+		if (*p == '-')
+			max = strtoul(p + 1, &p, 10);
+		else
+			max = min;
+	}
+
+	switch (*p) {
+	case 'c':
+		printf("char");
+		if (!isdigit(p[1]))
+			printf(" *** missing string size ***");
+		else {
+			while (isdigit(p[1]))
+				++p;
+		}
+		break;
+
+	case 'b':
+		printf("byte");
+		break;
+	case 'h':
+		printf("short");
+		break;
+	case 'i':
+		printf("int");
+		break;
+	case 'l':
+		printf("long");
+		break;
+	case 's':
+		printf("string");
+		break;
+	case '\0':
+		printf("no format character");
+		return;
+	default:
+		printf("unknown format character '%c'", *p);
+		return;
+	}
+
+	switch (*++p) {
+	case 'p':
+		printf(" persistent");
+		if (p[-1] == 's')
+			printf(" (invalid)");
+		break;
+	case '\0':
+		break;
+	default:
+		printf(" unknown format modifier '%c'", *p);
+		break;
+	}
+
+	if (min > 1 || max > 1)
+		printf(" array (min = %u, max = %u%s)", min, max,
+		       (max < min) ? " [invalid]" : "");
+
+	desc = find_tag(desc_tag_name, info, size);
+	if (desc) {
+		eq = strchr(desc, '=');
+		if (eq)
+			printf(": %s", eq + 1);
+	}
+}
+
+static void print_all_legacy_parms(const char *info, unsigned long size,
+				   char sep)
+{
+	const char *saved_info = info;
+	unsigned long saved_size = size;
+
+	for (; info; info = next_string(info, &size)) {
+		if (strncmp(info, "parm_", 5) == 0
+		    && strncmp(info, "parm_desc_", 10) != 0) {
+			print_legacy_parm(info, saved_info, saved_size);
+			putchar(sep);
+		}
+	}
+}
+
 static void print_tag(const char *tag, const char *info, unsigned long size,
 		      const char *filename, char sep)
 {
+	int legacy_mode = find_tag("vermagic", info, size) == NULL;
 	unsigned int taglen = strlen(tag);
 
 	if (streq(tag, "filename")) {
@@ -125,6 +245,11 @@ static void print_tag(const char *tag, c
 		return;
 	}
 
+	if (legacy_mode && strcmp(tag, "parm") == 0) {
+		print_all_legacy_parms(info, size, sep);
+		return;
+	}
+
 	for (; info; info = next_string(info, &size))
 		if (strncmp(info, tag, taglen) == 0 && info[taglen] == '=')
 			printf("%s%c", info + taglen + 1, sep);
@@ -133,9 +258,44 @@ static void print_tag(const char *tag, c
 static void print_all(const char *info, unsigned long size,
 		      const char *filename, char sep)
 {
+	int legacy_mode = find_tag("vermagic", info, size) == NULL;
+	const char *saved_info = info;
+	unsigned long saved_size = size;
+	int found_kernel_version = 0;
+	int found_using_checksums = 0;
+
 	printf("%-16s%s%c", "filename:", filename, sep);
 	for (; info; info = next_string(info, &size)) {
 		char *eq;
+
+		if (legacy_mode) {
+			/* Old modules had lots of duplicate entries */
+			if (strncmp(info, "kernel_version=",
+				    sizeof("kernel_version=") - 1) == 0) {
+				if (found_kernel_version)
+					continue;
+				found_kernel_version = 1;
+			}
+			if (strncmp(info, "using_checksums=",
+				    sizeof("using_checksums=") - 1) == 0) {
+				if (found_using_checksums)
+					continue;
+				found_using_checksums = 1;
+			}
+		}
+
+		if (legacy_mode && strncmp(info, "parm_", 5) == 0) {
+			if (strncmp(info, "parm_desc_", 10) == 0)
+				continue;
+			if (!sep)
+				printf("parm=");
+			else
+				printf("%-16s", "parm:");
+			print_legacy_parm(info, saved_info, saved_size);
+			putchar(sep);
+			continue;
+		}
+
 		if (!sep) {
 			printf("%s%c", info, sep);
 			continue;
 
design & coding: Vladimir Lettiev aka crux © 2004-2005