Logo Search packages:      
Sourcecode: dctc version File versions  Download package

ls_cache.c

/* DCTC - a Direct Connect text clone for Linux
 * Copyright (C) 2001 Eric Prevoteau
 *
 * ls_cache.c: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
$Id: ls_cache.c,v 1.3 2003/12/28 08:12:38 uid68112 Exp $
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_ZLIB
#include <zlib.h>
#endif
#include <glib.h>

#include "display.h"
#include "ls_cache.h"
#include "var.h"

/*************************************/
/* save /LS result in the cache file */
/********************************************************************/
/* input: nickname= the nickname of the user having this share list */
/*        ls_content= the formatted result of /LS                   */
/*        ttl_size= size of the shared files.                       */
/********************************************************************/
/* output: 0=ok, 1=error */
/*************************/
int save_ls_file(char *nickname,GString *ls_content, guint64 ttl_size)
{
      FILE *f;
      GString *filename;
      int ret_value=1;        /* default: error */

      filename=g_string_new(dctc_ls_cache_dir->str);
      g_string_append(filename,nickname);
      if(strchr(nickname,'/')!=NULL)                  /* there is only 1 forbidden character */
      {
            int i;

            i=dctc_ls_cache_dir->len;
            while(i<filename->len)
            {
                  if(filename->str[i]=='/')
                        filename->str[i]='$';
                  i++;
            }
      }

      f=fopen(filename->str,"wb");
      if(f!=NULL)
      {
            LS_CACHE_HEADER lsch;
#ifdef HAVE_ZLIB
            unsigned long tsize;
            unsigned char *pack_area=NULL;
#endif

            lsch.ls_magic=LS_CACHE_MAGIC;
            lsch.unpacked_size=ls_content->len;
            lsch.retrieve_time=time(NULL);
            lsch.share_size=ttl_size;

#ifdef HAVE_ZLIB
            /* size of the temporary pack area: zlib.h says 12bytes + 1.001*original file size, I use 12 bytes + 1.0625*original file size */
            tsize=12+lsch.unpacked_size+lsch.unpacked_size/16;
            pack_area=malloc(tsize);
            if(pack_area!=NULL)
            {
                  if(compress2(pack_area,&tsize,ls_content->str,ls_content->len,9)!=Z_OK) /* use the best compression level */
                  {
                        free(pack_area);
                        goto no_packing;
                  }
                  lsch.packed_size=tsize;
                  lsch.pack_algorithm=LS_CACHE_PACK_BZIP;

                  if( (fwrite(&lsch,1,sizeof(LS_CACHE_HEADER),f)!=sizeof(LS_CACHE_HEADER)) ||
                        (fwrite(pack_area,1,tsize,f)!=tsize) )
                  {
                        disp_msg(ERR_MSG,"save_ls_file","Write fail for LScache file ","|s",filename->str,": ","|s",strerror(errno),NULL);
                        free(pack_area);
                        fclose(f);
                        unlink(filename->str);
                        goto abrt;
                  }
                  free(pack_area);
            }
            else
#endif
            {
#ifdef HAVE_ZLIB
                  no_packing:
#endif
                  lsch.packed_size=lsch.unpacked_size;
                  lsch.pack_algorithm=LS_CACHE_PACK_NONE;

                  if( (fwrite(&lsch,1,sizeof(LS_CACHE_HEADER),f)!=sizeof(LS_CACHE_HEADER)) ||
                        (fwrite(ls_content->str,1,ls_content->len,f)!=ls_content->len) )
                  {
                        disp_msg(ERR_MSG,"save_ls_file","Write fail for LScache file ","|s",filename->str,": ","|s",strerror(errno),NULL);
                        fclose(f);
                        unlink(filename->str);
                        goto abrt;
                  }
            }

            fclose(f);
            ret_value=0;
      }
      else
      {
            disp_msg(ERR_MSG,"save_ls_file","Unable to create LScache file ","|s",filename->str,": ","|s",strerror(errno),NULL);
      }

      abrt:
      g_string_free(filename,TRUE);
      return ret_value;
}

/***************************************/
/* load /LS result from the cache file */
/********************************************************************/
/* input: nickname= the nickname of the user having this share list */
/*        ttl_size= variable to set to the size of the shared files.*/
/************************************************************************/
/* output: the content (to free with free() when no more useful or NULL */
/************************************************************************/
char *load_ls_file(char *nickname, guint64 *ttl_size)
{
      FILE *f;
      GString *filename;
      char *ret=NULL;

      filename=g_string_new(dctc_ls_cache_dir->str);
      filename=g_string_append(filename,nickname);

      f=fopen(filename->str,"rb");
      if(f!=NULL)
      {
            LS_CACHE_HEADER lsch;

            /* read LS cache header */
            if(fread(&lsch,1,sizeof(LS_CACHE_HEADER),f)!=sizeof(LS_CACHE_HEADER))
            {
                  disp_msg(ERR_MSG,"load_ls_file","Truncated LScache file ","|s",filename->str,": ","|s",strerror(errno),NULL);
                  fclose(f);
                  goto abrt;
            }

            /* valid magic ? */
            if(lsch.ls_magic!=LS_CACHE_MAGIC)
            {     
                  disp_msg(ERR_MSG,"load_ls_file","Not a LScache file ","|s",filename->str,NULL);
                  fclose(f);
                  goto abrt;
            }

            switch(lsch.pack_algorithm)
            {
                  case LS_CACHE_PACK_NONE:            /* result no compressed */
                                                                  ret=malloc(lsch.unpacked_size+1);
                                                                  if(ret==NULL)
                                                                  {
                                                                        disp_msg(ERR_MSG,"load_ls_file","Out of memory",NULL);
                                                                        fclose(f);
                                                                        goto abrt;
                                                                  }

                                                                  if(fread(ret,1,lsch.unpacked_size,f)!=lsch.unpacked_size)
                                                                  {
                                                                        disp_msg(ERR_MSG,"load_ls_file","truncated file",NULL);
                                                                        fclose(f);
                                                                        free(ret);
                                                                        ret=NULL;
                                                                        goto abrt;
                                                                  }
                                                                  fclose(f);
                                                                  ret[lsch.unpacked_size]='\0';
                                                                  break;

#ifdef HAVE_ZLIB
                  case LS_CACHE_PACK_BZIP:
                                                                  {
                                                                        char *pack_area;
                                                                        unsigned long upack;
                                                                        pack_area=malloc(lsch.packed_size);
                                                                        if(pack_area==NULL)
                                                                        {
                                                                              disp_msg(ERR_MSG,"load_ls_file","Out of memory",NULL);
                                                                              fclose(f);
                                                                              goto abrt;
                                                                        }
                                                                        if(fread(pack_area,1,lsch.packed_size,f)!=lsch.packed_size)
                                                                        {
                                                                              disp_msg(ERR_MSG,"load_ls_file","truncated file",NULL);
                                                                              fclose(f);
                                                                              free(pack_area);
                                                                              goto abrt;
                                                                        }
                                                                        fclose(f);

                                                                        ret=malloc(lsch.unpacked_size+1);
                                                                        if(ret==NULL)
                                                                        {
                                                                              disp_msg(ERR_MSG,"load_ls_file","Out of memory",NULL);
                                                                              free(pack_area);
                                                                              goto abrt;
                                                                        }

                                                                        upack=lsch.unpacked_size;
                                                                        if(uncompress(ret,&upack,pack_area,lsch.packed_size)!=Z_OK)
                                                                        {
                                                                              disp_msg(ERR_MSG,"load_ls_file","Fail to uncompress LS cache file",NULL);
                                                                              free(pack_area);
                                                                              free(ret);
                                                                              ret=NULL;
                                                                              goto abrt;
                                                                        }

                                                                        free(pack_area);
                                                                        if(upack!=lsch.unpacked_size)
                                                                        {
                                                                              disp_msg(ERR_MSG,"load_ls_file","Invalid uncompress result",NULL);
                                                                              free(ret);
                                                                              ret=NULL;
                                                                              goto abrt;
                                                                        }
                                                                        ret[lsch.unpacked_size]='\0';
                                                                  }
                                                                  break;
#endif

                  default:
                                                                  disp_msg(ERR_MSG,"load_ls_file","Unknown encoding scheme",NULL);
                                                                  fclose(f);
                                                                  break;
            }
      }
      else
      {
            disp_msg(ERR_MSG,"load_ls_file","Unable to open LScache file ","|s",filename->str,": ","|s",strerror(errno),NULL);
      }

      abrt:
      g_string_free(filename,TRUE);
      return ret;
}


Generated by  Doxygen 1.6.0   Back to index