minix/lib/libsffs/path.c
David van Moolenbroek ef7b484e5c Create SFFS library out of HGFS
This Shared Folders File System library (libsffs) now contains all the
file system logic originally in HGFS. The actual HGFS server code is
now a stub that passes on all the work to libsffs. The libhgfs library
is changed accordingly.
2012-04-09 18:08:26 +02:00

114 lines
2.7 KiB
C

/* This file contains routines for creating and manipulating path strings.
*
* The entry points into this file are:
* make_path construct a path string for an inode
* push_path add a path component to the end of a path string
* pop_path remove the last path component from a path string
*
* Created:
* April 2009 (D.C. van Moolenbroek)
*/
#include "inc.h"
/*===========================================================================*
* make_path *
*===========================================================================*/
int make_path(path, ino)
char path[PATH_MAX];
struct inode *ino;
{
/* Given an inode, construct the path identifying that inode.
*/
char buf[PATH_MAX], *p, *prefix;
size_t len, plen, total;
p = &buf[sizeof(buf) - 1];
p[0] = 0;
dprintf(("%s: make_path: constructing path for inode %d\n",
sffs_name, ino->i_num));
/* Get the length of the prefix, skipping any leading slashes. */
for (prefix = sffs_params->p_prefix; prefix[0] == '/'; prefix++);
plen = strlen(prefix);
/* Construct the path right-to-left in a temporary buffer first. */
for (total = plen; ino != NULL && !IS_ROOT(ino); ino = ino->i_parent) {
len = strlen(ino->i_name);
total += len + 1;
p -= len + 1;
if (total >= sizeof(buf))
return ENAMETOOLONG;
p[0] = '/';
memcpy(p + 1, ino->i_name, len);
}
/* If any of the intermediate inodes has no parent, the final inode is no
* longer addressable by name.
*/
if (ino == NULL)
return ENOENT;
/* Put the result in the actual buffer. We need the leading slash in the
* temporary buffer only when the prefix is not empty.
*/
if (!prefix[0] && p[0] == '/') p++;
strcpy(path, prefix);
strcpy(&path[plen], p);
dprintf(("%s: make_path: resulting path is '%s'\n", sffs_name, path));
return OK;
}
/*===========================================================================*
* push_path *
*===========================================================================*/
int push_path(path, name)
char path[PATH_MAX];
char *name;
{
/* Add a component to the end of a path.
*/
size_t len, add;
len = strlen(path);
add = strlen(name);
if (len > 0) add++;
if (len + add >= PATH_MAX)
return ENAMETOOLONG;
if (len > 0) path[len++] = '/';
strcpy(&path[len], name);
return OK;
}
/*===========================================================================*
* pop_path *
*===========================================================================*/
void pop_path(path)
char path[PATH_MAX];
{
/* Remove the last component from a path.
*/
char *p;
p = strrchr(path, '/');
if (p == NULL) {
p = path;
/* Can't pop the root component */
assert(p[0] != 0);
}
p[0] = 0;
}