root/fs/ncpfs/ncplib_kernel.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. min
  2. assert_server_locked
  3. ncp_add_byte
  4. ncp_add_word
  5. ncp_add_dword
  6. ncp_add_mem
  7. ncp_add_mem_fromfs
  8. ncp_add_pstring
  9. ncp_init_request
  10. ncp_init_request_s
  11. ncp_reply_data
  12. ncp_reply_byte
  13. ncp_reply_word
  14. ncp_reply_dword
  15. ncp_negotiate_buffersize
  16. ncp_get_volume_info_with_number
  17. ncp_get_volume_number
  18. ncp_close_file
  19. ncp_add_handle_path
  20. ncp_extract_file_info
  21. ncp_do_lookup
  22. ncp_modify_file_or_subdir_dos_info
  23. ncp_del_file_or_subdir
  24. ConvertToNWfromDWORD
  25. ncp_open_create_file_or_subdir
  26. ncp_initialize_search
  27. ncp_search_for_file_or_subdir
  28. ncp_ren_or_mov_file_or_subdir
  29. ncp_read
  30. ncp_write

   1 #include "ncplib_kernel.h"
   2 
   3 typedef __u8  byte;
   4 typedef __u16 word;
   5 typedef __u32 dword;
   6 
   7 static inline int min(int a, int b)
     /* [previous][next][first][last][top][bottom][index][help] */
   8 {
   9         return a<b ? a : b;
  10 }
  11 
  12 static void
  13 assert_server_locked(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
  14 {
  15         if (server->lock == 0)
  16         {
  17                 DPRINTK("ncpfs: server not locked!\n");
  18         }
  19 }
  20 
  21 static void
  22 ncp_add_byte(struct ncp_server *server, byte x)
     /* [previous][next][first][last][top][bottom][index][help] */
  23 {
  24         assert_server_locked(server);
  25         *(byte *)(&(server->packet[server->current_size])) = x;
  26         server->current_size += 1;
  27         return;
  28 }
  29 
  30 static void
  31 ncp_add_word(struct ncp_server *server, word x)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         assert_server_locked(server);
  34         *(word *)(&(server->packet[server->current_size])) = x;
  35         server->current_size += 2;
  36         return;
  37 }
  38 
  39 static void
  40 ncp_add_dword(struct ncp_server *server, dword x)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         assert_server_locked(server);
  43         *(dword *)(&(server->packet[server->current_size])) = x;
  44         server->current_size += 4;
  45         return;
  46 }
  47 
  48 static void
  49 ncp_add_mem(struct ncp_server *server, const void *source, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51         assert_server_locked(server);
  52         memcpy(&(server->packet[server->current_size]), source, size);
  53         server->current_size += size;
  54         return;
  55 }
  56 
  57 static void
  58 ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60         assert_server_locked(server);
  61         memcpy_fromfs(&(server->packet[server->current_size]), source, size);
  62         server->current_size += size;
  63         return;
  64 }
  65 
  66 static void
  67 ncp_add_pstring(struct ncp_server *server, const char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         int len = strlen(s);
  70         assert_server_locked(server);
  71         if (len > 255)
  72         {
  73                 DPRINTK("ncpfs: string too long: %s\n", s);
  74                 len = 255;
  75         }
  76         ncp_add_byte(server, len);
  77         ncp_add_mem(server, s, len);
  78         return;
  79 }
  80 
  81 static void
  82 ncp_init_request(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84         ncp_lock_server(server);
  85 
  86         server->current_size = sizeof(struct ncp_request_header);
  87         server->has_subfunction = 0;
  88 }
  89 
  90 static void
  91 ncp_init_request_s(struct ncp_server *server, int subfunction)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         ncp_init_request(server);
  94         ncp_add_word(server, 0); /* preliminary size */
  95 
  96         ncp_add_byte(server, subfunction);
  97 
  98         server->has_subfunction = 1;
  99 }
 100 
 101 static char *
 102 ncp_reply_data(struct ncp_server *server, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
 105 }
 106 
 107 static byte
 108 ncp_reply_byte(struct ncp_server *server, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 109 {
 110         return *(byte *)(ncp_reply_data(server, offset));
 111 }
 112 
 113 static word
 114 ncp_reply_word(struct ncp_server *server, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116         return *(word *)(ncp_reply_data(server, offset));
 117 }
 118 
 119 static dword
 120 ncp_reply_dword(struct ncp_server *server, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122         return *(dword *)(ncp_reply_data(server, offset));
 123 }
 124 
 125 int
 126 ncp_negotiate_buffersize(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 127                          int size, int *target)
 128 {
 129         int result;
 130 
 131         ncp_init_request(server);
 132         ncp_add_word(server, htons(size));
 133         
 134         if ((result = ncp_request(server, 33)) != 0)
 135         {
 136                 ncp_unlock_server(server);
 137                 return result;
 138         }
 139 
 140         *target =min(ntohs(ncp_reply_word(server, 0)), size);
 141 
 142         ncp_unlock_server(server);
 143         return 0;
 144 }
 145 
 146 int
 147 ncp_get_volume_info_with_number(struct ncp_server *server, int n,
     /* [previous][next][first][last][top][bottom][index][help] */
 148                                 struct ncp_volume_info *target)
 149 {
 150         int result;
 151         int len;
 152 
 153         ncp_init_request_s(server, 44);
 154         ncp_add_byte(server, n);
 155 
 156         if ((result = ncp_request(server, 22)) != 0)
 157         {
 158                 ncp_unlock_server(server);
 159                 return result;
 160         }
 161 
 162         target->total_blocks = ncp_reply_dword(server, 0);
 163         target->free_blocks  = ncp_reply_dword(server, 4);
 164         target->purgeable_blocks = ncp_reply_dword(server, 8);
 165         target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12);
 166         target->total_dir_entries = ncp_reply_dword(server, 16);
 167         target->available_dir_entries = ncp_reply_dword(server, 20);
 168         target->sectors_per_block = ncp_reply_byte(server, 28);
 169 
 170         memset(&(target->volume_name), 0, sizeof(target->volume_name));
 171 
 172         len = ncp_reply_byte(server, 29);
 173         if (len > NCP_VOLNAME_LEN)
 174         {
 175                 DPRINTK("ncpfs: volume name too long: %d\n", len);
 176                 ncp_unlock_server(server);
 177                 return -EIO;
 178         }
 179 
 180         memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
 181         ncp_unlock_server(server);
 182         return 0;
 183 }
 184 
 185 int
 186 ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         int result;
 189 
 190         ncp_init_request_s(server, 5);
 191         ncp_add_pstring(server, name);
 192 
 193         if ((result = ncp_request(server, 22)) != 0)
 194         {
 195                 ncp_unlock_server(server);
 196                 return result;
 197         }
 198 
 199         *target = ncp_reply_byte(server, 0);
 200         ncp_unlock_server(server);
 201         return 0;
 202 }
 203 
 204 int
 205 ncp_close_file(struct ncp_server *server, const char *file_id)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207         int result;
 208 
 209         ncp_init_request(server);
 210         ncp_add_byte(server, 0);
 211         ncp_add_mem(server, file_id, 6);
 212 
 213         if ((result = ncp_request(server, 66)) != 0)
 214         {
 215                 ncp_unlock_server(server);
 216                 return result;
 217         }
 218 
 219         ncp_unlock_server(server);
 220         return 0;
 221 }
 222 
 223 static void
 224 ncp_add_handle_path(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 225                     __u8 vol_num,
 226                     __u32 dir_base, int have_dir_base,
 227                     char *path)
 228 {
 229         ncp_add_byte(server, vol_num);
 230         ncp_add_dword(server, dir_base);
 231         if (have_dir_base != 0)
 232         {
 233                 ncp_add_byte(server, 1); /* dir_base */
 234         }
 235         else
 236         {
 237                 ncp_add_byte(server, 0xff); /* no handle */
 238         }
 239         if (path != NULL)
 240         {
 241                 ncp_add_byte(server, 1); /* 1 component */
 242                 ncp_add_pstring(server, path);
 243         }
 244         else
 245         {
 246                 ncp_add_byte(server, 0);
 247         }
 248 }
 249 
 250 static void
 251 ncp_extract_file_info(void *structure, struct nw_info_struct *target)
     /* [previous][next][first][last][top][bottom][index][help] */
 252 {
 253         __u8 *name_len;
 254         const int info_struct_size = sizeof(struct nw_info_struct) - 257;
 255 
 256         memcpy(target, structure, info_struct_size);
 257         name_len = structure + info_struct_size;
 258         target->nameLen = *name_len;
 259         strncpy(target->entryName, name_len+1, *name_len);
 260         target->entryName[*name_len] = '\0';
 261         return;
 262 }
 263                 
 264 
 265 int
 266 ncp_do_lookup(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 267               struct nw_info_struct *dir,
 268               char *path,       /* may only be one component */
 269               struct nw_info_struct *target)
 270 {
 271         __u8  vol_num;
 272         __u32 dir_base;
 273         int result;
 274         char *volname = NULL;
 275 
 276         if (target == NULL)
 277         {
 278                 return -EINVAL;
 279         }
 280  
 281         if (dir == NULL)
 282         {
 283 
 284                 DDPRINTK("ncp_do_lookup: looking up vol %s\n", path);
 285 
 286                 /* Access a volume's root directory */
 287                 ncp_init_request(server);
 288                 ncp_add_byte(server, 22); /* subfunction */
 289                 ncp_add_byte(server, 0); /* dos name space */
 290                 ncp_add_byte(server, 0); /* reserved */
 291                 ncp_add_byte(server, 0); /* reserved */
 292                 ncp_add_byte(server, 0); /* reserved */
 293                 ncp_add_handle_path(server, 0, 0, 0, /* no handle */
 294                                     path);
 295 
 296                 if ((result = ncp_request(server, 87)) != 0)
 297                 {
 298                         ncp_unlock_server(server);
 299                         return result;
 300                 }
 301 
 302                 dir_base = ncp_reply_dword(server, 4);
 303                 vol_num  = ncp_reply_byte (server, 8);
 304                 ncp_unlock_server(server);
 305                 volname = path;
 306                 path = NULL;
 307         }
 308         else
 309         {
 310                 vol_num = dir->volNumber;
 311                 dir_base = dir->DosDirNum;
 312         }
 313 
 314         ncp_init_request(server);
 315         ncp_add_byte(server, 6); /* subfunction */
 316         ncp_add_byte(server, 0); /* dos name space */
 317         ncp_add_byte(server, 0); /* dos name space as dest */
 318         ncp_add_word(server, 0xff); /* get all */
 319         ncp_add_dword(server, RIM_ALL);
 320         ncp_add_handle_path(server, vol_num, dir_base, 1,
 321                             path);
 322 
 323         if ((result = ncp_request(server, 87)) != 0)
 324         {
 325                 ncp_unlock_server(server);
 326                 return result;
 327         }
 328 
 329         ncp_extract_file_info(ncp_reply_data(server, 0), target);
 330 
 331         if (volname != NULL)
 332         {
 333                 target->nameLen = strlen(volname);
 334                 strcpy(target->entryName, volname);
 335         }
 336 
 337         ncp_unlock_server(server);
 338         return 0;
 339 }
 340 
 341 int
 342 ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 343                                    struct nw_info_struct *file,
 344                                    __u32 info_mask,
 345                                    struct nw_modify_dos_info *info)
 346 {
 347         int result;
 348 
 349         ncp_init_request(server);
 350         ncp_add_byte(server, 7); /* subfunction */
 351         ncp_add_byte(server, 0); /* dos name space */
 352         ncp_add_byte(server, 0); /* reserved */
 353         ncp_add_word(server, 0x8006); /* search attribs: all */
 354 
 355         ncp_add_dword(server, info_mask);
 356         ncp_add_mem(server, info, sizeof(*info));
 357         ncp_add_handle_path(server, file->volNumber,
 358                             file->DosDirNum, 1, NULL);
 359 
 360         if ((result = ncp_request(server, 87)) != 0)
 361         {
 362                 ncp_unlock_server(server);
 363                 return result;
 364         }
 365 
 366         ncp_unlock_server(server);
 367         return 0;
 368 }
 369 
 370 int
 371 ncp_del_file_or_subdir(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 372                        struct nw_info_struct *dir, char *name)
 373 {
 374         int result;
 375 
 376         ncp_init_request(server);
 377         ncp_add_byte(server, 8); /* subfunction */
 378         ncp_add_byte(server, 0); /* dos name space */
 379         ncp_add_byte(server, 0); /* reserved */
 380         ncp_add_word(server, 0x8006); /* search attribs: all */
 381         ncp_add_handle_path(server, dir->volNumber,
 382                             dir->DosDirNum, 1, name);
 383         
 384         if ((result = ncp_request(server, 87)) != 0)
 385         {
 386                 ncp_unlock_server(server);
 387                 return result;
 388         }
 389 
 390         ncp_unlock_server(server);
 391         return 0;
 392 }
 393 
 394 static inline void
 395 ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
     /* [previous][next][first][last][top][bottom][index][help] */
 396 {
 397     __u16 *dest = (__u16 *) ret;
 398     memcpy(&(dest[1]), &sfd, 4);
 399     dest[0] = dest[1] + 1;
 400     return;
 401 }
 402 
 403 /* If both dir and name are NULL, then in target there's already a
 404    looked-up entry that wants to be opened. */
 405 int
 406 ncp_open_create_file_or_subdir(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 407                                struct nw_info_struct *dir, char *name,
 408                                int open_create_mode,
 409                                __u32 create_attributes,
 410                                int desired_acc_rights,
 411                                struct nw_file_info *target)
 412 {
 413         int result;
 414         __u16 search_attribs = 0x0006;
 415 
 416         if ((create_attributes & aDIR) != 0)
 417         {
 418                 search_attribs |= 0x8000;
 419         }
 420 
 421         ncp_init_request(server);
 422         ncp_add_byte(server, 1); /* subfunction */
 423         ncp_add_byte(server, 0); /* dos name space */
 424         ncp_add_byte(server, open_create_mode);
 425         ncp_add_word(server, search_attribs);
 426         ncp_add_dword(server, RIM_ALL);
 427         ncp_add_dword(server, create_attributes);
 428         /* The desired acc rights seem to be the inherited rights mask
 429            for directories */
 430         ncp_add_word(server, desired_acc_rights);
 431 
 432         if (dir != NULL)
 433         {
 434                 ncp_add_handle_path(server, dir->volNumber,
 435                                     dir->DosDirNum, 1, name);
 436         }
 437         else
 438         {
 439                 ncp_add_handle_path(server,
 440                                     target->i.volNumber, target->i.DosDirNum,
 441                                     1, NULL);
 442         }       
 443 
 444         if ((result = ncp_request(server, 87)) != 0)
 445         {
 446                 ncp_unlock_server(server);
 447                 return result;
 448         }
 449 
 450         target->opened = 1;
 451         target->server_file_handle = ncp_reply_dword(server, 0);
 452         target->open_create_action = ncp_reply_byte(server, 4);
 453 
 454         if (dir != NULL)
 455         {
 456                 /* in target there's a new finfo to fill */
 457                 ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
 458         }
 459 
 460         ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
 461 
 462         ncp_unlock_server(server);
 463         return 0;
 464 }
 465         
 466 
 467 int
 468 ncp_initialize_search(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 469                       struct nw_info_struct *dir,
 470                       struct nw_search_sequence *target)
 471 {
 472         int result;
 473 
 474         ncp_init_request(server);
 475         ncp_add_byte(server, 2); /* subfunction */
 476         ncp_add_byte(server, 0); /* dos name space */
 477         ncp_add_byte(server, 0); /* reserved */
 478         ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
 479         
 480         if ((result = ncp_request(server, 87)) != 0)
 481         {
 482                 ncp_unlock_server(server);
 483                 return result;
 484         }
 485 
 486         memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
 487 
 488         ncp_unlock_server(server);
 489         return 0;
 490 }
 491         
 492 /* Search for everything */
 493 int
 494 ncp_search_for_file_or_subdir(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 495                               struct nw_search_sequence *seq,
 496                               struct nw_info_struct *target)
 497 {
 498         int result;
 499 
 500         ncp_init_request(server);
 501         ncp_add_byte(server, 3); /* subfunction */
 502         ncp_add_byte(server, 0); /* dos name space */
 503         ncp_add_byte(server, 0); /* data stream (???) */
 504         ncp_add_word(server, 0xffff); /* Search attribs */
 505         ncp_add_dword(server, RIM_ALL); /* return info mask */
 506         ncp_add_mem(server, seq, 9);
 507         ncp_add_byte(server, 2); /* 2 byte pattern */
 508         ncp_add_byte(server, 0xff); /* following is a wildcard */
 509         ncp_add_byte(server, '*');
 510         
 511         if ((result = ncp_request(server, 87)) != 0)
 512         {
 513                 ncp_unlock_server(server);
 514                 return result;
 515         }
 516 
 517         memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
 518         ncp_extract_file_info(ncp_reply_data(server, 10), target);
 519 
 520         ncp_unlock_server(server);
 521         return 0;
 522 }
 523 
 524 int
 525 ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 526                               struct nw_info_struct *old_dir, char *old_name,
 527                               struct nw_info_struct *new_dir, char *new_name)
 528 {
 529         int result;
 530 
 531         if (   (old_dir == NULL) || (old_name == NULL)
 532             || (new_dir == NULL) || (new_name == NULL))
 533                 return -EINVAL;
 534         
 535         ncp_init_request(server);
 536         ncp_add_byte(server, 4); /* subfunction */
 537         ncp_add_byte(server, 0); /* dos name space */
 538         ncp_add_byte(server, 1); /* rename flag */
 539         ncp_add_word(server, 0x8006); /* search attributes */
 540 
 541         /* source Handle Path */
 542         ncp_add_byte(server, old_dir->volNumber);
 543         ncp_add_dword(server, old_dir->DosDirNum);
 544         ncp_add_byte(server, 1);
 545         ncp_add_byte(server, 1); /* 1 source component */
 546 
 547         /* dest Handle Path */
 548         ncp_add_byte(server, new_dir->volNumber);
 549         ncp_add_dword(server, new_dir->DosDirNum);
 550         ncp_add_byte(server, 1);
 551         ncp_add_byte(server, 1); /* 1 destination component */
 552 
 553         /* source path string */
 554         ncp_add_pstring(server, old_name);
 555         /* dest path string */
 556         ncp_add_pstring(server, new_name);
 557 
 558         result = ncp_request(server, 87);
 559         ncp_unlock_server(server);
 560         return result;
 561 }
 562         
 563 
 564 /* We have to transfer to/from user space */
 565 int
 566 ncp_read(struct ncp_server *server, const char *file_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 567          __u32 offset, __u16 to_read,
 568          char *target, int *bytes_read)
 569 {
 570         int result;
 571 
 572         ncp_init_request(server);
 573         ncp_add_byte(server, 0);
 574         ncp_add_mem(server, file_id, 6);
 575         ncp_add_dword(server, htonl(offset));
 576         ncp_add_word(server, htons(to_read));
 577 
 578         if ((result = ncp_request(server, 72)) != 0)
 579         {
 580                 ncp_unlock_server(server);
 581                 return result;
 582         }
 583 
 584         *bytes_read = ntohs(ncp_reply_word(server, 0));
 585 
 586         memcpy_tofs(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
 587 
 588         ncp_unlock_server(server);
 589         return 0;
 590 }
 591 
 592 int
 593 ncp_write(struct ncp_server *server, const char *file_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 594           __u32 offset, __u16 to_write,
 595           const char *source, int *bytes_written)
 596 {
 597         int result;
 598 
 599         ncp_init_request(server);
 600         ncp_add_byte(server, 0);
 601         ncp_add_mem(server, file_id, 6);
 602         ncp_add_dword(server, htonl(offset));
 603         ncp_add_word(server, htons(to_write));
 604         ncp_add_mem_fromfs(server, source, to_write);
 605 
 606         if ((result = ncp_request(server, 73)) != 0)
 607         {
 608                 ncp_unlock_server(server);
 609                 return result;
 610         }
 611 
 612         *bytes_written = to_write;
 613 
 614         ncp_unlock_server(server);
 615         return 0;
 616 }
 617 

/* [previous][next][first][last][top][bottom][index][help] */