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