<commit_before>/*
  Copyright (C) 2002 - 2007 <NAME> <<EMAIL>>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Library General Public License, version 2
  as published by the Free Software Foundation (see file COPYING for details).

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


#include <trurl/nmalloc.h>
#include <trurl/narray.h>
#include <trurl/nassert.h>

#define ENABLE_TRACE 0
#include "tndb_int.h"
#include "tndb.h"


static int st_write_hook_write(const void *buf, size_t size, void *arg) 
{
    struct tndb_sign *sign = arg;
    tndb_sign_update(sign, buf, size);
    return 1;
}

static int st_write_hook_nowrite(const void *buf, size_t size, void *arg) 
{
    struct tndb_sign *sign = arg;
    tndb_sign_update(sign, buf, size);
    return 0;
}

struct tndb *tndb_creat(const char *name, int comprlevel, unsigned flags)
{
    char                path[PATH_MAX], mode[32] = "w+b";
    tn_stream           *st;
    struct tndb         *db = NULL;
    int                 fd, n, type = TN_STREAM_STDIO;
    
    snprintf(path, sizeof(path), "%s.tmpXXXXXX", name);

#ifdef HAVE_MKSTEMP
    fd = mkstemp(path);
#else
    fd = open(path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
#endif
    if (fd < 0)
        return NULL;

    fchmod(fd, 0600);
    
    rmdir(path);
    unlink(path); /* unlink just after create, it's temporary file */

    n = strlen(name);
    if (n > 3 && strcmp(&name[n - 3], ".gz") == 0) {
        type = TN_STREAM_GZIO;
        if (comprlevel >= 0 && comprlevel < 10)
            snprintf(mode, sizeof(mode), "w+b%d", comprlevel);
    }
    
    if ((st = n_stream_dopen(fd, mode, type)) == NULL)
        return NULL;
    
    db = tndb_new(flags);
    db->rtflags |= TNDB_R_MODE_W;
    db->st = st;
    db->path = n_strdupl(path, n);
    
    if (db->hdr.flags & TNDB_SIGN_DIGEST)
        n_stream_set_write_hook(st, st_write_hook_write, &db->hdr.sign);
    
    return db;
}

static inline int put_key(struct tndb *db, const char *key, unsigned int aklen)<commit_msg>Newer zlib (>= 1.3.3.7 for example) reject + as it's not possible to do simultaneous read and write.<commit_after>/*
  Copyright (C) 2002 - 2007 <NAME> <<EMAIL>>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Library General Public License, version 2
  as published by the Free Software Foundation (see file COPYING for details).

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


#include <trurl/nmalloc.h>
#include <trurl/narray.h>
#include <trurl/nassert.h>

#define ENABLE_TRACE 0
#include "tndb_int.h"
#include "tndb.h"


static int st_write_hook_write(const void *buf, size_t size, void *arg) 
{
    struct tndb_sign *sign = arg;
    tndb_sign_update(sign, buf, size);
    return 1;
}

static int st_write_hook_nowrite(const void *buf, size_t size, void *arg) 
{
    struct tndb_sign *sign = arg;
    tndb_sign_update(sign, buf, size);
    return 0;
}

struct tndb *tndb_creat(const char *name, int comprlevel, unsigned flags)
{
    char                path[PATH_MAX], mode[32] = "wb";
    tn_stream           *st;
    struct tndb         *db = NULL;
    int                 fd, n, type = TN_STREAM_STDIO;
    
    snprintf(path, sizeof(path), "%s.tmpXXXXXX", name);

#ifdef HAVE_MKSTEMP
    fd = mkstemp(path);
#else
    fd = open(path, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
#endif
    if (fd < 0)
        return NULL;

    fchmod(fd, 0600);
    
    rmdir(path);
    unlink(path); /* unlink just after create, it's temporary file */

    n = strlen(name);
    if (n > 3 && strcmp(&name[n - 3], ".gz") == 0) {
        type = TN_STREAM_GZIO;
        if (comprlevel >= 0 && comprlevel < 10)
            snprintf(mode, sizeof(mode), "wb%d", comprlevel);
    }
    
    if ((st = n_stream_dopen(fd, mode, type)) == NULL)
        return NULL;
    
    db = tndb_new(flags);
    db->rtflags |= TNDB_R_MODE_W;
    db->st = st;
    db->path = n_strdupl(path, n);
    
    if (db->hdr.flags & TNDB_SIGN_DIGEST)
        n_stream_set_write_hook(st, st_write_hook_write, &db->hdr.sign);
    
    return db;
}

static inline int put_key(struct tndb *db, const char *key, unsigned int aklen)
{'fraction_non_alphanumeric': 0.12430080795525171, 'fraction_numerical': 0.016159105034182723, 'mean_word_length': 2.9638752052545154, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6727893', 'n_tokens_mistral': 1852, 'n_tokens_neox': 1751, 'n_words': 522}