예제 #1
0
파일: file.c 프로젝트: albertz/navit
int file_mkdir(char *name, int pflag)
{
	char *buffer=g_alloca(sizeof(char)*(strlen(name)+1));
	int ret;
	char *next;
	dbg(1,"enter %s %d\n",name,pflag);
	if (!pflag) {
		if (file_is_dir(name))
			return 0;
#if defined HAVE_API_WIN32_BASE || defined _MSC_VER
		return mkdir(name);
#else
		return mkdir(name, 0777);
#endif
	}
	strcpy(buffer, name);
	next=buffer;
	while ((next=strchr(next, '/'))) {
		*next='\0';
		if (*buffer) {
			ret=file_mkdir(buffer, 0);
			if (ret)
				return ret;
		}
		*next++='/';
	}
	if (pflag == 2)
		return 0;
	return file_mkdir(buffer, 0);
}
예제 #2
0
/*FUNCTION*/
int hook_mkdir(pExecuteObject pEo,
               char *pszDirectoryName
  ){
/*noverbatim
CUT*/
  return file_mkdir(pszDirectoryName);
  }
예제 #3
0
파일: hcache.c 프로젝트: caryhaynie/jamplus
void
	hcache_writefile(HCACHEFILE *file)
{
	FILE	*f;
	HCACHEDATA	*c;
	int		header_count = 0;
	int		maxage;

	if( !file  ||  !file->dirty  ||  !file->cachefilename )
		return;

	file_mkdir(file->cachefilename);

	if( ! (f = fopen( file->cachefilename, "wb" ) ) )
		return;

	maxage = cache_maxage();

	/* print out the version */
	fprintf( f, "@%s@\n", CACHE_FILE_VERSION );

	for( c = file->hcachelist; c; c = c->next ) {
		LISTITEM	*l;

		if( maxage == 0 )
			c->age = 0;
		else if( c->age > maxage )
			continue;

		write_string( f, c->boundname );
		write_int( f, (int)c->time );
		write_int( f, c->age );

#ifdef OPT_BUILTIN_MD5CACHE_EXT
		write_md5sum( f, c->rulemd5sum );
#endif

		write_int( f, list_length( c->includes ) );
		for( l = list_first(c->includes); l; l = list_next( l ) ) {
			write_string( f, list_value(l) );
		}

		write_int( f, list_length( c->hdrscan ) );
		for( l = list_first(c->hdrscan); l; l = list_next( l ) ) {
			write_string( f, list_value(l) );
		}

		fputc( '!', f );
		fputc( '\n', f );
		++header_count;
	}

	if( DEBUG_HEADER )
		printf( "hcache written to %s.	 %d dependencies, %.0f%% hit rate\n",
		file->cachefilename, header_count,
		queries ? 100.0 * hits / queries : 0 );

	fclose( f );
}
예제 #4
0
static char *
user_log_path(User *user, char *fname) {
  char path[100];
  if (!valid_log_name(fname)) return NULL;
  snprintf(path, 100, "%s/logs", user->dir);
  file_mkdir(path);
  snprintf(path, 100, "%s/logs/%s", user->dir, fname);
  return strdup(path);
}
예제 #5
0
/*
 * copyfile() - copy one file into another. returns 1 if successful
 */
int copyfile(const char *dst, const char *src, MD5SUM* md5sum)
{
    MD5_CTX context;
    size_t size = 0, sizeout = 0;
    FILE *fsrc = NULL, *fdst = NULL;
    unsigned char block[1<<16];

    /* printf("copy %s->%s\n", src, dst); */

    file_mkdir(dst);

    fsrc = fopen(src, "rb");
    if (fsrc==NULL) {
	printf("cannot open %s for reading - %s\n", src, strerror(errno));
	return 0;
    }

    fdst = fopen(dst, "wb");
    if (fdst==NULL) {
	fclose(fsrc);
	printf("cannot open %s for writing - %s\n", dst, strerror(errno));
	return 0;
    }

    if (md5sum) {
	MD5Init(&context);
    }

    while(!feof(fsrc)) {
	size = fread(block, 1, sizeof(block), fsrc);
	if (size==0) {
	    break;
	}

	if (md5sum) {
	    MD5Update(&context, block, size);
	}

	sizeout = fwrite(block, 1, size, fdst);
	if (sizeout!=size) {
	    printf("error while copying %s to %s - %s\n", src, dst, strerror(errno));
	    fclose(fsrc);
	    fclose(fdst);
	    return 0;
	}
    }

    if (md5sum) {
	MD5Final(*md5sum, &context);
    }

    fclose(fsrc);
    fclose(fdst);
    return 1;
}
예제 #6
0
// creates directory
struct variable *sys_mkdir(struct context *context)
{
    struct variable *value = (struct variable*)stack_pop(context->operand_stack);
    struct variable *path = (struct variable*)array_get(value->list.ordered, 1);
    char *path2 = byte_array_to_string(path->str);

    file_mkdir(path2);

    free(path2);
    return NULL;
}
예제 #7
0
/*
** Make sure empty directories are created
*/
void ensure_empty_dirs_created(void){
  /* Make empty directories? */
  char *zEmptyDirs = db_get("empty-dirs", 0);
  if( zEmptyDirs!=0 ){
    char *bc;
    Blob dirName;
    Blob dirsList;

    blob_zero(&dirsList);
    blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
    /* Replace commas by spaces */
    bc = blob_str(&dirsList);
    while( (*bc)!='\0' ){
      if( (*bc)==',' ) { *bc = ' '; }
      ++bc;
    }
    /* Make directories */
    blob_zero(&dirName);
    while( blob_token(&dirsList, &dirName) ){
      const char *zDir = blob_str(&dirName);
      /* Make full pathname of the directory */
      Blob path;
      const char *zPath;

      blob_zero(&path);
      blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
      zPath = blob_str(&path);
      /* Handle various cases of existence of the directory */
      switch( file_wd_isdir(zPath) ){
        case 0: { /* doesn't exist */
          if( file_mkdir(zPath, 0)!=0 ) {
            fossil_warning("couldn't create directory %s as "
                           "required by empty-dirs setting", zDir);
          }
          break;
        }
        case 1: { /* exists, and is a directory */
          /* do nothing - required directory exists already */
          break;
        }
        case 2: { /* exists, but isn't a directory */
          fossil_warning("file %s found, but a directory is required "
                         "by empty-dirs setting", zDir);
        }
      }
      blob_reset(&path);
    }
  }
}
예제 #8
0
파일: hcache.c 프로젝트: caryhaynie/jamplus
static void checksums_writefile() {
	CHECKSUMDATA	*c;
	FILE *f;
	int maxage;

	if ( !checksumsdirty ) {
		return;
	}

	maxage = cache_maxage();

	f = NULL;
	for( c = checksumdatalist; c; c = c->next ) {
		if ( c->mtime == 0  ||  ismd5empty( (unsigned char*)&c->contentmd5sum ) ) {
			continue;
		}

		if ( maxage == 0 ) {
			c->age = 0;
		} else if ( c->age > maxage ) {
			continue;
		}

		if ( !f ) {
			file_mkdir( checksums_filename() );

			if ( !( f = fopen( checksums_filename(), "wb" ) ) )
				return;

			/* print out the version */
			fprintf( f, "@%s@\n", CHECKSUM_FILE_VERSION );
		}

		write_string( f, c->boundname );

		write_int( f, c->age );

		write_int( f, (int)c->mtime );
		write_md5sum( f, c->contentmd5sum );

		fputc( '!', f );
		fputc( '\n', f );
	}

	if ( f ) {
		fclose( f );
	}
}
예제 #9
0
파일: sys.c 프로젝트: chobits/tinyos
int sys_mkdir(char *path, unsigned int mode)
{
	struct file *file;
	int fd = fd_alloc();
	if (fd < 0)
		goto out;
	file = file_mkdir(path, mode);
	if (!file)
		goto out_free_fd;
	fd_save_file(fd, file);
	return fd;
out_free_fd:
	fd_free(fd);
out:
	return -1;
}
예제 #10
0
파일: binfile.c 프로젝트: justinzane/navit
static char *
binfile_extract(struct map_priv *m, char *dir, char *filename, int partial)
{
	char *full,*fulld,*sep;
	unsigned char *start;
	int len,offset=m->index_offset;
	struct zip_cd *cd;
	struct zip_lfh *lfh;
	FILE *f;

	for (;;) {
		offset=binfile_search_cd(m, offset, filename, partial, 1);
		if (offset == -1)
			break;
		cd=binfile_read_cd(m, offset, -1);
		len=strlen(dir)+1+cd->zipcfnl+1;
		full=g_malloc(len);
		strcpy(full,dir);
		strcpy(full+strlen(full),"/");
		strncpy(full+strlen(full),cd->zipcfn,cd->zipcfnl);
		full[len-1]='\0';
		fulld=g_strdup(full);
		sep=strrchr(fulld, '/');
		if (sep) {
			*sep='\0';
			file_mkdir(fulld, 1);
		}
		if (full[len-2] != '/') {
			lfh=binfile_read_lfh(m->fi, cd->zipofst);
			start=binfile_read_content(m->fi, cd->zipofst, lfh);
			dbg(0,"fopen '%s'\n", full);
			f=fopen(full,"w");
			fwrite(start, lfh->zipuncmp, 1, f);
			fclose(f);
			file_data_free(m->fi, start);
			file_data_free(m->fi, (unsigned char *)lfh);
		}
		file_data_free(m->fi, (unsigned char *)cd);
		g_free(fulld);
		g_free(full);
		if (! partial)
			break;
	}
	
	return g_strdup_printf("%s/%s",dir,filename);
}
예제 #11
0
파일: log.c 프로젝트: justinzane/navit
static void
log_open(struct log *this_)
{
	char *mode;
	if (this_->overwrite)
		mode="w";
	else
		mode="r+";
	if (this_->mkdir)
		file_mkdir(this_->filename_ex2, 2);
	this_->f=fopen(this_->filename_ex2, mode);
	if (! this_->f)
		this_->f=fopen(this_->filename_ex2, "w");
	if (! this_->f)
		return;
	if (!this_->overwrite) 
		fseek(this_->f, 0, SEEK_END);
	this_->empty = !ftell(this_->f);
	log_set_last_flush(this_);
}
static int copy_default_file (const char *srcfile, const char *dstfile)
{
	char *local_path, *default_path, *target_dir;

	target_dir = stringf_dup ("%s/FastTrack", platform_local_dir());
	local_path = stringf_dup ("%s/FastTrack/%s", platform_local_dir(), dstfile);
	default_path = stringf_dup ("%s/FastTrack/%s", platform_data_dir(), srcfile);

	if (!file_exists (local_path))
	{
		FST_WARN_2 ("Local file \"%s\" does not exist, copying default from \"%s\"",
					local_path, default_path);

		/* make sure the target directory exists */
		if (!file_mkdir (target_dir, 0777))
		{
			FST_ERR_1 ("Unable to create directory \"%s\"", target_dir);

			free (target_dir);
			free (local_path);
			free (default_path);
			return FALSE;
		}


		if (!file_cp (default_path, local_path))
		{		
			FST_ERR_1 ("Unable to copy default file \"%s\"", default_path);

			free (target_dir);
			free (local_path);
			free (default_path);
			return FALSE;
		}
	}

	free (target_dir);
	free (local_path);
	free (default_path);
	return TRUE;
}
예제 #13
0
파일: file.c 프로젝트: oopos/fossil
/*
** Create symlink to file on Unix, or plain-text file with
** symlink target if "allow-symlinks" is off or we're on Windows.
**
** Arguments: target file (symlink will point to it), link file
**/
void symlink_create(const char *zTargetFile, const char *zLinkFile) {
#if !defined(_WIN32)
    if( g.allowSymlinks ) {
        int i, nName;
        char *zName, zBuf[1000];

        nName = strlen(zLinkFile);
        if( nName>=sizeof(zBuf) ) {
            zName = mprintf("%s", zLinkFile);
        } else {
            zName = zBuf;
            memcpy(zName, zLinkFile, nName+1);
        }
        nName = file_simplify_name(zName, nName);
        for(i=1; i<nName; i++) {
            if( zName[i]=='/' ) {
                zName[i] = 0;
                if( file_mkdir(zName, 1) ) {
                    fossil_fatal_recursive("unable to create directory %s", zName);
                    return;
                }
                zName[i] = '/';
            }
        }
        if( zName!=zBuf ) free(zName);

        if( symlink(zTargetFile, zName)!=0 ) {
            fossil_fatal_recursive("unable to create symlink \"%s\"", zName);
        }
    } else
#endif
    {
        Blob content;
        blob_set(&content, zTargetFile);
        blob_write_to_file(&content, zLinkFile);
        blob_reset(&content);
    }
}
예제 #14
0
파일: FileStore.cpp 프로젝트: ifzz/FDK
FileStore::FileStore( std::string path, const SessionID& s )
: m_msgFile( 0 ), m_headerFile( 0 ), m_seqNumsFile( 0 ), m_sessionFile( 0 )
{
  file_mkdir( path.c_str() );

  if ( path.empty() ) path = ".";
  const std::string& begin =
    s.getBeginString().getString();
  const std::string& sender =
    s.getSenderCompID().getString();
  const std::string& target =
    s.getTargetCompID().getString();
  const std::string& qualifier =
    s.getSessionQualifier();

  std::string sessionid = begin + "-" + sender + "-" + target;
  if( qualifier.size() )
    sessionid += "-" + qualifier;

  std::string prefix
    = file_appendpath(path, sessionid + ".");

  m_msgFileName = prefix + "body";
  m_headerFileName = prefix + "header";
  m_seqNumsFileName = prefix + "seqnums";
  m_sessionFileName = prefix + "session";

  try
  {
    open( false );
  }
  catch ( IOException & e )
  {
    throw ConfigError( e.what() );
  }
}
예제 #15
0
파일: hcache.c 프로젝트: larus/jamplus
void filecache_update(TARGET *t)
{
	MD5SUM blobmd5sum;
	int haveblobmd5sum = 0;
	const char *cachedname;
	const char *blobname;
	int cacheerror;

	if (!t->filecache_generate)
		return;

	/* If the buildmd5sum is empty, then the file doesn't exist. */
	cacheerror = ismd5empty(t->buildmd5sum);
	if (cacheerror)
		return;

	haveblobmd5sum = 0;
	cachedname = filecache_getfilename(t, t->buildmd5sum, NULL);
	if (!cachedname)
		return;

	/* Search for the appropriate .link file that matches the target. */
	haveblobmd5sum = filecache_findlink(cachedname, blobmd5sum);

	/* If we weren't able to determine the target md5sum, do it now. */
	if (!haveblobmd5sum)
	{
#ifdef OPT_BUILTIN_LUA_SUPPORT_EXT
		LIST *md5callback;

		pushsettings( t->settings );
		md5callback = var_get( "MD5CALLBACK" );
		popsettings( t->settings );

		if ( md5callback )
		{
			luahelper_md5callback(t->boundname, blobmd5sum, md5callback->string);
		}
		else
		{
#endif
			md5file(t->boundname, blobmd5sum);
#ifdef OPT_BUILTIN_LUA_SUPPORT_EXT
		}
#endif
		memcpy(t->contentmd5sum, blobmd5sum, sizeof(MD5SUM));
		if (ismd5empty(t->contentmd5sum))
			return;
	}

	{
		/* Is the blob already there? */
		time_t blobtime;
		blobname = filecache_getfilename(t, blobmd5sum, ".blob");
		if (file_time(blobname, &blobtime) == -1)
		{
			time_t blobpartialtime;
			const char *blobpartialname;

			if(DEBUG_MD5HASH)
				printf("Caching %s as %s\n", t->name, cachedname);
			else
				printf("Caching %s\n", t->name);

			/* Write the new .blob to the cache. */
			blobpartialname = filecache_getfilename(t, blobmd5sum, ".blob.partial");
			if (file_time(blobpartialname, &blobpartialtime) == -1)
			{
				if (copyfile(blobpartialname, t->boundname, &blobmd5sum) == 0  ||
					rename(blobpartialname, blobname) != 0)
				{
					printf("** Unable to write %s to cache.\n", t->name, cachedname);
					filecache_disable(t);
					return;
				}
			}
		}
	}

	/* Write the new .link file to the cache. */
	{
		FILE *file;
		BUFFER linknamebuff;
		buffer_init(&linknamebuff);
		buffer_addstring(&linknamebuff, cachedname, strlen(cachedname));
		buffer_addchar(&linknamebuff, '-');
		buffer_addstring(&linknamebuff, md5tostring(blobmd5sum), 32);
		buffer_addstring(&linknamebuff, ".link", 5);
		buffer_addchar(&linknamebuff, 0);

		file_mkdir(buffer_ptr(&linknamebuff));
		file = fopen(buffer_ptr(&linknamebuff), "wb");
		if (file)
		{
			write_md5sum(file, blobmd5sum);
			write_string(file, t->name);
			fclose(file);
		}

		buffer_free(&linknamebuff);
	}
}
예제 #16
0
/*
** Write the content of a blob into a file.
**
** If the filename is blank or "-" then write to standard output.
**
** Return the number of bytes written.
*/
int blob_write_to_file(Blob *pBlob, const char *zFilename){
  FILE *out;
  int nWrote;

  if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
    nWrote = blob_size(pBlob);
#if defined(_WIN32)
    if( fossil_utf8_to_console(blob_buffer(pBlob), nWrote, 0) >= 0 ){
      return nWrote;
    }
#endif
    fwrite(blob_buffer(pBlob), 1, nWrote, stdout);
  }else{
    int i, nName;
    char *zName, zBuf[1000];

    nName = strlen(zFilename);
    if( nName>=sizeof(zBuf) ){
      zName = mprintf("%s", zFilename);
    }else{
      zName = zBuf;
      memcpy(zName, zFilename, nName+1);
    }
    nName = file_simplify_name(zName, nName, 0);
    for(i=1; i<nName; i++){
      if( zName[i]=='/' ){
        zName[i] = 0;
#if defined(_WIN32) || defined(__CYGWIN__)
        /*
        ** On Windows, local path looks like: C:/develop/project/file.txt
        ** The if stops us from trying to create a directory of a drive letter
        ** C: in this example.
        */
        if( !(i==2 && zName[1]==':') ){
#endif
          if( file_mkdir(zName, 1) && file_isdir(zName)!=1 ){
            fossil_fatal_recursive("unable to create directory %s", zName);
            return 0;
          }
#if defined(_WIN32) || defined(__CYGWIN__)
        }
#endif
        zName[i] = '/';
      }
    }
    out = fossil_fopen(zName, "wb");
    if( out==0 ){
      fossil_fatal_recursive("unable to open file \"%s\" for writing", zName);
      return 0;
    }
    if( zName!=zBuf ) free(zName);
    blob_is_init(pBlob);
    nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out);
    fclose(out);
    if( nWrote!=blob_size(pBlob) ){
      fossil_fatal_recursive("short write: %d of %d bytes to %s", nWrote,
         blob_size(pBlob), zFilename);
    }
  }
  return nWrote;
}
예제 #17
0
int gfm_tifiles_ungroup(const char *filename, int type)
{
	gchar *dirname = g_path_get_dirname(filename);
	gchar *basename = g_path_get_basename(filename);
	
	gchar *src_file;
	gchar *dst_file;
	
	gchar *folder, *tmp;
	gchar *input;	
	gchar *e;
	int err = 0;

	// Ask for folder
	folder = g_strdup(basename);
	e = strrchr(folder, '.');
	if(e) *e = '\0';

	input = msgbox_input(_("Create new directory"), folder, _("Directory where files will be ungrouped: "));
	g_free(folder);
	if (input == NULL)
		return -1;

	tmp = g_filename_from_utf8(input, -1, NULL, NULL, NULL);
	g_free(input);

	folder = g_strconcat(dirname, G_DIR_SEPARATOR_S, tmp, NULL);
	g_free(tmp);

	// Check for folder existence
	if(!strcmp(dirname, ".") || !strcmp(dirname, ""))
	{
		msgbox_one(MSGBOX_ERROR, _("You can't ungroup in this folder."));
		g_free(basename);
		g_free(dirname);
		return -1;
	}
   
	// Create folder
	if(file_mkdir(folder))
	{
		g_free(basename);
		g_free(dirname);
		return -1;
	}
	file_chdir(folder);

	// Copy file to target
	src_file = g_strdup(filename);	
	dst_file = g_strconcat(folder, G_DIR_SEPARATOR_S, basename, NULL);
	file_copy(src_file, dst_file);
	
	// Ungroup
	if(type == TIFILE_GROUP)
		err = tifiles_ungroup_file(dst_file, NULL);
	else if(type == TIFILE_TIGROUP)
		err = tifiles_untigroup_file(dst_file, NULL);
	if(err)
	{
		gchar *str;

		tifiles_error_get(err, &str);
		msgbox_one(MSGBOX_ERROR, str);
		g_free(str);
	}
	file_chdir("..");

	// And release
	g_free(basename);
	g_free(dirname);
	g_free(src_file);
	g_free(dst_file);

	return 0;
}
예제 #18
0
static int mkdir_recursive(const char * path, unsigned short perms) {
    char * tmp_str = NULL;
    char * dirname_ptr;
    char * tmp_iter;

    tmp_str = kmalloc(strlen(path) + 1, GFP_KERNEL);
    if (!tmp_str) {
        printk(KERN_ERR "Cannot kmallocate in mkdir recursive\n");
        return -1;
    }

    memset(tmp_str, 0, strlen(path) + 1);
    strncpy(tmp_str, path, strlen(path));

    dirname_ptr = tmp_str;
    tmp_iter = tmp_str;

    // parse path string, call file_mkdir recursively.


    while (dirname_ptr != NULL) {
        int done = 0;

        while ((*tmp_iter != '/') &&
                (*tmp_iter != '\0')) {

            if ( (!isprint(*tmp_iter))) {
                printk(KERN_ERR "Invalid character in path name (%d)\n", *tmp_iter);
                kfree(tmp_str);
                return -1;
            } else {
                tmp_iter++;
            }
        }

        if (*tmp_iter == '/') {
            *tmp_iter = '\0';
        } else {
            done = 1;
        }

        // Ignore empty directories
        if ((tmp_iter - dirname_ptr) > 1) {
            if (file_mkdir(tmp_str, perms, 0) != 0) {
                printk(KERN_ERR "Could not create directory (%s)\n", tmp_str);
                kfree(tmp_str);
                return -1;
            }
        }

        if (done) {
            break;
        } else {
            *tmp_iter = '/';
        }

        tmp_iter++;

        dirname_ptr = tmp_iter;
    }

    kfree(tmp_str);

    return 0;
}
예제 #19
0
파일: hcache.c 프로젝트: caryhaynie/jamplus
void filecache_update(TARGET *t, MD5SUM buildmd5sum)
{
	MD5SUM blobmd5sum;
	int haveblobmd5sum = 0;
	const char *cachedname;
	const char *blobname;
	int cacheerror;

	if (!t->filecache_generate)
		return;

	/* If the buildmd5sum is empty, then the file doesn't exist. */
	cacheerror = ismd5empty(buildmd5sum);
	if (cacheerror)
		return;

	haveblobmd5sum = 0;
	cachedname = filecache_getfilename(t, buildmd5sum, NULL);
	if (!cachedname)
		return;

	/* Search for the appropriate .link file that matches the target. */
	haveblobmd5sum = filecache_findlink(cachedname, blobmd5sum);

	/* If we weren't able to determine the target md5sum, do it now. */
	if (!haveblobmd5sum)
	{
		getcachedmd5sum( t, 1 );
		memcpy(blobmd5sum, t->contentchecksum->contentmd5sum, MD5_SUMSIZE);
		if (ismd5empty(t->contentchecksum->contentmd5sum))
			return;
	}

	{
		/* Is the blob already there? */
		time_t blobtime;
		blobname = filecache_getfilename(t, blobmd5sum, ".blob");
		if (file_time(blobname, &blobtime) == -1)
		{
			time_t blobpartialtime;
			const char *blobpartialname;

			if(DEBUG_MD5HASH)
				printf("Caching %s as %s\n", t->name, cachedname);
			else
				printf("Caching %s\n", t->name);

			/* Write the new .blob to the cache. */
			blobpartialname = filecache_getfilename(t, blobmd5sum, ".blob.partial");
			if (file_time(blobpartialname, &blobpartialtime) == -1)
			{
				if (copyfile(blobpartialname, t->boundname, &blobmd5sum) == 0  ||
					rename(blobpartialname, blobname) != 0)
				{
					printf("** Unable to write %s to cache.\n", t->name);
					filecache_disable(t);
					return;
				}
			}
		}
	}

	/* Write the new .link file to the cache. */
	{
		FILE *file;
		BUFFER linknamebuff;
		buffer_init(&linknamebuff);
		buffer_addstring(&linknamebuff, cachedname, strlen(cachedname));
		buffer_addchar(&linknamebuff, '-');
		buffer_addstring(&linknamebuff, md5tostring(blobmd5sum), 32);
		buffer_addstring(&linknamebuff, ".link", 5);
		buffer_addchar(&linknamebuff, 0);

		file_mkdir(buffer_ptr(&linknamebuff));
		file = fopen(buffer_ptr(&linknamebuff), "wb");
		if (file)
		{
			write_md5sum(file, blobmd5sum);
			write_string(file, t->name);
			fclose(file);
		}

		buffer_free(&linknamebuff);
	}
}