* seeking on files.
*
* The entry points into this file are
- * do_creat: perform the CREAT system call
- * do_open: perform the OPEN system call
- * do_mknod: perform the MKNOD system call
- * do_mkdir: perform the MKDIR system call
- * do_close: perform the CLOSE system call
- * do_lseek: perform the LSEEK system call
- * do_symlink: perform the LSEEK system call
+ * do_creat: perform the CREAT system call
+ * do_open: perform the OPEN system call
+ * do_mknod: perform the MKNOD system call
+ * do_mkdir: perform the MKDIR system call
+ * do_close: perform the CLOSE system call
+ * do_lseek: perform the LSEEK system call
*/
#include "fs.h"
#include <sys/stat.h>
-#include <string.h>
#include <fcntl.h>
#include <minix/callnr.h>
#include <minix/com.h>
*/
register struct inode *rlast_dir_ptr, *rip;
- struct inode *old_workdir_ip;
register int r;
- int slink_found, loops = 0;
char string[NAME_MAX];
- old_workdir_ip = fp->fp_workdir; /* Save the current working directory */
-
- do {
- slink_found = FALSE;
- /* See if the path can be opened down to the last directory. */
- if ((rlast_dir_ptr = last_dir(path, string)) == NIL_INODE) {
- fp->fp_workdir = old_workdir_ip; /* Restore cwd */
- return(NIL_INODE);
- }
-
- /* The final directory is accessible. Get final component of the path. */
- rip = advance(rlast_dir_ptr, string);
- if (rip != NIL_INODE && (rip->i_mode & I_TYPE) == I_SYMBOLIC_LINK) {
- if (++loops > MAX_SYM_LOOPS) {
- fp->fp_workdir = old_workdir_ip;
- put_inode(rlast_dir_ptr);
- err_code = ELOOP;
- return(NIL_INODE);
- }
- rip = slink_traverse(rip, path, string, rlast_dir_ptr);
- slink_found = TRUE;
- put_inode(rlast_dir_ptr);
- fp->fp_workdir = rip; /* cd to symlink target dir */
- }
- } while (slink_found);
+ /* See if the path can be opened down to the last directory. */
+ if ((rlast_dir_ptr = last_dir(path, string)) == NIL_INODE) return(NIL_INODE);
+ /* The final directory is accessible. Get final component of the path. */
+ rip = advance(rlast_dir_ptr, string);
if ( rip == NIL_INODE && err_code == ENOENT) {
/* Last path component does not exist. Make new directory entry. */
if ( (rip = alloc_inode(rlast_dir_ptr->i_dev, bits)) == NIL_INODE) {
m_out.reply_l1 = pos; /* insert the long into the output message */
return(OK);
}
-
-
-/*===========================================================================*
- * do_symlink *
- *===========================================================================*/
-PUBLIC int do_symlink()
-{
-/* perform the symlink(name1, name2) system call */
-
- register struct inode *ip;
- register int r;
- char string[NAME_MAX];
- register struct inode *new_ip;
- struct buf *bp;
-
- if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK)
- return(err_code);
-
- /* Does the final directory of 'name2' exist? */
- if ( (ip = last_dir(user_path, string)) == NIL_INODE)
- return(err_code);
-
- r = OK;
- /* if name2 exists in full set 'r' to error */
- if ( (new_ip = advance(ip, string)) == NIL_INODE) {
- r = err_code;
- if (r == ENOENT) r = OK;
- } else {
- put_inode(new_ip);
- r = EEXIST;
- }
- put_inode(ip);
- if (r != OK) return(r);
-
- if ( (new_ip = new_node(user_path, (mode_t)(I_SYMBOLIC_LINK | 0777),
- (off_t)0)) == NIL_INODE) {
- put_inode(new_ip);
- return(err_code);
- }
-
- truncate(new_ip);
- wipe_inode(new_ip);
- new_ip->i_size = m_in.name1_length;
-
- if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) {
- put_inode(new_ip);
- return(err_code);
- }
- /* allocate disk block for name1 */
- if ( (bp = new_block(new_ip, 0)) == NIL_BUF) {
- put_inode(new_ip);
- return(err_code);
- }
- /* stuff pathname into diskblock and set immediate writing */
- memcpy(bp->b_data, user_path, m_in.name1_length);
- bp->b_dirt = DIRTY;
- put_block(bp, INODE_BLOCK);
- new_ip->i_dirt = DIRTY;
- rw_inode(new_ip, WRITING);
- put_inode(new_ip);
- return(err_code);
-}
-
-/** open.c **/
* return NIL_INODE as function value and an error code in 'err_code'.
*/
- register struct inode *ldip, *rip, *old_workdir_ip;
- char string[NAME_MAX]; /* hold 1 path component name here */
- int slink_found;
- int loops = 0; /* count symlink traversals */
-
- old_workdir_ip = fp->fp_workdir; /* save the current working directory */
-
- do {
- slink_found = FALSE;
-
- /* First open the path down to the final directory. */
- if ( (ldip = last_dir(path, string)) == NIL_INODE) {
- fp->fp_workdir = old_workdir_ip;
- return(NIL_INODE); /* we couldn't open final directory */
- }
-
- /* The path consisting only of "/" is a special case, check for it. */
- if (string[0] == '\0') return(ldip);
-
- /* Get final component of the path. */
- rip = advance(ldip, string);
-
- if (rip != NIL_INODE && (rip->i_mode & I_TYPE) == I_SYMBOLIC_LINK) {
- if (++loops > MAX_SYM_LOOPS) {
- put_inode(rip);
- put_inode(ldip);
- fp->fp_workdir = old_workdir_ip;
- err_code = ELOOP;
- return(NIL_INODE);
- }
- rip = slink_traverse(rip, path, string, ldip);
- slink_found = TRUE;
- fp->fp_workdir = rip; /* cd to link's starting dir */
- put_inode(rip);
- }
- put_inode(ldip);
- } while (slink_found);
- fp->fp_workdir = old_workdir_ip;
+ register struct inode *ldip, *rip;
+ char string[NAME_MAX]; /* hold 1 path component name here */
+
+ /* First open the path down to the final directory. */
+ if ( (ldip = last_dir(path, string)) == NIL_INODE) {
+ return(NIL_INODE); /* we couldn't open final directory */
+ }
+
+ /* The path consisting only of "/" is a special case, check for it. */
+ if (string[0] == '\0') return(ldip);
+
+ /* Get final component of the path. */
+ rip = advance(ldip, string);
+ put_inode(ldip);
return(rip);
}
register struct inode *rip;
register char *new_name;
register struct inode *new_ip;
- int loops = 0; /* count symlink traversals */
/* Is the path absolute or relative? Initialize 'rip' accordingly. */
rip = (*path == '/' ? fp->fp_rootdir : fp->fp_workdir);
/* There is more path. Keep parsing. */
new_ip = advance(rip, string);
- if (new_ip == NIL_INODE) {
- put_inode(rip);
- return(NIL_INODE);
- }
-
+ put_inode(rip); /* rip either obsolete or irrelevant */
+ if (new_ip == NIL_INODE) return(NIL_INODE);
+
/* The call to advance() succeeded. Fetch next component. */
- if ((new_ip->i_mode & I_TYPE) == I_SYMBOLIC_LINK) {
- if (++loops > MAX_SYM_LOOPS) {
- err_code = ELOOP;
- put_inode(rip);
- put_inode(new_ip);
- return(NIL_INODE);
- }
- new_ip = slink_traverse(new_ip, path, string, rip);
- } else
- path = new_name;
-
- put_inode(rip); /* rip either obsolete or irrelevant */
+ path = new_name;
rip = new_ip;
}
}
}
return(OK);
}
-
-
-/*===========================================================================*
- * slink_traverse *
- *===========================================================================*/
-PUBLIC struct inode *slink_traverse(rip, path, string, ldip)
-register struct inode *rip;
-char *path;
-char *string;
-register struct inode *ldip;
-{
-
- /* copy path out of symlink's disk block -- return inode pointer to
- * the directory that the path infers */
-
- register char *p, *q;
- char temp[PATH_MAX];
- struct buf *bp;
- block_t b;
-
- b = read_map(rip, 0);
- bp = get_block(rip->i_dev, b, NORMAL); /* get the pathname block */
- memcpy(temp, bp->b_data, rip->i_size);
- temp[rip->i_size] = '\0';
- put_block(bp, NORMAL);
-
- q = strstr(path, string);
- if ((p = strchr(q, '/')) != NULL && (q + strlen(string)) == p) {
- strcat(temp, p);
- }
- strcpy(path, temp);
-
- put_inode(rip);
- rip = (*path == '/') ? fp->fp_rootdir : ldip;
-
- dup_inode(rip);
- return (rip);
-}
-
-/** path.c **/
_PROTOTYPE( int do_mknod, (void) );
_PROTOTYPE( int do_mkdir, (void) );
_PROTOTYPE( int do_open, (void) );
-_PROTOTYPE( int do_symlink, (void) );
/* path.c */
_PROTOTYPE( struct inode *advance,(struct inode *dirp, char string[NAME_MAX]));
char string [NAME_MAX], ino_t *numb, int flag) );
_PROTOTYPE( struct inode *eat_path, (char *path) );
_PROTOTYPE( struct inode *last_dir, (char *path, char string [NAME_MAX]));
-_PROTOTYPE( struct inode *slink_traverse, (struct inode *rip, char *path,
- char string[NAME_MAX], struct inode *ldip) );
/* pipe.c */
_PROTOTYPE( int do_pipe, (void) );
_PROTOTYPE( int do_fchdir, (void) );
_PROTOTYPE( int do_chroot, (void) );
_PROTOTYPE( int do_fstat, (void) );
-_PROTOTYPE( int do_lstat, (void) );
-_PROTOTYPE( int do_rdlink, (void) );
_PROTOTYPE( int do_stat, (void) );
_PROTOTYPE( int do_fstatfs, (void) );
* do_chroot: perform the CHROOT system call
* do_stat: perform the STAT system call
* do_fstat: perform the FSTAT system call
- * do_rdlink: perform the RDLINK system call
- * do_lstat: perform the LSTAT system call
* do_fstatfs: perform the FSTATFS system call
*/
#include "fs.h"
-#include "buf.h"
#include <sys/stat.h>
#include <sys/statfs.h>
#include <minix/com.h>
return(r);
}
-/*===========================================================================*
- * do_rdlink *
- *===========================================================================*/
-PUBLIC int do_rdlink()
-{
-/* Perform the readlink(name, buf, bufsiz) system call. */
-
- register struct inode *ldip, *rip;
- register int r;
- char string[NAME_MAX];
- register char *p;
- vir_bytes v;
- block_t b;
- struct buf *bp;
-
- if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
- if ( (ldip = last_dir(user_path, string)) == NIL_INODE) return(err_code);
-
- /* Get final component of the path. */
- rip = advance(ldip, string);
- put_inode(ldip);
-
- if (rip == NIL_INODE) return(err_code);
-
- if ((rip->i_mode & I_TYPE) == I_SYMBOLIC_LINK) {
-#define bufsiz m1_i2
- int len = MIN(rip->i_size, m_in.bufsiz);
- b = read_map(rip, 0);
- bp = get_block(rip->i_dev, b, NORMAL);
- /* Copy the name to user space. */
- r = sys_datacopy(FS_PROC_NR, (phys_bytes) bp->b_data,
- who, (phys_bytes) m_in.name2, (phys_bytes) len);
- put_block(bp, NORMAL);
- r = rip->i_size;
- } else
- r = EINVAL;
- put_inode(rip); /* release the inode */
- return(r);
-}
-
-/*===========================================================================*
- * do_lstat *
- *===========================================================================*/
-PUBLIC int do_lstat()
-{
-/* Perform the lstat(name, buf) system call. */
-
- register struct inode *ldip, *rip;
- register int r;
- char string[NAME_MAX];
- register char *p;
-
- if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
-
- /* Can't use eat_path() since it will traverse the link */
- if ( (ldip = last_dir(user_path, string)) == NIL_INODE) return(err_code);
-
- /* Get final component of the path. */
- rip = advance(ldip, string);
- put_inode(ldip);
-
- if (rip == NIL_INODE) return(err_code);
-
- r = stat_inode(rip, NIL_FILP, m_in.name2); /* Work just like stat */
-
- put_inode(rip); /* Release the inode */
- return(r);
-}
-
/*===========================================================================*
* do_fstatfs *
*===========================================================================*/
return(r);
}
-/** stadir.c **/
do_pipe, /* 42 = pipe */
no_sys, /* 43 = times */
no_sys, /* 44 = (prof) */
- do_symlink, /* 45 = symlink */
+ no_sys, /* 45 = symlink */
do_set, /* 46 = setgid */
no_sys, /* 47 = getgid */
no_sys, /* 48 = (signal)*/
- do_rdlink, /* 49 = readlink*/
- do_lstat, /* 50 = lstat */
+ no_sys, /* 49 = readlink*/
+ no_sys, /* 50 = lstat */
no_sys, /* 51 = (acct) */
no_sys, /* 52 = (phys) */
no_sys, /* 53 = (lock) */