inoptr newfile(inoptr pino, char *name) { inoptr nindex; uint8_t j; /* First see if parent is writeable */ if(!(getperm(pino) & OTH_WR)) goto nogood; if(!(nindex = i_open(pino->c_dev, 0))) goto nogood; /* BUG FIX: user/group setting was missing SN */ nindex->c_node.i_uid = udata.u_euid; nindex->c_node.i_gid = udata.u_egid; nindex->c_node.i_mode = F_REG; /* For the time being */ nindex->c_node.i_nlink = 1; nindex->c_node.i_size = 0; for(j=0; j <20; j++) nindex->c_node.i_addr[j] = 0; wr_inode(nindex); if(!ch_link(pino, "", name, nindex)) { i_deref(nindex); goto nogood; } i_deref(pino); return nindex; nogood: i_deref(pino); return NULLINODE; }
arg_t _link(void) { inoptr ino; inoptr ino2; inoptr parent2; char fname[FILENAME_LEN + 1]; if (!(ino = n_open(name1, NULLINOPTR))) return (-1); if (getmode(ino) == F_DIR && esuper()) goto nogood; if (ino->c_node.i_nlink == 0xFFFF) { udata.u_error = EMLINK; goto nogood; } /* Make sure file2 doesn't exist, and get its parent */ if ((ino2 = n_open(name2, &parent2)) != NULL) { i_deref(ino2); i_deref(parent2); udata.u_error = EEXIST; goto nogood; } if (!parent2) goto nogood; if (ino->c_dev != parent2->c_dev) { i_deref(parent2); udata.u_error = EXDEV; goto nogood; } filename(name2, fname); if (!ch_link(parent2, "", fname, ino)) { i_deref(parent2); goto nogood; } /* Update the link count. */ ++ino->c_node.i_nlink; wr_inode(ino); setftime(ino, C_TIME); i_deref(parent2); i_deref(ino); return 0; nogood: i_deref(ino); return -1; }
/* Helper for the bits shared with rename */ int16_t unlinki(inoptr ino, inoptr pino, char *fname) { if (getmode(ino) == F_DIR) { udata.u_error = EISDIR; return -1; } /* Remove the directory entry (ch_link checks perms) */ if (!ch_link(pino, fname, "", NULLINODE)) return -1; /* Decrease the link count of the inode */ if (!(ino->c_node.i_nlink--)) { ino->c_node.i_nlink += 2; kprintf("_unlink: bad nlink\n"); } setftime(ino, C_TIME); return (0); }