This source file includes following definitions.
- ncp_read_inode
- ncp_put_inode
- ncp_read_super
- ncp_put_super
- ncp_trigger_message
- ncp_statfs
- ncp_notify_change
- init_ncp_fs
- init_module
- cleanup_module
1
2
3
4
5
6
7
8 #include <linux/module.h>
9 #include <linux/config.h>
10
11 #include <asm/system.h>
12 #include <asm/segment.h>
13
14 #include <linux/sched.h>
15 #include <linux/ncp_fs.h>
16 #include <linux/kernel.h>
17 #include <linux/mm.h>
18 #include <linux/string.h>
19 #include <linux/stat.h>
20 #include <linux/errno.h>
21 #include <linux/locks.h>
22 #include <linux/fcntl.h>
23 #include <linux/malloc.h>
24 #ifdef CONFIG_KERNELD
25 #include <linux/kerneld.h>
26 #endif
27 #include "ncplib_kernel.h"
28
29 extern int close_fp(struct file *filp);
30
31 static void ncp_put_inode(struct inode *);
32 static void ncp_read_inode(struct inode *);
33 static void ncp_put_super(struct super_block *);
34 static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
35 static int ncp_notify_change(struct inode *inode, struct iattr *attr);
36
37 static struct super_operations ncp_sops = {
38 ncp_read_inode,
39 ncp_notify_change,
40 NULL,
41 ncp_put_inode,
42 ncp_put_super,
43 NULL,
44 ncp_statfs,
45 NULL
46 };
47
48
49
50
51
52 static void
53 ncp_read_inode(struct inode *inode)
54 {
55
56
57
58
59
60
61 struct ncp_inode_info *inode_info
62 = (struct ncp_inode_info *)(inode->i_ino);
63
64 #if 1
65 struct ncp_inode_info *root = &(NCP_SERVER(inode)->root);
66 struct ncp_inode_info *check_info = root;
67
68 do
69 {
70 if (inode_info == check_info)
71 {
72 if (check_info->state == NCP_INODE_LOOKED_UP)
73 {
74 DDPRINTK("ncp_read_inode: found it!\n");
75 goto good;
76 }
77 else
78 {
79 printk("ncp_read_inode: "
80 "state != NCP_INODE_LOOKED_UP\n");
81 goto good;
82 }
83 }
84 check_info = check_info->next;
85 }
86 while (check_info != root);
87
88
89
90 printk("ncp_read_inode: inode info not found\n");
91 return;
92
93 good:
94 DDPRINTK("ncp_read_inode: read entry %s\n",
95 inode_info->finfo.i.entryName);
96 #endif
97 inode_info->state = NCP_INODE_VALID;
98
99 NCP_INOP(inode) = inode_info;
100
101 if (NCP_ISTRUCT(inode)->attributes & aDIR)
102 {
103 inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
104
105
106 inode->i_size = 512;
107 }
108 else
109 {
110 inode->i_mode = NCP_SERVER(inode)->m.file_mode;
111 inode->i_size = NCP_ISTRUCT(inode)->dataStreamSize;
112 }
113
114 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
115
116 inode->i_nlink = 1;
117 inode->i_uid = NCP_SERVER(inode)->m.uid;
118 inode->i_gid = NCP_SERVER(inode)->m.gid;
119 inode->i_blksize = 1024;
120 inode->i_rdev = 0;
121
122 if ((inode->i_blksize != 0) && (inode->i_size != 0))
123 {
124 inode->i_blocks =
125 (inode->i_size - 1) / inode->i_blksize + 1;
126 }
127 else
128 {
129 inode->i_blocks = 0;
130 }
131
132 inode->i_mtime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->modifyTime,
133 NCP_ISTRUCT(inode)->modifyDate);
134 inode->i_ctime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->creationTime,
135 NCP_ISTRUCT(inode)->creationDate);
136 inode->i_atime = ncp_date_dos2unix(0,
137 NCP_ISTRUCT(inode)->lastAccessDate);
138
139 if (S_ISREG(inode->i_mode))
140 {
141 inode->i_op = &ncp_file_inode_operations;
142 }
143 else if (S_ISDIR(inode->i_mode))
144 {
145 inode->i_op = &ncp_dir_inode_operations;
146 }
147 else
148 {
149 inode->i_op = NULL;
150 }
151 }
152
153 static void
154 ncp_put_inode(struct inode *inode)
155 {
156 struct nw_file_info *finfo = NCP_FINFO(inode);
157
158 if (finfo->opened != 0)
159 {
160 if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
161 {
162
163 printk("ncp_put_inode: could not close\n");
164 }
165 }
166
167 DDPRINTK("ncp_put_inode: put %s\n",
168 finfo->i.entryName);
169
170 ncp_free_inode_info(NCP_INOP(inode));
171
172 if (S_ISDIR(inode->i_mode))
173 {
174 DDPRINTK("ncp_put_inode: put directory %ld\n",
175 inode->i_ino);
176 ncp_invalid_dir_cache(inode->i_ino);
177 }
178
179 clear_inode(inode);
180 }
181
182 struct super_block *
183 ncp_read_super(struct super_block *sb, void *raw_data, int silent)
184 {
185 struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
186 struct ncp_server *server;
187 struct file *ncp_filp;
188 struct file *wdog_filp;
189 struct file *msg_filp;
190 kdev_t dev = sb->s_dev;
191 int error;
192
193 if (data == NULL)
194 {
195 printk("ncp_read_super: missing data argument\n");
196 sb->s_dev = 0;
197 return NULL;
198 }
199
200 if (data->version != NCP_MOUNT_VERSION)
201 {
202 printk("ncp warning: mount version %s than kernel\n",
203 (data->version < NCP_MOUNT_VERSION) ?
204 "older" : "newer");
205 sb->s_dev = 0;
206 return NULL;
207 }
208
209 if ( (data->ncp_fd >= NR_OPEN)
210 || ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL)
211 || (!S_ISSOCK(ncp_filp->f_inode->i_mode)))
212 {
213 printk("ncp_read_super: invalid ncp socket\n");
214 sb->s_dev = 0;
215 return NULL;
216 }
217
218 if ( (data->wdog_fd >= NR_OPEN)
219 || ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL)
220 || (!S_ISSOCK(wdog_filp->f_inode->i_mode)))
221 {
222 printk("ncp_read_super: invalid wdog socket\n");
223 sb->s_dev = 0;
224 return NULL;
225 }
226
227 if ( (data->message_fd >= NR_OPEN)
228 || ((msg_filp = current->files->fd[data->message_fd]) == NULL)
229 || (!S_ISSOCK(msg_filp->f_inode->i_mode)))
230 {
231 printk("ncp_read_super: invalid wdog socket\n");
232 sb->s_dev = 0;
233 return NULL;
234 }
235
236
237 server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
238 GFP_KERNEL);
239
240 if (server == NULL)
241 {
242 printk("ncp_read_super: could not alloc ncp_server\n");
243 return NULL;
244 }
245
246 ncp_filp->f_count += 1;
247 wdog_filp->f_count += 1;
248 msg_filp->f_count += 1;
249
250 lock_super(sb);
251
252 NCP_SBP(sb) = server;
253
254 sb->s_blocksize = 1024;
255 sb->s_blocksize_bits = 10;
256 sb->s_magic = NCP_SUPER_MAGIC;
257 sb->s_dev = dev;
258 sb->s_op = &ncp_sops;
259
260 server->ncp_filp = ncp_filp;
261 server->wdog_filp = wdog_filp;
262 server->msg_filp = msg_filp;
263 server->lock = 0;
264 server->wait = NULL;
265 server->packet = NULL;
266 server->buffer_size = 0;
267 server->conn_status = 0;
268
269 server->m = *data;
270 server->m.file_mode = (server->m.file_mode &
271 (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
272 server->m.dir_mode = (server->m.dir_mode &
273 (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
274
275
276 server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0';
277
278 server->packet_size = NCP_PACKET_SIZE;
279 server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
280
281 if (server->packet == NULL)
282 {
283 printk("ncpfs: could not alloc packet\n");
284 error = -ENOMEM;
285 unlock_super(sb);
286 goto fail;
287 }
288
289 ncp_init_root(server);
290
291
292
293
294
295 if (ncp_catch_watchdog(server) != 0)
296 {
297 printk("ncp_read_super: Could not catch watchdog\n");
298 error = -EINVAL;
299 unlock_super(sb);
300 goto fail;
301 }
302
303 if (ncp_catch_message(server) != 0)
304 {
305 printk("ncp_read_super: Could not catch messages\n");
306 ncp_dont_catch_watchdog(server);
307 error = -EINVAL;
308 unlock_super(sb);
309 goto fail;
310 }
311
312 ncp_lock_server(server);
313 error = ncp_connect(server);
314 ncp_unlock_server(server);
315 unlock_super(sb);
316
317 if (error < 0)
318 {
319 sb->s_dev = 0;
320 printk("ncp_read_super: Failed connection, bailing out "
321 "(error = %d).\n", -error);
322 ncp_kfree_s(server->packet, server->packet_size);
323 ncp_dont_catch_watchdog(server);
324 goto fail;
325 }
326
327 DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));
328
329 if (!(sb->s_mounted = iget(sb, (int)&(server->root))))
330 {
331 sb->s_dev = 0;
332 printk("ncp_read_super: get root inode failed\n");
333 goto disconnect;
334 }
335
336 if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
337 &(server->buffer_size)) != 0)
338 {
339 sb->s_dev = 0;
340 printk("ncp_read_super: could not get bufsize\n");
341 goto disconnect;
342 }
343
344 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
345
346 MOD_INC_USE_COUNT;
347 return sb;
348
349 disconnect:
350 ncp_lock_server(server);
351 ncp_disconnect(server);
352 ncp_unlock_server(server);
353 ncp_kfree_s(server->packet, server->packet_size);
354 ncp_dont_catch_watchdog(server);
355 fail:
356 ncp_filp->f_count -= 1;
357 wdog_filp->f_count -= 1;
358 msg_filp->f_count -= 1;
359 ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
360 return NULL;
361 }
362
363 static void
364 ncp_put_super(struct super_block *sb)
365 {
366 struct ncp_server *server = NCP_SBP(sb);
367
368 lock_super(sb);
369
370 ncp_lock_server(server);
371 ncp_disconnect(server);
372 ncp_unlock_server(server);
373
374 close_fp(server->ncp_filp);
375
376 ncp_dont_catch_watchdog(server);
377 close_fp(server->wdog_filp);
378 close_fp(server->msg_filp);
379
380 ncp_free_all_inodes(server);
381
382 ncp_kfree_s(server->packet, server->packet_size);
383
384 sb->s_dev = 0;
385 ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
386 NCP_SBP(sb) = NULL;
387
388 unlock_super(sb);
389
390 MOD_DEC_USE_COUNT;
391 }
392
393
394
395 void
396 ncp_trigger_message(struct ncp_server *server)
397 {
398 char command[ sizeof(server->m.mount_point)
399 + sizeof(NCP_MSG_COMMAND) + 2];
400
401 if (server == NULL)
402 {
403 printk("ncp_trigger_message: invalid server!\n");
404 return;
405 }
406
407 DPRINTK("ncp_trigger_message: on %s\n",
408 server->m.mount_point);
409
410 #ifdef CONFIG_KERNELD
411 strcpy(command, NCP_MSG_COMMAND);
412 strcat(command, " ");
413 strcat(command, server->m.mount_point);
414 DPRINTK("ksystem: %s\n", command);
415 ksystem(command, KERNELD_NOWAIT);
416 #endif
417 }
418
419 static void
420 ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
421 {
422 struct statfs tmp;
423
424
425
426
427
428
429
430 tmp.f_type = NCP_SUPER_MAGIC;
431 tmp.f_bsize = 512;
432 tmp.f_blocks = 0;
433 tmp.f_bfree = 0;
434 tmp.f_bavail = 0;
435 tmp.f_files = -1;
436 tmp.f_ffree = -1;
437 tmp.f_namelen = 12;
438 memcpy_tofs(buf, &tmp, bufsiz);
439 }
440
441 static int
442 ncp_notify_change(struct inode *inode, struct iattr *attr)
443 {
444 int result = 0;
445 int info_mask;
446 struct nw_modify_dos_info info;
447
448 if (!ncp_conn_valid(NCP_SERVER(inode)))
449 {
450 return -EIO;
451 }
452
453 if ((result = inode_change_ok(inode, attr)) < 0)
454 return result;
455
456 if (((attr->ia_valid & ATTR_UID) &&
457 (attr->ia_uid != NCP_SERVER(inode)->m.uid)))
458 return -EPERM;
459
460 if (((attr->ia_valid & ATTR_GID) &&
461 (attr->ia_uid != NCP_SERVER(inode)->m.gid)))
462 return -EPERM;
463
464 if (((attr->ia_valid & ATTR_MODE) &&
465 (attr->ia_mode &
466 ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO))))
467 return -EPERM;
468
469 info_mask = 0;
470 memset(&info, 0, sizeof(info));
471
472 if ((attr->ia_valid & ATTR_CTIME) != 0)
473 {
474 info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
475 ncp_date_unix2dos(attr->ia_ctime,
476 &(info.creationTime), &(info.creationDate));
477 }
478
479 if ((attr->ia_valid & ATTR_MTIME) != 0)
480 {
481 info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
482 ncp_date_unix2dos(attr->ia_mtime,
483 &(info.modifyTime), &(info.modifyDate));
484 }
485
486 if ((attr->ia_valid & ATTR_ATIME) != 0)
487 {
488 __u16 dummy;
489 info_mask |= (DM_LAST_ACCESS_DATE);
490 ncp_date_unix2dos(attr->ia_ctime,
491 &(dummy), &(info.lastAccessDate));
492 }
493
494 if (info_mask != 0)
495 {
496 if ((result =
497 ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
498 NCP_ISTRUCT(inode),
499 info_mask,
500 &info)) != 0)
501 {
502 result = -EACCES;
503
504 if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE))
505 {
506
507
508
509
510
511 result = 0;
512 }
513 }
514 }
515
516 if ((attr->ia_valid & ATTR_SIZE) != 0)
517 {
518 int written;
519
520 DPRINTK("ncpfs: trying to change size of %s to %ld\n",
521 NCP_ISTRUCT(inode)->entryName, attr->ia_size);
522
523 if ((result = ncp_make_open(inode, O_RDWR)) < 0)
524 {
525 return -EACCES;
526 }
527
528 ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
529 attr->ia_size, 0, "", &written);
530
531
532
533 ncp_close_file(NCP_SERVER(inode),
534 NCP_FINFO(inode)->file_handle);
535 NCP_FINFO(inode)->opened = 0;
536
537 result = 0;
538 }
539
540 ncp_invalid_dir_cache((unsigned long)(NCP_INOP(inode)->dir));
541
542 return result;
543 }
544
545 #ifdef DEBUG_NCP_MALLOC
546 int ncp_malloced;
547 int ncp_current_malloced;
548 #endif
549
550 static struct file_system_type ncp_fs_type = {
551 ncp_read_super, "ncpfs", 0, NULL
552 };
553
554 int init_ncp_fs(void)
555 {
556 return register_filesystem(&ncp_fs_type);
557 }
558
559 #ifdef MODULE
560 int
561 init_module( void)
562 {
563 int status;
564
565 DPRINTK("ncpfs: init_module called\n");
566
567 #ifdef DEBUG_NCP_MALLOC
568 ncp_malloced = 0;
569 ncp_current_malloced = 0;
570 #endif
571 ncp_init_dir_cache();
572
573 if ((status = init_ncp_fs()) == 0)
574 register_symtab(0);
575 return status;
576 }
577
578 void
579 cleanup_module(void)
580 {
581 DPRINTK("ncpfs: cleanup_module called\n");
582 ncp_free_dir_cache();
583 unregister_filesystem(&ncp_fs_type);
584 #ifdef DEBUG_NCP_MALLOC
585 printk("ncp_malloced: %d\n", ncp_malloced);
586 printk("ncp_current_malloced: %d\n", ncp_current_malloced);
587 #endif
588 }
589
590 #endif