Exemplo n.º 1
0
void SG_vfile__end(
	SG_context* pCtx,
	SG_vfile** ppvf,
	const SG_vhash* pvh
	)
{
	SG_string* pstr = NULL;
	SG_vfile* pvf = NULL;

	SG_NULLARGCHECK_RETURN(ppvf);

	pvf = *ppvf;

	if (pvh)
	{
		SG_ARGCHECK_RETURN( !(pvf->mode & SG_FILE_RDONLY) , pvh );

		SG_ERR_CHECK(  SG_STRING__ALLOC(pCtx, &pstr)  );

		SG_ERR_CHECK(  SG_vhash__to_json(pCtx, pvh,pstr)  );

		SG_ERR_CHECK(  SG_file__seek(pCtx, pvf->pFile, 0)  );

		SG_ERR_CHECK(  SG_file__truncate(pCtx, pvf->pFile)  );

#if TRACE_VFILE
		SG_ERR_IGNORE(  SG_console(pCtx, SG_CS_STDERR, "VFileEnd: Writing %d bytes to file.\n",
								   SG_string__length_in_bytes(pstr))  );
#endif

		SG_ERR_CHECK(  SG_file__write(pCtx, pvf->pFile, SG_string__length_in_bytes(pstr), (const SG_byte *)SG_string__sz(pstr), NULL)  );
		SG_STRING_NULLFREE(pCtx, pstr);
	}
	else
	{
		if (!(pvf->mode & SG_FILE_RDONLY))
		{
			SG_ERR_CHECK(  SG_file__seek(pCtx, pvf->pFile, 0)  );

			SG_ERR_CHECK(  SG_file__truncate(pCtx, pvf->pFile)  );

#if TRACE_VFILE
			SG_ERR_IGNORE(  SG_console(pCtx, SG_CS_STDERR, "VFileEnd: Truncating file.\n")  );
#endif
		}
	}

	SG_FILE_NULLCLOSE(pCtx, pvf->pFile);

	SG_NULLFREE(pCtx, pvf);
	*ppvf = NULL;

	return;
fail:
	SG_STRING_NULLFREE(pCtx, pstr);
}
static int _my_seek__file(void *instream, curl_off_t offset, int origin)
{
	_sg_curl* pMe = (_sg_curl*)instream;

	if (origin == SEEK_SET)
	{
		SG_context__push_level(pMe->pCtx);
		SG_log__report_verbose(pMe->pCtx, "SG_curl handling SEEK_SET.");
		SG_context__pop_level(pMe->pCtx);

		SG_file__seek(pMe->pCtx, pMe->readState.pFile, (SG_uint64)offset);
		if(SG_context__has_err(pMe->pCtx))
			return CURL_SEEKFUNC_FAIL;

		pMe->readState.pos = (SG_uint64)offset;
		pMe->readState.finished = SG_FALSE;
		return CURL_SEEKFUNC_OK;
	}
	else if (origin == SEEK_CUR)
	{
		SG_uint64 new_pos = (SG_uint64)((SG_int64)pMe->readState.pos+(SG_int64)offset);

		SG_context__push_level(pMe->pCtx);
		SG_log__report_verbose(pMe->pCtx, "SG_curl handling SEEK_CUR.");
		SG_context__pop_level(pMe->pCtx);

		SG_file__seek(pMe->pCtx, pMe->readState.pFile, new_pos);
		if(SG_context__has_err(pMe->pCtx))
			return CURL_SEEKFUNC_FAIL;

		pMe->readState.pos = new_pos;
		pMe->readState.finished = SG_FALSE;
		return CURL_SEEKFUNC_OK;
	}
	else if (origin == SEEK_END)
	{
		SG_uint64 new_pos = (SG_uint64)((SG_int64)pMe->readState.len+(SG_int64)offset);

		SG_context__push_level(pMe->pCtx);
		SG_log__report_verbose(pMe->pCtx, "SG_curl handling SEEK_END.");
		SG_context__pop_level(pMe->pCtx);

		SG_file__seek(pMe->pCtx, pMe->readState.pFile, new_pos);
		if(SG_context__has_err(pMe->pCtx))
			return CURL_SEEKFUNC_FAIL;

		pMe->readState.pos = new_pos;
		pMe->readState.finished = SG_FALSE;
		return CURL_SEEKFUNC_OK;
	}
	else
	{
		return CURL_SEEKFUNC_CANTSEEK;
	}
}
Exemplo n.º 3
0
void SG_vfile__reread(
	SG_context* pCtx,
	SG_vfile * pvf,
	SG_vhash** ppvh)
{
	SG_vhash* pvh = NULL;
	SG_uint64 len64;
	SG_uint32 len32;
	SG_byte* p = NULL;

	SG_ERR_CHECK(  SG_file__seek_end(pCtx, pvf->pFile, &len64)  );
	SG_ERR_CHECK(  SG_file__seek(pCtx, pvf->pFile, 0)  );
	
	// TODO "len64" is uint64 because we can have huge files, but
	// TODO our buffer is limited to uint32 (on 32bit systems).
	// TODO verify that len will fit in uint32.
	len32 = (SG_uint32)len64;
	if (len32 > 0)
	{
		SG_ERR_CHECK(  SG_alloc(pCtx, 1,len32+1,&p)  );
		SG_ERR_CHECK(  SG_file__read(pCtx, pvf->pFile, len32, p, NULL)  );

		p[len32] = 0;

		SG_ERR_CHECK(  SG_VHASH__ALLOC__FROM_JSON(pCtx, &pvh, (const char*) p)  );
		*ppvh = pvh;
	}

fail:
	SG_NULLFREE(pCtx, p);
}
static curlioerr _my_ioctl__file(CURL *handle, int cmd, void *clientp)
{
	_sg_curl* pMe = (_sg_curl*)clientp;

	SG_UNUSED(handle);

	if (cmd == CURLIOCMD_NOP)
	{
		SG_context__push_level(pMe->pCtx);
		SG_log__report_verbose(pMe->pCtx, "SG_curl handling CURLIOCMD_NOP.");
		SG_context__pop_level(pMe->pCtx);

		return CURLIOE_OK;
	}
	else if (cmd == CURLIOCMD_RESTARTREAD)
	{
		SG_context__push_level(pMe->pCtx);
		SG_log__report_verbose(pMe->pCtx, "SG_curl handling CURLIOCMD_RESTARTREAD.");
		SG_context__pop_level(pMe->pCtx);

		SG_file__seek(pMe->pCtx, pMe->readState.pFile, 0);
		if(SG_context__has_err(pMe->pCtx))
			return CURLIOE_FAILRESTART;

		pMe->readState.pos = 0;
		pMe->readState.finished = SG_FALSE;
		return CURLIOE_OK;
	}
	else
	{
		return CURLIOE_UNKNOWNCMD;
	}
}
Exemplo n.º 5
0
static void sg_unzip__currentfile__get_info(SG_context* pCtx, SG_unzip* s)
{
    SG_uint32 uMagic;

    SG_NULLARGCHECK_RETURN( s );

    SG_ERR_CHECK(  SG_file__seek(pCtx, s->pFile, s->pos_in_central_dir + s->byte_before_the_zipfile)  );

    /* we check the magic */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&uMagic)  );
    if (uMagic != 0x02014b50)
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.version)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.version_needed)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.flag)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.compression_method)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&s->cur_file_info.dosDate)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&s->cur_file_info.crc)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&s->cur_file_info.compressed_size)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&s->cur_file_info.uncompressed_size)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.size_filename)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.size_file_extra)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.size_file_comment)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.disk_num_start)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&s->cur_file_info.internal_fa)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&s->cur_file_info.external_fa)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&s->cur_file_info_internal.offset_curfile)  );

    SG_ASSERT (s->cur_file_info.size_filename < UNZ_MAXFILENAMEINZIP);

    SG_ERR_CHECK(  SG_file__read(pCtx, s->pFile, s->cur_file_info.size_filename, (SG_byte*) s->cur_file_name, NULL)  );
    s->cur_file_name[s->cur_file_info.size_filename] = 0;

fail:
    return;
}
Exemplo n.º 6
0
void SG_unzip__currentfile__read(SG_context* pCtx, SG_unzip* s, SG_byte* pBuf, SG_uint32 iLenBuf, SG_uint32* piBytesRead)
{
    int zerr=Z_OK;
    SG_uint32 iRead = 0;
    file_in_zip_read_info_s* pfile_in_zip_read_info;

    SG_NULLARGCHECK_RETURN( s );

    pfile_in_zip_read_info = s->pfile_in_zip_read;

	SG_NULLARGCHECK_RETURN( pfile_in_zip_read_info );

    if (!pfile_in_zip_read_info->read_buffer)
    {
        SG_ERR_THROW_RETURN( SG_ERR_UNSPECIFIED );
    }

    if (!iLenBuf)
    {
        return;
    }

    pfile_in_zip_read_info->stream.next_out = pBuf;

    pfile_in_zip_read_info->stream.avail_out = iLenBuf;

    if (iLenBuf > pfile_in_zip_read_info->rest_read_uncompressed)
    {
        pfile_in_zip_read_info->stream.avail_out = (SG_uint32)pfile_in_zip_read_info->rest_read_uncompressed;
    }

    while (pfile_in_zip_read_info->stream.avail_out>0)
    {
        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
            (pfile_in_zip_read_info->rest_read_compressed>0))
        {
            SG_uint32 uReadThis = UNZ_BUFSIZE;

            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
            {
                uReadThis = (SG_uint32)pfile_in_zip_read_info->rest_read_compressed;
            }
            if (uReadThis == 0)
            {
				//TODO - maybe we should change this
                SG_ERR_THROW(  SG_ERR_EOF  );
            }

            SG_ERR_CHECK(  SG_file__seek(pCtx, s->pFile, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile)  );
            SG_ERR_CHECK(  SG_file__read(pCtx, s->pFile, uReadThis, (SG_byte*) pfile_in_zip_read_info->read_buffer, NULL)  );

            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;

            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;

            pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer;
            pfile_in_zip_read_info->stream.avail_in = (SG_uint32)uReadThis;
        }

        if (pfile_in_zip_read_info->compression_method==0)
        {
            SG_uint32 uDoCopy,i ;

            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
                (pfile_in_zip_read_info->rest_read_compressed == 0))
            {
                if (iRead == 0)
                {
                    SG_ERR_THROW(  SG_ERR_EOF  );
                }
                goto done;
            }

            if (pfile_in_zip_read_info->stream.avail_out <
                            pfile_in_zip_read_info->stream.avail_in)
            {
                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
            }
            else
            {
                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
            }

            for (i=0;i<uDoCopy;i++)
            {
                *(pfile_in_zip_read_info->stream.next_out+i) =
                        *(pfile_in_zip_read_info->stream.next_in+i);
            }

            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
                                pfile_in_zip_read_info->stream.next_out,
                                uDoCopy);

            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
            pfile_in_zip_read_info->stream.next_out += uDoCopy;
            pfile_in_zip_read_info->stream.next_in += uDoCopy;
            pfile_in_zip_read_info->stream.total_out += uDoCopy;
            iRead += uDoCopy;
        }
        else
        {
            SG_uint32 uTotalOutBefore,uTotalOutAfter;
            const Bytef *bufBefore;
            SG_uint32 uOutThis;
            int flush=Z_SYNC_FLUSH;

            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
            bufBefore = pfile_in_zip_read_info->stream.next_out;

            /*
            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
                     pfile_in_zip_read_info->stream.avail_out) &&
                (pfile_in_zip_read_info->rest_read_compressed == 0))
                flush = Z_FINISH;
            */
            zerr = inflate(&pfile_in_zip_read_info->stream,flush);

            if ((zerr>=0) && (pfile_in_zip_read_info->stream.msg))
            {
                SG_ERR_THROW(  SG_ERR_ZLIB(zerr)  );
            }

            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
            uOutThis = uTotalOutAfter-uTotalOutBefore;

            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (SG_uint32)(uOutThis));

            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;

            iRead += (SG_uint32)(uTotalOutAfter - uTotalOutBefore);

            if (zerr == Z_STREAM_END)
            {
            //    return (iRead==0) ? UNZ_EOF : iRead;
            //    break;
            }
        }
    }

done:
    *piBytesRead = iRead;

fail:
    return;
}
Exemplo n.º 7
0
/*
  Read the local header of the current zipfile
  Check the coherency of the local header and info in the end of central
        directory about this file
  store in *piSizeVar the size of extra info in local header
        (filename and size of extra field data)
*/
static void sg_unzip__check_coherency(
        SG_context* pCtx,
        SG_unzip* s,
        SG_uint32* piSizeVar,
        SG_uint32* poffset_local_extrafield,
        SG_uint32* psize_local_extrafield
        )
{
    /* TODO what is uFlags?  It seems to be unused here. */
    SG_uint32 uMagic,uData,uFlags = 0;
    SG_uint16 u16 = 0;
    SG_uint16 size_filename = 0;
    SG_uint16 size_extra_field = 0;

    *piSizeVar = 0;
    *poffset_local_extrafield = 0;
    *psize_local_extrafield = 0;

    SG_ERR_CHECK(  SG_file__seek(pCtx, s->pFile, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile)  );

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&uMagic)  );

    if (uMagic!=0x04034b50)
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&u16)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&u16)  );

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&u16)  );
    if (u16 != s->cur_file_info.compression_method)
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }
    if ((s->cur_file_info.compression_method!=0) && (s->cur_file_info.compression_method != Z_DEFLATED))
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&uData)  ); /* date/time */

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&uData)  ); /* crc */
    if ((uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&uData)  ); /* size compr */
    if ((uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, s->pFile,&uData)  ); /* size uncompr */
    if ((uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }


    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&size_filename)  );
    if (size_filename!=s->cur_file_info.size_filename)
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    *piSizeVar += (SG_uint32)size_filename;

    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, s->pFile,&size_extra_field)  );

    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
                                    SIZEZIPLOCALHEADER + size_filename;
    *psize_local_extrafield = (SG_uint32)size_extra_field;

    *piSizeVar += (SG_uint32)size_extra_field;

fail:
    return;
}
Exemplo n.º 8
0
void SG_unzip__open(SG_context* pCtx, const SG_pathname* pPath, SG_unzip** ppResult)
{
    SG_unzip us;
    SG_unzip *s;
    SG_uint64 central_pos = 0;
    SG_uint32 uL;

    SG_uint16 number_disk = 0;          /* number of the current dist, used for
                                   spaning ZIP, unsupported, always 0*/
    SG_uint16 number_disk_with_CD = 0;  /* number the the disk with central dir, used
                                   for spaning ZIP, unsupported, always 0*/
    SG_uint16 number_entry_CD = 0;      /* total number of entries in
                                   the central dir
                                   (same than number_entry on nospan) */


    SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, SG_FILE_RDONLY | SG_FILE_OPEN_EXISTING, SG_FSOBJ_PERMS__UNUSED, &us.pFile)  );

    SG_ERR_CHECK(  sg_unzip__locate_central_dir(pCtx, us.pFile, &central_pos)  );

    SG_ERR_CHECK(  SG_file__seek(pCtx, us.pFile, central_pos)  );

    /* the signature, already checked */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, us.pFile,&uL)  );

    /* number of this disk */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&number_disk)  );

    /* number of the disk with the start of the central directory */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&number_disk_with_CD)  );

    /* total number of entries in the central dir on this disk */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&us.gi.number_entry)  );

    /* total number of entries in the central dir */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&number_entry_CD)  );

    if ((number_entry_CD!=us.gi.number_entry) ||
        (number_disk_with_CD!=0) ||
        (number_disk!=0))
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    /* size of the central directory */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, us.pFile,&us.size_central_dir)  );

    /* offset of start of central directory with respect to the
          starting disk number */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, us.pFile,&us.offset_central_dir)  );

    /* zipfile comment length */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&us.gi.size_comment)  );

    if (central_pos<us.offset_central_dir+us.size_central_dir)
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    us.byte_before_the_zipfile = (SG_uint32) (central_pos - (us.offset_central_dir+us.size_central_dir));
    us.central_pos = central_pos;
    us.pfile_in_zip_read = NULL;

    us.current_file_ok = SG_FALSE;

	SG_ERR_CHECK(  SG_malloc(pCtx, sizeof(SG_unzip), &s)  );
    *s=us;

    *ppResult = s;

    return;

fail:
    /* TODO free stuff */
    SG_FILE_NULLCLOSE(pCtx, us.pFile);
}
Exemplo n.º 9
0
static void sg_unzip__locate_central_dir(SG_context* pCtx, SG_file* pFile, SG_uint64* piPosition)
{
    unsigned char* buf = NULL;
    SG_uint64 uSizeFile;
    SG_uint32 uBackRead;
    SG_uint32 uMaxBack=0xffff; /* maximum size of global comment */
    SG_uint64 uPosFound=0;

    SG_ERR_CHECK(  SG_file__seek_end(pCtx, pFile, &uSizeFile)  );

    if (uMaxBack > uSizeFile)
    {
        uMaxBack = (SG_uint32) uSizeFile;
    }

	SG_ERR_CHECK(  SG_malloc(pCtx, BUFREADCOMMENT+4, &buf)  );

    uBackRead = 4;
    while (uBackRead<uMaxBack)
    {
        SG_uint32 uReadSize;
        SG_uint64 uReadPos;
        int i;

        if (uBackRead+BUFREADCOMMENT>uMaxBack)
        {
            uBackRead = uMaxBack;
        }
        else
        {
            uBackRead += BUFREADCOMMENT;
        }
        uReadPos = uSizeFile-uBackRead ;

        uReadSize = (SG_uint32) (((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos));
        SG_ERR_CHECK(  SG_file__seek(pCtx, pFile, uReadPos)  );

        SG_ERR_CHECK(  SG_file__read(pCtx, pFile, uReadSize, buf, NULL)  );

        for (i=(int)uReadSize-3; (i--)>0;)
        {
            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
            {
                uPosFound = uReadPos+i;
                break;
            }
        }

        if (uPosFound!=0)
        {
            break;
        }
    }

    *piPosition = uPosFound;

fail:
    SG_NULLFREE(pCtx, buf);
}
Exemplo n.º 10
0
void MyFn(create_blob_from_file)(SG_context * pCtx,
								 SG_repo * pRepo,
								 const SG_pathname * pPathnameTempDir,
								 SG_uint64 lenFile,
								 const char * szSrc)
{
	// create a file of length "lenFile" in the temp directory.
	// use it to create a blob.
	// try to create it a second time and verify that we get an duplicate-hid error.

	char* pszidGidRandom1 = NULL;
	char* pszidGidRandom2 = NULL;
	SG_pathname * pPathnameTempFile1 = NULL;
	SG_pathname * pPathnameTempFile2 = NULL;
	SG_file * pFileTempFile1 = NULL;
	SG_file * pFileTempFile2 = NULL;
	SG_uint32 lenSrc;
	SG_uint64 lenWritten;
	char* pszidHidBlob1 = NULL;
	char* pszidHidBlob1Dup = NULL;
	char* pszidHidBlob2 = NULL;
	char* pszidHidVerify1 = NULL;
	char* pszidHidVerify2 = NULL;
	SG_bool bEqual;
	SG_repo_tx_handle* pTx = NULL;
	SG_uint64 iBlobFullLength = 0;

	//////////////////////////////////////////////////////////////////
	// create temp-file-1 of length "lenFile" in the temp directory.

	VERIFY_ERR_CHECK_DISCARD(  SG_gid__alloc(pCtx, &pszidGidRandom1)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_gid__alloc(pCtx, &pszidGidRandom2)  );

	VERIFY_ERR_CHECK_DISCARD(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameTempFile1,pPathnameTempDir,(pszidGidRandom1))  );

	VERIFY_ERR_CHECK_DISCARD(  SG_file__open__pathname(pCtx, pPathnameTempFile1,SG_FILE_RDWR|SG_FILE_CREATE_NEW,0644,&pFileTempFile1)  );

	// write random gid at the beginning of the file
	// so that we won't get collisions if we are called
	// multiple times.

	VERIFY_ERR_CHECK_DISCARD(  SG_file__write(pCtx, pFileTempFile1,(SG_uint32)strlen(pszidGidRandom1),(SG_byte *)pszidGidRandom1,NULL)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_file__write(pCtx, pFileTempFile1,1,(SG_byte *)"\n",NULL)  );

	// generate lots of data in the file so that we'll cause the
	// blob routines to exercise the chunking stuff.

	lenSrc = (SG_uint32)strlen(szSrc);
	lenWritten = 0;
	while (lenWritten < lenFile)
	{
		VERIFY_ERR_CHECK_DISCARD(  SG_file__write(pCtx, pFileTempFile1,lenSrc,(SG_byte *)szSrc,NULL)  );

		lenWritten += lenSrc;
	}
	// the test file does NOT have a final LF.  i'm not sure it matters one way or the
	// other, but i'm just saying that we're not putting on a final LF.

	SG_ERR_IGNORE(  SG_file__seek(pCtx, pFileTempFile1,0)  );

	//////////////////////////////////////////////////////////////////
	// use currently open temp file to create a blob.
	// we get the HID back.  (we need to free it later.)

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__begin_tx(pCtx, pRepo, &pTx)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_repo__store_blob_from_file(pCtx, pRepo,pTx,NULL,SG_FALSE,pFileTempFile1,&pszidHidBlob1,&iBlobFullLength)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_repo__commit_tx(pCtx, pRepo, &pTx)  );

	INFOP("create_blob_from_file",("Created blob [%s]",(pszidHidBlob1)));

	//////////////////////////////////////////////////////////////////
	// try to create blob again and verify we get an duplicate-hid error.

	// Ian TODO: Put this back when SG_ERR_BLOBFILEALREADYEXISTS has been replaced.
// 	VERIFY_ERR_CHECK_DISCARD(  SG_repo__begin_tx(pCtx, pRepo, &pTx)  );
// 	err = SG_repo__store_blob_from_file(pRepo,pTx,SG_FALSE,pFileTempFile1,&pszidHidBlob1Dup);
// 	VERIFYP_CTX_ERR_IS("create_blob_from_file(duplicate)", pCtx, SG_ERR_BLOBFILEALREADYEXISTS, ("Duplicate create failed [%s][%s]",pszidHidBlob1,pszidHidBlob1Dup));
// 	VERIFY_ERR_CHECK_DISCARD(  SG_repo__commit_tx(pCtx, pRepo, SG_DAGNUM__NONE, NULL, &pTx)  );

	//////////////////////////////////////////////////////////////////
	// create empty temp-file-2 and try to read the blob from the repo.

	VERIFY_ERR_CHECK_DISCARD(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameTempFile2,pPathnameTempDir,(pszidGidRandom2))  );

	VERIFY_ERR_CHECK_DISCARD(  SG_file__open__pathname(pCtx, pPathnameTempFile2,SG_FILE_RDWR|SG_FILE_CREATE_NEW,0644,&pFileTempFile2)  );

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__fetch_blob_into_file(pCtx, pRepo,pszidHidBlob1,pFileTempFile2,NULL)  );

	//////////////////////////////////////////////////////////////////
	// verify that the contents of temp-file-2 is identical to the
	// contents of temp-file-1.  (we already know that the HIDs match
	// and was verified during the fetch, but there are times when the
	// HID is just being used as a key -- it doesn't mean that what we
	// actually restored is correct.

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__alloc_compute_hash__from_file(pCtx, pRepo, pFileTempFile1, &pszidHidVerify1)  );

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__alloc_compute_hash__from_file(pCtx, pRepo, pFileTempFile2, &pszidHidVerify2)  );

	bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidVerify2)));
	VERIFY_COND("create_blob_from_file(verify v1==v2)",bEqual);

	bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidBlob1)));
	VERIFY_COND("create_blob_from_file(verify v1==id)",bEqual);

	//////////////////////////////////////////////////////////////////
	// TODO delete temp source file

	SG_ERR_IGNORE(  SG_file__close(pCtx, &pFileTempFile1)  );
	SG_ERR_IGNORE(  SG_file__close(pCtx, &pFileTempFile2)  );

	//////////////////////////////////////////////////////////////////
	// cleanup

	SG_NULLFREE(pCtx, pszidGidRandom1);
	SG_NULLFREE(pCtx, pszidGidRandom2);
	SG_NULLFREE(pCtx, pszidHidBlob1);
	SG_NULLFREE(pCtx, pszidHidBlob1Dup);
	SG_NULLFREE(pCtx, pszidHidBlob2);
	SG_NULLFREE(pCtx, pszidHidVerify1);
	SG_NULLFREE(pCtx, pszidHidVerify2);
	SG_PATHNAME_NULLFREE(pCtx, pPathnameTempFile1);
	SG_PATHNAME_NULLFREE(pCtx, pPathnameTempFile2);
}
Exemplo n.º 11
0
/**
 * create 1 test file.
 * cat it to a second file using files bound to child's STDIN and STDOUT.
 * repeat using still open files.
 * verify that we get an append effect.
 *
 * do this again using input file on the command line into a third file.
 */
void MyFn(test2)(SG_context * pCtx)
{
	SG_exit_status exitStatusChild;
	SG_file * pFileF1 = NULL;
	SG_file * pFileF2 = NULL;
	SG_file * pFileF3 = NULL;
	SG_pathname * pPathTempDir = NULL;
	SG_pathname * pPathF1 = NULL;
	SG_pathname * pPathF2 = NULL;
	SG_pathname * pPathF3 = NULL;
	SG_exec_argvec * pArgVec = NULL;
	SG_uint64 lenFileF1, lenFileF2, lenFileF3;
	SG_uint64 posFileF1, posFileF2, posFileF3;

	// create a GID temp directory in the current directory.

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_cwd(pCtx,&pPathTempDir)  );
	VERIFY_ERR_CHECK(  SG_fsobj__mkdir_recursive__pathname(pCtx,pPathTempDir)  );

	// create a couple of pathnames to test files in the temp directory.

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF1)  );
	INFOP("exec",("PathF1 is %s",SG_pathname__sz(pPathF1)));
	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF2)  );
	INFOP("exec",("PathF2 is %s",SG_pathname__sz(pPathF2)));
	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF3)  );
	INFOP("exec",("PathF3 is %s",SG_pathname__sz(pPathF3)));

	//////////////////////////////////////////////////////////////////
	// create F1 and write some data to it.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF1,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0644,&pFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  SG_pathname__length_in_bytes(pPathF1),
									  (SG_byte *)SG_pathname__sz(pPathF1),
									  NULL)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  1,
									  (SG_byte *)"\n",
									  NULL)  );
	SG_FILE_NULLCLOSE(pCtx, pFileF1);

	// get length of F1 as created on disk.

	VERIFY_ERR_CHECK(  SG_fsobj__length__pathname(pCtx,pPathF1,&lenFileF1,NULL)  );
	INFOP("lenCheck",("Length F1[%d]",(SG_uint32)lenFileF1));
	VERIFY_COND("lenCheck",(lenFileF1 > 0));

	//////////////////////////////////////////////////////////////////
	// re-open F1 for reading.
	// create F2 as a place for STDOUT of command.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF1,SG_FILE_RDONLY|SG_FILE_OPEN_EXISTING,0644,&pFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF2,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,   0644,&pFileF2)  );

	// exec: "/bin/cat <f1 >f2" three times holding the file handles open between runs.

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF1,&posFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF2,&posFileF2)  );
	INFOP("tell",("Position F1[%d] Position F2[%d]",(SG_uint32)posFileF1,(SG_uint32)posFileF2));
	VERIFY_COND("tell",(posFileF1 == lenFileF1));		// child has dup'd version of handles and so we share seek positions.
	VERIFY_COND("tell",(posFileF2 == posFileF1));		// so, the child should have caused our position to change.

	VERIFY_ERR_CHECK(  SG_file__seek(pCtx,pFileF1,0)  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF1,&posFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF2,&posFileF2)  );
	INFOP("tell",("Position F1[%d] Position F2[%d]",(SG_uint32)posFileF1,(SG_uint32)posFileF2));
	VERIFY_COND("tell",(posFileF1 == lenFileF1));		// child has dup'd version of handles and so we share seek positions.
	VERIFY_COND("tell",(posFileF2 == 2*posFileF1));		// so, the child should have caused our position to change.

	VERIFY_ERR_CHECK(  SG_file__seek(pCtx,pFileF1,0)  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF1,&posFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF2,&posFileF2)  );
	INFOP("tell",("Position F1[%d] Position F2[%d]",(SG_uint32)posFileF1,(SG_uint32)posFileF2));
	VERIFY_COND("tell",(posFileF1 == lenFileF1));		// child has dup'd version of handles and so we share seek positions.
	VERIFY_COND("tell",(posFileF2 == 3*posFileF1));		// so, the child should have caused our position to change.

	SG_FILE_NULLCLOSE(pCtx, pFileF1);
	SG_FILE_NULLCLOSE(pCtx, pFileF2);

	// get length of F2 and see how it compares with F1.

	VERIFY_ERR_CHECK(  SG_fsobj__length__pathname(pCtx,pPathF2,&lenFileF2,NULL)  );
	INFOP("lenCheck",("Length F1[%d] Length F2[%d]",(SG_uint32)lenFileF1,(SG_uint32)lenFileF2));
	VERIFY_COND("lenCheck",(lenFileF2 == 3*lenFileF1));

	//////////////////////////////////////////////////////////////////
	// let F1 be given on the command line.
	// create F3 as a place for STDOUT of command.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF3,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,   0644,&pFileF3)  );

	// exec: "/bin/cat f1 >f3" three times holding F3 open between runs.

	VERIFY_ERR_CHECK(  SG_exec_argvec__alloc(pCtx,&pArgVec)  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF1))  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat f1 >f3",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF3,&posFileF3)  );
	INFOP("tell",("Position F3[%d]",(SG_uint32)posFileF3));
	VERIFY_COND("tell",(posFileF3 == lenFileF1));

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat f1 >f3",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF3,&posFileF3)  );
	INFOP("tell",("Position F3[%d]",(SG_uint32)posFileF3));
	VERIFY_COND("tell",(posFileF3 == 2*lenFileF1));

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat f1 >f3",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF3,&posFileF3)  );
	INFOP("tell",("Position F3[%d]",(SG_uint32)posFileF3));
	VERIFY_COND("tell",(posFileF3 == 3*lenFileF1));

	SG_FILE_NULLCLOSE(pCtx, pFileF3);

	// get length of F3 and see how it compares with F1.

	VERIFY_ERR_CHECK(  SG_fsobj__length__pathname(pCtx,pPathF3,&lenFileF3,NULL)  );
	INFOP("lenCheck",("Length F1[%d] Length F3[%d]",(SG_uint32)lenFileF1,(SG_uint32)lenFileF3));
	VERIFY_COND("tell",(lenFileF3 == 3*lenFileF1));

	//////////////////////////////////////////////////////////////////

	// fall through to common cleanup.

fail:
	SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec);
	SG_PATHNAME_NULLFREE(pCtx, pPathTempDir);
	SG_PATHNAME_NULLFREE(pCtx, pPathF1);
	SG_PATHNAME_NULLFREE(pCtx, pPathF2);
	SG_PATHNAME_NULLFREE(pCtx, pPathF3);
	SG_FILE_NULLCLOSE(pCtx, pFileF1);
	SG_FILE_NULLCLOSE(pCtx, pFileF2);
	SG_FILE_NULLCLOSE(pCtx, pFileF3);
}