Npfcall* diod_getattr(Npfid *fid, u64 request_mask) { Fid *f = fid->aux; Npfcall *ret; Npqid qid; struct stat sb; if ((f->flags & DIOD_FID_FLAGS_MOUNTPT)) { if (_statmnt (path_s (f->path), &sb) < 0) { np_uerror (errno); goto error_quiet; } } else { if (lstat (path_s (f->path), &sb) < 0) { np_uerror (errno); goto error_quiet; } } diod_ustat2qid (&sb, &qid); if (!(ret = np_create_rgetattr(request_mask, &qid, sb.st_mode, sb.st_uid, sb.st_gid, sb.st_nlink, sb.st_rdev, sb.st_size, sb.st_blksize, sb.st_blocks, sb.st_atim.tv_sec, sb.st_atim.tv_nsec, sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec, sb.st_ctim.tv_sec, sb.st_ctim.tv_nsec, 0, 0, 0, 0))) { np_uerror (ENOMEM); goto error; } return ret; error: errn (np_rerror (), "diod_getattr %s@%s:%s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path)); error_quiet: return NULL; }
/* Twalk - walk a file path * Called from fcall.c::np_walk () on each wname component in succession. * On error, call np_uerror () and return 0. */ int diod_walk (Npfid *fid, Npstr* wname, Npqid *wqid) { Npsrv *srv = fid->conn->srv; Fid *f = fid->aux; struct stat sb, sb2; Path npath = NULL; if ((f->flags & DIOD_FID_FLAGS_MOUNTPT)) { np_uerror (ENOENT); goto error_quiet; } if (!(npath = path_append (srv, f->path, wname))) { np_uerror (ENOMEM); goto error; } if (lstat (path_s (npath), &sb) < 0) { np_uerror (errno); goto error_quiet; } if (lstat (path_s (f->path), &sb2) < 0) { np_uerror (errno); goto error; } if (sb.st_dev != sb2.st_dev) { if (_statmnt (path_s (npath), &sb) < 0) goto error; f->flags |= DIOD_FID_FLAGS_MOUNTPT; } path_decref (srv, f->path); f->path = npath; diod_ustat2qid (&sb, wqid); return 1; error: errn (np_rerror (), "diod_walk %s@%s:%s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path), wname->len, wname->str); error_quiet: if (npath) path_decref (srv, npath); return 0; }
/* Twalk - walk a file path * Called from fcall.c::np_walk () on each wname component in succession. * On error, call np_uerror () and return 0. */ int diod_walk (Npfid *fid, Npstr* wname, Npqid *wqid) { Fid *f = fid->aux; struct stat sb, sb2; char *npath = NULL; if (f->mountpt) { np_uerror (ENOENT); goto error_quiet; } if (!(npath = _mkpath (f->path, wname))) { np_uerror (ENOMEM); goto error; } if (lstat (npath, &sb) < 0) { np_uerror (errno); goto error_quiet; } if (lstat (f->path, &sb2) < 0) { np_uerror (errno); goto error; } if (sb.st_dev != sb2.st_dev) { if (_statmnt (npath, &sb) < 0) goto error; f->mountpt = 1; } free (f->path); f->path = npath; _ustat2qid (&sb, wqid); return 1; error: errn (np_rerror (), "diod_walk %s@%s:%s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), f->path, wname->len, wname->str); error_quiet: if (npath) free (npath); return 0; }