Browse code

initial version of update script generator

git-svn: trunk@2049

Tomasz Kojm authored on 2006/06/28 07:02:59
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Jun 28 00:00:50 CEST 2006 (tk)
2
+----------------------------------
3
+  * sigtool: --diff: initial version of update script generator
4
+
1 5
 Mon Jun 26 20:23:22 CEST 2006 (tk)
2 6
 ----------------------------------
3 7
   * libclamav: allow wildcarded prefix when signature contains static
... ...
@@ -929,6 +929,212 @@ static int runcdiff(struct optstruct *opt)
929 929
     return ret;
930 930
 }
931 931
 
932
+static int compare(const char *oldpath, const char *newpath, FILE *diff)
933
+{
934
+	FILE *old, *new;
935
+	char obuff[1024], nbuff[1024], *pt, *omd5, *nmd5;
936
+	unsigned int line = 0;
937
+
938
+
939
+    if(!(new = fopen(newpath, "r"))) {
940
+	mprintf("!compare: Can't open file %s for reading\n", newpath);
941
+	return -1;
942
+    }
943
+
944
+    if((omd5 = cli_md5file(oldpath))) {
945
+	if(!(nmd5 = cli_md5file(newpath))) {
946
+	    mprintf("!compare: Can't get MD5 checksum of %s\n", newpath);
947
+	    free(omd5);
948
+	    return -1;
949
+	}
950
+	if(!strcmp(omd5, nmd5)) {
951
+	    free(omd5);
952
+	    free(nmd5);
953
+	    return 0;
954
+	}
955
+	free(omd5);
956
+	free(nmd5);
957
+    }
958
+
959
+    fprintf(diff, "OPEN %s\n", newpath);
960
+
961
+    old = fopen(oldpath, "r");
962
+
963
+    while(fgets(nbuff, sizeof(nbuff), new)) {
964
+	line++;
965
+	cli_chomp(nbuff);
966
+
967
+	if(!old) {
968
+	    fprintf(diff, "ADD %s\n", nbuff);
969
+	} else {
970
+	    if(fgets(obuff, sizeof(obuff), old)) {
971
+		cli_chomp(obuff);
972
+		if(!strcmp(nbuff, obuff)) {
973
+		    continue;
974
+		} else {
975
+		    /* TODO: Improve/add detection of DEL, XCHG */
976
+		    if(!strncmp(nbuff, obuff, 5)) {
977
+			obuff[8] = 0;
978
+			if((pt = strchr(obuff, ' ')))
979
+			    *pt = 0;
980
+			fprintf(diff, "XCHG %u %s %s\n", line, obuff, nbuff);
981
+		    }
982
+		}
983
+	    } else {
984
+		fclose(old);
985
+		old = NULL;
986
+		fprintf(diff, "ADD %s\n", nbuff);
987
+	    }
988
+	}
989
+    }
990
+
991
+    if(old)
992
+	fclose(old);
993
+    fprintf(diff, "CLOSE\n");
994
+    return 0;
995
+}
996
+
997
+static int makediff(struct optstruct *opt)
998
+{
999
+	FILE *diff;
1000
+	DIR *dd;
1001
+	struct dirent *dent;
1002
+	char *odir, *ndir, opath[1024], name[32];
1003
+	struct cl_cvd *cvd;
1004
+	unsigned int oldver, newver;
1005
+
1006
+
1007
+    if(!opt->filename) {
1008
+	mprintf("!makediff: --diff requires two arguments\n");
1009
+	return -1;
1010
+    }
1011
+
1012
+    if(!(cvd = cl_cvdhead(opt->filename))) {
1013
+	mprintf("!makediff: Can't read CVD header from %s\n", opt->filename);
1014
+	return -1;
1015
+    }
1016
+    newver = cvd->version;
1017
+    free(cvd);
1018
+
1019
+    if(!(cvd = cl_cvdhead(opt_arg(opt, "diff")))) {
1020
+	mprintf("!makediff: Can't read CVD header from %s\n", opt_arg(opt, "diff"));
1021
+	return -1;
1022
+    }
1023
+    oldver = cvd->version;
1024
+    free(cvd);
1025
+
1026
+    if(oldver + 1 != newver) {
1027
+	mprintf("!makediff: The old CVD must be %u\n", newver - 1);
1028
+	return -1;
1029
+    }
1030
+
1031
+    odir = cli_gentemp(NULL);
1032
+    if(!odir) {
1033
+	mprintf("!makediff: Can't generate temporary name for odir\n");
1034
+	return -1;
1035
+    }
1036
+
1037
+    if(mkdir(odir, 0700) == -1) {
1038
+	mprintf("!makediff: Can't create directory %s\n", odir);
1039
+	free(odir);
1040
+	return -1;
1041
+    }
1042
+
1043
+    if(cvd_unpack(opt_arg(opt, "diff"), odir) == -1) {
1044
+	mprintf("!makediff: Can't unpack CVD file %s\n", opt_arg(opt, "diff"));
1045
+	rmdirs(odir);
1046
+	free(odir);
1047
+	return -1;
1048
+    }
1049
+
1050
+    ndir = cli_gentemp(NULL);
1051
+    if(!ndir) {
1052
+	mprintf("!makediff: Can't generate temporary name for ndir\n");
1053
+	rmdirs(odir);
1054
+	free(odir);
1055
+	return -1;
1056
+    }
1057
+
1058
+    if(mkdir(ndir, 0700) == -1) {
1059
+	mprintf("!makediff: Can't create directory %s\n", ndir);
1060
+	free(ndir);
1061
+	rmdirs(odir);
1062
+	free(odir);
1063
+	return -1;
1064
+    }
1065
+
1066
+    if(cvd_unpack(opt->filename, ndir) == -1) {
1067
+	mprintf("!makediff: Can't unpack CVD file %s\n", opt->filename);
1068
+	rmdirs(odir);
1069
+	rmdirs(ndir);
1070
+	free(odir);
1071
+	free(ndir);
1072
+	return -1;
1073
+    }
1074
+
1075
+    if(strstr(opt->filename, "main"))
1076
+	snprintf(name, sizeof(name), "main-%u.cdiff", newver);
1077
+    else
1078
+	snprintf(name, sizeof(name), "daily-%u.cdiff", newver);
1079
+
1080
+    if(!(diff = fopen(name, "w"))) {
1081
+        mprintf("!makediff: Can't open %s for writing\n", name);
1082
+	rmdirs(odir);
1083
+	rmdirs(ndir);
1084
+	free(odir);
1085
+	free(ndir);
1086
+	return -1;
1087
+    }
1088
+
1089
+    if(chdir(ndir) == -1) {
1090
+	mprintf("!makediff: Can't chdir to %s\n", ndir);
1091
+	rmdirs(odir);
1092
+	rmdirs(ndir);
1093
+	free(odir);
1094
+	free(ndir);
1095
+	fclose(diff);
1096
+	return -1;
1097
+    }
1098
+
1099
+    if((dd = opendir(ndir)) == NULL) {
1100
+        mprintf("!makediff: Can't open directory %s\n", ndir);
1101
+	rmdirs(odir);
1102
+	rmdirs(ndir);
1103
+	free(odir);
1104
+	free(ndir);
1105
+	fclose(diff);
1106
+	return -1;
1107
+    }
1108
+
1109
+    while((dent = readdir(dd))) {
1110
+#ifndef C_INTERIX
1111
+	if(dent->d_ino)
1112
+#endif
1113
+	{
1114
+	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
1115
+		continue;
1116
+
1117
+	    snprintf(opath, sizeof(opath), "%s/%s", odir, dent->d_name);
1118
+	    if(compare(opath, dent->d_name, diff) == -1) {
1119
+		rmdirs(odir);
1120
+		rmdirs(ndir);
1121
+		free(odir);
1122
+		free(ndir);
1123
+		fclose(diff);
1124
+		unlink(name);
1125
+		return -1;
1126
+	    }
1127
+	}
1128
+    }
1129
+
1130
+    fclose(diff);
1131
+    rmdirs(odir);
1132
+    rmdirs(ndir);
1133
+    free(odir);
1134
+    free(ndir);
1135
+    return 0;
1136
+}
1137
+
932 1138
 void help(void)
933 1139
 {
934 1140
     mprintf("\n");
... ...
@@ -954,6 +1160,7 @@ void help(void)
954 954
     mprintf("    --vba=FILE                             Extract VBA/Word6 macro code\n");
955 955
     mprintf("    --vba-hex=FILE                         Extract Word6 macro code with hex values\n");
956 956
     mprintf("    --vba-hex=FILE                         Extract Word6 macro code with hex values\n");
957
+    mprintf("    --diff=OLD NEW         -d OLD NEW      Create diff for OLD and NEW CVDs\n");
957 958
     mprintf("    --run-cdiff=FILE       -r FILE         Execute update script FILE in cwd\n");
958 959
     mprintf("\n");
959 960
 
... ...
@@ -964,7 +1171,7 @@ int main(int argc, char **argv)
964 964
 {
965 965
 	int ret = 1;
966 966
         struct optstruct *opt;
967
-	const char *short_options = "hvVb:i:u:l::r:";
967
+	const char *short_options = "hvVb:i:u:l::r:d:";
968 968
 	static struct option long_options[] = {
969 969
 	    {"help", 0, 0, 'h'},
970 970
 	    {"quiet", 0, 0, 0},
... ...
@@ -984,6 +1191,7 @@ int main(int argc, char **argv)
984 984
 	    {"list-sigs", 2, 0, 'l'},
985 985
 	    {"vba", 1, 0 ,0},
986 986
 	    {"vba-hex", 1, 0, 0},
987
+	    {"diff", 1, 0, 'd'},
987 988
 	    {"run-cdiff", 1, 0, 'r'},
988 989
 	    {0, 0, 0, 0}
989 990
     	};
... ...
@@ -1033,6 +1241,8 @@ int main(int argc, char **argv)
1033 1033
 	ret = listsigs(opt);
1034 1034
     else if(opt_check(opt, "vba") || opt_check(opt, "vba-hex"))
1035 1035
 	ret = vbadump(opt);
1036
+    else if(opt_check(opt, "diff"))
1037
+	ret = makediff(opt);
1036 1038
     else if(opt_check(opt, "run-cdiff"))
1037 1039
 	ret = runcdiff(opt);
1038 1040
     else