2 * $Id: buildindex.c,v 1.2 1999/02/14 09:50:42 dirk Exp $
4 * This file is part of WorkMan, the civilized CD player library
5 * (c) 1991-1997 by Steven Grimm (original author)
6 * (c) by Dirk Försterling (current 'author' = maintainer)
7 * The maintainer can be contacted by his e-mail address:
8 * milliByte@DeathsDoor.com
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Build a WorkMan database index file from a flat text file. Requires
26 * 4.4BSD libdb library.
29 static char buildindex_id
[] = "$Id: buildindex.c,v 1.2 1999/02/14 09:50:42 dirk Exp $";
35 #include <netinet/in.h> /* for htonl() */
36 #include <sys/types.h>
37 #include <sys/param.h>
41 static char buildindex_id
[]="$Id: buildindex.c,v 1.2 1999/02/14 09:50:42 dirk Exp $";
52 int lock
= 1, i
= 0, locked
, frame
;
53 char buf
[1000], indname
[MAXPATHLEN
+ 100], framebuf
[8], *c
;
58 if (argc
> 2 && !strcmp(argv
[1], "-n"))
66 fprintf(stderr
, "Usage: %s [-n] dbfile [dbfile ...]\n",
72 data
.size
= sizeof(pos
);
74 key
.size
= 7; /* %07d */
78 fprintf(stderr
, "Building index for %s\n", argv
[i
]);
80 if ((fp
= fopen(argv
[i
], "r")) == NULL
)
87 * Figure out the file's mode, uid, gid, so we can set the
88 * permissions on the index file to the same thing.
90 if (fstat(fileno(fp
), &st
))
92 sprintf(indname
, "%s: fstat", argv
[i
]);
98 if (lock
&& lockit(fileno(fp
), F_WRLCK
))
100 sprintf(indname
, "%s: Warning: Couldn't lock", argv
[i
]);
108 * Create a database file.
110 bt
.flags
= R_DUP
; /* allow duplicate keys */
115 bt
.compare
= NULL
; /* use lexical comparison */
116 bt
.prefix
= NULL
; /* no prefix comparisons */
118 /* Index files have ".ind" extensions */
119 sprintf(indname
, "%s.ind", argv
[i
]);
120 if ((db
= dbopen(indname
, O_CREAT
| O_RDWR
| O_TRUNC
,
121 st
.st_mode
, DB_BTREE
, &bt
)) == NULL
)
125 lockit(fileno(fp
), F_UNLCK
);
131 * Now loop through the text file, inserting a record into
132 * the index file for each "tracks" line.
138 if (fgets(buf
, sizeof(buf
), fp
) == NULL
|| ! buf
[0])
144 /* Nope. A read error. Unlink the database. */
146 (void) unlink(indname
);
150 if (strncmp(buf
, "tracks ", 7))
154 * Found the start of a record. Figure out the start
155 * time of the last track and put an entry in the
156 * index file with that as the key.
158 c
= strrchr(buf
, ' '); /* this will always succeed */
160 c
= strrchr(buf
, ' '); /* this should too, but... */
164 "%s: Malformed tracks line at %lu\n",
168 sscanf(c
+1, "%d", &frame
);
169 sprintf(framebuf
, "%07d", frame
);
172 if ((db
->put
)(db
, &key
, &data
, 0))
183 (void) (db
->close
)(db
);
185 lockit(fileno(fp
), F_UNLCK
);
190 * Lock a file. Time out after a little while if we can't get a lock;
191 * this usually means the locking system is broken.
193 * Unfortunately, if there are lots of people contending for a lock,
194 * this can result in the file not getting locked when it probably should.
202 int result
, timer
= 0;
209 while ((result
= fcntl(fd
, F_SETLK
, &fl
)) < 0)
211 if (errno
!= EACCES
|| errno
!= EAGAIN
)