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 
 415         ncp_init_request(server);
 416         ncp_add_byte(server, 1); /* subfunction */
 417         ncp_add_byte(server, 0); /* dos name space */
 418         ncp_add_byte(server, open_create_mode);
 419         ncp_add_word(server, 0x8006);
 420         ncp_add_dword(server, RIM_ALL);
 421         ncp_add_dword(server, create_attributes);
 422         /* The desired acc rights seem to be the inherited rights mask
 423            for directories */
 424         ncp_add_word(server, desired_acc_rights);
 425 
 426         if (dir != NULL)
 427         {
 428                 ncp_add_handle_path(server, dir->volNumber,
 429                                     dir->DosDirNum, 1, name);
 430         }
 431         else
 432         {
 433                 ncp_add_handle_path(server,
 434                                     target->i.volNumber, target->i.DosDirNum,
 435                                     1, NULL);
 436         }       
 437 
 438         if ((result = ncp_request(server, 87)) != 0)
 439         {
 440                 ncp_unlock_server(server);
 441                 return result;
 442         }
 443 
 444         target->opened = 1;
 445         target->server_file_handle = ncp_reply_dword(server, 0);
 446         target->open_create_action = ncp_reply_byte(server, 4);
 447 
 448         if (dir != NULL)
 449         {
 450                 /* in target there's a new finfo to fill */
 451                 ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
 452         }
 453 
 454         ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
 455 
 456         ncp_unlock_server(server);
 457         return 0;
 458 }
 459         
 460 
 461 int
 462 ncp_initialize_search(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 463                       struct nw_info_struct *dir,
 464                       struct nw_search_sequence *target)
 465 {
 466         int result;
 467 
 468         ncp_init_request(server);
 469         ncp_add_byte(server, 2); /* subfunction */
 470         ncp_add_byte(server, 0); /* dos name space */
 471         ncp_add_byte(server, 0); /* reserved */
 472         ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
 473         
 474         if ((result = ncp_request(server, 87)) != 0)
 475         {
 476                 ncp_unlock_server(server);
 477                 return result;
 478         }
 479 
 480         memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
 481 
 482         ncp_unlock_server(server);
 483         return 0;
 484 }
 485         
 486 /* Search for everything */
 487 int
 488 ncp_search_for_file_or_subdir(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 489                               struct nw_search_sequence *seq,
 490                               struct nw_info_struct *target)
 491 {
 492         int result;
 493 
 494         ncp_init_request(server);
 495         ncp_add_byte(server, 3); /* subfunction */
 496         ncp_add_byte(server, 0); /* dos name space */
 497         ncp_add_byte(server, 0); /* data stream (???) */
 498         ncp_add_word(server, 0xffff); /* Search attribs */
 499         ncp_add_dword(server, RIM_ALL); /* return info mask */
 500         ncp_add_mem(server, seq, 9);
 501         ncp_add_byte(server, 2); /* 2 byte pattern */
 502         ncp_add_byte(server, 0xff); /* following is a wildcard */
 503         ncp_add_byte(server, '*');
 504         
 505         if ((result = ncp_request(server, 87)) != 0)
 506         {
 507                 ncp_unlock_server(server);
 508                 return result;
 509         }
 510 
 511         memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
 512         ncp_extract_file_info(ncp_reply_data(server, 10), target);
 513 
 514         ncp_unlock_server(server);
 515         return 0;
 516 }
 517 
 518 int
 519 ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 520                               struct nw_info_struct *old_dir, char *old_name,
 521                               struct nw_info_struct *new_dir, char *new_name)
 522 {
 523         int result;
 524 
 525         if (   (old_dir == NULL) || (old_name == NULL)
 526             || (new_dir == NULL) || (new_name == NULL))
 527                 return -EINVAL;
 528         
 529         ncp_init_request(server);
 530         ncp_add_byte(server, 4); /* subfunction */
 531         ncp_add_byte(server, 0); /* dos name space */
 532         ncp_add_byte(server, 1); /* rename flag */
 533         ncp_add_word(server, 0x8006); /* search attributes */
 534 
 535         /* source Handle Path */
 536         ncp_add_byte(server, old_dir->volNumber);
 537         ncp_add_dword(server, old_dir->DosDirNum);
 538         ncp_add_byte(server, 1);
 539         ncp_add_byte(server, 1); /* 1 source component */
 540 
 541         /* dest Handle Path */
 542         ncp_add_byte(server, new_dir->volNumber);
 543         ncp_add_dword(server, new_dir->DosDirNum);
 544         ncp_add_byte(server, 1);
 545         ncp_add_byte(server, 1); /* 1 destination component */
 546 
 547         /* source path string */
 548         ncp_add_pstring(server, old_name);
 549         /* dest path string */
 550         ncp_add_pstring(server, new_name);
 551 
 552         result = ncp_request(server, 87);
 553         ncp_unlock_server(server);
 554         return result;
 555 }
 556         
 557 
 558 /* We have to transfer to/from user space */
 559 int
 560 ncp_read(struct ncp_server *server, const char *file_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 561          __u32 offset, __u16 to_read,
 562          char *target, int *bytes_read)
 563 {
 564         int result;
 565 
 566         ncp_init_request(server);
 567         ncp_add_byte(server, 0);
 568         ncp_add_mem(server, file_id, 6);
 569         ncp_add_dword(server, htonl(offset));
 570         ncp_add_word(server, htons(to_read));
 571 
 572         if ((result = ncp_request(server, 72)) != 0)
 573         {
 574                 ncp_unlock_server(server);
 575                 return result;
 576         }
 577 
 578         *bytes_read = ntohs(ncp_reply_word(server, 0));
 579 
 580         memcpy_tofs(target, ncp_reply_data(server, 2), *bytes_read);
 581 
 582         ncp_unlock_server(server);
 583         return 0;
 584 }
 585 
 586 int
 587 ncp_write(struct ncp_server *server, const char *file_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 588           __u32 offset, __u16 to_write,
 589           const char *source, int *bytes_written)
 590 {
 591         int result;
 592 
 593         ncp_init_request(server);
 594         ncp_add_byte(server, 0);
 595         ncp_add_mem(server, file_id, 6);
 596         ncp_add_dword(server, htonl(offset));
 597         ncp_add_word(server, htons(to_write));
 598         ncp_add_mem_fromfs(server, source, to_write);
 599 
 600         if ((result = ncp_request(server, 73)) != 0)
 601         {
 602                 ncp_unlock_server(server);
 603                 return result;
 604         }
 605 
 606         *bytes_written = to_write;
 607 
 608         ncp_unlock_server(server);
 609         return 0;
 610 }
 611 

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