1 /* $Id$
2 The function ul_sort() sorts a file in FIDOUSER.LST format alphabetically
3 (case-insensitive) by sysop name, so that message readers etc. can
4 use a binary search mechanism to look up node numbers by sysop name.
5
6 Note: The file *MUST* be opened in binary mode and SHOULD contain CRLF in
7 DOSish style even on UNIX!!!
8
9 Written 1999 by Tobias Ernst and released to the Public Domain.
10
11 This file is part of NLTOOLS, the nodelist processor of the Husky fidonet
12 software project.
13 */
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <assert.h>
18 #include <stdlib.h>
19
20 #include <huskylib/log.h>
21 #include "nlstring.h"
22 #include "ulc.h"
23
24 #define CACHESIZE 400
25
26 int rl;
27
ulcomp(const void * p1,const void * p2)28 static int ulcomp( const void *p1, const void *p2 )
29 {
30 return ncasecmp( ( const char * ) p1, ( const char * ) p2, rl );
31 }
32
ul_sort(FILE * f)33 int ul_sort( FILE * f )
34 {
35 unsigned long filelen;
36 unsigned long reclen;
37 unsigned long n;
38 void *buffer;
39 char buf[200];
40
41
42 if( fseek( f, 0L, SEEK_END ) )
43 return 0;
44
45 if( ( filelen = ftell( f ) ) == -1 )
46 return 0;
47
48 if( fseek( f, 0L, SEEK_SET ) )
49 return 0;
50
51 if( fgets( buf, sizeof buf, f ) != NULL )
52 {
53 reclen = strlen( buf );
54 }
55 else
56 {
57 return 0;
58 }
59
60 n = filelen / reclen;
61
62 if( ( filelen % reclen ) > 1 ) /* allow for one byte Ctrl+Z garbage */
63 return 0;
64
65 buffer = malloc( n * reclen );
66
67 if( buffer == NULL )
68 {
69 w_log( LL_ERROR, "Out of memory (request for %ld bytes failed).", n * reclen );
70 return 0;
71 }
72
73 if( fseek( f, 0L, SEEK_SET ) )
74 return 0;
75
76 if( fread( buffer, reclen, n, f ) != n )
77 return 0;
78
79 rl = reclen;
80
81 qsort( buffer, n, reclen, ulcomp );
82
83 if( fseek( f, 0L, SEEK_SET ) )
84 return 0;
85
86 if( fwrite( buffer, reclen, n, f ) != n )
87 return 0;
88
89 free( buffer );
90
91 return 1;
92 }
93