Thanks Carlos and Stas for your thoughts.  Indeed, the code in
newplayer() simply seeks to the end of file (SEEK_END), and so if
anything ever adds something that is not sizeof(struct statentry) then
new entries will be added with wrong alignment, and are thus not

I agree, I'll need to find the point of departure in the .players file
and truncate it at that point.

I'm also considering this change for the future; it detects an end of
file offset that isn't a multiple of struct statentry, and blindly
truncates downwards.

int newplayer(struct statentry *player)
  int fd, offset, position;

  ERROR(8,("db.c: newplayer: adding '%s'\n", player->name));
  fd = open(PlayerFile, O_RDWR|O_CREAT, 0644);
  if (fd < 0) return -1;
  if ((offset = lseek(fd, 0, SEEK_END)) < 0) return -1;
  position = offset / sizeof(struct statentry);
  if ((offset % sizeof(struct statentry)) != 0) {
    ERROR(1,("db.c: newplayer: SEEK_END not multiple of struct statentry, truncating down\n"));
    offset = position * sizeof(struct statentry);
    if ((offset = lseek(fd, position, SEEK_SET)) < 0) return -1;
  write(fd, (char *) player, sizeof(struct statentry));
  ERROR(8,("db.c: newplayer: sizeof '%d' offset '%d' position '%d'\n", 
	   sizeof(struct statentry), offset, position));
  return position;

On Thu, Dec 23, 2004 at 02:15:10AM +0200, Stas Pirogov wrote:
> Even if it isn't the case it would be better (IMO) to get rid
> of direct access to file and just use some kind of hash database
> instead (same dbm as used for indexes ?).

Yes, I've thought about that, but the problem is that writes to the file
can be done by either the daemon (on ghostbust) or ntserv (on death).
Whatever method is chosen might need some way to prevent accidental
simultaneous access; currently the lseek() and write() handles that
reasonably well; last writer wins.

James Cameron    mailto:quozl at

vanilla-devel mailing list
vanilla-devel at