int ncp_request2(struct ncp_server *server, int function, void* rpl, int size) { struct ncp_request_header *h; struct ncp_reply_header* reply = rpl; int result; h = (struct ncp_request_header *) (server->packet); if (server->has_subfunction != 0) { *(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2); } h->type = NCP_REQUEST; h->task = 2; h->function = function; result = ncp_do_request(server, server->current_size, reply, size); if (result < 0) { DPRINTK("ncp_request_error: %d\n", result); goto out; } server->completion = reply->completion_code; server->conn_status = reply->connection_state; server->reply_size = result; server->ncp_reply_size = result - sizeof(struct ncp_reply_header); result = reply->completion_code; if (result != 0) PPRINTK("ncp_request: completion code=%x\n", result); out: return result; }
/* ncp_do_request assures that at least a complete reply header is * received. It assumes that server->current_size contains the ncp * request size */ int ncp_request2(struct ncp_server *server, int function, void* rpl, int size) { struct ncp_request_header *h; struct ncp_reply_header* reply = rpl; int request_size = server->current_size - sizeof(struct ncp_request_header); int result; h = (struct ncp_request_header *) (server->packet); if (server->has_subfunction != 0) { *(__u16 *) & (h->data[0]) = htons(request_size - 2); } h->type = NCP_REQUEST; server->sequence += 1; h->sequence = server->sequence; h->conn_low = (server->connection) & 0xff; h->conn_high = ((server->connection) & 0xff00) >> 8; /* * The server shouldn't know or care what task is making a * request, so we always use the same task number. */ h->task = 2; /* (current->pid) & 0xff; */ h->function = function; result = ncp_do_request(server, request_size + sizeof(*h), reply, size); if (result < 0) { DPRINTK("ncp_request_error: %d\n", result); goto out; } server->completion = reply->completion_code; server->conn_status = reply->connection_state; server->reply_size = result; server->ncp_reply_size = result - sizeof(struct ncp_reply_header); result = reply->completion_code; if (result != 0) PPRINTK("ncp_request: completion code=%x\n", result); out: return result; }
/* * Open a file with the specified read/write mode. */ int ncp_make_open(struct inode *inode, int right) { int error; int access; error = -EINVAL; if (!inode) { printk(KERN_ERR "ncp_make_open: got NULL inode\n"); goto out; } DPRINTK("ncp_make_open: opened=%d, volume # %u, dir entry # %u\n", atomic_read(&NCP_FINFO(inode)->opened), NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); error = -EACCES; down(&NCP_FINFO(inode)->open_sem); if (!atomic_read(&NCP_FINFO(inode)->opened)) { struct ncp_entry_info finfo; int result; finfo.i.dirEntNum = NCP_FINFO(inode)->dirEntNum; finfo.i.volNumber = NCP_FINFO(inode)->volNumber; /* tries max. rights */ finfo.access = O_RDWR; result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), NULL, NULL, OC_MODE_OPEN, 0, AR_READ | AR_WRITE, &finfo); if (!result) goto update; /* RDWR did not succeeded, try readonly or writeonly as requested */ switch (right) { case O_RDONLY: finfo.access = O_RDONLY; result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), NULL, NULL, OC_MODE_OPEN, 0, AR_READ, &finfo); break; case O_WRONLY: finfo.access = O_WRONLY; result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), NULL, NULL, OC_MODE_OPEN, 0, AR_WRITE, &finfo); break; } if (result) { PPRINTK("ncp_make_open: failed, result=%d\n", result); goto out_unlock; } /* * Update the inode information. */ update: ncp_update_inode(inode, &finfo); atomic_set(&NCP_FINFO(inode)->opened, 1); } access = NCP_FINFO(inode)->access; PPRINTK("ncp_make_open: file open, access=%x\n", access); if (access == right || access == O_RDWR) { atomic_inc(&NCP_FINFO(inode)->opened); error = 0; } out_unlock: up(&NCP_FINFO(inode)->open_sem); out: return error; }
int ncp_make_open(struct inode *inode, int right) { int error; int access; error = -EINVAL; if (!inode) { printk(KERN_ERR "ncp_make_open: got NULL inode\n"); goto out; } DPRINTK("ncp_make_open: opened=%d, volume # %u, dir entry # %u\n", atomic_read(&NCP_FINFO(inode)->opened), NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); error = -EACCES; mutex_lock(&NCP_FINFO(inode)->open_mutex); if (!atomic_read(&NCP_FINFO(inode)->opened)) { struct ncp_entry_info finfo; int result; /* */ finfo.access = O_RDWR; result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), inode, NULL, OC_MODE_OPEN, 0, AR_READ | AR_WRITE, &finfo); if (!result) goto update; /* */ switch (right) { case O_RDONLY: finfo.access = O_RDONLY; result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), inode, NULL, OC_MODE_OPEN, 0, AR_READ, &finfo); break; case O_WRONLY: finfo.access = O_WRONLY; result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), inode, NULL, OC_MODE_OPEN, 0, AR_WRITE, &finfo); break; } if (result) { PPRINTK("ncp_make_open: failed, result=%d\n", result); goto out_unlock; } /* */ update: ncp_update_inode(inode, &finfo); atomic_set(&NCP_FINFO(inode)->opened, 1); } access = NCP_FINFO(inode)->access; PPRINTK("ncp_make_open: file open, access=%x\n", access); if (access == right || access == O_RDWR) { atomic_inc(&NCP_FINFO(inode)->opened); error = 0; } out_unlock: mutex_unlock(&NCP_FINFO(inode)->open_mutex); out: return error; }