root/fs/smbfs/sock.c

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

DEFINITIONS

This source file includes following definitions.
  1. _recvfrom
  2. _send
  3. smb_data_callback
  4. smb_catch_keepalive
  5. smb_dont_catch_keepalive
  6. smb_receive_raw
  7. smb_receive
  8. smb_receive_trans2
  9. server_sock
  10. smb_release
  11. smb_connect
  12. smb_request
  13. smb_trans2_request
  14. smb_request_read_raw
  15. smb_request_write_raw

   1 /*
   2  *  sock.c
   3  *
   4  *  Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
   5  *
   6  */
   7 
   8 #include <linux/module.h>
   9 
  10 #include <linux/sched.h>
  11 #include <linux/smb_fs.h>
  12 #include <linux/errno.h>
  13 #include <linux/socket.h>
  14 #include <linux/fcntl.h>
  15 #include <linux/stat.h>
  16 #include <asm/segment.h>
  17 #include <linux/in.h>
  18 #include <linux/net.h>
  19 #include <linux/mm.h>
  20 #include <linux/netdevice.h>
  21 #include <net/ip.h>
  22 
  23 #include <linux/smb.h>
  24 #include <linux/smbno.h>
  25 
  26 
  27 #define _S(nr) (1<<((nr)-1))
  28 
  29 static int _recvfrom(struct socket *sock, unsigned char *ubuf, int size, int noblock, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
  30                 struct sockaddr_in *sa, int *addr_len)
  31 {
  32         struct iovec iov;
  33         struct msghdr msg;
  34 
  35         iov.iov_base = ubuf;
  36         iov.iov_len  = size;
  37 
  38         msg.msg_name      = (void *)sa;
  39         msg.msg_namelen   = 0;
  40         if (addr_len)
  41                 msg.msg_namelen = *addr_len;
  42         msg.msg_accrights = NULL;
  43         msg.msg_iov       = &iov;
  44         msg.msg_iovlen    = 1;
  45 
  46         return sock->ops->recvmsg(sock, &msg, size, noblock, flags, addr_len);
  47 }
  48 
  49 static int _send(struct socket *sock, const void *buff, int len, int nonblock, unsigned flags) {
     /* [previous][next][first][last][top][bottom][index][help] */
  50         struct iovec iov;
  51         struct msghdr msg;
  52 
  53         iov.iov_base = (void *)buff;
  54         iov.iov_len  = len;
  55 
  56         msg.msg_name      = NULL;
  57         msg.msg_namelen   = 0;
  58         msg.msg_accrights = NULL;
  59         msg.msg_iov       = &iov;
  60         msg.msg_iovlen    = 1;
  61 
  62         return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);
  63 }
  64 
  65 static void
  66 smb_data_callback(struct sock *sk,int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         struct socket *sock = sk->socket;
  69 
  70         if(!sk->dead)
  71         {
  72                 unsigned char peek_buf[4];
  73                 int result;
  74                 unsigned short fs;
  75 
  76                 fs = get_fs();
  77                 set_fs(get_ds());
  78 
  79                 result = _recvfrom(sock, (void *)peek_buf, 1, 1,
  80                                              MSG_PEEK, NULL, NULL);
  81 
  82                 while ((result != -EAGAIN) && (peek_buf[0] == 0x85)) {
  83 
  84                         /* got SESSION KEEP ALIVE */
  85                         result = _recvfrom(sock, (void *)peek_buf,
  86                                                      4, 1, 0, NULL, NULL);
  87 
  88                         DDPRINTK("smb_data_callback:"
  89                                  " got SESSION KEEP ALIVE\n");
  90 
  91                         if (result == -EAGAIN)
  92                                 break;
  93 
  94                         result = _recvfrom(sock, (void *)peek_buf,
  95                                                      1, 1, MSG_PEEK,
  96                                                      NULL, NULL);
  97 
  98                 }
  99 
 100                 set_fs(fs);
 101 
 102                 if (result != -EAGAIN) {
 103                         wake_up_interruptible(sk->sleep);
 104                 }
 105         }
 106 }
 107 
 108 int
 109 smb_catch_keepalive(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         struct file   *file;
 112         struct inode  *inode;
 113         struct socket *sock;
 114         struct sock   *sk;
 115 
 116         if (   (server == NULL)
 117             || ((file  = server->sock_file) == NULL)
 118             || ((inode = file->f_inode) == NULL)
 119             || (!S_ISSOCK(inode->i_mode))) {
 120 
 121                 printk("smb_catch_keepalive: did not get valid server!\n");
 122                 server->data_ready = NULL;
 123                 return -EINVAL;
 124         }
 125 
 126         sock = &(inode->u.socket_i);
 127 
 128         if (sock->type != SOCK_STREAM) {
 129                 printk("smb_catch_keepalive: did not get SOCK_STREAM\n");
 130                 server->data_ready = NULL;
 131                 return -EINVAL;
 132         }
 133 
 134         sk   = (struct sock *)(sock->data);
 135 
 136         if (sk == NULL) {
 137                 printk("smb_catch_keepalive: sk == NULL");
 138                 server->data_ready = NULL;
 139                 return -EINVAL;
 140         }
 141 
 142         DDPRINTK("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
 143                  (unsigned int)(sk->data_ready),
 144                  (unsigned int)(server->data_ready));
 145 
 146         if (sk->data_ready == smb_data_callback) {
 147                 printk("smb_catch_keepalive: already done\n");
 148                 return -EINVAL;
 149         }
 150 
 151         server->data_ready = sk->data_ready;
 152         sk->data_ready = smb_data_callback;
 153         return 0;
 154 }
 155                 
 156 int
 157 smb_dont_catch_keepalive(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         struct file   *file;
 160         struct inode  *inode;
 161         struct socket *sock;
 162         struct sock   *sk;
 163 
 164         if (   (server == NULL)
 165             || ((file  = server->sock_file) == NULL)
 166             || ((inode = file->f_inode) == NULL)
 167             || (!S_ISSOCK(inode->i_mode))) {
 168 
 169                 printk("smb_dont_catch_keepalive: "
 170                        "did not get valid server!\n");
 171                 return -EINVAL;
 172         }
 173 
 174         sock = &(inode->u.socket_i);
 175 
 176         if (sock->type != SOCK_STREAM) {
 177                 printk("smb_dont_catch_keepalive: did not get SOCK_STREAM\n");
 178                 return -EINVAL;
 179         }
 180 
 181         sk   = (struct sock *)(sock->data);
 182 
 183         if (sk == NULL) {
 184                 printk("smb_dont_catch_keepalive: sk == NULL");
 185                 return -EINVAL;
 186         }
 187 
 188         if (server->data_ready == NULL) {
 189                 printk("smb_dont_catch_keepalive: "
 190                        "server->data_ready == NULL\n");
 191                 return -EINVAL;
 192         }
 193 
 194         if (sk->data_ready != smb_data_callback) {
 195                 printk("smb_dont_catch_keepalive: "
 196                        "sk->data_callback != smb_data_callback\n");
 197                 return -EINVAL;
 198         }
 199 
 200         DDPRINTK("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
 201                  (unsigned int)(sk->data_ready),
 202                  (unsigned int)(server->data_ready));
 203 
 204         sk->data_ready = server->data_ready;
 205         server->data_ready = NULL;
 206         return 0;
 207 }
 208 
 209 /*
 210  * smb_receive_raw
 211  * fs points to the correct segment, sock != NULL, target != NULL
 212  * The smb header is only stored if want_header != 0.
 213  */
 214 static int
 215 smb_receive_raw(struct socket *sock, unsigned char *target,
     /* [previous][next][first][last][top][bottom][index][help] */
 216                 int max_raw_length, int want_header)
 217 {
 218         int len, result;
 219         int already_read;
 220         unsigned char peek_buf[4];
 221         unsigned short fs;      /* We fool the kernel to believe
 222                                    we call from user space. */
 223 
 224 
 225  re_recv:
 226 
 227         fs = get_fs();
 228         set_fs(get_ds());
 229         result = _recvfrom(sock, (void *)peek_buf, 4, 0,
 230                                      0, NULL, NULL);
 231         set_fs(fs);
 232 
 233         if (result < 0) {
 234                 DPRINTK("smb_receive_raw: recv error = %d\n", -result);
 235                 return result;
 236         }
 237 
 238         if (result < 4) {
 239                 DPRINTK("smb_receive_raw: got less than 4 bytes\n");
 240                 return -EIO;
 241         }
 242 
 243         switch (peek_buf[0]) {
 244 
 245         case 0x00:
 246         case 0x82:
 247                 break;
 248 
 249         case 0x85:
 250                 DPRINTK("smb_receive_raw: Got SESSION KEEP ALIVE\n");
 251                 goto re_recv;
 252                 
 253         default:
 254                 printk("smb_receive_raw: Invalid packet\n");
 255                 return -EIO;
 256         }
 257 
 258         /* The length in the RFC NB header is the raw data length */
 259         len = smb_len(peek_buf); 
 260         if (len > max_raw_length) { 
 261                 printk("smb_receive_raw: Received length (%d) > max_xmit (%d)!\n", 
 262                        len, max_raw_length);
 263                 return -EIO;
 264         }
 265 
 266         if (want_header != 0) {
 267                 memcpy_tofs(target, peek_buf, 4);
 268                 target += 4;
 269         }
 270 
 271         already_read = 0;
 272 
 273         while (already_read < len) {
 274                 
 275                 result = _recvfrom(sock,
 276                                  (void *)(target+already_read),
 277                                  len - already_read, 0, 0,
 278                                  NULL, NULL);
 279    
 280                 if (result < 0) {
 281                         printk("smb_receive_raw: recvfrom error = %d\n",
 282                                -result);
 283                         return result;
 284                 }
 285 
 286                 already_read += result;
 287         }
 288         return already_read;
 289 }
 290 
 291 /*
 292  * smb_receive
 293  * fs points to the correct segment, server != NULL, sock!=NULL
 294  */
 295 static int
 296 smb_receive(struct smb_server *server, struct socket *sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 297 {
 298         int result;
 299 
 300         result = smb_receive_raw(sock, server->packet,
 301                                  server->max_xmit - 4, /* max_xmit in server
 302                                                           includes NB header */
 303                                  1); /* We want the header */
 304 
 305         if (result < 0) {
 306                 printk("smb_receive: receive error: %d\n", result);
 307                 return result;
 308         }
 309 
 310         server->rcls = *((unsigned char *)(server->packet+9));
 311         server->err  = *((unsigned short *)(server->packet+11));
 312 
 313         if (server->rcls != 0) {
 314                 DPRINTK("smb_receive: rcls=%d, err=%d\n",
 315                         server->rcls, server->err);
 316         }
 317 
 318         return result;
 319 }
 320 
 321 
 322 /*
 323  * smb_receive's preconditions also apply here.
 324  */
 325 static int
 326 smb_receive_trans2(struct smb_server *server, struct socket *sock,
     /* [previous][next][first][last][top][bottom][index][help] */
 327                    int *data_len, int *param_len,
 328                    char **data, char **param)
 329 {
 330         int total_data=0;
 331         int total_param=0;
 332         int result;
 333         unsigned char *inbuf = server->packet;
 334 
 335         *data_len = *param_len = 0;
 336 
 337         DDPRINTK("smb_receive_trans2: enter\n");
 338         
 339         if ((result = smb_receive(server, sock)) < 0) {
 340                 return result;
 341         }
 342 
 343         if (server->rcls != 0) {
 344                 return result;
 345         }
 346 
 347         /* parse out the lengths */
 348         total_data = WVAL(inbuf,smb_tdrcnt);
 349         total_param = WVAL(inbuf,smb_tprcnt);
 350 
 351         if (   (total_data  > TRANS2_MAX_TRANSFER)
 352             || (total_param > TRANS2_MAX_TRANSFER)) {
 353                 printk("smb_receive_trans2: data/param too long\n");
 354                 return -EIO;
 355         }
 356 
 357         /* allocate it */
 358         if ((*data  = smb_kmalloc(total_data, GFP_KERNEL)) == NULL) {
 359                 printk("smb_receive_trans2: could not alloc data area\n");
 360                 return -ENOMEM;
 361         }
 362 
 363         if ((*param = smb_kmalloc(total_param, GFP_KERNEL)) == NULL) {
 364                 printk("smb_receive_trans2: could not alloc param area\n");
 365                 smb_kfree_s(*data, total_data);
 366                 return -ENOMEM;
 367         }
 368 
 369         DDPRINTK("smb_rec_trans2: total_data/param: %d/%d\n",
 370                  total_data, total_param);
 371 
 372         while (1)
 373         {
 374                 if (WVAL(inbuf,smb_prdisp)+WVAL(inbuf, smb_prcnt)
 375                     > total_param) {
 376                         printk("smb_receive_trans2: invalid parameters\n");
 377                         result = -EIO;
 378                         goto fail;
 379                 }
 380                 memcpy(*param + WVAL(inbuf,smb_prdisp),
 381                        smb_base(inbuf) + WVAL(inbuf,smb_proff),
 382                        WVAL(inbuf,smb_prcnt));
 383                 *param_len += WVAL(inbuf,smb_prcnt);
 384 
 385 
 386                 if (WVAL(inbuf,smb_drdisp)+WVAL(inbuf, smb_drcnt)>total_data) {
 387                         printk("smb_receive_trans2: invalid data block\n");
 388                         result = -EIO;
 389                         goto fail;
 390                 }
 391                 memcpy(*data + WVAL(inbuf,smb_drdisp),
 392                        smb_base(inbuf) + WVAL(inbuf,smb_droff),
 393                        WVAL(inbuf,smb_drcnt));
 394                 *data_len += WVAL(inbuf,smb_drcnt);
 395 
 396                 DDPRINTK("smb_rec_trans2: drcnt/prcnt: %d/%d\n",
 397                          WVAL(inbuf, smb_drcnt), WVAL(inbuf, smb_prcnt));
 398 
 399                 /* parse out the total lengths again - they can shrink! */
 400 
 401                 if (   (WVAL(inbuf,smb_tdrcnt) > total_data)
 402                     || (WVAL(inbuf,smb_tprcnt) > total_param)) {
 403                         printk("smb_receive_trans2: data/params grew!\n");
 404                         result = -EIO;
 405                         goto fail;
 406                 }
 407 
 408                 total_data = WVAL(inbuf,smb_tdrcnt);
 409                 total_param = WVAL(inbuf,smb_tprcnt);
 410 
 411                 if (total_data <= *data_len && total_param <= *param_len)
 412                         break;
 413 
 414                 if ((result = smb_receive(server, sock)) < 0) {
 415                         goto fail;
 416                 }
 417                 if (server->rcls != 0) {
 418                         result = -EIO;
 419                         goto fail;
 420                 }
 421         }
 422 
 423         DDPRINTK("smb_receive_trans2: normal exit\n");
 424 
 425         return 0;
 426 
 427  fail:
 428         DPRINTK("smb_receive_trans2: failed exit\n");
 429 
 430         smb_kfree_s(*param, 0); *param = NULL;
 431         smb_kfree_s(*data, 0);  *data = NULL;
 432         return result;
 433 }
 434 
 435 static inline struct socket *
 436 server_sock(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438         struct file *file;
 439         struct inode *inode;
 440 
 441         if (server == NULL)
 442                 return NULL;
 443         if ((file = server->sock_file) == NULL)
 444                 return NULL;
 445         if ((inode = file->f_inode) == NULL)
 446                 return NULL;
 447         return &(inode->u.socket_i);
 448 }
 449 
 450 int
 451 smb_release(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 452 {
 453         struct socket *sock = server_sock(server);
 454         int result;
 455 
 456         if (sock == NULL)
 457                 return -EINVAL;
 458 
 459         result = sock->ops->release(sock, NULL);
 460         DPRINTK("smb_release: sock->ops->release = %d\n", result);
 461 
 462         /* inet_release does not set sock->state.  Maybe someone is
 463            confused about sock->state being SS_CONNECTED while there
 464            is nothing behind it, so I set it to SS_UNCONNECTED.*/
 465         sock->state = SS_UNCONNECTED;
 466 
 467         result = sock->ops->create(sock, 0);
 468         DPRINTK("smb_release: sock->ops->create = %d\n", result);
 469         return result;
 470 }
 471 
 472 int
 473 smb_connect(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 474 {
 475         struct socket *sock = server_sock(server);
 476         if (sock == NULL)
 477                 return -EINVAL;
 478         if (sock->state != SS_UNCONNECTED) {
 479                 DPRINTK("smb_connect: socket is not unconnected: %d\n",
 480                         sock->state);
 481         }
 482         return sock->ops->connect(sock, (struct sockaddr *)&(server->m.addr),
 483                                   sizeof(struct sockaddr_in), 0);
 484 }
 485         
 486 /*****************************************************************************/
 487 /*                                                                           */
 488 /*  This routine was once taken from nfs, wich is for udp. Here TCP does     */
 489 /*  most of the ugly stuff for us (thanks, Alan!)                            */
 490 /*                                                                           */
 491 /*****************************************************************************/
 492 int
 493 smb_request(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 494 {
 495         unsigned long old_mask;
 496         unsigned short fs;      /* We fool the kernel to believe
 497                                    we call from user space. */
 498         int len, result, result2;
 499 
 500         struct socket *sock = server_sock(server);
 501         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 502 
 503         if ((sock == NULL) || (buffer == NULL)) {
 504                 printk("smb_request: Bad server!\n");
 505                 return -EBADF;
 506         }
 507 
 508         if (server->state != CONN_VALID)
 509                 return -EIO;
 510                 
 511         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 512                 server->state = CONN_INVALID;
 513                 smb_invalidate_all_inodes(server);
 514                 return result;
 515         }
 516 
 517         len = smb_len(buffer) + 4;
 518 
 519         DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
 520 
 521         old_mask = current->blocked;
 522         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 523         fs = get_fs();
 524         set_fs(get_ds());
 525 
 526         result = _send(sock, (void *)buffer, len, 0, 0);
 527         if (result < 0) {
 528                 printk("smb_request: send error = %d\n", result);
 529         }
 530         else {
 531                 result = smb_receive(server, sock);
 532         }
 533 
 534         /* read/write errors are handled by errno */
 535         current->signal &= ~_S(SIGPIPE);
 536 
 537         current->blocked = old_mask;
 538         set_fs(fs);
 539 
 540         if ((result2 = smb_catch_keepalive(server)) < 0) {
 541                 result = result2;
 542         }
 543 
 544         if (result < 0) {
 545                 server->state = CONN_INVALID;
 546                 smb_invalidate_all_inodes(server);
 547         }
 548         
 549         DDPRINTK("smb_request: result = %d\n", result);
 550 
 551         return result;
 552 }
 553 
 554 /*
 555  * This is not really a trans2 request, we assume that you only have
 556  * one packet to send.
 557  */ 
 558 int
 559 smb_trans2_request(struct smb_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 560                    int *data_len, int *param_len,
 561                    char **data, char **param)
 562 {
 563         unsigned long old_mask;
 564         unsigned short fs;      /* We fool the kernel to believe
 565                                    we call from user space. */
 566         int len, result, result2;
 567 
 568         struct socket *sock = server_sock(server);
 569         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 570 
 571         if ((sock == NULL) || (buffer == NULL)) {
 572                 printk("smb_trans2_request: Bad server!\n");
 573                 return -EBADF;
 574         }
 575 
 576         if (server->state != CONN_VALID)
 577                 return -EIO;
 578                 
 579         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 580                 server->state = CONN_INVALID;
 581                 smb_invalidate_all_inodes(server);
 582                 return result;
 583         }
 584 
 585         len = smb_len(buffer) + 4;
 586 
 587         old_mask = current->blocked;
 588         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 589         fs = get_fs();
 590         set_fs(get_ds());
 591 
 592         DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
 593 
 594         result = _send(sock, (void *)buffer, len, 0, 0);
 595         if (result < 0) {
 596                 printk("smb_trans2_request: send error = %d\n", result);
 597         }
 598         else {
 599                 result = smb_receive_trans2(server, sock,
 600                                             data_len, param_len,
 601                                             data, param);
 602         }
 603 
 604         /* read/write errors are handled by errno */
 605         current->signal &= ~_S(SIGPIPE);
 606 
 607         current->blocked = old_mask;
 608         set_fs(fs);
 609 
 610         if ((result2 = smb_catch_keepalive(server)) < 0) {
 611                 result = result2;
 612         }
 613 
 614         if (result < 0) {
 615                 server->state = CONN_INVALID;
 616                 smb_invalidate_all_inodes(server);
 617         }
 618         
 619         DDPRINTK("smb_trans2_request: result = %d\n", result);
 620 
 621         return result;
 622 }
 623 
 624 /* target must be in user space */
 625 int
 626 smb_request_read_raw(struct smb_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 627                      unsigned char *target, int max_len)
 628 {
 629         unsigned long old_mask;
 630         int len, result, result2;
 631         unsigned short fs;      /* We fool the kernel to believe
 632                                    we call from user space. */
 633 
 634         struct socket *sock = server_sock(server);
 635         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 636 
 637         if ((sock == NULL) || (buffer == NULL)) {
 638                 printk("smb_request_read_raw: Bad server!\n");
 639                 return -EBADF;
 640         }
 641 
 642         if (server->state != CONN_VALID)
 643                 return -EIO;
 644                 
 645         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 646                 server->state = CONN_INVALID;
 647                 smb_invalidate_all_inodes(server);
 648                 return result;
 649         }
 650 
 651         len = smb_len(buffer) + 4;
 652 
 653         old_mask = current->blocked;
 654         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 655         fs = get_fs();
 656         set_fs(get_ds());
 657 
 658         DPRINTK("smb_request_read_raw: len = %d cmd = 0x%X\n",
 659                 len, buffer[8]);
 660         DPRINTK("smb_request_read_raw: target=%X, max_len=%d\n",
 661                 (unsigned int)target, max_len);
 662         DPRINTK("smb_request_read_raw: buffer=%X, sock=%X\n",
 663                 (unsigned int)buffer, (unsigned int)sock);
 664 
 665         result = _send(sock, (void *)buffer, len, 0, 0);
 666 
 667         DPRINTK("smb_request_read_raw: send returned %d\n", result);
 668 
 669         set_fs(fs);             /* We recv into user space */
 670 
 671         if (result < 0) {
 672                 printk("smb_request_read_raw: send error = %d\n", result);
 673         }
 674         else {
 675                 result = smb_receive_raw(sock, target, max_len, 0);
 676         }
 677 
 678         /* read/write errors are handled by errno */
 679         current->signal &= ~_S(SIGPIPE);
 680         current->blocked = old_mask;
 681 
 682         if ((result2 = smb_catch_keepalive(server)) < 0) {
 683                 result = result2;
 684         }
 685 
 686         if (result < 0) {
 687                 server->state = CONN_INVALID;
 688                 smb_invalidate_all_inodes(server);
 689         }
 690         
 691         DPRINTK("smb_request_read_raw: result = %d\n", result);
 692 
 693         return result;
 694 }
 695 
 696 /* Source must be in user space. smb_request_write_raw assumes that
 697  * the request SMBwriteBraw has been completed successfully, so that
 698  * we can send the raw data now.  */
 699 int
 700 smb_request_write_raw(struct smb_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 701                       unsigned const char *source, int length)
 702 {
 703         unsigned long old_mask;
 704         int result, result2;
 705         unsigned short fs;      /* We fool the kernel to believe
 706                                    we call from user space. */
 707         byte nb_header[4];
 708 
 709         struct socket *sock = server_sock(server);
 710         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 711 
 712         if ((sock == NULL) || (buffer == NULL)) {
 713                 printk("smb_request_write_raw: Bad server!\n");
 714                 return -EBADF;
 715         }
 716 
 717         if (server->state != CONN_VALID)
 718                 return -EIO;
 719                 
 720         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 721                 server->state = CONN_INVALID;
 722                 smb_invalidate_all_inodes(server);
 723                 return result;
 724         }
 725 
 726         old_mask = current->blocked;
 727         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 728         fs = get_fs();
 729         set_fs(get_ds());
 730 
 731         smb_encode_smb_length(nb_header, length);
 732 
 733         result = _send(sock, (void *)nb_header, 4, 0, 0);
 734 
 735         if (result == 4) {
 736                 set_fs(fs);     /* source is in user-land */
 737                 result = _send(sock, (void *)source, length, 0, 0);
 738                 set_fs(get_ds());
 739         } else {
 740                 result = -EIO;
 741         }
 742 
 743         DPRINTK("smb_request_write_raw: send returned %d\n", result);
 744 
 745         if (result == length) {
 746                 result = smb_receive(server, sock);
 747         } else {
 748                 result = -EIO;
 749         }
 750 
 751         /* read/write errors are handled by errno */
 752         current->signal &= ~_S(SIGPIPE);
 753         current->blocked = old_mask;
 754         set_fs(fs);
 755 
 756         if ((result2 = smb_catch_keepalive(server)) < 0) {
 757                 result = result2;
 758         }
 759 
 760         if (result < 0) {
 761                 server->state = CONN_INVALID;
 762                 smb_invalidate_all_inodes(server);
 763         }
 764 
 765         if (result > 0) {
 766                 result = length;
 767         }
 768         
 769         DPRINTK("smb_request_write_raw: result = %d\n", result);
 770 
 771         return result;
 772 }
 773 
 774 /*
 775  * Overrides for Emacs so that we follow Linus's tabbing style.
 776  * Emacs will notice this stuff at the end of the file and automatically
 777  * adjust the settings for this buffer only.  This must remain at the end
 778  * of the file.
 779  * ---------------------------------------------------------------------------
 780  * Local variables:
 781  * c-indent-level: 8
 782  * c-brace-imaginary-offset: 0
 783  * c-brace-offset: -8
 784  * c-argdecl-indent: 8
 785  * c-label-offset: -8
 786  * c-continued-statement-offset: 8
 787  * c-continued-brace-offset: 0
 788  * End:
 789  */

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