Changeset 1558
- Timestamp:
- 02/19/08 00:27:59 (6 months ago)
- Files:
-
- nebula/trunk/Makefile.am (modified) (1 diff)
- nebula/trunk/configure.in (modified) (1 diff)
- nebula/trunk/gst (deleted)
- nebula/trunk/src/Makefile.am (modified) (2 diffs)
- nebula/trunk/src/Makefile.in (added)
- nebula/trunk/src/avl.c (added)
- nebula/trunk/src/avl.h (added)
- nebula/trunk/src/classify.c (added)
- nebula/trunk/src/classify.h (added)
- nebula/trunk/src/cluster.c (modified) (3 diffs)
- nebula/trunk/src/cluster.h (modified) (2 diffs)
- nebula/trunk/src/cstr.c (added)
- nebula/trunk/src/cstr.h (added)
- nebula/trunk/src/hash.c (modified) (2 diffs)
- nebula/trunk/src/hash.h (modified) (1 diff)
- nebula/trunk/src/lca.c (added)
- nebula/trunk/src/lca.h (added)
- nebula/trunk/src/nebula.c (modified) (8 diffs)
- nebula/trunk/src/nebula.h (modified) (1 diff)
- nebula/trunk/src/nebulad.c (added)
- nebula/trunk/src/net.c (added)
- nebula/trunk/src/net.h (added)
- nebula/trunk/src/queue.c (modified) (11 diffs)
- nebula/trunk/src/queue.h (modified) (2 diffs)
- nebula/trunk/src/session.c (added)
- nebula/trunk/src/session.h (added)
- nebula/trunk/src/sig.c (added)
- nebula/trunk/src/sig.h (added)
- nebula/trunk/src/signals.c (modified) (1 diff)
- nebula/trunk/src/stree.c (added)
- nebula/trunk/src/stree.h (added)
- nebula/trunk/src/util.c (modified) (2 diffs)
- nebula/trunk/src/util.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
nebula/trunk/Makefile.am
r1524 r1558 1 1 AUTOMAKE_OPTIONS = foreign 2 2 3 SUBDIRS = src gst3 SUBDIRS = src 4 4 5 5 EXTRA_DIST = ChangeLog LICENSE README nebula/trunk/configure.in
r1524 r1558 37 37 AC_PROG_INSTALL 38 38 AC_CONFIG_FILES([Makefile 39 src/Makefile 40 gst/Makefile]) 39 src/Makefile]) 41 40 42 41 AC_OUTPUT nebula/trunk/src/Makefile.am
r1431 r1558 1 1 AM_CFLAGS=-Wall -Werror 2 2 3 LIBS += -lm 3 LIBS += -lm -lz -lpthread 4 4 5 5 bin_PROGRAMS = nebula … … 12 12 hash.c hash.h \ 13 13 cluster.c cluster.h \ 14 session.c session.h \ 15 net.c net.h \ 16 classify.c classify.h \ 17 avl.c avl.h \ 18 lca.c lca.h \ 19 sig.c sig.h \ 20 cstr.c cstr.h \ 21 stree.c stree.h \ 14 22 nebula.c nebula.h nebula/trunk/src/cluster.c
r1434 r1558 48 48 49 49 /* delete cluster */ 50 void cluster_free(void *cl , u_char list_flag) {50 void cluster_free(void *cl) { 51 51 if (!cl) return; 52 52 53 if (list_flag & list_files) printf("-- Cluster has %u elements\n", (unsigned int) ((cluster *)cl)->hq->size); 54 queue_free(((cluster *)cl)->hq, list_flag & list_files, hash_free); 53 queue_free(((cluster *)cl)->hq, hash_free); 55 54 free(cl); 56 55 … … 71 70 exit(EXIT_FAILURE); 72 71 } 72 cl->cnt++; 73 73 } else { 74 74 if (verbose) fprintf(stderr, "Warning - Could not add hash to cluster queue: Maximum size reached.\n"); … … 103 103 104 104 // unlink and free old cluster 105 queue_free(src->hq, 0,NULL);105 queue_free(src->hq, NULL); 106 106 entry = queue_unlink(q, src->parent); 107 cluster_free(entry->data , 1);107 cluster_free(entry->data); 108 108 free(entry); 109 109 nebula/trunk/src/cluster.h
r1432 r1558 41 41 struct cluster *next; 42 42 queue *hq; 43 43 44 } cluster; 44 45 45 46 46 47 47 inline cluster *cluster_new(void); 48 void cluster_free(void *cl , u_char list_flag);48 void cluster_free(void *cl); 49 49 50 50 inline cluster *create_hashlist(hash *hl1, hash *hl2); … … 52 52 cluster *create_cluster(hash *l1, hash *l2); 53 53 cluster *clusters_merge(queue *q, cluster *dst, cluster *src); 54 void clusterlist_delete(cluster *list , u_char list_files);54 void clusterlist_delete(cluster *list); 55 55 56 56 #endif nebula/trunk/src/hash.c
r1432 r1558 26 26 #include "hash.h" 27 27 #include "nebula.h" 28 #include "session.h" 28 29 29 30 hash *hash_new(void) { … … 37 38 38 39 39 void hash_free(void *h , u_char list_flag) {40 void hash_free(void *h) { 40 41 if (!h) return; 41 42 42 if (list_flag && ((hash *)h)->filename) printf(" %s\n", ((hash *)h)->filename);43 43 free(((hash *)h)->md5sum); 44 ((hash *)h)->md5sum = NULL; 45 ((submission *)((hash *)h)->submission)->md5sum = NULL; 46 44 47 free(((hash *)h)->spamsum); 45 free(((hash *)h)->filename); 48 ((hash *)h)->spamsum = NULL; 49 50 free(((hash *)h)->sha512sum); 51 ((hash *)h)->sha512sum = NULL; 52 53 session_reset(((hash *)h)->submission, NULL); 54 free(((hash *)h)->submission); 55 ((hash *)h)->submission = NULL; 46 56 47 57 if (((hash *)h)->free) ((hash *)h)->free(h); nebula/trunk/src/hash.h
r1432 r1558 30 30 31 31 typedef struct hash { 32 u_int16_t cnt; 33 u_int16_t hashlen; 34 u_int16_t filecnt; 35 char *md5sum; 36 char *spamsum; 37 char *filename; 38 struct cluster *cl; 39 void (*free)(struct hash *h); 32 u_int16_t cnt; 33 u_int16_t hashlen; 34 u_int16_t filecnt; 35 char *md5sum; 36 char *spamsum; 37 char *sha512sum; 38 void *submission; 39 struct cluster *cl; 40 void (*free)(struct hash *h); 40 41 } hash; 41 42 42 43 43 44 hash *hash_new(void); 44 void hash_free(void *cl , u_char list_flag);45 void hash_free(void *cl); 45 46 46 47 #endif nebula/trunk/src/nebula.c
r1435 r1558 23 23 #include <fcntl.h> 24 24 #include <math.h> 25 #include <poll.h> 26 #include <pthread.h> 25 27 #include <stdlib.h> 26 28 #include <stdio.h> … … 32 34 #include <unistd.h> 33 35 36 #include "classify.h" 34 37 #include "cluster.h" 35 38 #include "md5.h" 36 39 #include "nebula.h" 40 #include "net.h" 37 41 #include "ngram.h" 42 #include "session.h" 43 #include "sig.h" 38 44 #include "signals.h" 39 45 #include "spamsum.h" … … 45 51 46 52 53 #define POLLFD_SET_SIZE 10 54 55 47 56 void usage(const char* progname, const int exit_val) { 48 57 printf("Usage: %s " 49 58 " -C <size>\t cluster queue size\n" 59 "\t\t -c <similarity> cluster criteria (a similarity measure in percent)\n" 60 "\t\t -d\t\t daemonize\n" 50 61 "\t\t -E <size>\t cluster element queue size\n" 62 "\t\t -h\t\t show this help\n" 51 63 "\t\t -O <size>\t outlier queue size\n" 52 #ifdef PROFILE 53 "\t\t -a <seconds>\t alarm interval for profiling output\n" 54 #endif 55 "\t\t -c <similarity> cluster criteria (a similarity measure in percent)\n" 56 "\t\t -d <directory>\t process direcory content\n" 57 "\t\t -h\t\t show this help\n" 58 "\t\t -l\t\t list clustered files in result\n" 59 "\t\t -o\t\t list outlier in result\n" 60 "\t\t -p\t\t show progress\n" 61 "\t\t -r\t\t hide result (only calculate cluster)\n" 62 "\t\t -t\t\t sort input files by creation time\n" 64 "\t\t -p <port>\t listen on this port\n" 65 "\t\t -s <secret>\t secret string for use in submissions\n" 63 66 "\t\t -v\t\t be verbose\n" 64 67 "\t\t\t\t [files ...]\n", … … 69 72 70 73 int main(int argc, char *argv[]) { 71 //int j; 72 int i, qsize; 73 u_char time_sort, *content, *tmpbuf; 74 char option, *dirname, *filename; 75 hash *tmp_hash; 76 qelem *cur_cqelem, *tmp_cqelem, *cur_hqelem, *tmp_hqelem; 77 double score; 78 trie_node *t; 79 bstring bstr; 80 int n; 81 82 83 dirname = NULL; 84 namelist = NULL; 74 int i, qsize, port, listen_fd, rv; 75 struct pollfd pfdset[POLLFD_SET_SIZE]; 76 u_char daemonize; 77 char option; 78 submission s[POLLFD_SET_SIZE-1], tmp_submission; 79 pthread_t ntid; 80 81 82 memset(pfdset, 0, sizeof(struct pollfd) * POLLFD_SET_SIZE); 83 memset(s, 0, sizeof(submission) * (POLLFD_SET_SIZE-1)); 84 85 global_sid = 2000000; 85 86 86 87 outlierq = NULL; 87 88 clusterq = NULL; 88 89 content = NULL; 90 num_of_files = 0; 91 num_of_duplicates = 0; 89 aconnq = NULL; 90 92 91 i = 0; 93 92 qsize = 0; 94 total_files = 0;95 #ifdef PROFILE96 alarm_time = 5;97 #endif98 93 99 94 /* default values for parameters */ 100 time_sort = 0; // don't process files chronologically 101 verbose = 0; // don't be verbose 102 hide_result = 0; // show resulting clusters 103 show_progress = 0; // don't show progress dots 104 list_files = 0; // don't list cluster objects 105 list_outlier = 0; // don't list outlier 106 cluster_radius = 95.0; // 95% similarity as cluster criteria 107 outlierq_max = 500000; 108 clusterhashq_max = 500000; 109 clusterq_max = 5000; 95 secret = NULL; // s: NULL 96 daemonize = 0; // d: 0 97 port = 12346; // p: 12345 98 verbose = 0; // v: don't be verbose 99 cluster_radius = 95.0; // c: 95% similarity as cluster criteria 100 outlierq_max = 500000; // O 101 clusterhashq_max = 500000; // E 102 clusterq_max = 5000; // C 110 103 111 104 memset(&md5sum_trie, 0, sizeof(trie_node)); 112 105 memset(&spamsum_trie, 0, sizeof(trie_node)); 113 106 114 printf("\n Nebula %s Copyright (C) 2007 Tillmann Werner <tillmann.werner@gmx.de>\n\n", VERSION); 107 pthread_rwlock_init(&md5sum_trie_lock, NULL); 108 pthread_rwlock_init(&spamsum_trie_lock, NULL); 109 pthread_rwlock_init(&sidlock, NULL); 110 111 printf("\n Nebula %s Copyright (C) 2007-2008 Tillmann Werner <tillmann.werner@gmx.de>\n\n", VERSION); 115 112 116 113 // process args 117 #ifdef PROFILE 118 while((option = getopt(argc, argv, "a:c:C:E:O:rtplovd:h?")) > 0) { 119 #else 120 while((option = getopt(argc, argv, "c:C:E:O:rtplovd:h?")) > 0) { 121 #endif 114 while((option = getopt(argc, argv, "c:C:dE:hO:p:s:v?")) > 0) { 122 115 switch(option) { 123 #ifdef PROFILE124 case 'a':125 alarm_time = atoi(optarg);126 if (alarm_time < 0) {127 fprintf(stderr, "Error - Profile time interval must be a non-negative value (0 means 'off').\n");128 exit(EXIT_FAILURE);129 }130 break;131 #endif132 116 case 'c': 133 117 cluster_radius = atof(optarg); … … 145 129 break; 146 130 case 'd': 147 if (chdir(dirname = optarg) != 0) { 148 fprintf(stderr, "Error - Unable to change into directory %s: %m.\n", dirname); 149 exit(EXIT_FAILURE); 150 } 131 daemonize = 1; 151 132 break; 152 133 case 'E': … … 157 138 } 158 139 break; 159 case 'l':160 list_files = 1;161 break;162 case 'o':163 list_outlier = 1;164 break;165 140 case 'O': 166 141 outlierq_max = atoi(optarg); … … 171 146 break; 172 147 case 'p': 173 show_progress = 1; 174 break; 175 case 'r': 176 hide_result = 1; 177 break; 178 case 't': 179 time_sort = 1; 148 port = atoi(optarg); 149 if (!port || port > 65535) { 150 fprintf(stderr, "Error - Invalid port.\n"); 151 exit(EXIT_FAILURE); 152 } 153 break; 154 case 's': 155 secret = optarg; 180 156 break; 181 157 case 'v': 182 verbose = 1;158 verbose++; 183 159 break; 184 160 case 'h': … … 190 166 } 191 167 192 if (hide_result && list_files) list_files = 0;193 194 168 set_signal_handlers(); 195 169 196 197 // if a directory is given, scan (and sort) its content 198 if (dirname) { 199 printf("Scanning directory... "); 200 fflush(stdout); 201 if (time_sort) { 202 if ((n = scandir(dirname, &namelist, regular_file, timesort)) == -1) { 203 fprintf(stderr, "Error - Unable to read directory entries: %m.\n"); 204 exit(EXIT_FAILURE); 170 // initialize queues 171 outlierq = queue_new(); 172 clusterq = queue_new(); 173 174 175 // bind to port 176 listen_fd = net_listen(port); 177 178 if (!secret) { 179 printf("Warning - No submission secret given.\n"); 180 } else if (verbose) printf("Submission secret: %s\n", secret); 181 182 // process incoming connections 183 printf("[*] Ready.\n"); 184 185 pfdset[0].fd = listen_fd; 186 pfdset[0].events = POLLIN; 187 for(;;) { 188 switch (rv = poll(pfdset, POLLFD_SET_SIZE, -1)) { 189 case -1: 190 fprintf(stderr, "Error with select(): %s.\n", strerror(errno)); 191 exit(1); 192 case 0: 193 break; 194 default: 195 // check listen_fd 196 197 if (pfdset[0].revents) { 198 if (pfdset[0].revents & POLLERR) { 199 fprintf(stderr, "Error - Unable to poll listening socket: %s.\n", strerror(errno)); 200 exit(EXIT_FAILURE); 201 } else if (pfdset[0].revents & POLLHUP) { 202 fprintf(stderr, "Error - Listening socket hangup.\n"); 203 exit(EXIT_FAILURE); 204 } else if (pfdset[0].revents & POLLNVAL) { 205 fprintf(stderr, "Error - Listening socket descriptor is invalid.\n"); 206 exit(EXIT_FAILURE); 207 } 208 209 if (pfdset[0].revents & POLLIN) { 210 // incoming connection, find next free place in poll fd set 211 212 for (i=1; i<POLLFD_SET_SIZE; i++) if (!pfdset[i].events) break; 213 pfdset[i].fd = net_accept(pfdset[0].fd); 214 pfdset[i].events = POLLIN; 215 216 if (verbose) printf("Connection accepted.\n"); 217 } 205 218 } 206 } else { 207 if ((n = scandir(dirname, &namelist, regular_file, alphasort)) == -1) { 208 fprintf(stderr, "Error - Unable to read directory entries: %m.\n"); 209 exit(EXIT_FAILURE); 219 for (i=1; i<POLLFD_SET_SIZE; i++) { 220 if (pfdset[i].revents & POLLIN) { 221 switch (session_handle_data(&pfdset[i], &s[i])) { 222 case 1: 223 // create submission copy so that we can reset the session 224 memcpy(&tmp_submission, &s[i], sizeof(submission)); 225 s[i].secret = NULL; 226 s[i].attack = NULL; 227 s[i].cattack = NULL; 228 s[i].md5sum = NULL; 229 230 // create clustering thread 231 if (pthread_create(&ntid, NULL, pt_classify, (void *) &tmp_submission)) { 232 fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno)); 233 exit(EXIT_FAILURE); 234 } 235 236 // reset session 237 session_reset(&s[i], &pfdset[i]); 238 break; 239 case -1: 240 fprintf(stderr, "Error - Invalid submission state. Terminating session.\n"); 241 break; 242 default: 243 break; 244 } 245 } 210 246 } 211 247 } 212 total_files = n;213 } else {214 if ((argc - optind) < 1) usage(argv[0], EXIT_FAILURE);215 i = optind;216 total_files = argc - i;217 if (time_sort) printf("Only directories (-d) can be processed chronologically (-t).\n");218 248 } 219 249 220 // initialize outlier queue221 outlierq = queue_new();222 clusterq = queue_new();223 224 225 #ifdef PROFILE226 if (alarm_time) {227 alarm(alarm_time);228 printf("Profiling enabled, printing statistics every %d seconds.\n", alarm_time);229 files_in_interval = 0;230 bytes_in_interval = 0;231 checkpoint = 0;232 }233 #endif234 235 printf("processing %u files.\n", (unsigned int) total_files);236 if (!verbose && show_progress) {237 printf("files processed: ");238 fflush(stdout);239 }240 241 242 for (n=0; n<total_files; n++) {243 filename = (dirname ? namelist[n]->d_name : argv[n+i]);244 245 bstr = bstr_map(filename);246 num_of_files++;247 #ifdef PROFILE248 files_in_interval++;249 bytes_in_interval += bstr.len;250 #endif251 252 if (verbose) printf(" processing file %s.\n", filename);253 else if (show_progress) {254 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");255 if (num_of_files < total_files)256 printf("files processed: %05.2f%% (%04u clusters)", num_of_files/total_files*100, (unsigned int) clusterq->size);257 else258 printf("files processed: 100.00%% (%04u clusters)\n", (unsigned int) clusterq->size);259 fflush(stdout);260 }261 262 263 // calculate md5sum264 if ((tmpbuf = (u_char *) mem_md5sum(bstr.data, bstr.len)) == NULL) {265 fprintf(stderr, "Error - Unable to allocate memory: %m.\n");266 exit(EXIT_FAILURE);267 }268 269 if ((t = trie_find_memstr(&md5sum_trie, tmpbuf, strlen((char *)tmpbuf))) != NULL) {270 271 // md5sum is already in trie272 free(tmpbuf);273 ((hash*)t->data)->cnt++;274 if (verbose) printf(" md5sum is %s (%u instances)\n", ((hash*)t->data)->md5sum, ((hash*)t->data)->cnt);275 if (verbose) printf(" absolute match found.\n");276 num_of_duplicates++;277 } else {278 // md5sum not in trie, create new element279 t = trie_memins(&md5sum_trie, tmpbuf, strlen((char *)tmpbuf), NULL);280 if ((t->data = calloc(1, sizeof(hash))) == NULL) {281 fprintf(stderr, "Error - Unable to allocate memory: %m.\n");282 exit(EXIT_FAILURE);283 }284 ((hash*)t->data)->hashlen = 32;285 ((hash*)t->data)->md5sum = (char *) tmpbuf;286 ((hash*)t->data)->cnt++;287 // set filename288 if ((((hash*)t->data)->filename = strdup(filename)) == NULL) {289 fprintf(stderr, "Error - Unable to allocate memory: %m.\n");290 exit(EXIT_FAILURE);291 }292 // set spamsum hash293 if ((((hash*)t->data)->spamsum = spamsum(bstr.data, bstr.len, 0)) == NULL) {294 fprintf(stderr, "Error - Unable to allocate memoory: %m.\n");295 exit(EXIT_FAILURE);296 }297 if (verbose) printf(" md5sum is %s (%u instances)\n", ((hash*)t->data)->md5sum, ((hash*)t->data)->cnt);298 299 // connect all clusters within range300 for (cur_cqelem = clusterq->head; cur_cqelem; cur_cqelem = cur_cqelem->next) {301 for (cur_hqelem = ((cluster *)cur_cqelem->data)->hq->head; cur_hqelem; cur_hqelem = cur_hqelem->next) {302 if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= cluster_radius) {303 if (!((hash*)t->data)->cl) {304 add_entry_to_cluster((cluster *)cur_cqelem->data, (hash*)t->data);305 break;306 } else {307 if ((cluster *) cur_cqelem->data != ((hash*)t->data)->cl)308 clusters_merge(clusterq, (cluster *) cur_cqelem->data, ((hash*)t->data)->cl);309 break;310 }311 }312 }313 }314 315 // connect all outliers within range316 for (cur_hqelem = outlierq->head; cur_hqelem; cur_hqelem = cur_hqelem->next) {317 if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= cluster_radius) {318 // unlink match from outlier list319 tmp_hqelem = cur_hqelem;320 cur_hqelem = cur_hqelem->next;321 if ((tmp_hash = queue_unlink(outlierq, tmp_hqelem)) == NULL) {322 fprintf(stderr, "Error - Unable to unlink outlier from queue.\n");323 exit(EXIT_FAILURE);324 }325 if (((hash*)t->data)->cl) {326 // add other outliers to cluster327 if (add_entry_to_cluster(((hash*)t->data)->cl, tmp_hash) == NULL) {328 trie_del_memstr(&md5sum_trie, (u_char *) tmp_hash->md5sum, strlen(tmp_hash->md5sum));329 trie_del_memstr(&spamsum_trie, (u_char *) tmp_hash->spamsum, strlen(tmp_hash->spamsum));330 hash_free(tmp_hash, 0);331 }332 } else {333 // create new cluster of two outliers334 if ((tmp_cqelem = queue_ins(clusterq, create_cluster(((hash*)t->data), tmp_hash), clusterq_max)) != NULL) {335 /* cluster queue is full, last element was dropped and must be free()d */336 337 /* first remove hashes from tries */338 for (tmp_hqelem = ((cluster *)tmp_cqelem->data)->hq->head; tmp_hqelem; tmp_hqelem = tmp_hqelem->next) {339 trie_del_memstr(&md5sum_trie, (u_char *) ((hash *)tmp_hqelem->data)->md5sum,340 strlen(((hash *)tmp_hqelem->data)->md5sum));341 trie_del_memstr(&spamsum_trie, (u_char *) ((hash *)tmp_hqelem->data)->spamsum,342 strlen(((hash *)tmp_hqelem->data)->spamsum));343 }344 /* now free cluster */345 cluster_free((cluster *)tmp_cqelem->data, 0);346 free(tmp_cqelem);347 }348 /* set cluster element's parent pointer to cluster queue head349 * we need this to be able to unlink a cluster from the queue */350 ((cluster *) clusterq->head->data)->parent = clusterq->head;351 }352 }353 if (!cur_hqelem) break;354 }355 356 357 if (verbose) printf(" spamsum is %s (%u instances)\n", ((hash*)t->data)->spamsum, ((hash*)t->data)->cnt);358 359 if (!((hash*)t->data)->cl) {360 // insert outlier into queue361 if (outlierq->size >= outlierq_max) {362 tmp_hash = queue_unlink(outlierq, outlierq->tail);363 trie_del_memstr(&md5sum_trie, (u_char *) tmp_hash->md5sum, strlen(tmp_hash->md5sum));364 trie_del_memstr(&spamsum_trie, (u_char *) tmp_hash->spamsum, strlen(tmp_hash->spamsum));365 hash_free(tmp_hash, 0);366 }367 queue_ins(outlierq, t->data, outlierq_max);368 }369 }370 bstr_unmap(bstr);371 if (verbose) printf("\n");372 }373 250 374 251 cleanup(); nebula/trunk/src/nebula.h
r1435 r1558 27 27 28 28 #include <sys/types.h> 29 #include <pthread.h> 29 30 31 #include "avl.h" 30 32 #include "cluster.h" 31 33 #include "hash.h" 34 #include "stree.h" 32 35 33 u_char verbose, list_files, list_outlier, show_progress, hide_result; 34 struct dirent **namelist; 36 u_char verbose; 37 char *secret; 38 trie_node spamsum_trie, md5sum_trie; 39 35 40 ssize_t clusterq_max, clusterhashq_max, outlierq_max; 36 u_int32_t num_of_duplicates;37 float num_of_files, total_files;38 41 double cluster_radius; 39 trie_node spamsum_trie, md5sum_trie; 42 40 43 queue *clusterq; 41 44 queue *outlierq; 45 queue *aconnq; 42 46 43 #ifdef PROFILE 44 int alarm_time; // number of seconds for profile output interval 45 float files_in_interval; 46 float bytes_in_interval; 47 u_int32_t checkpoint; 48 #endif 47 pthread_rwlock_t md5sum_trie_lock; 48 pthread_rwlock_t spamsum_trie_lock; 49 49 50 50 #endif nebula/trunk/src/queue.c
r1433 r1558 30 30 qelem *new; 31 31 32 if (!data) return(NULL); 32 if (!q || !data) return(NULL); 33 34 pthread_rwlock_wrlock(&q->lock); 33 35 34 36 if ((new = calloc(1, sizeof(qelem))) == NULL) return(NULL); … … 44 46 q->size++; 45 47 48 pthread_rwlock_unlock(&q->lock); 46 49 return(new); 47 50 } … … 51 54 qelem *new; 52 55 53 if (!data) return(NULL); 56 if (!q || !data) return(NULL); 57 58 pthread_rwlock_wrlock(&q->lock); 54 59 55 60 if ((new = calloc(1, sizeof(qelem))) == NULL) return(NULL); … … 65 70 q->size++; 66 71 72 pthread_rwlock_unlock(&q->lock); 67 73 return(new); 68 74 } … … 72 78 qelem *tmp; 73 79 74 if (q->head == NULL) return(NULL); 80 if (!q || q->head == NULL) return(NULL); 81 82 pthread_rwlock_wrlock(&q->lock); 75 83 76 84 tmp = q->head; … … 80 88 q->size--; 81 89 90 pthread_rwlock_unlock(&q->lock); 82 91 return(tmp); 83 92 } … … 87 96 qelem *tmp; 88 97 89 if (q->tail == NULL) return(NULL); 98 if (!q || q->tail == NULL) return(NULL); 99 100 pthread_rwlock_wrlock(&q->lock); 90 101 91 102 tmp = q->tail; … … 95 106 q->size--; 96 107 108 pthread_rwlock_unlock(&q->lock); 97 109 return(tmp); 98 110 } … … 102 114 qelem* tmp = NULL; 103 115 104 if (! data) return(NULL);116 if (!q || !data) return(NULL); 105 117 106 118 /* need to cut off last queue element? */ … … 124 136 e = queue_cuttail(q); 125 137 } else { 138 pthread_rwlock_wrlock(&q->lock); 139 126 140 e->prev->next = e->next; 127 141 e->next->prev = e->prev; 128 142 if (!q->size--) q->head = q->tail = NULL; 143 144 pthread_rwlock_unlock(&q->lock); 129 145 } 130 146 … … 142 158 exit(EXIT_FAILURE); 143 159 } 160 if (pthread_rwlock_init(&q->lock, NULL) != 0) { 161 fprintf(stderr, "Error - Unable to initialize queue mutex: %m.\n"); 162 exit(EXIT_FAILURE); 163 } 164 144 165 return(q); 145 166 } 146 167 147 168 148 void queue_free(queue *q, u_char list_flag, void(*cbfn)(void *data, u_char list_flag)) {169 void queue_free(queue *q, void(*cbfn)(void *data)) { 149 170 qelem *cur; 150 171 151 172 if (!q) return; 152 173
