/* * Removes an entry from a directory. */ PUBLIC int dir_remove(struct inode *dinode, const char *filename) { struct buffer *buf; /* Block buffer. */ struct d_dirent *d; /* Directory entry. */ struct inode *file; /* File inode. */ d = dirent_search(dinode, filename, &buf, 0); /* Not found. */ if (d == NULL) return (-ENOENT); /* Cannot remove '.' */ if (d->d_ino == dinode->num) { brelse(buf); return (-EBUSY); } file = inode_get(dinode->dev, d->d_ino); /* Failed to get file's inode. */ if (file == NULL) { brelse(buf); return (-ENOENT); } /* Unlinking directory. */ if (S_ISDIR(file->mode)) { /* Not allowed. */ if (!IS_SUPERUSER(curr_proc)) { inode_put(file); brelse(buf); return (-EPERM); } /* Directory not empty. */ if (dinode->size) { inode_put(file); brelse(buf); return (-EBUSY); } } /* Remove directory entry. */ d->d_ino = INODE_NULL; buf->flags |= BUFFER_DIRTY; inode_touch(dinode); file->nlinks--; inode_touch(file); inode_put(file); brelse(buf); return (0); }
/** * @brief Shutdowns the system. */ PUBLIC int sys_shutdown(void) { /* Not allowed. */ if (!IS_SUPERUSER(curr_proc)) return (-EPERM); shutting_down = 1; cdev_ioctl(kout, TTY_CLEAR, 0); kprintf("system is going to shutdown NOW"); kprintf("synchronizing data..."); sys_sync(); kprintf("asking process to terminate..."); sys_kill(-1, SIGKILL); return (0); }
/* * Checks rwx permissions on a file. */ PUBLIC mode_t permission(mode_t mode, uid_t uid, gid_t gid, struct process *proc, mode_t mask, int oreal) { mode &= mask; /* Super user. */ if (IS_SUPERUSER(proc)) mode &= S_IRWXU | S_IRWXG | S_IRWXO; /* Owner user. */ else if ((proc->uid == uid) || ((!oreal && proc->euid == uid))) mode &= S_IRWXU | S_IRWXG | S_IRWXO; /* Owner's group user. */ else if ((proc->gid == gid) || ((!oreal && proc->egid == gid))) mode &= S_IRWXG | S_IRWXO; /* Other user. */ else mode &= S_IRWXO; return (mode); }
/* * Sets the real user ID of the calling process. */ PUBLIC int sys_setuid(pid_t uid) { /* Superuser authentication. */ if (IS_SUPERUSER(curr_proc)) { curr_proc->uid = uid; curr_proc->euid = uid; curr_proc->suid = uid; } else { /* User authentication. */ if ((uid == curr_proc->uid) || (uid == curr_proc->suid)) curr_proc->euid = uid; /* No authentication. */ else return (-EPERM); } return (0); }