experimental/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-1.2.0_to_2.0.0...

32749 lines
913 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff -uNr src.old/LICENSE src/LICENSE
--- src.old/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ src/LICENSE 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,343 @@
+"Use of the novfs source code is governed by the terms of the GPL:"
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff -uNr src.old/include/commands.h src/include/commands.h
--- src.old/include/commands.h 2006-07-11 21:24:18.000000000 +0200
+++ src/include/commands.h 2006-10-16 15:08:23.000000000 +0200
@@ -73,6 +73,7 @@
#define VFS_COMMAND_SET_MOUNT_PATH 31
#define VFS_COMMAND_GET_USER_SPACE 32
#define VFS_COMMAND_DBG 33
+#define VFS_COMMAND_GET_CACHE_FLAG 34
#define NWD_ACCESS_QUERY 0x00000001
@@ -1167,6 +1168,21 @@
} NwdCVerifyKey, *PNwdCVerifyKey;
+typedef struct _GET_CACHE_FLAG
+{
+ COMMAND_REQUEST_HEADER Command;
+ int pathLen;
+ unsigned char path[0];
+
+} GET_CACHE_FLAG_REQUEST, *PGET_CACHE_FLAG_REQUEST;
+
+typedef struct _GET_CACHE_FLAG_REPLY
+{
+ COMMAND_REPLY_HEADER Reply;
+ int CacheFlag;
+
+} GET_CACHE_FLAG_REPLY, *PGET_CACHE_FLAG_REPLY;
+
#pragma pack(pop)
diff -uNr src.old/novfs/Makefile src/novfs/Makefile
--- src.old/novfs/Makefile 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/Makefile 1970-01-01 01:00:00.000000000 +0100
@@ -1,52 +0,0 @@
-##*++======================================================================
-## Program Name: Novell NCP Redirector for Linux
-## File Name: Makefile
-## Version: v1.01
-## Author: James Turner
-##
-## Abstract: This is used to generate the novfs module
-## Notes:
-## Revision History:
-## 6/10/2005 - Added lines for SuSE
-##
-## Copyright (C) 2005 Novell, Inc.
-##
-## This program is free software; you can redistribute it and/or
-## modify it under the terms of the GNU General Public License
-## as published by the Free Software Foundation; either version 2
-## of the License, or (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-##=====================================================================--*/
-
-#
-# Makefile for the Novell NetWare Client for Linux filesystem.
-#
-NOVFS_VFS_MAJOR = 1
-NOVFS_VFS_MINOR = 2
-NOVFS_VFS_SUB = 0
-NOVFS_VFS_RELEASE = 17
-
-# Remove # from the following line for debug version
-EXTRA_CFLAGS += -finstrument-functions
-EXTRA_CFLAGS += -g
-EXTRA_CFLAGS += -I.
-EXTRA_CFLAGS += -I$(obj)/../include
-#EXTRA_CFLAGS += -I$(obj)/../../include
-EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR)
-EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR)
-EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB)
-EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH)
-EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE)
-
-
-obj-m := novfs.o
-
-novfs-y := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o
diff -uNr src.old/novfs/blank.c src/novfs/blank.c
--- src.old/novfs/blank.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/blank.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,61 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: .c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module
- *
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-
-/*===[ Include files specific to this module ]============================*/
-
-/*===[ External data ]====================================================*/
-
-/*===[ External prototypes ]==============================================*/
-
-/*===[ Manifest constants ]===============================================*/
-
-/*===[ Type definitions ]=================================================*/
-
-/*===[ Function prototypes ]==============================================*/
-
-/*===[ Global variables ]=================================================*/
-
-/*===[ Code ]=============================================================*/
-
-/*++======================================================================*/
-Function
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
diff -uNr src.old/novfs/daemon.c src/novfs/daemon.c
--- src.old/novfs/daemon.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/daemon.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,2877 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: daemon.c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module contains all the functions necessary
- * for sending commands to our daemon module.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/poll.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
-#include <asm/semaphore.h>
-#include <asm/uaccess.h>
-#include <linux/time.h>
-
-
-/*===[ Include files specific to this module ]============================*/
-#include "vfs.h"
-#include "nwcapi.h"
-#include "commands.h"
-#include "nwerror.h"
-
-/*===[ External data ]====================================================*/
-extern char *Novfs_CurrentMount;
-extern char DbgDaemonLogOn;
-
-
-/*===[ External prototypes ]==============================================*/
-extern int DbgPrint( char *Fmt, ... );
-extern void mydump(int size, void *dumpptr);
-
-extern char *Scope_Get_UserName( void *Scope );
-extern void *Scope_Lookup( void );
-extern session_t Scope_Get_SessionId( void *Scope );
-extern void Scope_Cleanup( void );
-
-extern int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
-extern int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
-extern int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
-
-extern int Novfs_Add_to_Root(char *);
-
-/*
- * nwcapi.c functions
- */
-extern int NwAuthConnWithId(PXPLAT pdata, session_t Session);
-extern int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
-extern int NwGetConnInfo(PXPLAT pdata, session_t Session);
-extern int NwSetConnInfo(PXPLAT pdata, session_t Session);
-extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session);
-extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session);
-extern int NwLicenseConn(PXPLAT pdata, session_t Session);
-extern int NwLoginIdentity(PXPLAT pdata, session_t Session);
-extern int NwLogoutIdentity(PXPLAT pdata, session_t Session);
-extern int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session);
-extern int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session);
-extern int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session);
-extern int NwQueryFeature(PXPLAT pdata, session_t Session);
-extern int NwRawSend(PXPLAT pdata, session_t Session);
-extern int NwScanConnInfo(PXPLAT pdata, session_t Session);
-extern int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
-extern int NwUnAuthenticate(PXPLAT pdata, session_t Session);
-extern int NwUnlicenseConn(PXPLAT pdata, session_t Session);
-extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session);
-extern int NwcEnumIdentities(PXPLAT pdata, session_t Session);
-extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session);
-extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session);
-extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session);
-extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session);
-extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session);
-extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session);
-extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session);
-extern int NwcSetMapDrive(PXPLAT pdata, session_t Session);
-extern int NwcUnMapDrive(PXPLAT pdata, session_t Session);
-extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session);
-extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session);
-extern int NwdSetKeyValue(PXPLAT pdata, session_t Session);
-extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session);
-
-/*===[ Manifest constants ]===============================================*/
-#define QUEUE_SENDING 0
-#define QUEUE_WAITING 1
-#define QUEUE_TIMEOUT 2
-#define QUEUE_ACKED 3
-#define QUEUE_DONE 4
-
-#define TIMEOUT_VALUE 10
-
-#define DH_TYPE_UNDEFINED 0
-#define DH_TYPE_STREAM 1
-#define DH_TYPE_CONNECTION 2
-
-/*===[ Type definitions ]=================================================*/
-typedef struct _DAEMON_QUEUE
-{
- struct list_head list; /* Must be first entry */
- spinlock_t lock; /* Used to control access to list */
- struct semaphore semaphore; /* Used to signal when data is available */
-} daemon_queue_t;
-
-typedef struct _DAEMON_COMMAND
-{
- struct list_head list; /* Must be first entry */
- atomic_t reference;
- u_long status;
- u_long flags;
- struct semaphore semaphore;
- u_long sequence;
- struct timer_list timer;
- void *request;
- u_long reqlen;
- void *data;
- int datalen;
- void *reply;
- u_long replen;
-} daemon_command_t;
-
-
-typedef struct _DAEMON_HANDLE_
-{
- struct list_head list;
- rwlock_t lock;
- session_t session;
-} daemon_handle_t;
-
-typedef struct _DAEMON_RESOURCE_
-{
- struct list_head list;
- int type;
- u_long connection;
- u_char handle[6];
- mode_t mode;
- loff_t size;
-} daemon_resource_t;
-
-typedef struct _DRIVE_MAP_
-{
- struct list_head list; /* Must be first item */
- session_t session;
- u_long hash;
- int namelen;
- char name[1];
-} drive_map_t;
-
-/*===[ Function prototypes ]==============================================*/
-int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size);
-int Daemon_Close_Control(struct inode *Inode, struct file *File);
-int Daemon_CreateSessionId( uint64_t *SessionId );
-int Daemon_DestroySessionId( uint64_t SessionId );
-void Daemon_Dumpque( void );
-int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
-int Daemon_Library_close(struct inode *inode, struct file *file);
-int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
-int Daemon_Library_open(struct inode *inode, struct file *file);
-ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
-ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
-loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
-int Daemon_Login(PLOGIN Login, session_t Session);
-int Daemon_Logout(PLOGOUT Logout, session_t Session);
-int Daemon_Open_Control(struct inode *Inode, struct file *File);
-uint Daemon_Poll(struct file *file, struct poll_table_struct *poll_table);
-ssize_t Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
-int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle);
-
-ssize_t Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
-int Daemon_SetMountPoint( char *Path );
-void Daemon_Timer(u_long data);
-int Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
-int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
-void Init_Daemon_Queue( void );
-int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
-void Queue_get(daemon_command_t *que);
-void Queue_put(daemon_command_t *que);
-void Uninit_Daemon_Queue( void );
-int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
-int do_logout( struct qstr *Server, session_t Session );
-daemon_command_t *find_queue(u_long sequence);
-daemon_command_t *get_next_queue(int Set_Queue_Waiting);
-int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle);
-int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle);
-int NwdGetMountPath(PXPLAT pdata);
-int NwdSetMapDrive(PXPLAT pdata, session_t Session);
-int NwdUnMapDrive(PXPLAT pdata, session_t Session);
-void RemoveDriveMaps( void );
-int local_unlink(const char *pathname);
-
-/*===[ Global variables ]=================================================*/
-daemon_queue_t Daemon_Queue;
-
-static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue);
-
-u_long Sequence = 0;
-atomic_t Daemon_Open_Count=ATOMIC_INIT(0);
-
-u_long Daemon_Command_Timeout = TIMEOUT_VALUE;
-
-DECLARE_MUTEX ( DriveMapLock );
-LIST_HEAD( DriveMapList );
-
-int MaxIoSize=PAGE_SIZE;
-
-/*===[ Code ]=============================================================*/
-
-/*++======================================================================*/
-void Init_Daemon_Queue()
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- INIT_LIST_HEAD(&Daemon_Queue.list);
- spin_lock_init(&Daemon_Queue.lock);
- init_MUTEX_LOCKED(&Daemon_Queue.semaphore);
-}
-
-/*++======================================================================*/
-void Uninit_Daemon_Queue( void )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- /* Does nothing for now but we maybe should clear the queue. */
-}
-
-/*++======================================================================*/
-void
-NO_TRACE
-Daemon_Timer(u_long data)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que = (daemon_command_t *)data;
-
- if ( QUEUE_ACKED != que->status )
- {
- que->status = QUEUE_TIMEOUT;
- }
- up(&que->semaphore);
-}
-
-/*++======================================================================*/
-int Queue_Daemon_Command(
- void *request,
- u_long reqlen,
- void *data,
- int dlen,
- void **reply,
- u_long *replen,
- int interruptible)
-/*
- *
- * Arguments: void *request - pointer to the request that is to be sent. Needs to be kernel memory.
- * int reqlen - length of the request.
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
- int retCode = 0;
- struct timespec ts1, ts2;
-
- ts1 = current_kernel_time();
-
- DbgPrint( "Queue_Daemon_Command: 0x%x %d\n", request, reqlen);
-
- if (atomic_read(&Daemon_Open_Count))
- {
-
- que = (daemon_command_t *)Novfs_Malloc(sizeof(*que), GFP_KERNEL);
-
- DbgPrint( "Queue_Daemon_Command: que=0x%x\n", que);
- if (que)
- {
- atomic_set( &que->reference, 0 );
- que->status = QUEUE_SENDING;
- que->flags = 0;
-
- init_MUTEX_LOCKED(&que->semaphore);
-
- DbgPrint( "Queue_Daemon_Command: semaphore inited que=0x%x\n", que);
-
- que->sequence = InterlockedIncrement(&Sequence);
-
- DbgPrint( "Queue_Daemon_Command: sequence=0x%x\n", que->sequence);
-
- ((PCOMMAND_REQUEST_HEADER)request)->SequenceNumber = que->sequence;
-
- /*
- * Setup and start que timer
- */
- init_timer(&que->timer);
- que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout);
- que->timer.data = (u_long)que;
- que->timer.function = Daemon_Timer;
- add_timer(&que->timer);
-
- DbgPrint( "Queue_Daemon_Command: timer started que=0x%x\n", que);
-
- /*
- * Setup request
- */
- que->request = request;
- que->reqlen = reqlen;
- que->data = data;
- que->datalen = dlen;
- que->reply = NULL;
- que->replen = 0;
-
- DbgPrint( "Queue_Daemon_Command: setting up que=0x%x\n", que);
-
- /*
- * Added entry to queue.
- */
- DbgPrint( "Queue_Daemon_Command: Daemon_Queue locked\n");
-
- /*
- * Check to see if interruptible and set flags.
- */
- if (interruptible)
- {
- que->flags |= INTERRUPTIBLE;
- }
-
- spin_lock(&Daemon_Queue.lock);
- Queue_get( que );
- list_add_tail(&que->list, &Daemon_Queue.list);
- spin_unlock(&Daemon_Queue.lock);
-
- DbgPrint( "Queue_Daemon_Command: 0x%x added to Daemon_Queue\n", que);
- /*
- * Signal that there is data to be read
- */
- up(&Daemon_Queue.semaphore);
-
- /*
- * Give a change to the other processes.
- */
- yield();
-
- DbgPrint( "Queue_Daemon_Command: calling down 0x%x\n", CURRENT_TIME);
-
- /*
- * Block waiting for reply or timeout
- */
- down(&que->semaphore);
-
- DbgPrint( "Queue_Daemon_Command: after down 0x%x\n", CURRENT_TIME);
-
- if ( QUEUE_ACKED == que->status )
- {
- que->status = QUEUE_WAITING;
- mod_timer(&que->timer, jiffies + (HZ * 2 * Daemon_Command_Timeout));
- DbgPrint( "Queue_Daemon_Command: mod_timer 0x%x\n", CURRENT_TIME);
- if (interruptible)
- {
- retCode = down_interruptible(&que->semaphore);
- }
- else
- {
- down(&que->semaphore);
- }
- DbgPrint( "Queue_Daemon_Command: after down2 0x%x\n", CURRENT_TIME);
- }
-
- DbgPrint( "Queue_Daemon_Command: after down 0x%d 0x%x\n", retCode, CURRENT_TIME);
- /*
- * Delete timer
- */
- del_timer(&que->timer);
-
- /*
- * Check for timeout
- */
- if ((QUEUE_TIMEOUT == que->status) && (NULL == que->reply) )
- {
- DbgPrint( "Queue_Daemon_Command: Timeout\n");
- retCode = -ETIME;
- }
- *reply = que->reply;
- *replen = que->replen;
-
- /*
- * Remove item from queue
- */
- Queue_put( que );
-
- }
- else /* Error case with no memory */
- {
- retCode = -ENOMEM;
- *reply = NULL;
- *replen = 0;
- }
- }
- else
- {
- retCode = -EIO;
- *reply = NULL;
- *replen = 0;
-
- }
- ts2 = current_kernel_time();
- if (ts2.tv_nsec < ts1.tv_nsec)
- {
- ts2.tv_sec--;
- ts2.tv_nsec += NSEC_PER_SEC;
- }
- ts2.tv_sec = ts2.tv_sec-ts1.tv_sec;
- ts2.tv_nsec = ts2.tv_nsec-ts1.tv_nsec;
-
- DbgPrint( "Queue_Daemon_Command: %ld:%lu retCode=%d \n", ts2.tv_sec, ts2.tv_nsec, retCode);
- return(retCode);
-}
-
-/*++======================================================================*/
-void Queue_get(daemon_command_t *Que)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference));
- atomic_inc( &Que->reference );
-}
-
-/*++======================================================================*/
-void Queue_put(daemon_command_t *Que)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- spin_lock(&Daemon_Queue.lock);
-
- DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference));
- if ( atomic_dec_and_test( &Que->reference ))
- {
- /*
- * Remove item from queue
- */
- list_del(&Que->list);
-
- spin_unlock(&Daemon_Queue.lock);
-
- /*
- * Free item memory
- */
- Novfs_Free(Que);
- }
- else
- {
- spin_unlock(&Daemon_Queue.lock);
- }
-}
-
-/*++======================================================================*/
-daemon_command_t *get_next_queue(int Set_Queue_Waiting)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
-
- spin_lock(&Daemon_Queue.lock);
- que = (daemon_command_t *)Daemon_Queue.list.next;
-
- DbgPrint( "get_next_queue: que=0x%x\n", que);
-
- while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && ( que->status != QUEUE_SENDING ) )
- {
- que = (daemon_command_t *)que->list.next;
- DbgPrint( "get_next_queue: que1=0x%x\n", que);
- }
-
- if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list) || (que->status != QUEUE_SENDING))
- {
- que = NULL;
- }
- else if (Set_Queue_Waiting)
- {
- que->status = QUEUE_WAITING;
- }
-
- if (que)
- {
- atomic_inc( &que->reference );
- }
-
- spin_unlock(&Daemon_Queue.lock);
-
- DbgPrint( "get_next_queue: return=0x%x\n", que);
- return(que);
-}
-
-/*++======================================================================*/
-daemon_command_t *find_queue(u_long sequence)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
-
- DbgPrint( "find_queue: 0x%x\n", sequence);
-
- spin_lock(&Daemon_Queue.lock);
- que = (daemon_command_t *)Daemon_Queue.list.next;
-
- DbgPrint( "find_queue: que=0x%x\n", que);
-
- while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->sequence != sequence))
- {
- DbgPrint( "find_queue: que1=0x%x\n", que);
- que = (daemon_command_t *)que->list.next;
- }
-
- if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list.next) || (que->sequence != sequence))
- {
- que = NULL;
- }
-
- if (que)
- {
- atomic_inc( &que->reference );
- }
-
- spin_unlock(&Daemon_Queue.lock);
-
- DbgPrint( "find_queue: return 0x%x\n", que);
- return(que);
-}
-/*++======================================================================*/
-int Daemon_Open_Control(struct inode *Inode, struct file *File)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
- atomic_inc(&Daemon_Open_Count);
-
- return(0);
-}
-
-/*++======================================================================*/
-int Daemon_Close_Control(struct inode *Inode, struct file *File)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
-
- DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
-
- if (atomic_dec_and_test(&Daemon_Open_Count))
- {
- /*
- * Signal any pending que itmes.
- */
-
- spin_lock(&Daemon_Queue.lock);
- que = (daemon_command_t *)Daemon_Queue.list.next;
-
- DbgPrint( "Daemon_Close_Control: que=0x%x\n", que);
-
- while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->status != QUEUE_DONE))
- {
- que->status = QUEUE_TIMEOUT;
- up(&que->semaphore);
-
- que = (daemon_command_t *)que->list.next;
- DbgPrint( "Daemon_Close_Control: que1=0x%x\n", que);
- }
- spin_unlock(&Daemon_Queue.lock);
-
- RemoveDriveMaps();
-
- Scope_Cleanup();
- }
-
- return(0);
-}
-
-/*++======================================================================*/
-ssize_t
-Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
- size_t retValue = 0;
- int Finished=0;
- PDATA_LIST dlist;
- int i, dcnt, bcnt, ccnt, error;
- char *vadr;
- u_long cpylen;
-
- DbgPrint( "Daemon_Send_Command: %u %lld\n", len, *off);
- if (len > MaxIoSize)
- {
- MaxIoSize = len;
- }
-
- while ( !Finished )
- {
- que = get_next_queue(1);
- DbgPrint( "Daemon_Send_Command: 0x%x\n", que);
- if (que)
- {
- retValue = que->reqlen;
- if (retValue > len)
- {
- retValue = len;
- }
- if (retValue > 0x80)
- mydump(0x80, que->request);
- else
- mydump(retValue, que->request);
-
- cpylen = copy_to_user(buf, que->request, retValue);
- if (que->datalen && (retValue < len))
- {
- buf += retValue;
- dlist = que->data;
- dcnt = que->datalen;
- for (i=0; i<dcnt; i++, dlist++)
- {
- if ( DLREAD == dlist->rwflag )
- {
- bcnt = dlist->len;
- DbgPrint("Daemon_Send_Command%d: page=0x%x offset=0x%x len=%d\n", i, dlist->page, dlist->offset, dlist->len);
- if ((bcnt + retValue) <= len)
- {
- void *km_adr=NULL;
-
- if (dlist->page)
- {
- //vadr = kmap(dlist->page);
- km_adr = kmap_atomic(dlist->page, KM_USER1);
- vadr = km_adr;
- vadr += (u_int)dlist->offset;
- }
- else
- {
- vadr = dlist->offset;
- }
-
- ccnt = copy_to_user(buf, vadr, bcnt);
-
- if ( km_adr )
- {
- //kunmap(dlist->page);
- kunmap_atomic(km_adr, KM_USER1);
- }
-
- DbgPrint("Daemon_Send_Command: Copy %d from 0x%x to 0x%x.\n", bcnt, vadr, buf);
- if (bcnt > 0x80)
- mydump(0x80, vadr);
- else
- mydump(bcnt, vadr);
-
- retValue += bcnt;
- buf += bcnt;
- }
- else
- {
- break;
- }
- }
- }
- }
- Queue_put( que );
- break;
- }
-
- if (O_NONBLOCK & file->f_flags)
- {
- retValue = -EAGAIN;
- break;
- }
- else
- {
- if ((error = down_interruptible(&Daemon_Queue.semaphore)))
- {
- DbgPrint( "Daemon_Send_Command: after down_interruptible error...%d\n", error);
- retValue = -EINTR;
- break;
- }
- DbgPrint( "Daemon_Send_Command: after down_interruptible\n");
- }
- }
-
- *off = *off;
-
- DbgPrint( "Daemon_Send_Command: return 0x%x\n", retValue);
-
- return(retValue);
-}
-
-/*++======================================================================*/
-ssize_t
-Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
- size_t retValue = 0;
- void *reply;
- u_long sequence, cpylen;
-
- PDATA_LIST dlist;
- char *vadr;
- int i;
-
- DbgPrint( "Daemon_Receive_Reply: buf=0x%x nbytes=%d ppos=%llx\n", buf, nbytes, *ppos);
-
- /*
- * Get sequence number from reply buffer
- */
-
- cpylen = copy_from_user(&sequence, buf, sizeof(sequence));
-
- /*
- * Find item based on sequence number
- */
- que = find_queue(sequence);
-
- DbgPrint( "Daemon_Receive_Reply: 0x%x 0x%x %d\n", sequence, que, nbytes);
- if (que)
- {
- do
- {
- retValue = nbytes;
- /*
- * Ack packet from novfsd. Remove timer and
- * return
- */
- if (nbytes == sizeof(sequence))
- {
- que->status = QUEUE_ACKED;
- break;
- }
-
- /*
- * Set status that packet is done.
- */
- que->status = QUEUE_DONE;
-
- if ( NULL != (dlist = que->data) )
- {
- int thiscopy, left=nbytes;
- retValue = 0;
-
-
- DbgPrint( "Daemon_Receive_Reply: dlist=0x%x count=%d\n", dlist, que->datalen);
- for (i=0; i < que->datalen; i++, dlist++)
- {
- DbgPrint( "Daemon_Receive_Reply:\n" \
- " dlist[%d].page: 0x%x\n" \
- " dlist[%d].offset: 0x%x\n" \
- " dlist[%d].len: 0x%x\n" \
- " dlist[%d].rwflag: 0x%x\n",
- i, dlist->page,
- i, dlist->offset,
- i, dlist->len,
- i, dlist->rwflag);
-
- if (DLWRITE == dlist->rwflag)
- {
- void *km_adr=NULL;
-
- if (dlist->page)
- {
- //vadr = kmap(dlist->page);
- km_adr = kmap_atomic(dlist->page, KM_USER1);
- vadr = km_adr;
- vadr += (u_int)dlist->offset;
- }
- else
- {
- vadr = dlist->offset;
- }
-
- thiscopy = dlist->len;
- if (thiscopy > left)
- {
- thiscopy = left;
- dlist->len = left;
- }
- cpylen = copy_from_user(vadr, buf, thiscopy);
-
- if ( km_adr )
- {
- //kunmap(dlist->page);
- kunmap_atomic(km_adr, KM_USER1);
- }
-
- left -= thiscopy;
- retValue += thiscopy;
- buf += thiscopy;
- }
- }
- }
- else
- {
- reply = Novfs_Malloc(nbytes, GFP_KERNEL);
- DbgPrint( "Daemon_Receive_Reply: reply=0x%x\n", reply);
- if (reply)
- {
- retValue = nbytes;
- que->reply = reply;
- que->replen = nbytes;
-
- retValue -= copy_from_user(reply, buf, retValue);
- if (retValue > 0x80)
- mydump(0x80, reply);
- else
- mydump(retValue, reply);
-
-
- }
- else
- {
- retValue = -ENOMEM;
- }
- }
- } while (0);
- up(&que->semaphore);
- Queue_put( que );
- }
-
- DbgPrint( "Daemon_Receive_Reply: return 0x%x\n", retValue);
-
- return(retValue);
-}
-
-/*++======================================================================*/
-int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PLOGIN_USER_REQUEST cmd;
- PLOGIN_USER_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen, datalen;
- u_char *data;
-
- datalen = Server->len+Username->len+Password->len;
- cmdlen = sizeof(*cmd) + datalen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- data = (u_char *)cmd + sizeof(*cmd);
- cmd->Command.CommandType = VFS_COMMAND_LOGIN_USER;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
-
- cmd->srvNameType = Server->type;
- cmd->serverLength = Server->len;
- cmd->serverOffset = (u_long)(data-(u_char *)cmd);
- memcpy(data, Server->buffer, Server->len);
- data += Server->len;
-
- cmd->usrNameType = Username->type;
- cmd->userNameLength = Username->len;
- cmd->userNameOffset = (u_long)(data-(u_char *)cmd);
- memcpy(data, Username->buffer, Username->len);
- data += Username->len;
-
- cmd->pwdNameType = Password->type;
- cmd->passwordLength = Password->len;
- cmd->passwordOffset = (u_long)(data-(u_char *)cmd);
- memcpy(data, Password->buffer, Password->len);
- data += Password->len;
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- retCode = reply->Reply.ErrorCode;
- }
- else
- {
- retCode = 0;
- if (lgnId)
- {
- *lgnId = reply->loginIdentity;
- }
- }
- Novfs_Free(reply);
- }
- memset(cmd, 0, cmdlen);
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-
-}
-
-/*++======================================================================*/
-int do_logout( struct qstr *Server, session_t Session )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PLOGOUT_REQUEST cmd;
- PLOGOUT_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen;
-
- cmdlen = (int)(&((PLOGOUT_REQUEST)0)->Name) + Server->len;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_LOGOUT_USER;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
-
- cmd->Length = Server->len;
- memcpy(cmd->Name, Server->name, Server->len);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-
-}
-
-/*++======================================================================*/
-int Daemon_getpwuid( uid_t uid, int unamelen, char *uname )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- GETPWUID_REQUEST cmd;
- PGETPWUID_REPLY reply;
- u_long replylen=0;
- int retCode;
-
- cmd.Command.CommandType = VFS_COMMAND_GETPWUD;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = 0;
- cmd.uid = uid;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- else
- {
- retCode = 0;
- memset(uname, 0, unamelen);
- replylen = replylen - (int)(&((PGETPWUID_REPLY)0)->UserName);
- if (replylen)
- {
- if (replylen > unamelen)
- {
- retCode = -EINVAL;
- replylen = unamelen-1;
- }
- memcpy(uname, reply->UserName, replylen);
- }
- }
- Novfs_Free(reply);
- }
- return( retCode );
-
-}
-
-/*++======================================================================*/
-int Daemon_getversion( char *Buf, int Length )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- GET_VERSION_REQUEST cmd;
- PGET_VERSION_REPLY reply;
- u_long replylen=0;
- int retVal=0;
-
- cmd.Command.CommandType = VFS_COMMAND_GET_VERSION;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = 0;
-
- Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- retVal = -EIO;
- }
- else
- {
- retVal = replylen - (int)(&((PGET_VERSION_REPLY)0)->Version);
- if (retVal < Length)
- {
- memcpy(Buf, reply->Version, retVal);
- Buf[retVal] = '\0';
- }
- }
- Novfs_Free(reply);
- }
- return( retVal );
-
-}
-
-/*++======================================================================*/
-int Daemon_Login(PLOGIN Login, session_t Session)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOMEM;
- LOGIN lLogin;
- NclString server;
- NclString username;
- NclString password;
-
- if ( !copy_from_user(&lLogin, Login, sizeof(lLogin)))
- {
- if ( (server.buffer = Novfs_Malloc(lLogin.Server.Length, GFP_KERNEL)) )
- {
- server.len = lLogin.Server.Length;
- server.type = NWC_STRING_TYPE_ASCII;
- if ( !copy_from_user((void *)server.buffer, lLogin.Server.Data, server.len) )
- {
- if ( (username.buffer = Novfs_Malloc(lLogin.UserName.Length, GFP_KERNEL)) )
- {
- username.len = lLogin.UserName.Length;
- username.type = NWC_STRING_TYPE_ASCII;
- if ( !copy_from_user((void *)username.buffer, lLogin.UserName.Data, username.len) )
- {
- if ( (password.buffer = Novfs_Malloc(lLogin.Password.Length, GFP_KERNEL)) )
- {
- password.len = lLogin.Password.Length;
- password.type = NWC_STRING_TYPE_ASCII;
- if ( !copy_from_user((void *)password.buffer, lLogin.Password.Data, password.len) )
- {
- retCode = do_login(&server, &username, &password, NULL, Session);
- if ( !retCode )
- {
- char *username;
- username = Scope_Get_UserName( NULL );
- if (username)
- {
- Novfs_Add_to_Root( username );
- }
- }
- }
- memset(password.buffer, 0, password.len);
- Novfs_Free(password.buffer);
- }
- }
- memset(username.buffer, 0, username.len);
- Novfs_Free(username.buffer);
- }
- }
- Novfs_Free(server.buffer);
- }
- }
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Daemon_Logout(PLOGOUT Logout, session_t Session)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- LOGOUT lLogout;
- struct qstr server;
- int retCode=0;
-
- if ( !copy_from_user(&lLogout, Logout, sizeof(lLogout)))
- {
- if ( (server.name = Novfs_Malloc(lLogout.Server.Length, GFP_KERNEL)) )
- {
- server.len = lLogout.Server.Length;
- if ( !copy_from_user((void *)server.name, lLogout.Server.Data, server.len) )
- {
- retCode = do_logout( &server, Session );
- }
- Novfs_Free(server.name);
- }
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Daemon_CreateSessionId( uint64_t *SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- CREATE_CONTEXT_REQUEST cmd;
- PCREATE_CONTEXT_REPLY reply;
- u_long replylen=0;
- int retCode=0;
-
- DbgPrint("Daemon_CreateSessionId: %d\n", current->pid);
-
- cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = 0;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- if ( !reply->Reply.ErrorCode && replylen > sizeof(COMMAND_REPLY_HEADER))
- {
- *SessionId = reply->SessionId;
- retCode = 0;
- }
- else
- {
- *SessionId = 0;
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId);
- return(retCode);
-}
-
-/*++======================================================================*/
-int Daemon_DestroySessionId( uint64_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DESTROY_CONTEXT_REQUEST cmd;
- PDESTROY_CONTEXT_REPLY reply;
- u_long replylen=0;
- int retCode=0;
-
- DbgPrint("Daemon_DestroySessionId: 0x%llx\n", SessionId);
-
- cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- if ( !reply->Reply.ErrorCode )
- {
- drive_map_t *dm;
- struct list_head *list;
-
- retCode = 0;
-
- /*
- * When destroying the session check to see if there are any
- * mapped drives. If there are then remove them.
- */
- down( &DriveMapLock );
- list_for_each( list, &DriveMapList )
- {
- dm = list_entry( list, drive_map_t, list );
- if ( SessionId == dm->session)
- {
- local_unlink( dm->name );
- list = list->prev;
- list_del( &dm->list );
- Novfs_Free( dm );
- }
-
- }
- up( &DriveMapLock );
-
- }
- else
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- GET_USER_SPACE_REQUEST cmd;
- PGET_USER_SPACE_REPLY reply;
- u_long replylen=0;
- int retCode=0;
-
- DbgPrint("Daemon_Get_UserSpace: 0x%llx\n", SessionId);
-
- cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- if ( !reply->Reply.ErrorCode )
- {
-
- DbgPrint("TotalSpace: %llu\n", reply->TotalSpace);
- DbgPrint("FreeSpace: %llu\n", reply->FreeSpace);
- DbgPrint("TotalEnties: %llu\n", reply->TotalEnties);
- DbgPrint("FreeEnties: %llu\n", reply->FreeEnties);
-
- if (TotalSize) *TotalSize = reply->TotalSpace;
- if (Free) *Free = reply->FreeSpace;
- if (TotalEnties) *TotalEnties = reply->TotalEnties;
- if (FreeEnties) *FreeEnties = reply->FreeEnties;
- retCode = 0;
- }
- else
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Daemon_SetMountPoint ( char *Path )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSET_MOUNT_PATH_REQUEST cmd;
- PSET_MOUNT_PATH_REPLY reply;
- u_long replylen, cmdlen;
- int retCode = -ENOMEM;
-
- DbgPrint("Daemon_SetMountPoint: %s\n", Path);
-
- replylen = strlen(Path);
-
- cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen;
-
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if ( cmd )
- {
- cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = 0;
- cmd->PathLength = replylen;
-
- strcpy(cmd->Path, Path);
-
- replylen = 0;
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- if ( !reply->Reply.ErrorCode )
- {
- retCode = 0;
- }
- else
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Daemon_SendDebugCmd ( char *Command )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DEBUG_REQUEST cmd;
- PDEBUG_REPLY reply;
- DEBUG_REPLY lreply;
- u_long replylen, cmdlen;
- DATA_LIST dlist[2];
-
- int retCode = -ENOMEM;
-
- DbgPrint("Daemon_SendDebugCmd: %s\n", Command);
-
- dlist[0].page = NULL;
- dlist[0].offset = (char *)Command;
- dlist[0].len = strlen(Command);
- dlist[0].rwflag = DLREAD;
-
- dlist[1].page = NULL;
- dlist[1].offset = (char *)&lreply;
- dlist[1].len = sizeof(lreply);
- dlist[1].rwflag = DLWRITE;
-
- cmdlen = (int)(&((PDEBUG_REQUEST)0)->dbgcmd);
-
- cmd.Command.CommandType = VFS_COMMAND_DBG;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = 0;
- cmd.cmdlen = strlen(Command);
-
- replylen = 0;
-
- retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- Novfs_Free(reply);
- }
- if (0 == retCode)
- {
- retCode = lreply.Reply.ErrorCode;
- }
-
- return(retCode);
-}
-
-/*++======================================================================*/
-int
-NO_TRACE
-Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOSYS;
- u_long cpylen;
-
-
- switch (cmd)
- {
- case IOC_LOGIN:
- {
- retCode = Daemon_Login((PLOGIN)arg, Scope_Get_SessionId( NULL ));
- break;
- }
-
- case IOC_LOGOUT:
- {
- retCode = Daemon_Logout((PLOGOUT)arg, Scope_Get_SessionId( NULL ));
- break;
- }
- case IOC_DEBUGPRINT:
- {
- struct Ioctl_Debug {
- int length;
- char *data;
- } io;
- char *buf;
- io.length = 0;
- cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
- if (io.length)
- {
- buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
- if (buf)
- {
- buf[0] = 0;
- cpylen = copy_from_user(buf, io.data, io.length);
- buf[io.length] = '\0';
- if( DbgDaemonLogOn )
- printk("%s", buf);
- else
- DbgPrint("%s", buf);
- Novfs_Free(buf);
- retCode = 0;
- }
- }
- break;
- }
-
- case IOC_XPLAT:
- {
- XPLAT data;
-
- cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
- retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
-
- switch(data.xfunction)
- {
- case NWC_GET_MOUNT_PATH:
- DbgPrint("[Daemon_ioctl] Call NwdGetMountPath\n");
- retCode = NwdGetMountPath( &data );
- break;
- }
-
- DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
- break;
- }
-
- }
- return (retCode);
-}
-
-/*++======================================================================*/
-int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_resource_t *resource;
- int retVal = NWE_OUT_OF_HEAP_SPACE;
-
- if (FHandle)
- DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u_long *)&FHandle[2], Mode, Size);
- else
- DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x\n", DHandle, Type, CHandle);
-
- resource = Novfs_Malloc(sizeof(daemon_resource_t), GFP_KERNEL);
- if (resource)
- {
- resource->type = Type;
- resource->connection = CHandle;
- if (FHandle)
- {
- memcpy( resource->handle, FHandle, sizeof(resource->handle) );
- }
- else
- {
- memset( resource->handle, 0, sizeof(resource->handle) );
- }
- resource->mode = Mode;
- resource->size = Size;
- write_lock( &DHandle->lock );
- list_add( &resource->list, &DHandle->list );
- write_unlock( &DHandle->lock );
- DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource);
- retVal = 0;
- }
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_resource_t *resource;
- struct list_head *l;
- int retVal = -ENOMEM;
-
- DbgPrint("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x\n", DHandle, Type, CHandle, FHandle);
-
- write_lock( &DHandle->lock );
-
- list_for_each( l, &DHandle->list )
- {
- resource = list_entry( l, daemon_resource_t, list );
-
- if ( (Type == resource->type) &&
- (resource->connection == CHandle) )
- {
- DbgPrint("Daemon_Remove_Resource: Found resource=0x%p\n", resource);
- l = l->prev;
- list_del( &resource->list );
- Novfs_Free( resource );
- break;
- }
- }
-
- write_unlock( &DHandle->lock );
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int Daemon_Library_open(struct inode *inode, struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal = -ENOMEM;
- daemon_handle_t *dh;
-
- DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file);
-
- if ((dh = Novfs_Malloc(sizeof(daemon_handle_t), GFP_KERNEL)))
- {
- file->private_data = dh;
- INIT_LIST_HEAD( &dh->list);
- rwlock_init( &dh->lock );
- dh->session = Scope_Get_SessionId( NULL );
- retVal = 0;
- }
- return(retVal);
-}
-
-/*++======================================================================*/
-int Daemon_Library_close(struct inode *inode, struct file *file)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_handle_t *dh;
- daemon_resource_t *resource;
- struct list_head *l;
-
- char commanddata[sizeof(XPLAT_CALL_REQUEST)+sizeof(NwdCCloseConn)];
- PXPLAT_CALL_REQUEST cmd;
- PXPLAT_CALL_REPLY reply;
- PNwdCCloseConn nwdClose;
- u_long cmdlen, replylen;
-
- DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file);
- if (file->private_data)
- {
- dh = (daemon_handle_t *)file->private_data;
-
- list_for_each( l, &dh->list )
- {
- resource = list_entry( l, daemon_resource_t, list );
-
- if (DH_TYPE_STREAM == resource->type)
- {
- Novfs_Close_Stream( resource->connection, resource->handle, dh->session );
- }
- else if (DH_TYPE_CONNECTION == resource->type)
- {
- cmd = (PXPLAT_CALL_REQUEST)commanddata;
- cmdlen = offsetof(XPLAT_CALL_REQUEST, data) + sizeof(NwdCCloseConn);
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = dh->session;
- cmd->NwcCommand = NWC_CLOSE_CONN;
-
- cmd->dataLen = sizeof(NwdCCloseConn);
- nwdClose = (PNwdCCloseConn)cmd->data;
- nwdClose->ConnHandle = resource->connection;
-
- Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
- if (reply)
- {
- Novfs_Free(reply);
- }
- }
- l = l->prev;
- list_del( &resource->list );
- Novfs_Free( resource );
- }
- Novfs_Free(dh);
- file->private_data = NULL;
- }
-
- return(0);
-}
-
-/*++======================================================================*/
-ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_handle_t *dh;
- daemon_resource_t *resource;
-
- size_t thisread, totalread=0;
- loff_t offset = *off;
-
- DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n", file, len, *off);
-
- if (file->private_data)
- {
- dh = file->private_data;
- read_lock( &dh->lock );
- if (&dh->list != dh->list.next)
- {
- resource = list_entry( dh->list.next, daemon_resource_t, list );
-
- if (DH_TYPE_STREAM == resource->type)
- {
- while( len > 0 && (offset < resource->size) )
- {
- thisread = len;
- if (Novfs_Read_Stream(resource->connection,
- resource->handle,
- buf, &thisread,
- &offset, 1,
- dh->session) || !thisread)
- {
- break;
- }
- len -= thisread;
- buf += thisread;
- offset += thisread;
- totalread += thisread;
- }
- }
- }
- read_unlock( &dh->lock );
- }
- *off = offset;
- DbgPrint("Daemon_Library_read return = 0x%x\n", totalread);
- return(totalread);
-}
-
-/*++======================================================================*/
-ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_handle_t *dh;
- daemon_resource_t *resource;
-
- size_t thiswrite, totalwrite=-EINVAL;
- loff_t offset = *off;
- int status;
-
- DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n", file, len, *off);
-
- if (file->private_data)
- {
- dh = file->private_data;
- write_lock( &dh->lock );
- if (&dh->list != dh->list.next)
- {
- resource = list_entry( dh->list.next, daemon_resource_t, list );
-
- if ( (DH_TYPE_STREAM == resource->type) && (len >= 0) )
- {
- totalwrite = 0;
- do
- {
- thiswrite = len;
- status = Novfs_Write_Stream(resource->connection,
- resource->handle,
- (PVOID)buf,
- &thiswrite,
- &offset,
- dh->session);
- if ( status || !thiswrite )
- {
- /*
- * If len is zero then the file will have just been
- * truncated to offset. Update size.
- */
- if ( !status && !len )
- {
- resource->size = offset;
- }
- totalwrite = status;
- break;
- }
- len -= thiswrite;
- buf += thiswrite;
- offset += thiswrite;
- totalwrite += thiswrite;
- if (offset > resource->size)
- {
- resource->size = offset;
- }
- } while(len > 0);
- }
- }
- write_unlock( &dh->lock );
- }
- *off = offset;
- DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite);
-
- return(totalwrite);
-}
-
-/*++======================================================================*/
-loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_handle_t *dh;
- daemon_resource_t *resource;
-
- loff_t retVal = -EINVAL;
-
- DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", file, offset, origin);
-
- if (file->private_data)
- {
- dh = file->private_data;
- read_lock( &dh->lock );
- if (&dh->list != dh->list.next)
- {
- resource = list_entry( dh->list.next, daemon_resource_t, list );
-
- if (DH_TYPE_STREAM == resource->type)
- {
- switch (origin) {
- case 2:
- offset += resource->size;
- break;
- case 1:
- offset += file->f_pos;
- }
- if (offset >= 0) {
- if (offset != file->f_pos) {
- file->f_pos = offset;
- file->f_version = 0;
- }
- retVal = offset;
- }
- }
- }
- read_unlock( &dh->lock );
- }
-
- DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal);
-
- return retVal;
-}
-
-/*++======================================================================*/
-int
-NO_TRACE
-Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOSYS;
- daemon_handle_t *dh;
- u_long handle=0, cpylen;
-
-
- dh = file->private_data;
-
- DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%x dh=0x%p\n", file, cmd, arg, dh);
-
- if (dh)
- {
-
- switch (cmd)
- {
- case IOC_LOGIN:
- {
- retCode = Daemon_Login((PLOGIN)arg, dh->session);
- break;
- }
-
- case IOC_LOGOUT:
- {
- retCode = Daemon_Logout((PLOGOUT)arg, dh->session);
- break;
- }
-
- case IOC_DEBUGPRINT:
- {
- struct Ioctl_Debug {
- int length;
- char *data;
- } io;
- char *buf;
- io.length = 0;
- cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
- if (io.length)
- {
- buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
- if (buf)
- {
- buf[0] = 0;
- cpylen = copy_from_user(buf, io.data, io.length);
- buf[io.length] = '\0';
- DbgPrint("%s", buf);
- Novfs_Free(buf);
- retCode = 0;
- }
- }
- break;
- }
-
- case IOC_XPLAT:
- {
- XPLAT data;
-
- cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
- retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
-
- switch(data.xfunction)
- {
- case NWC_OPEN_CONN_BY_NAME:
- DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n");
- retCode = NwOpenConnByName(&data, &handle, dh->session);
- if ( !retCode )
- {
- Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
- }
- break;
-
- case NWC_OPEN_CONN_BY_ADDRESS:
- DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n");
- retCode = NwOpenConnByAddr(&data, &handle, dh->session);
- if ( !retCode )
- {
- Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
- }
- break;
-
- case NWC_OPEN_CONN_BY_REFERENCE:
-
- DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n");
- retCode = NwOpenConnByRef(&data, &handle, dh->session);
- if ( !retCode )
- {
- Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
- }
- break;
-
- case NWC_SYS_CLOSE_CONN:
- DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n");
- retCode = NwSysConnClose(&data, &handle, dh->session);
- Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
- break;
-
- case NWC_CLOSE_CONN:
- DbgPrint("[VFS XPLAT] Call NwCloseConn\n");
- retCode = NwConnClose(&data, &handle, dh->session);
- Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
- break;
-
- case NWC_LOGIN_IDENTITY:
- DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n");
- retCode = NwLoginIdentity(&data, dh->session);
- break;
-
- case NWC_RAW_NCP_REQUEST:
- DbgPrint("[VFS XPLAT] Send Raw NCP Request\n");
- retCode = NwRawSend(&data, dh->session);
- break;
-
- case NWC_AUTHENTICATE_CONN_WITH_ID:
- DbgPrint("[VFS XPLAT] Authenticate Conn With ID\n");
- retCode = NwAuthConnWithId(&data, dh->session);
- break;
-
- case NWC_UNAUTHENTICATE_CONN:
- DbgPrint("[VFS XPLAT] UnAuthenticate Conn With ID\n");
- retCode = NwUnAuthenticate(&data, dh->session);
- break;
-
- case NWC_LICENSE_CONN:
- DbgPrint("Call NwLicenseConn\n");
- retCode = NwLicenseConn(&data, dh->session);
- break;
-
- case NWC_LOGOUT_IDENTITY:
- DbgPrint("[VFS XPLAT] Call NwLogoutIdentity\n");
- retCode = NwLogoutIdentity(&data, dh->session);
- break;
-
- case NWC_UNLICENSE_CONN:
- DbgPrint("[VFS XPLAT] Call NwUnlicense\n");
- retCode = NwUnlicenseConn(&data, dh->session);
- break;
-
- case NWC_GET_CONN_INFO:
- DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
- retCode = NwGetConnInfo(&data, dh->session);
- break;
-
- case NWC_SET_CONN_INFO:
- DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
- retCode = NwSetConnInfo(&data, dh->session);
- break;
-
- case NWC_SCAN_CONN_INFO:
- DbgPrint("[VFS XPLAT] Call NwScanConnInfo\n");
- retCode = NwScanConnInfo(&data, dh->session);
- break;
-
-
- case NWC_GET_IDENTITY_INFO:
- DbgPrint("[VFS XPLAT] Call NwGetIdentityInfo\n");
- retCode = NwGetIdentityInfo(&data, dh->session);
- break;
-
- case NWC_GET_REQUESTER_VERSION:
- DbgPrint("[VFS XPLAT] Call NwGetDaemonVersion\n");
- retCode = NwGetDaemonVersion(&data, dh->session);
- break;
-
- case NWC_GET_PREFERRED_DS_TREE:
- DbgPrint("[VFS XPLAT] Call NwcGetPreferredDsTree\n");
- retCode = NwcGetPreferredDSTree(&data, dh->session);
- break;
-
- case NWC_SET_PREFERRED_DS_TREE:
- DbgPrint("[VFS XPLAT] Call NwcSetPreferredDsTree\n");
- retCode = NwcSetPreferredDSTree(&data, dh->session);
- break;
-
- case NWC_GET_DEFAULT_NAME_CONTEXT:
- DbgPrint("[VFS XPLAT] Call NwcGetDefaultNameContext\n");
- retCode = NwcGetDefaultNameCtx(&data, dh->session);
- break;
-
- case NWC_SET_DEFAULT_NAME_CONTEXT:
- DbgPrint("[VFS XPLAT] Call NwcSetDefaultNameContext\n");
- retCode = NwcSetDefaultNameCtx(&data, dh->session);
- break;
-
- case NWC_QUERY_FEATURE:
- DbgPrint("[VFS XPLAT] Call NwQueryFeature\n");
- retCode = NwQueryFeature(&data, dh->session);
- break;
-
-
- case NWC_GET_TREE_MONITORED_CONN_REF:
- DbgPrint("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n");
- retCode = NwcGetTreeMonitoredConn(&data, dh->session);
- break;
-
- case NWC_ENUMERATE_IDENTITIES:
- DbgPrint("[VFS XPLAT] Call NwcEnumerateIdentities\n");
- retCode = NwcEnumIdentities(&data, dh->session);
- break;
-
- case NWC_CHANGE_KEY:
- DbgPrint("[VFS XPLAT] Call NwcChangeAuthKey\n");
- retCode = NwcChangeAuthKey(&data, dh->session);
- break;
-
- case NWC_CONVERT_LOCAL_HANDLE:
- DbgPrint("[VFS XPLAT] Call NwdConvertLocalHandle\n");
- retCode = NwdConvertLocalHandle(&data, dh);
- break;
-
- case NWC_CONVERT_NETWARE_HANDLE:
- DbgPrint("[VFS XPLAT] Call NwdConvertNetwareHandle\n");
- retCode = NwdConvertNetwareHandle(&data, dh);
- break;
-
- case NWC_SET_PRIMARY_CONN:
- DbgPrint("[VFS XPLAT] Call NwcSetPrimaryConn\n");
- retCode = NwcSetPrimaryConn(&data, dh->session);
- break;
-
- case NWC_GET_PRIMARY_CONN:
- DbgPrint("[VFS XPLAT] Call NwcGetPrimaryConn\n");
- retCode = NwcGetPrimaryConn(&data, dh->session);
- break;
-
- case NWC_MAP_DRIVE:
- DbgPrint("[VFS XPLAT] Call NwcMapDrive\n");
- retCode = NwdSetMapDrive(&data, dh->session);
- break;
-
- case NWC_UNMAP_DRIVE:
- DbgPrint("[VFS XPLAT] Call NwcUnMapDrive\n");
- retCode = NwdUnMapDrive(&data, dh->session);
- break;
-
- case NWC_ENUMERATE_DRIVES:
- DbgPrint("[VFS XPLAT] Call NwcEnumerateDrives\n");
- retCode = NwcEnumerateDrives(&data, dh->session);
- break;
-
- case NWC_GET_MOUNT_PATH:
- DbgPrint("[VFS XPLAT] Call NwdGetMountPath\n");
- retCode = NwdGetMountPath( &data );
- break;
-
- case NWC_GET_BROADCAST_MESSAGE:
- DbgPrint("[VSF XPLAT Call NwdGetBroadcastMessage\n");
- retCode = NwcGetBroadcastMessage(&data, dh->session);
- break;
-
- case NWC_SET_KEY:
- DbgPrint("[VSF XPLAT Call NwdSetKey\n");
- retCode = NwdSetKeyValue(&data, dh->session);
- break;
-
- case NWC_VERIFY_KEY:
- DbgPrint("[VSF XPLAT Call NwdVerifyKey\n");
- retCode = NwdVerifyKeyValue(&data, dh->session);
- break;
-
- case NWC_RAW_NCP_REQUEST_ALL:
- case NWC_NDS_RESOLVE_NAME_TO_ID:
- case NWC_FRAGMENT_REQUEST:
- case NWC_GET_CONFIGURED_NSPS:
- default:
- break;
-
- }
-
- DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
- break;
- }
- }
- }
-
- return( retCode );
-}
-
-/*++======================================================================*/
-unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- daemon_command_t *que;
- unsigned int mask = POLLOUT | POLLWRNORM;
-
- que = get_next_queue(0);
- if (que)
- {
- mask |= (POLLIN | POLLRDNORM);
- }
- else
- {
-
- }
- return(mask);
-}
-
-
-void Daemon_Dumpque( void )
-{
-#ifdef CONFIG_KDB
- daemon_command_t *que;
-
- que = (daemon_command_t *)Daemon_Queue.list.next;
-
- while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next))
- {
- kdb_printf("DaemonQue:\n" \
- " Que: 0x%p\n" \
- " status: 0x%lx\n" \
- " flags: 0x%lx\n" \
- " semaphore: 0x%x\n" \
- " sequence: 0x%lx\n" \
- " timer: 0x%lx\n" \
- " request: 0x%p\n" \
- " reqlen: %ld\n" \
- " data: 0x%p\n" \
- " datalen: %d\n" \
- " reply: 0x%p\n" \
- " replen: %ld\n",
- que,
- que->status,
- que->flags,
- atomic_read(&que->semaphore.count),
- que->sequence,
- que->timer.expires,
- que->request,
- que->reqlen,
- que->data,
- que->datalen,
- que->reply,
- que->replen);
- que = (daemon_command_t *)que->list.next;
- }
-#endif
-}
-
-/*++======================================================================*/
-int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal;
- NwcConvertNetWareHandle nh;
- u_long cpylen;
-
- DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle);
-
- cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle));
-
- retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, nh.ConnHandle, nh.NetWareHandle, nh.uAccessMode, nh.uFileSize);
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal = NWE_REQUESTER_FAILURE;
- daemon_resource_t *resource;
- NwcConvertLocalHandle lh;
- struct list_head *l;
- u_long cpylen;
-
- DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle);
-
- read_lock( &DHandle->lock );
-
- list_for_each( l, &DHandle->list )
- {
- resource = list_entry( l, daemon_resource_t, list );
-
- if ( DH_TYPE_STREAM == resource->type )
- {
- lh.uConnReference = resource->connection;
-
- memcpy(lh.NwFileHandle, resource->handle, sizeof(resource->handle));
- if (pdata->repLen >= sizeof(NwcConvertLocalHandle))
- {
- cpylen = copy_to_user(pdata->repData, &lh, sizeof(NwcConvertLocalHandle));
- retVal = 0;
- }
- else
- {
- retVal = NWE_BUFFER_OVERFLOW;
- }
- break;
- }
- }
-
- read_unlock( &DHandle->lock );
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int NwdGetMountPath(PXPLAT pdata)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal = NWE_REQUESTER_FAILURE;
- int len;
- u_long cpylen;
- NwcGetMountPath mp;
-
- cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen);
-
- if ( Novfs_CurrentMount )
- {
-
- len = strlen(Novfs_CurrentMount)+1;
- if ( (len > mp.MountPathLen) && mp.pMountPath)
- {
- retVal = NWE_BUFFER_OVERFLOW;
- }
- else
- {
- if (mp.pMountPath)
- {
- cpylen = copy_to_user(mp.pMountPath, Novfs_CurrentMount, len);
- }
- retVal = 0;
- }
-
- mp.MountPathLen = len;
-
- if (pdata->repData && (pdata->repLen >= sizeof(mp)) )
- {
- cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp));
- }
- }
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int NwdSetMapDrive(PXPLAT pdata, session_t Session)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal;
- u_long cpylen;
-
- retVal = NwcSetMapDrive(pdata, Session);
- if ( !retVal )
- {
- NwcMapDriveEx symInfo;
- char *path;
- drive_map_t *drivemap, *dm;
- struct list_head *list;
-
- cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
- drivemap = Novfs_Malloc( sizeof(drive_map_t)+symInfo.linkOffsetLength, GFP_KERNEL );
- if (drivemap)
- {
- path = (char *)pdata->reqData;
- path += symInfo.linkOffset;
- cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength);
-
- drivemap->session = Session;
- drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength-1);
- drivemap->namelen = symInfo.linkOffsetLength-1;
- DbgPrint( "NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name);
-
- dm = (drive_map_t *)&DriveMapList.next;
-
- down( &DriveMapLock );
-
- list_for_each( list, &DriveMapList )
- {
- dm = list_entry( list, drive_map_t, list );
- DbgPrint( "NwdSetMapDrive: dm=0x%p\n" \
- " hash: 0x%x\n" \
- " namelen: %d\n" \
- " name: %s\n",
- dm, dm->hash, dm->namelen, dm->name);
-
- if (drivemap->hash == dm->hash)
- {
- if ( 0 == strcmp(dm->name, drivemap->name))
- {
- dm = NULL;
- break;
- }
- }
- else if (drivemap->hash < dm->hash)
- {
- break;
- }
- }
-
- if (dm)
- {
- if ( (dm == (drive_map_t *)&DriveMapList) ||
- (dm->hash < drivemap->hash) )
- {
- list_add( &drivemap->list, &dm->list);
- }
- else
- {
- list_add_tail( &drivemap->list, &dm->list);
- }
- }
- else
- {
- Novfs_Free( drivemap );
- }
- up( &DriveMapLock );
- }
- }
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int NwdUnMapDrive(PXPLAT pdata, session_t Session)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal = NWE_REQUESTER_FAILURE;
- u_long cpylen;
-
- retVal = NwcUnMapDrive(pdata, Session);
- if ( !retVal )
- {
- NwcUnmapDriveEx symInfo;
- char *path;
- drive_map_t *dm;
- struct list_head *list;
- u_long hash;
-
-
- cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
- path = Novfs_Malloc( symInfo.linkLen, GFP_KERNEL );
- if (path)
- {
- cpylen = copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen);
-
- hash = full_name_hash(path, symInfo.linkLen-1);
- DbgPrint( "NwdUnMapDrive: hash=0x%x path=%s\n", hash, path);
-
- dm = NULL;
-
- down( &DriveMapLock );
-
- list_for_each( list, &DriveMapList )
- {
- dm = list_entry( list, drive_map_t, list );
- DbgPrint( "NwdUnMapDrive: dm=0x%p %s\n" \
- " hash: 0x%x\n" \
- " namelen: %d\n",
- dm, dm->name, dm->hash, dm->namelen);
-
- if (hash == dm->hash)
- {
- if ( 0 == strcmp(dm->name, path))
- {
- break;
- }
- }
- else if (hash < dm->hash)
- {
- dm = NULL;
- break;
- }
- }
-
- if (dm)
- {
- DbgPrint( "NwdUnMapDrive: Remove dm=0x%p %s\n" \
- " hash: 0x%x\n" \
- " namelen: %d\n",
- dm, dm->name, dm->hash, dm->namelen);
- list_del( &dm->list );
- Novfs_Free( dm );
- }
-
- up( &DriveMapLock );
- }
- }
-
- return(retVal);
-}
-
-/*++======================================================================*/
-void RemoveDriveMaps( void )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- drive_map_t *dm;
- struct list_head *list;
-
- down( &DriveMapLock );
- list_for_each( list, &DriveMapList )
- {
- dm = list_entry( list, drive_map_t, list );
-
- DbgPrint( "RemoveDriveMap: dm=0x%p\n" \
- " hash: 0x%x\n" \
- " namelen: %d\n" \
- " name: %s\n",
- dm, dm->hash, dm->namelen, dm->name);
- local_unlink( dm->name );
- list = list->prev;
- list_del( &dm->list );
- Novfs_Free( dm );
- }
- up( &DriveMapLock );
-}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
-/*++======================================================================*/
-int local_unlink(const char *pathname)
-{
- int error;
- struct dentry *dentry;
- struct nameidata nd;
- struct inode *inode = NULL;
-
- DbgPrint("local_unlink: %s\n", pathname);
- error = path_lookup(pathname, LOOKUP_PARENT, &nd);
- DbgPrint("local_unlink: path_lookup %d\n", error);
- if ( !error )
- {
- error = -EISDIR;
- if (nd.last_type == LAST_NORM)
- {
- mutex_lock(&nd.dentry->d_inode->i_mutex);
- dentry = lookup_hash( &nd );
- DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
-
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry))
- {
- if (nd.last.name[nd.last.len])
- {
- error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
- }
- else
- {
- inode = dentry->d_inode;
- if (inode)
- {
- atomic_inc(&inode->i_count);
- }
- error = vfs_unlink(nd.dentry->d_inode, dentry);
- DbgPrint("local_unlink: vfs_unlink %d\n", error);
- }
- dput(dentry);
- }
- mutex_unlock(&nd.dentry->d_inode->i_mutex);
-
- }
- path_release(&nd);
- }
-
- if (inode)
- {
- iput(inode); /* truncate the inode here */
- }
-
- DbgPrint("local_unlink: error=%d\n", error);
- return error;
-}
-
-#else
-/*++======================================================================*/
-int local_unlink(const char *pathname)
-{
- int error;
- struct dentry *dentry;
- struct nameidata nd;
- struct inode *inode = NULL;
-
- DbgPrint("local_unlink: %s\n", pathname);
- error = path_lookup(pathname, LOOKUP_PARENT, &nd);
- DbgPrint("local_unlink: path_lookup %d\n", error);
- if ( !error )
- {
- error = -EISDIR;
- if (nd.last_type == LAST_NORM)
- {
- down(&nd.dentry->d_inode->i_sem);
- dentry = lookup_hash(&nd.last, nd.dentry);
- DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
-
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry))
- {
- if (nd.last.name[nd.last.len])
- {
- error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
- }
- else
- {
- inode = dentry->d_inode;
- if (inode)
- {
- atomic_inc(&inode->i_count);
- }
- error = vfs_unlink(nd.dentry->d_inode, dentry);
- DbgPrint("local_unlink: vfs_unlink %d\n", error);
- }
- dput(dentry);
- }
- up(&nd.dentry->d_inode->i_sem);
- }
- path_release(&nd);
- }
-
- if (inode)
- {
- iput(inode); /* truncate the inode here */
- }
-
- DbgPrint("local_unlink: error=%d\n", error);
- return error;
-}
-#endif
diff -uNr src.old/novfs/file.c src/novfs/file.c
--- src.old/novfs/file.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/file.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,2188 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: file.c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module contains functions for accessing
- * files through the daemon.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/dcache.h>
-#include <linux/pagemap.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
-/*===[ Include files specific to this module ]============================*/
-#include "commands.h"
-#include "nwerror.h"
-#include "vfs.h"
-
-/*===[ External data ]====================================================*/
-extern struct dentry_operations Novfs_dentry_operations;
-
-/*===[ External prototypes ]==============================================*/
-extern int DbgPrint( char *Fmt, ... );
-extern void mydump(int size, void *dumpptr);
-extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
-extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid);
-
-extern void *Scope_Lookup( void );
-
-/*===[ Manifest constants ]===============================================*/
-
-/*===[ Type definitions ]=================================================*/
-
-/*===[ Function prototypes ]==============================================*/
-
-int Novfs_verify_file( struct qstr *Path, session_t SessionId );
-int Novfs_get_alltrees(struct dentry *parent);
-ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off);
-
-int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId );
-int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, session_t SessionId );
-int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List );
-int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId );
-int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId );
-int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId );
-int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
-int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
-int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId );
-int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId );
-int Novfs_Close_File( u_long Handle, session_t SessionId );
-int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
-int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
-int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
-int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
-int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
-int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId );
-int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId );
-int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId );
-int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId );
-
-/*===[ Global variables ]=================================================*/
-static struct file_operations Novfs_tree_operations = {
- read: Novfs_tree_read,
-};
-
-/*
- * StripTrailingDots was added because some apps will
- * try and create a file name with a trailing dot. NetWare
- * doesn't like this and will return an error.
- */
-u_char StripTrailingDots=1;
-
-/*===[ Code ]=============================================================*/
-
-/*++======================================================================*/
-int Novfs_verify_file( struct qstr *Path, scope_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PVERIFY_FILE_REPLY reply=NULL;
- u_long replylen=0;
- PVERIFY_FILE_REQUEST cmd;
- int cmdlen;
- int retCode=0;
-
- cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + Path->len;
- cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
- cmd->pathLen = Path->len;
- memcpy(cmd->path, Path->name, Path->len);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- DbgPrint("Novfs_verify_file: reply\n");
- mydump(replylen, reply);
- if (reply->Reply.ErrorCode)
- {
- retCode = -ENOENT;
- }
- else
- {
- retCode = 0;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_get_alltrees(struct dentry *parent)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- u_char *p;
- PCOMMAND_REPLY_HEADER reply=NULL;
- u_long replylen=0;
- COMMAND_REQUEST_HEADER cmd;
- int retCode;
- struct dentry *entry;
- struct qstr name;
- struct inode *inode;
-
- cmd.CommandType = 0;
- cmd.SequenceNumber = 0;
- cmd.SessionId = 0x1234;
-
- DbgPrint( "Novfs_get_alltrees:\n");
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- DbgPrint( "Novfs_get_alltrees: relpy=0x%x replylen=%d\n", reply, replylen);
- if (reply)
- {
- mydump(replylen, reply);
- if ( !reply->ErrorCode && (replylen > sizeof(COMMAND_REPLY_HEADER)))
- {
- p = (char *)reply+8;
- while (*p)
- {
- DbgPrint( "Novfs_get_alltrees: %s\n",p);
- name.len = strlen(p);
- name.name = p;
- name.hash = full_name_hash(name.name, name.len);
- entry = d_lookup(parent, &name);
- if ( NULL == entry )
- {
- DbgPrint( "Novfs_get_alltrees: adding %s\n",p);
- entry = d_alloc(parent, &name);
- if (entry)
- {
- entry->d_op = &Novfs_dentry_operations;
- inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0);
- if (inode)
- {
- inode->i_fop = &Novfs_tree_operations;
- d_add(entry, inode);
- }
- }
- }
- p += (name.len+1);
- }
- }
- Novfs_Free(reply);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- if (file->f_pos != 0)
- {
- return(0);
- }
- if (copy_to_user(buf, "Tree\n", 5))
- {
- return(0);
- }
- return(5);
-}
-
-/*++======================================================================*/
-int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- GET_CONNECTED_SERVER_LIST_REQUEST req;
- PGET_CONNECTED_SERVER_LIST_REPLY reply=NULL;
- u_long replylen=0;
- int retCode=0;
-
- *ServerList = NULL;
-
- req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST;
- req.Command.SessionId = SessionId;
-
- retCode = Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- DbgPrint("Novfs_Get_Connected_Server_List: reply\n");
- replylen -= sizeof(COMMAND_REPLY_HEADER);
- if ( !reply->Reply.ErrorCode && replylen )
- {
- memcpy(reply, reply->List, replylen);
- *ServerList = (u_char *)reply;
- retCode = 0;
- }
- else
- {
- Novfs_Free(reply);
- retCode = -ENOENT;
- }
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, scope_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PGET_SERVER_VOLUME_LIST_REQUEST req;
- PGET_SERVER_VOLUME_LIST_REPLY reply=NULL;
- u_long replylen=0, reqlen;
- int retCode;
-
- *VolumeList = NULL;
- reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST)+Server->len;
- req = Novfs_Malloc(reqlen, GFP_KERNEL);
- if (req)
- {
- req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST;
- req->Length = Server->len;
- memcpy(req->Name, Server->name, Server->len);
- req->Command.SessionId = SessionId;
-
- retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if ( reply )
- {
- DbgPrint("Novfs_Get_Server_Volume_List: reply\n");
- mydump(replylen, reply);
- replylen -= sizeof(COMMAND_REPLY_HEADER);
-
- if ( !reply->Reply.ErrorCode && replylen )
- {
- memcpy(reply, reply->List, replylen);
- *VolumeList = (u_char *)reply;
- retCode = 0;
- }
- else
- {
- Novfs_Free(reply);
- retCode = -ENOENT;
- }
- }
- Novfs_Free(req);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int len;
- int retCode = 0;
-
- while (*List)
- {
- len = strlen(List);
- if ((len == Name->len) && !strncmp(Name->name, List, len))
- {
- retCode = 1;
- break;
- }
- List += (len+1);
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- u_char *list;
- int retCode = 0;
-
- DbgPrint("Novfs_Verify_Server_Name: %.*s\n", Server->len, Server->name);
-
- list = NULL;
- Novfs_Get_Connected_Server_List( &list, SessionId );
-
- if (list)
- {
- retCode = Novfs_Find_Name_In_List( Server, list );
- Novfs_Free(list);
- }
- DbgPrint("Novfs_Verify_Server_Name: %d\n", retCode);
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId )
-/*
- *
- * Arguments: Server - Server name.
- * Volume - Volume name to check for.
- *
- * Returns: zero - not found.
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- u_char *list;
- int retCode = 0;
- u_char *name;
- int namelen;
- struct qstr path;
-
- list = NULL;
- namelen = Server->len+Volume->len+2;
- name = Novfs_Malloc(namelen, GFP_KERNEL);
-
- if (name)
- {
- name[0] = '\\';
- memcpy(&name[1], Server->name, Server->len);
- name[1+Server->len] = '\\';
- memcpy(&name[2+Server->len], Volume->name, Volume->len);
- path.len = namelen;
- path.name = name;
-
- if (Novfs_verify_file(&path, SessionId))
- {
- retCode = 0;
- }
- else
- {
- retCode = 1;
- }
-
- Novfs_Free(name);
- }
- else
- {
-
- Novfs_Get_Server_Volume_List( Server, &list, SessionId );
-
- if (list)
- {
- retCode = Novfs_Find_Name_In_List( Volume, list );
- Novfs_Free(list);
- }
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PVERIFY_FILE_REPLY reply=NULL;
- u_long replylen=0;
- PVERIFY_FILE_REQUEST cmd;
- int cmdlen;
- int retCode=-ENOENT;
- int pathlen;
-
- DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
-
- Info->mode = S_IFDIR | 0700;
- Info->uid = current->uid;
- Info->gid = current->gid;
- Info->size = 0;
- Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
-
- if (Path && *Path)
- {
- pathlen = strlen(Path);
- if (StripTrailingDots)
- {
- if ('.' == Path[pathlen-1]) pathlen--;
- }
- cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + pathlen;
- cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
- cmd->pathLen = pathlen;
- memcpy(cmd->path, Path, cmd->pathLen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-/*
- * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0);
- */
- if (reply)
- {
-
- if ( reply->Reply.ErrorCode )
- {
- retCode = -ENOENT;
- }
- else
- {
- Info->type = 3;
- Info->mode = S_IRWXU;
-
- if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
- {
- Info->mode |= S_IFDIR;
- }
- else
- {
- Info->mode |= S_IFREG;
- }
-
- if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
- {
- Info->mode &= ~(S_IWUSR);
- }
-
- Info->uid = current->euid;
- Info->gid = current->egid;
- Info->size = reply->fileSize;
- Info->atime.tv_sec = reply->lastAccessTime;
- Info->atime.tv_nsec = 0;
- Info->mtime.tv_sec = reply->modifyTime;
- Info->mtime.tv_nsec = 0;
- Info->ctime.tv_sec = reply->createTime;
- Info->ctime.tv_nsec = 0;
- retCode = 0;
- }
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- }
-
- DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Get_File_Info2( u_char *Path, PENTRY_INFO Info, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PVERIFY_FILE_REPLY reply=NULL;
- u_long replylen=0;
- PVERIFY_FILE_REQUEST cmd;
- int cmdlen;
- struct qstr server = {0}, volume = {0};
- u_char *p;
- int i;
- int retCode=-ENOENT;
- p = Path;
-
- DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
-
- Info->mode = S_IFDIR | 0700;
- Info->uid = current->uid;
- Info->gid = current->gid;
- Info->size = 0;
- Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
-
- if ('\\' == *p)
- {
- p++;
- }
- server.name = p;
-
- for(i=0; *p && ('\\' != *p); i++, p++);
- server.len = i;
- if (*p)
- {
- if ('\\' == *p)
- {
- p++;
- }
- volume.name = p;
- for(i=0; *p && ('\\' != *p); i++, p++);
- if (i)
- {
- volume.len = i;
- if (*p)
- {
- if ('\\' == *p)
- {
- p++;
- }
- if (*p)
- {
- cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + strlen(Path);
- cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
- cmd->pathLen = strlen(Path);
- memcpy(cmd->path, Path, cmd->pathLen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
-
- if ( reply->Reply.ErrorCode )
- {
- retCode = -ENOENT;
- }
- else
- {
- Info->type = 3;
- Info->mode = S_IRWXU;
-
- if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
- {
- Info->mode |= S_IFDIR;
- }
- else
- {
- Info->mode |= S_IFREG;
- }
-
- if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
- {
- Info->mode &= ~(S_IWUSR);
- }
-
- Info->uid = current->euid;
- Info->gid = current->egid;
- Info->size = reply->fileSize;
- Info->atime.tv_sec = reply->lastAccessTime;
- Info->atime.tv_nsec = 0;
- Info->mtime.tv_sec = reply->modifyTime;
- Info->mtime.tv_nsec = 0;
- Info->ctime.tv_sec = reply->createTime;
- Info->ctime.tv_nsec = 0;
- retCode = 0;
- }
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- }
- }
- }
- if (('\0' == *p) && volume.len)
- {
- if ( Novfs_Verify_Volume_Name( &server, &volume, SessionId ) )
- {
- retCode = 0;
- Info->type = 2;
- }
- }
- }
- if (server.len && !volume.len)
- {
- if ( Novfs_Verify_Server_Name( &server, SessionId ) )
- {
- retCode = 0;
- Info->type = 1;
- }
- }
- DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
- return(retCode);
-}
-
-/*++======================================================================*/
-int begin_directory_enumerate( u_char *Path, int PathLen, u_long *EnumHandle, session_t SessionId)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd;
- PBEGIN_ENUMERATE_DIRECTORY_REPLY reply=NULL;
- u_long replylen=0;
- int retCode, cmdlen;
-
- *EnumHandle = 0;
-
- cmdlen = (int)(&((PBEGIN_ENUMERATE_DIRECTORY_REQUEST)0)->path) + PathLen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_START_ENUMERATE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->pathLen = PathLen;
- memcpy(cmd->path, Path, PathLen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-/*
- * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0);
- */
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- else
- {
- *EnumHandle = reply->enumerateHandle;
- retCode = 0;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int end_directory_enumerate( u_long EnumHandle, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- END_ENUMERATE_DIRECTORY_REQUEST cmd;
- PEND_ENUMERATE_DIRECTORY_REPLY reply=NULL;
- u_long replylen=0;
- int retCode;
-
-
- cmd.Command.CommandType = VFS_COMMAND_END_ENUMERATE;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.enumerateHandle = EnumHandle;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
- if (reply)
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int directory_enumerate( u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- ENUMERATE_DIRECTORY_REQUEST cmd;
- PENUMERATE_DIRECTORY_REPLY reply=NULL;
- u_long replylen=0;
- int retCode;
-
-
- cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.enumerateHandle = *EnumHandle;
- cmd.pathLen = 0;
- cmd.path[0] = '\0';
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- /*
- * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
- * error but there could still be valid data.
- */
- if ( !reply->Reply.ErrorCode ||
- ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
- (reply->nameLen > 0)) )
- {
- Info->type = 3;
- Info->mode = S_IRWXU;
-
- if (reply->mode & NW_ATTRIBUTE_DIRECTORY)
- {
- Info->mode |= S_IFDIR;
- Info->mode |= S_IXUSR;
- }
- else
- {
- Info->mode |= S_IFREG;
- }
-
- if (reply->mode & NW_ATTRIBUTE_READ_ONLY)
- {
- Info->mode &= ~(S_IWUSR);
- }
-
- if (reply->mode & NW_ATTRIBUTE_EXECUTE)
- {
- Info->mode |= S_IXUSR;
- }
-
- Info->uid = current->uid;
- Info->gid = current->gid;
- Info->size = reply->size;
- Info->atime.tv_sec = reply->lastAccessTime;
- Info->atime.tv_nsec = 0;
- Info->mtime.tv_sec = reply->modifyTime;
- Info->mtime.tv_nsec = 0;
- Info->ctime.tv_sec = reply->createTime;
- Info->ctime.tv_nsec = 0;
- Info->namelength = reply->nameLen;
- memcpy(Info->name, reply->name, reply->nameLen);
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -1; /* Eof of data */
- }
- *EnumHandle = reply->enumerateHandle;
- }
- else
- {
- retCode = -ENODATA;
- }
- Novfs_Free(reply);
- }
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int directory_enumerate_ex( u_long *EnumHandle, session_t SessionId, int *Count, PENTRY_INFO *PInfo, int Interrupt)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- ENUMERATE_DIRECTORY_EX_REQUEST cmd;
- PENUMERATE_DIRECTORY_EX_REPLY reply=NULL;
- u_long replylen=0;
- int retCode=0;
- PENTRY_INFO info;
- PENUMERATE_DIRECTORY_EX_DATA data;
- int isize;
-
- if (PInfo)
- {
- *PInfo = NULL;
- }
- *Count = 0;
-
- cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY_EX;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.enumerateHandle = *EnumHandle;
- cmd.pathLen = 0;
- cmd.path[0] = '\0';
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, Interrupt);
-
- if (reply)
- {
- retCode = 0;
- /*
- * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
- * error but there could still be valid data.
- */
-
- if ( !reply->Reply.ErrorCode ||
- ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
- (reply->enumCount > 0)) )
- {
- DbgPrint("directory_enumerate_ex: isize=%d\n", replylen);
- data = (PENUMERATE_DIRECTORY_EX_DATA)((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY));
- isize = replylen -
- sizeof(PENUMERATE_DIRECTORY_EX_REPLY) -
- reply->enumCount * (int)(&((PENUMERATE_DIRECTORY_EX_DATA)0)->name);
- isize += (reply->enumCount * (int)(&((PENTRY_INFO)0)->name));
-
- if (PInfo)
- {
- *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL);
- if ( *PInfo )
- {
- DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info);
- *Count = reply->enumCount;
- do
- {
- DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data);
-
- info->type = 3;
- info->mode = S_IRWXU;
-
- if (data->mode & NW_ATTRIBUTE_DIRECTORY)
- {
- info->mode |= S_IFDIR;
- info->mode |= S_IXUSR;
- }
- else
- {
- info->mode |= S_IFREG;
- }
-
- if (data->mode & NW_ATTRIBUTE_READ_ONLY)
- {
- info->mode &= ~(S_IWUSR);
- }
-
- if (data->mode & NW_ATTRIBUTE_EXECUTE)
- {
- info->mode |= S_IXUSR;
- }
-
- info->uid = current->euid;
- info->gid = current->egid;
- info->size = data->size;
- info->atime.tv_sec = data->lastAccessTime;
- info->atime.tv_nsec = 0;
- info->mtime.tv_sec = data->modifyTime;
- info->mtime.tv_nsec = 0;
- info->ctime.tv_sec = data->createTime;
- info->ctime.tv_nsec = 0;
- info->namelength = data->nameLen;
- memcpy(info->name, data->name, data->nameLen);
- data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen];
- replylen = (int)((char *)&info->name[info->namelength] - (char *)info);
- DbgPrint("directory_enumerate_ex3: info=0x%p\n", info);
- mydump(replylen, info);
-
- info = (PENTRY_INFO)&info->name[info->namelength];
-
- } while (--reply->enumCount);
- }
- }
-
- if (reply->Reply.ErrorCode)
- {
- retCode = -1; /* Eof of data */
- }
- *EnumHandle = reply->enumerateHandle;
- }
- else
- {
- retCode = -ENODATA;
- }
- Novfs_Free(reply);
- }
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOENT;
-
- if ( -1 == *EnumHandle)
- {
- return( -ENODATA );
- }
-
- if ( 0 == *EnumHandle )
- {
- retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
- }
-
- if ( *EnumHandle )
- {
- retCode = directory_enumerate( EnumHandle, Info, SessionId );
- if (retCode)
- {
- end_directory_enumerate( *EnumHandle, SessionId );
- if ( -1 == retCode )
- {
- retCode = 0;
- *EnumHandle = -1;
- }
- }
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOENT;
-
- if (Count) *Count = 0;
- if (Info) *Info = NULL;
-
- if ( -1 == *EnumHandle)
- {
- return( -ENODATA );
- }
-
- if ( 0 == *EnumHandle )
- {
- retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
- }
-
- if ( *EnumHandle )
- {
- retCode = directory_enumerate_ex( EnumHandle, SessionId, Count, Info, INTERRUPTIBLE );
- if (retCode)
- {
- end_directory_enumerate( *EnumHandle, SessionId );
- if ( -1 == retCode )
- {
- retCode = 0;
- *EnumHandle = -1;
- }
- }
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- POPEN_FILE_REQUEST cmd;
- POPEN_FILE_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen, pathlen;
-
- pathlen = strlen(Path);
-
- if (StripTrailingDots)
- {
- if ('.' == Path[pathlen-1]) pathlen--;
- }
-
- cmdlen = (int)(&((POPEN_FILE_REQUEST)0)->path) + pathlen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_OPEN_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->access = 0;
-
- if ( !(Flags & O_WRONLY) || (Flags & O_RDWR))
- {
- cmd->access |= NWD_ACCESS_READ;
- }
-
- if ((Flags & O_WRONLY) || (Flags & O_RDWR))
- {
- cmd->access |= NWD_ACCESS_WRITE;
- }
-
- switch (Flags & (O_CREAT | O_EXCL | O_TRUNC))
- {
- case O_CREAT:
- cmd->disp = NWD_DISP_OPEN_ALWAYS;
- break;
-
- case O_CREAT | O_EXCL:
- cmd->disp = NWD_DISP_CREATE_NEW;
- break;
-
- case O_TRUNC:
- cmd->disp = NWD_DISP_CREATE_ALWAYS;
- break;
-
- case O_CREAT | O_TRUNC:
- cmd->disp = NWD_DISP_CREATE_ALWAYS;
- break;
-
- case O_CREAT | O_EXCL | O_TRUNC:
- cmd->disp = NWD_DISP_CREATE_NEW;
- break;
-
- default:
- cmd->disp = NWD_DISP_OPEN_EXISTING;
- break;
- }
-
- cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE;
-
- cmd->pathLen = pathlen;
- memcpy(cmd->path, Path, pathlen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- if( NWE_OBJECT_EXISTS == reply->Reply.ErrorCode)
- {
- retCode = -EEXIST;
- }
- else if( NWE_ACCESS_DENIED == reply->Reply.ErrorCode)
- {
- retCode = -EACCES;
- }
- else
- {
- retCode = -ENOENT;
- }
- }
- else
- {
- *Handle = reply->handle;
- retCode = 0;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PCREATE_FILE_REQUEST cmd;
- PCREATE_FILE_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen, pathlen;
-
- pathlen = strlen(Path);
-
- if (StripTrailingDots)
- {
- if ('.' == Path[pathlen-1]) pathlen--;
- }
-
- cmdlen = (int)(&((PCREATE_FILE_REQUEST)0)->path) + pathlen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_CREATE_FILE;
- if (DirectoryFlag)
- {
- cmd->Command.CommandType = VFS_COMMAND_CREATE_DIRECOTRY;
- }
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->pathlength = pathlen;
- memcpy(cmd->path, Path, pathlen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Close_File( u_long Handle, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- CLOSE_FILE_REQUEST cmd;
- PCLOSE_FILE_REPLY reply;
- u_long replylen=0;
- int retCode;
-
- cmd.Command.CommandType = VFS_COMMAND_CLOSE_FILE;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.handle = Handle;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
- if (reply)
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- READ_FILE_REQUEST cmd;
- PREAD_FILE_REPLY reply=NULL;
- u_long replylen=0;
- int retCode = 0;
- size_t len;
-
- len = *Bytes;
- *Bytes = 0;
-
- if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MAX_IO_SIZE)
- {
- len = MAX_IO_SIZE - (int)(&((PREAD_FILE_REPLY)0)->data);
- len = (len/PAGE_SIZE)*PAGE_SIZE;
- }
-
- cmd.Command.CommandType = VFS_COMMAND_READ_FILE;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.handle = Handle;
- cmd.len = len;
- cmd.offset = *Offset;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
-
- if (!retCode)
- {
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- else
- {
- replylen -= (int)(&((PREAD_FILE_REPLY)0)->data);
- if (replylen > 0)
- {
- if (User)
- {
- replylen -= copy_to_user(Buffer, reply->data, replylen);
- }
- else
- {
- memcpy(Buffer, reply->data, replylen);
- }
-
- *Bytes = replylen;
- }
- }
- }
-
- if ( reply )
- {
- Novfs_Free(reply);
- }
-
- DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- WRITE_FILE_REQUEST cmd;
- PWRITE_FILE_REPLY reply=NULL;
- unsigned long replylen=0;
- int retCode=0, cmdlen;
- size_t len;
-
- unsigned long boff;
- struct page **pages;
- DATA_LIST *dlist;
- int res=0, npage, i;
- WRITE_FILE_REPLY lreply;
-
-
- len = *Bytes;
- cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data);
-
- *Bytes = 0;
-
- memset(&lreply, 0, sizeof(lreply));
-
- DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
-
- if ( (cmdlen+len) > MAX_IO_SIZE)
- {
- len = MAX_IO_SIZE-cmdlen;
- len = (len/PAGE_SIZE)*PAGE_SIZE;
- }
- cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
- cmd.handle = Handle;
- cmd.len = len;
- cmd.offset = *Offset;
-
- DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
-
- npage = (((unsigned long)Buffer & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
-
- dlist = Novfs_Malloc(sizeof(DATA_LIST)*(npage+1), GFP_KERNEL);
- if (NULL == dlist)
- {
- return(-ENOMEM);
- }
-
- pages = Novfs_Malloc(sizeof(struct page *)*npage, GFP_KERNEL);
-
- if (NULL == pages)
- {
- Novfs_Free(dlist);
- return(-ENOMEM);
- }
-
- down_read(&current->mm->mmap_sem);
-
- res = get_user_pages(
- current,
- current->mm,
- (unsigned long)Buffer,
- npage,
- 0, /* read type */
- 0, /* don't force */
- pages,
- NULL);
-
- up_read(&current->mm->mmap_sem);
-
- DbgPrint("Novfs_Write_File res=%d\n", res);
-
- if ( res > 0 )
- {
- boff = (unsigned long)Buffer & ~PAGE_MASK;
-
- flush_dcache_page(pages[0]);
- dlist[0].page = pages[0];
- dlist[0].offset = (char *)boff;
- dlist[0].len = PAGE_SIZE - boff;
- dlist[0].rwflag = DLREAD;
-
- if (dlist[0].len > len)
- {
- dlist[0].len = len;
- }
-
- DbgPrint("Novfs_Write_File0: page=0x%x offset=0x%p len=%d\n", dlist[0].page, dlist[0].offset, dlist[0].len);
-
- boff = dlist[0].len;
-
- DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff);
-
- for (i=1; (i < res) && (boff < len); i++)
- {
- flush_dcache_page(pages[i]);
-
- dlist[i].page = pages[i];
- dlist[i].offset = NULL;
- dlist[i].len = len-boff;
- if (dlist[i].len > PAGE_SIZE)
- {
- dlist[i].len = PAGE_SIZE;
- }
- dlist[i].rwflag = DLREAD;
-
- boff += dlist[i].len;
- DbgPrint("Novfs_Write_File%d: page=0x%x offset=0x%p len=%d\n", i, dlist[i].page, dlist[i].offset, dlist[i].len);
- }
-
- dlist[i].page = NULL;
- dlist[i].offset = &lreply;
- dlist[i].len = sizeof(lreply);
- dlist[i].rwflag = DLWRITE;
- res++;
-
- DbgPrint("Novfs_Write_File Buffer=0x%x boff=0x%x len=%d\n", Buffer, boff, len);
-
- retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, res, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- }
- else
- {
- char *kdata;
-
- res = 0;
-
- kdata = Novfs_Malloc(len, GFP_KERNEL);
- if (kdata)
- {
- len -= copy_from_user(kdata, Buffer, len);
- dlist[0].page = NULL;
- dlist[0].offset = kdata;
- dlist[0].len = len;
- dlist[0].rwflag = DLREAD;
-
- dlist[1].page = NULL;
- dlist[1].offset = &lreply;
- dlist[1].len = sizeof(lreply);
- dlist[1].rwflag = DLWRITE;
-
- retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- Novfs_Free(kdata);
- }
- }
-
- DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%x\n", retCode, reply);
-
- if ( !retCode )
- {
- switch (lreply.Reply.ErrorCode)
- {
- case 0:
- *Bytes = (size_t)lreply.bytesWritten;
- retCode = 0;
- break;
-
- case NWE_INSUFFICIENT_SPACE:
- retCode = -ENOSPC;
- break;
-
- case NWE_ACCESS_DENIED:
- retCode = -EACCES;
- break;
-
- default:
- retCode = -EIO;
- break;
- }
- }
-
- if ( res )
- {
- for (i=0; i<res; i++)
- {
- if (dlist[i].page)
- {
- page_cache_release(dlist[i].page);
- }
- }
- }
-
- Novfs_Free(pages);
- Novfs_Free(dlist);
-
- DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Write_File2( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PWRITE_FILE_REQUEST cmd;
- PWRITE_FILE_REPLY reply=NULL;
- u_long replylen=0;
- int retCode=0, cmdlen;
- size_t len;
-
- len = *Bytes;
- cmdlen = len+(int)(&((PWRITE_FILE_REQUEST)0)->data);
- *Bytes = 0;
-
- if (cmdlen > MAX_IO_SIZE)
- {
- cmdlen = MAX_IO_SIZE;
- len = cmdlen - (int)(&((PWRITE_FILE_REQUEST)0)->data);
- }
-
- DbgPrint("Novfs_Write_File cmdlen=%d len=%d\n", cmdlen, len);
-
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- len -= copy_from_user(cmd->data, Buffer, len);
- DbgPrint("Novfs_Write_File len=%d\n", len);
- if (len)
- {
- cmd->Command.CommandType = VFS_COMMAND_WRITE_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->handle = Handle;
- cmd->len = len;
- cmd->offset = *Offset;
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (!retCode)
- {
- if (reply)
- {
- switch (reply->Reply.ErrorCode)
- {
- case 0:
- *Bytes = (size_t)reply->bytesWritten;
- retCode = 0;
- break;
-
- case NWE_INSUFFICIENT_SPACE:
- retCode = -ENOSPC;
- break;
-
- case NWE_ACCESS_DENIED:
- retCode = -EACCES;
- break;
-
- default:
- retCode = -EIO;
- break;
- }
- }
- }
- if ( reply )
- {
- Novfs_Free(reply);
- }
-
- }
- Novfs_Free(cmd);
- }
- DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- READ_STREAM_REQUEST cmd;
- PREAD_STREAM_REPLY reply=NULL;
- u_long replylen=0;
- int retCode = 0;
- size_t len;
-
- len = *Bytes;
- *Bytes = 0;
-
- if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MAX_IO_SIZE)
- {
- len = MAX_IO_SIZE - (int)(&((PREAD_FILE_REPLY)0)->data);
- len = (len/PAGE_SIZE)*PAGE_SIZE;
- }
-
- cmd.Command.CommandType = VFS_COMMAND_READ_STREAM;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.connection = ConnHandle;
- memcpy( cmd.handle, Handle, sizeof(cmd.handle));
- cmd.len = len;
- cmd.offset = *Offset;
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
-
- DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
-
- if ( reply )
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- else
- {
- replylen -= (int)(&((PREAD_STREAM_REPLY)0)->data);
- if (replylen > 0)
- {
- if (User)
- {
- replylen -= copy_to_user(Buffer, reply->data, replylen);
- }
- else
- {
- memcpy(Buffer, reply->data, replylen);
- }
-
- *Bytes = replylen;
- }
- }
- Novfs_Free(reply);
- }
-
- DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PWRITE_STREAM_REQUEST cmd;
- PWRITE_STREAM_REPLY reply=NULL;
- u_long replylen=0;
- int retCode=0, cmdlen;
- size_t len;
-
- len = *Bytes;
- cmdlen = len+(int)(&((PWRITE_STREAM_REQUEST)0)->data);
- *Bytes = 0;
-
- if (cmdlen > MAX_IO_SIZE)
- {
- cmdlen = MAX_IO_SIZE;
- len = cmdlen - (int)(&((PWRITE_STREAM_REQUEST)0)->data);
- }
-
- DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len);
-
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- if (Buffer && len)
- {
- len -= copy_from_user(cmd->data, Buffer, len);
- }
-
- DbgPrint("Novfs_Write_Stream len=%d\n", len);
-
- cmd->Command.CommandType = VFS_COMMAND_WRITE_STREAM;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->connection = ConnHandle;
- memcpy(cmd->handle, Handle, sizeof(cmd->handle));
- cmd->len = len;
- cmd->offset = *Offset;
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- switch (reply->Reply.ErrorCode)
- {
- case 0:
- retCode = 0;
- break;
-
- case NWE_INSUFFICIENT_SPACE:
- retCode = -ENOSPC;
- break;
-
- case NWE_ACCESS_DENIED:
- retCode = -EACCES;
- break;
-
- default:
- retCode = -EIO;
- break;
- }
- DbgPrint("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", reply->bytesWritten);
- *Bytes = reply->bytesWritten;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- CLOSE_STREAM_REQUEST cmd;
- PCLOSE_STREAM_REPLY reply;
- u_long replylen=0;
- int retCode;
-
- cmd.Command.CommandType = VFS_COMMAND_CLOSE_STREAM;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.connection = ConnHandle;
- memcpy(cmd.handle, Handle, sizeof(cmd.handle));
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
- if (reply)
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PDELETE_FILE_REQUEST cmd;
- PDELETE_FILE_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen, pathlen;
-
- pathlen = strlen(Path);
-
- if (StripTrailingDots)
- {
- if ('.' == Path[pathlen-1]) pathlen--;
- }
-
- cmdlen = (int)(&((PDELETE_FILE_REQUEST)0)->path) + pathlen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_DELETE_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->isDirectory = DirectoryFlag;
- cmd->pathlength = pathlen;
- memcpy(cmd->path, Path, pathlen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) /* Access Denied Error */
- {
- retCode = -EACCES;
- }
- else
- {
- retCode = -EIO;
- }
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PTRUNCATE_FILE_REQUEST cmd;
- PTRUNCATE_FILE_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen;
-
- if (StripTrailingDots)
- {
- if ('.' == Path[PathLen-1]) PathLen--;
- }
- cmdlen = (int)(&((PTRUNCATE_FILE_REQUEST)0)->path) + PathLen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_TRUNCATE_FILE;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
-
- cmd->pathLen = PathLen;
- memcpy(cmd->path, Path, PathLen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- if (reply->Reply.ErrorCode)
- {
- retCode = -EIO;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- RENAME_FILE_REQUEST cmd;
- PRENAME_FILE_REPLY reply;
- u_long replylen=0;
- int retCode;
-
- DbgPrint("Novfs_Rename_File:\n" \
- " DirectoryFlag: %d\n" \
- " OldName: %.*s\n" \
- " NewName: %.*s\n" \
- " SessionId: 0x%llx\n",
- DirectoryFlag,
- OldLen, OldName,
- NewLen, NewName,
- SessionId );
-
- cmd.Command.CommandType = VFS_COMMAND_RENAME_FILE;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = SessionId;
-
- cmd.directoryFlag = DirectoryFlag;
-
- if (StripTrailingDots)
- {
- if ('.' == OldName[OldLen-1]) OldLen--;
- if ('.' == NewName[NewLen-1]) NewLen--;
- }
-
- cmd.newnameLen = NewLen;
- memcpy(cmd.newname, NewName, NewLen);
-
- cmd.oldnameLen = OldLen;
- memcpy(cmd.oldname, OldName, OldLen);
-
- retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = 0;
- if (reply->Reply.ErrorCode)
- {
- retCode = -ENOENT;
- }
- Novfs_Free(reply);
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSET_FILE_INFO_REQUEST cmd;
- PSET_FILE_INFO_REPLY reply;
- u_long replylen=0;
- int retCode, cmdlen, pathlen;
-
- pathlen = strlen(Path);
-
- if (StripTrailingDots)
- {
- if ('.' == Path[pathlen-1]) pathlen--;
- }
-
- cmdlen = (int)(&((PSET_FILE_INFO_REQUEST)0)->path) + pathlen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_SET_FILE_INFO;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = SessionId;
- cmd->fileInfo.ia_valid = Attr->ia_valid;
- cmd->fileInfo.ia_mode = Attr->ia_mode;
- cmd->fileInfo.ia_uid = Attr->ia_uid;
- cmd->fileInfo.ia_gid = Attr->ia_uid;
- cmd->fileInfo.ia_size = Attr->ia_size;
- cmd->fileInfo.ia_atime = Attr->ia_atime.tv_sec;
- cmd->fileInfo.ia_mtime = Attr->ia_mtime.tv_sec;;
- cmd->fileInfo.ia_ctime = Attr->ia_ctime.tv_sec;;
-/*
- cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags;
-*/
- cmd->fileInfo.ia_attr_flags = 0;
-
- cmd->pathlength = pathlen;
- memcpy(cmd->path, Path, pathlen);
-
- retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- switch( reply->Reply.ErrorCode )
- {
- case 0:
- retCode = 0;
- break;
-
- case NWE_PARAM_INVALID:
- retCode = -EINVAL;
- break;
-
- default:
- retCode = -EIO;
- break;
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- else
- {
- retCode = -ENOMEM;
- }
- return( retCode );
-}
diff -uNr src.old/novfs/inode.c src/novfs/inode.c
--- src.old/novfs/inode.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/inode.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,4584 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: inode.c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module contains functions used to control
- * access to the Linux file system.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/dcache.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/string.h>
-#include <linux/smp_lock.h>
-#include <linux/slab.h>
-#include <linux/unistd.h>
-#include <linux/backing-dev.h>
-#include <asm/statfs.h>
-#include <asm/uaccess.h>
-#include <linux/ctype.h>
-#include <linux/statfs.h>
-
-/*===[ Include files specific to this module ]============================*/
-#include "vfs.h"
-
-/*===[ External data ]====================================================*/
-
-/*===[ External prototypes ]==============================================*/
-extern int DbgPrint( char *Fmt, ... );
-extern int LocalPrint( char *Fmt, ... );
-
-extern int Init_Procfs_Interface( void );
-extern void Uninit_Procfs_Interface( void );
-extern void mydump(int size, void *dumpptr);
-
-/*
- * Daemon.c functions
- */
-extern void Init_Daemon_Queue( void );
-extern void Uninit_Daemon_Queue( void );
-extern int do_logout( struct qstr *Server );
-extern int Daemon_SetMountPoint( char *Path );
-
-/*
- * file.c functions
- */
-extern int Novfs_verify_file( struct qstr *Path, session_t SessionId );
-extern int Novfs_get_alltrees(struct dentry *parent);
-extern int Novfs_Get_Connected_Server_List( unsigned char **ServerList, session_t SessionId );
-extern int Novfs_Get_Server_Volume_List( struct qstr *Server, unsigned char **VolumeList, session_t SessionId );
-extern int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId );
-extern int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId );
-extern int Novfs_Get_File_Info( unsigned char *Path, PENTRY_INFO Info, session_t SessionId );
-extern int Novfs_Get_Directory_List( unsigned char *Path, unsigned long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
-extern int Novfs_Get_Directory_ListEx( unsigned char *Path, unsigned long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
-extern int Novfs_Open_File( unsigned char *Path, int Flags, PENTRY_INFO Info, unsigned long *Handle, session_t SessionId );
-extern int Novfs_Create( unsigned char *Path, int DirectoryFlag, session_t SessionId );
-extern int Novfs_Close_File( unsigned long Handle, session_t SessionId );
-extern int Novfs_Read_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
-extern int Novfs_Write_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
-extern int Novfs_Delete( unsigned char *Path, int DirectoryFlag, session_t SessionId );
-extern int Novfs_Truncate_File( unsigned char *Path, int PathLen, session_t SessionId );
-extern int Novfs_Rename_File( int DirectoryFlag, unsigned char *OldName, int OldLen, unsigned char *NewName, int NewLen, session_t SessionId );
-extern int Novfs_Set_Attr( unsigned char *Path, struct iattr *Attr, session_t SessionId );
-
-/*
- * scope.c functions
- */
-extern void Scope_Init( void );
-extern void Scope_Uninit( void );
-extern void *Scope_Lookup( void );
-extern unsigned long Scope_Get_Hash( void *);
-extern uid_t Scope_Get_Uid( void *);
-extern session_t Scope_Get_SessionId( void *Scope );
-extern void *Scope_Get_ScopefromName( struct qstr *Name );
-extern void *Scope_Get_ScopefromPath( struct dentry *Dentry );
-extern char *Scope_Get_ScopeUsers( void );
-extern int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
-extern int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
-extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
-
-/*
- * profile.c functions
- */
-extern int init_profile( void );
-
-/*===[ Manifest constants ]===============================================*/
-#define FILE_UPDATE_TIMEOUT 2
-
-/*===[ Type definitions ]=================================================*/
-
-/*===[ Function prototypes ]==============================================*/
-int Novfs_Remove_from_Root(char *RemoveName);
-int Novfs_Add_to_Root(char *);
-char *Novfs_dget_path( struct dentry *d, char *path, unsigned int pathlen );
-int verify_dentry(struct dentry *dentry, int Flags);
-int invalidate_dentry(struct dentry *parent);
-struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name);
-int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add);
-int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2);
-struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name);
-unsigned long Novfs_internal_hash (struct qstr *name);
-
-struct super_block *Novfs_get_sb (struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data);
-void Novfs_kill_sb(struct super_block *SB);
-int Novfs_fill_super (struct super_block *SB, void *Data, int Silent);
-
-/*
- * Declared dentry_operations
- */
-int Novfs_d_revalidate(struct dentry *, struct nameidata *);
-int Novfs_d_hash (struct dentry *, struct qstr *);
-int Novfs_d_compare (struct dentry *, struct qstr *, struct qstr *);
-int Novfs_d_delete(struct dentry *dentry);
-void Novfs_d_release(struct dentry *dentry);
-void Novfs_d_iput(struct dentry *dentry, struct inode *inode);
-
-/*
- * Declared directory operations
- */
-int Novfs_dir_open(struct inode *inode, struct file *file);
-int Novfs_dir_release(struct inode *inode, struct file *file);
-loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin);
-int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off);
-void addtodentry( struct dentry *Parent, unsigned char *List, int Level );
-int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, ino_t ino, unsigned ftype);
-int Novfs_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
-int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync);
-
-/*
- * Declared address space operations
- */
-int Novfs_a_readpage(struct file *file, struct page *page);
-
-/*
- * Declared file_operations
- */
-ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *);
-ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *);
-int Novfs_f_readdir(struct file *, void *, filldir_t);
-int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma);
-int Novfs_f_open(struct inode *, struct file *);
-int Novfs_f_flush(struct file *);
-int Novfs_f_release(struct inode *, struct file *);
-int Novfs_f_fsync(struct file *, struct dentry *, int datasync);
-int Novfs_f_lock(struct file *, int, struct file_lock *);
-
-/*
- * Declared inode_operations
- */
-int Novfs_i_create(struct inode *,struct dentry *,int, struct nameidata *);
-struct dentry * Novfs_i_lookup(struct inode *,struct dentry *, struct nameidata *);
-int Novfs_i_mkdir(struct inode *,struct dentry *,int);
-int Novfs_i_unlink(struct inode *dir, struct dentry *dentry);
-int Novfs_i_rmdir(struct inode *,struct dentry *);
-int Novfs_i_mknod(struct inode *,struct dentry *,int,dev_t);
-int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-int Novfs_i_permission(struct inode *inode, int mask);
-int Novfs_i_setattr(struct dentry *, struct iattr *);
-int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *);
-int Novfs_i_revalidate(struct dentry *dentry);
-
-void update_inode(struct inode *Inode, PENTRY_INFO Info);
-
-/*
- * Declared super_operations
- */
-void Novfs_read_inode(struct inode *inode);
-void Novfs_write_inode(struct inode *inode);
-int Novfs_notify_change(struct dentry *dentry, struct iattr *attr);
-void Novfs_clear_inode(struct inode *inode);
-int Novfs_show_options( struct seq_file *s, struct vfsmount *m );
-int Novfs_statfs(struct super_block *sb, struct kstatfs *buf);
-
-/*
- * Declared control interface functions
- */
-ssize_t
-Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
-
-ssize_t
-Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos);
-
-int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-
-int __init init_novfs(void);
-void __exit exit_novfs(void);
-
-int Novfs_lock_inode_cache( struct inode *i );
-void Novfs_unlock_inode_cache( struct inode *i );
-int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info);
-int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info);
-int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime);
-int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info);
-void Novfs_invalidate_inode_cache( struct inode *i );
-PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino );
-int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino );
-int Novfs_add_inode_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
-int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
-void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino);
-void Novfs_free_invalid_entries( struct inode *i );
-void Novfs_free_inode_cache( struct inode *i );
-
-/*===[ Global variables ]=================================================*/
-struct dentry_operations Novfs_dentry_operations = {
- .d_revalidate = Novfs_d_revalidate,
- .d_hash = Novfs_d_hash,
- .d_compare = Novfs_d_compare,
- .d_delete = Novfs_d_delete,
- .d_release = Novfs_d_release,
- .d_iput = Novfs_d_iput,
-};
-
-struct file_operations Novfs_dir_operations = {
- .open = Novfs_dir_open,
- .release = Novfs_dir_release,
- .llseek = Novfs_dir_lseek,
- .read = Novfs_dir_read,
- .readdir = Novfs_dir_readdir,
- .fsync = Novfs_dir_fsync,
-};
-
-static struct file_operations Novfs_file_operations = {
- .read = Novfs_f_read,
- .write = Novfs_f_write,
- .readdir = Novfs_f_readdir,
- .ioctl = Novfs_f_ioctl,
- .mmap = Novfs_f_mmap,
- .open = Novfs_f_open,
- .release = Novfs_f_release,
- .fsync = Novfs_f_fsync,
- .llseek = generic_file_llseek,
-};
-
-static struct address_space_operations Novfs_aops = {
- .readpage = Novfs_a_readpage,
-};
-
-static struct inode_operations Novfs_inode_operations = {
- .create = Novfs_i_create,
- .lookup = Novfs_i_lookup,
- .unlink = Novfs_i_unlink,
- .mkdir = Novfs_i_mkdir,
- .rmdir = Novfs_i_rmdir,
- .mknod = Novfs_i_mknod,
- .rename = Novfs_i_rename,
- .setattr = Novfs_i_setattr,
- .getattr = Novfs_i_getattr,
-};
-
-static struct inode_operations Novfs_file_inode_operations = {
- .setattr = Novfs_i_setattr,
- .getattr = Novfs_i_getattr,
-};
-
-static struct super_operations Novfs_ops = {
- .read_inode = Novfs_read_inode,
- .statfs = Novfs_statfs,
- .clear_inode = Novfs_clear_inode,
- .drop_inode = generic_delete_inode,
- .show_options = Novfs_show_options,
-
-};
-
-/* Not currently used
-static struct file_operations Novfs_Control_operations = {
- .read = Novfs_Control_read,
- .write = Novfs_Control_write,
- .ioctl = Novfs_Control_ioctl,
-};
-*/
-
-ino_t Novfs_Inode_Number=1;
-
-static struct file_system_type Novfs_fs_type = {
- .name = "novfs",
- .get_sb = Novfs_get_sb,
- .kill_sb = Novfs_kill_sb,
- .owner = THIS_MODULE,
-};
-
-struct dentry *Novfs_root=NULL;
-
-int Novfs_Version_Major=NOVFS_VFS_MAJOR;
-int Novfs_Version_Minor=NOVFS_VFS_MINOR;
-int Novfs_Version_Sub=NOVFS_VFS_SUB;
-int Novfs_Version_Release=NOVFS_VFS_RELEASE;
-
-char *Novfs_CurrentMount=NULL;
-
-DECLARE_MUTEX(InodeList_lock);
-
-LIST_HEAD(InodeList);
-
-unsigned long InodeCount=0, DCCount=0;
-unsigned long File_update_timeout=FILE_UPDATE_TIMEOUT;
-/*===[ Code ]=============================================================*/
-static __inline__ void PRINT_DENTRY(const char *s, struct dentry *d)
-{
- DbgPrint("%s: 0x%x\n", s, d);
- DbgPrint(" d_count: 0x%x\n", d->d_count);
- DbgPrint(" d_lock: 0x%x\n", d->d_lock);
- DbgPrint(" d_inode: 0x%x\n", d->d_inode);
- DbgPrint(" d_lru: 0x%x\n" \
- " next: 0x%x\n" \
- " prev: 0x%x\n", &d->d_lru, d->d_lru.next, d->d_lru.prev);
- DbgPrint(" d_child: 0x%x\n" \
- " next: 0x%x\n" \
- " prev: 0x%x\n", &d->D_CHILD, d->D_CHILD.next, d->D_CHILD.prev);
- DbgPrint(" d_subdirs: 0x%x\n" \
- " next: 0x%x\n" \
- " prev: 0x%x\n", &d->d_subdirs, d->d_subdirs.next, d->d_subdirs.prev);
- DbgPrint(" d_alias: 0x%x\n" \
- " next: 0x%x\n" \
- " prev: 0x%x\n", &d->d_alias, d->d_alias.next, d->d_alias.prev);
- DbgPrint(" d_time: 0x%x\n", d->d_time);
- DbgPrint(" d_op: 0x%x\n", d->d_op);
- DbgPrint(" d_sb: 0x%x\n", d->d_sb);
- DbgPrint(" d_flags: 0x%x\n", d->d_flags);
- DbgPrint(" d_mounted: 0x%x\n", d->d_mounted);
- DbgPrint(" d_fsdata: 0x%x\n", d->d_fsdata);
-/* DbgPrint(" d_cookie: 0x%x\n", d->d_cookie); */
- DbgPrint(" d_parent: 0x%x\n", d->d_parent);
- DbgPrint(" d_name: 0x%x %.*s\n", &d->d_name, d->d_name.len, d->d_name.name);
- DbgPrint(" name: 0x%x\n" \
- " len: %d\n" \
- " hash: 0x%x\n", d->d_name.name, d->d_name.len, d->d_name.hash);
- DbgPrint(" d_hash: 0x%x\n" \
- " next: 0x%x\n" \
- " pprev: 0x%x\n", d->d_hash, d->d_hash.next, d->d_hash.pprev);
-}
-
-/*++======================================================================*/
-int Novfs_Remove_from_Root(char *RemoveName)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct qstr name;
- struct dentry *dentry;
- struct inode *dir;
-
- DbgPrint( "Novfs_Remove_from_Root: %s\n", RemoveName);
- name.len = strlen(RemoveName);
- name.name = RemoveName;
- Novfs_d_hash(Novfs_root, &name);
-
- dentry = d_lookup( Novfs_root, &name);
- if (dentry)
- {
- if (dentry->d_inode && dentry->d_inode->u.generic_ip)
- {
- ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL;
- }
- dput(dentry);
- }
-
-
- dir = Novfs_root->d_inode;
-
- Novfs_lock_inode_cache( dir );
- Novfs_remove_inode_entry( dir, &name, 0);
- Novfs_unlock_inode_cache( dir );
-
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_Add_to_Root(char *AddName)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct qstr name;
- struct inode *dir;
- ENTRY_INFO info;
- ino_t ino;
-
- DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
- name.len = strlen(AddName);
- name.name = AddName;
- Novfs_d_hash(Novfs_root, &name);
-
- dir = Novfs_root->d_inode;
-
- Novfs_lock_inode_cache( dir );
-
- ino = 0;
-
- if ( !Novfs_lookup_inode_cache(dir, &name, 0))
- {
- info.mode = S_IFDIR | 0700;
- info.size = 0;
- info.atime = info.ctime = info.mtime = CURRENT_TIME;
-
- ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
- Novfs_add_inode_entry( dir, &name, ino, &info);
- }
-
- Novfs_unlock_inode_cache( dir );
-
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_Add_to_Root2(char *AddName)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct dentry *entry;
- struct qstr name;
- struct inode *inode;
- void *scope;
-
- DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
- name.len = strlen(AddName);
- name.name = AddName;
-
- Novfs_d_hash(Novfs_root, &name);
-
- entry = Novfs_d_lookup(Novfs_root, &name);
- DbgPrint( "Novfs_Add_to_Root: Novfs_d_lookup 0x%x\n", entry);
- if ( NULL == entry )
- {
- scope = Scope_Lookup();
-
- entry = d_alloc(Novfs_root, &name);
- DbgPrint( "Novfs_Add_to_Root: d_alloc 0x%x\n", entry );
- if (entry)
- {
- entry->d_op = &Novfs_dentry_operations;
- entry->d_time = jiffies+(File_update_timeout*HZ);
- /*
- * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name );
- */
- inode = Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name);
- DbgPrint( "Novfs_Add_to_Root: Inode=0x%x\n", inode);
- if (inode)
- {
- inode->i_atime =
- inode->i_ctime =
- inode->i_mtime = CURRENT_TIME;
- if ( !Novfs_d_add(Novfs_root, entry, inode, 1))
- {
- if (inode->u.generic_ip)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE;
- }
- PRINT_DENTRY("After Novfs_d_add", entry);
- }
- else
- {
- dput(entry);
- iput(inode);
- }
- }
- }
- }
- else
- {
- dput(entry);
- PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry);
- }
- return(0);
-}
-
-/*++======================================================================*/
-char *Novfs_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen)
-/*
- * Arguments: struct dentry *Dentry - starting entry
- * char *Buf - pointer to memory buffer
- * unsigned int Buflen - size of memory buffer
- *
- * Returns: pointer to path.
- *
- * Abstract: Walks the dentry chain building a path.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *retval=&Buf[Buflen];
- struct dentry *p=Dentry;
-
- *(--retval) = '\0';
- Buflen--;
-
- if (!IS_ROOT(p) && !IS_ROOT(p->d_parent))
- {
- while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent))
- {
- if (Buflen > p->d_name.len)
- {
- retval -= p->d_name.len;
- Buflen -= p->d_name.len;
- memcpy(retval, p->d_name.name, p->d_name.len);
- *(--retval) = '\\';
- Buflen--;
- p = p->d_parent;
- }
- else
- {
- retval = NULL;
- break;
- }
- }
- }
- else
- {
- *(--retval) = '\\';
- }
-
-
-
-if (retval) DbgPrint("Novfs_dget_path: %s\n", retval);
- return(retval);
-}
-
-/*++======================================================================*/
-int verify_dentry( struct dentry *dentry, int Flags )
-/*
- * Arguments: struct dentry *dentry - entry to verify
- *
- * Returns: zero - Inode cache has been updated. If not in the cache
- * then file doesn't exist.
- * !zero - Error
- *
- * Abstract: This routine will verify if the file that dentry is pointing
- * at exist and if it does it will put it in the inode cache of
- * the parent.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal = -ENOENT;
- struct inode *dir;
- PENTRY_INFO info=NULL;
- PINODE_DATA id;
- session_t session;
- char *path, *list=NULL, *cp;
- ino_t ino;
- struct qstr name;
- int iLock=0;
- struct dentry *parent=NULL;
- u64 ctime;
- struct inode *inode;
-
- if ( IS_ROOT(dentry) )
- {
- DbgPrint("verify_dentry: Root entry\n");
- return( 0 );
- }
-
- if ( dentry && dentry->d_parent &&
- (dir = dentry->d_parent->d_inode) &&
- (id = dir->u.generic_ip) )
- {
- parent = dget_parent(dentry);
-
- info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
-
- if (info)
- {
- if (Novfs_lock_inode_cache( dir ))
- {
- name.len = dentry->d_name.len;
- name.name = dentry->d_name.name;
- name.hash = Novfs_internal_hash( &name );
- if ( !Novfs_get_entry_time(dir, &name, &ino, info, &ctime))
- {
- inode = dentry->d_inode;
- if ( inode &&
- ( (inode->i_size != info->size) ||
- (inode->i_mtime.tv_sec != info->mtime.tv_sec) ))
- {
- ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
- }
-
- ctime = get_jiffies_64() - ctime;
- if ( Flags || ctime < (u64)(File_update_timeout*HZ) )
- {
- retVal = 0;
- Novfs_unlock_inode_cache(dir);
- dput(parent);
- Novfs_Free(info);
- return(0);
- }
- }
- Novfs_unlock_inode_cache(dir);
- }
-
- if ( IS_ROOT(dentry->d_parent) )
- {
- session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name));
- }
- else
- {
- session = Scope_Get_SessionId( id->Scope );
- }
-
- if ( !session )
- {
- id->Scope = Scope_Get_ScopefromPath(dentry);
- session = Scope_Get_SessionId( id->Scope );
- }
-
- ino = 0;
- retVal = 0;
-
- if ( IS_ROOT(dentry->d_parent) )
- {
- DbgPrint("verify_dentry: parent is Root directory\n");
- list = Scope_Get_ScopeUsers();
-
- iLock = Novfs_lock_inode_cache( dir );
- Novfs_invalidate_inode_cache( dir );
-
- if ( list )
- {
- cp = list;
- while (*cp)
- {
- name.name = cp;
- name.len = strlen(cp);
- name.hash = Novfs_internal_hash( &name );
- cp += (name.len+1);
- ino = 0;
- if ( Novfs_get_entry( dir, &name, &ino, info ) )
- {
- info->mode = S_IFDIR | 0700;
- info->size = 0;
- info->atime = info->ctime = info->mtime = CURRENT_TIME;
- ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
- Novfs_add_inode_entry(dir, &name, ino, info);
- }
- }
- }
- Novfs_free_invalid_entries( dir );
- }
- else
- {
-
- path = Novfs_dget_path(dentry, info->name, PATH_LENGTH_BUFFER);
- if (path)
- {
- if (dentry->d_name.len <= NW_MAX_PATH_LENGTH)
- {
- name.hash = Novfs_internal_hash(&dentry->d_name);
- name.len = dentry->d_name.len;
- name.name = dentry->d_name.name;
-
-
-
- retVal = Novfs_Get_File_Info( path, info, session );
- if ( 0 == retVal)
- {
- dentry->d_time = jiffies+(File_update_timeout*HZ);
- iLock = Novfs_lock_inode_cache( dir );
- if ( Novfs_update_entry( dir, &name, 0, info ) )
- {
- if (dentry->d_inode)
- {
- ino = dentry->d_inode->i_ino;
- }
- else
- {
- ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
- }
- Novfs_add_inode_entry( dir, &name, ino, info);
- }
- if ( dentry->d_inode )
- {
- update_inode(dentry->d_inode, info);
- id->Flags &= ~UPDATE_INODE;
-
- dentry->d_inode->i_flags &= ~S_DEAD;
- if (dentry->d_inode->u.generic_ip)
- {
- ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope;
- }
- }
- }
- else if (-EINTR != retVal)
- {
- retVal = 0;
- iLock = Novfs_lock_inode_cache( dir );
- Novfs_remove_inode_entry( dir, &name, 0 );
- if ( dentry->d_inode && !(dentry->d_inode->i_flags & S_DEAD) )
- {
- dentry->d_inode->i_flags |= S_DEAD;
- dentry->d_inode->i_size = 0;
- dentry->d_inode->i_atime.tv_sec =
- dentry->d_inode->i_atime.tv_nsec =
- dentry->d_inode->i_ctime.tv_sec =
- dentry->d_inode->i_ctime.tv_nsec =
- dentry->d_inode->i_mtime.tv_sec =
- dentry->d_inode->i_mtime.tv_nsec = 0;
- dentry->d_inode->i_blocks = 0;
- d_delete(dentry); /* Remove from cache */
- }
- }
- }
- else
- {
- retVal = -ENAMETOOLONG;
- }
- }
- }
- }
- else
- {
- retVal = -ENOMEM;
- }
- if (iLock)
- {
- Novfs_unlock_inode_cache( dir );
- }
- dput(parent);
- }
-
- if (list) Novfs_Free(list);
- if (info) Novfs_Free(info);
-
- DbgPrint("verify_dentry: return=0x%x\n", retVal);
-
- return(retVal);
-}
-
-/*++======================================================================*/
-struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- return( d_lookup( Parent, Name));
-}
-
-/*++======================================================================*/
-int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- void *scope;
- PINODE_DATA id=NULL;
-
- char *path, *buf;
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, i->i_ino, path);
- }
- Novfs_Free(buf);
- }
-
- if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip)
- {
- id = (PINODE_DATA)Parent->d_inode->u.generic_ip;
- }
-
- if (id && id->Scope)
- {
- scope = id->Scope;
- }
- else
- {
- scope = Scope_Get_ScopefromPath( d );
- }
-
- ((PINODE_DATA)i->u.generic_ip)->Scope = scope;
-
- d->d_time = jiffies+(File_update_timeout*HZ);
- if (a)
- {
- d_add(d, i);
- }
- else
- {
- d_instantiate(d, i);
- }
-
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
-/*
- * Arguments: struct dentry *dentry - pointer to dentry to revalidate.
- * struct nameidata *nd - pointer to nameidata.
- *
- * Returns: zero - dentry is not valid.
- * !zero - valid entry
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = 0;
- struct inode *dir;
- PINODE_DATA id;
- struct qstr name;
-
- UNUSED_VARIABLE( nd );
-
- DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" \
- " d_count: %d\n" \
- " d_inode: 0x%p\n",
- dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
-
- if (IS_ROOT( dentry ))
- {
- retCode = 1;
- }
- else
- {
- if ( dentry->d_inode &&
- dentry->d_parent &&
- (dir = dentry->d_parent->d_inode) &&
- (id = dir->u.generic_ip) )
- {
- /*
- * Check timer to see if in valid time limit
- */
- if (jiffies > dentry->d_time)
- {
- /*
- * Revalidate entry
- */
- name.len = dentry->d_name.len;
- name.name = dentry->d_name.name;
- name.hash = Novfs_internal_hash(&dentry->d_name);
- dentry->d_time = 0;
-
- if ( 0 == verify_dentry( dentry, 0 ))
- {
- if (Novfs_lock_inode_cache( dir ))
- {
- if (Novfs_lookup_inode_cache( dir, &name, 0))
- {
- dentry->d_time = jiffies + (File_update_timeout*HZ);
- retCode = 1;
- }
- Novfs_unlock_inode_cache( dir );
- }
- }
- }
- else
- {
- retCode = 1;
- }
- }
- }
-
-
- if ( ( 0 == retCode ) && dentry->d_inode )
- {
- /*
- * Entry has become invalid
- */
-/* dput(dentry);
-*/
- }
-
- DbgPrint("Novfs_d_revalidate: return 0x%x\n", retCode);
-
- return(retCode);
-}
-
-/*++======================================================================*/
-unsigned long Novfs_internal_hash (struct qstr *name)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- unsigned long hash = 0;
- unsigned int len = name->len;
- unsigned char *c = (unsigned char *)name->name;
-
- while(len--)
- {
- /*
- * Lower case values for the hash.
- */
- hash = partial_name_hash(tolower(*c++), hash);
- }
-
- return(hash);
-}
-
-/*++======================================================================*/
-int Novfs_d_hash (struct dentry *dentry, struct qstr *name)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- UNUSED_VARIABLE( dentry );
-
- DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name);
-
- name->hash = Novfs_internal_hash( name );
-
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = 1;
- unsigned char *str1, *str2;
- unsigned int len;
-
- DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, s2->len, s2->name);
-
- if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash) )
- {
- len = s1->len;
- str1 = (unsigned char *)s1->name;
- str2 = (unsigned char *)s2->name;
- for ( retCode = 0; len-- ; str1++, str2++ )
- {
- if (*str1 != *str2)
- {
- if (tolower(*str1) != tolower(*str2))
- {
- retCode = 1;
- break;
- }
- }
- }
- }
-
- DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode);
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_d_compare (struct dentry *parent, struct qstr *s1, struct qstr *s2)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode;
-
- retCode = Novfs_d_strcmp(s1, s2);
-
- DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode);
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_d_delete(struct dentry *dentry)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retVal = 0;
-
- DbgPrint("Novfs_d_delete: 0x%p %.*s\n" \
- " d_count: %d\n" \
- " d_inode: 0x%p\n",
- dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
-
- if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD))
- {
- retVal = 1;
- }
-
- dentry->d_time = 0;
-
- return( retVal );
-}
-
-/*++======================================================================*/
-void Novfs_d_release(struct dentry *dentry)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DbgPrint("Novfs_d_release: 0x%x %.*s\n", dentry, dentry->d_name.len, dentry->d_name.name);
-}
-
-/*++======================================================================*/
-void Novfs_d_iput(struct dentry *dentry, struct inode *inode)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DbgPrint("Novfs_d_iput: Inode=0x%x Ino=%d Dentry=0x%x Name=%.*s\n",
- inode, inode->i_ino, dentry, dentry->d_name.len, dentry->d_name.name);
-
- iput(inode);
-
-}
-/*++======================================================================*/
-int Novfs_dir_open(struct inode *dir, struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *path, *buf;
-
-
- DbgPrint("Novfs_dir_open: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- DbgPrint("Novfs_dir_open: path %s\n", path);
- }
- Novfs_Free(buf);
- }
- file->private_data = NULL;
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_dir_release(struct inode *dir, struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct inode *inode;
-
- DbgPrint("Novfs_dir_release: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
- if (file->private_data)
- {
- inode = file->private_data;
- Novfs_free_inode_cache( inode );
- Novfs_Free(file->private_data);
- }
-
- return(0);
-}
-
-/*++======================================================================*/
-loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- return(dcache_dir_lseek(file, offset, origin));
-}
-
-/*++======================================================================*/
-int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-/*
- int rlen = 0;
-
- DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off);
-
- if (0 == *off)
- {
- rlen = 8;
- rlen -= copy_to_user(buf, "Testing\n", 8);
- *off += rlen;
- }
- return(rlen);
-*/
- return(generic_read_dir(file, buf, len, off));
-}
-
-/*++======================================================================*/
-void process_list(struct file *File, char *List, int Type, PENTRY_INFO Info, session_t SessionId)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- unsigned char *path, *buf=NULL, *cp;
- struct inode *dir = File->f_dentry->d_inode;
- struct qstr name;
- ino_t ino=0;
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- path = buf;
- if (buf)
- {
- path = Novfs_dget_path(File->f_dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- strcpy(buf, path);
- }
- path = buf+strlen(buf);
- *path++ = '\\';
- }
-
- if ( List )
- {
- cp = List;
- while (*cp)
- {
- name.name = cp;
- name.len = strlen(cp);
- name.hash = Novfs_internal_hash( &name );
- cp += (name.len+1);
-
- Info->mode = S_IFDIR | 0700;
- Info->size = 0;
- Info->atime = Info->ctime = Info->mtime = CURRENT_TIME;
-
- if ( (USER_LIST != Type) && buf && ((int)(path-buf)+name.len < PATH_LENGTH_BUFFER) )
- {
- strcpy(path, name.name);
- Novfs_Get_File_Info(buf, Info, SessionId);
- }
-
- if ( Novfs_update_entry( dir, &name, ino, Info ) )
- {
- Novfs_add_inode_entry(dir, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), Info);
- }
- }
- }
-
- if (buf) Novfs_Free(buf);
-
-}
-
-/*++======================================================================*/
-int Novfs_dir_readdir(struct file * file, void * dirent, filldir_t filldir)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- unsigned char *path, *buf=NULL;
- unsigned char *list=NULL;
- PENTRY_INFO info=NULL, pinfo, iinfo;
- int count;
-
- int status = -ENOMEM;
- struct inode *inode;
- session_t sessionId;
- uid_t uid;
- struct qstr name;
- struct list_head *inter;
- ino_t ino;
- int iLock=0;
- int type = 0;
-
- DbgPrint("Novfs_dir_readdir(%s): dentry path %.*s 0x%x\n", current->comm, file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_dentry->d_fsdata);
-
- inode = file->f_dentry->d_inode;
-
- info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (info)
- {
- if (file->f_pos)
- {
- if (file->private_data)
- {
- inode = file->private_data;
- while( !Novfs_get_remove_entry(inode, &ino, info) )
- {
- DbgPrint("Calling filedir-2 %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
- if ( filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12) < 0 )
- {
- /*
- * put entry back on the list.
- */
- name.len = info->namelength;
- name.name = info->name;
- name.hash = Novfs_internal_hash( &name );
- Novfs_add_inode_entry(inode, &name, ino, info);
-
- break;
- }
- file->f_pos++;
- }
- }
- Novfs_Free(info);
- return(0);
- }
-
- if ( inode && inode->u.generic_ip )
- {
- sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- if (0 == sessionId)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry);
- sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
- uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
- else
- {
- sessionId = 0;
- uid = current->euid;
- }
-
- if ( IS_ROOT(file->f_dentry) || /* Root */
- IS_ROOT(file->f_dentry->d_parent) || /* User */
- IS_ROOT(file->f_dentry->d_parent->d_parent) ) /* Server */
- {
- if ( IS_ROOT(file->f_dentry) )
- {
- DbgPrint("Novfs_dir_readdir: Root directory\n");
- list = Scope_Get_ScopeUsers();
- type = USER_LIST;
-
- } else if ( IS_ROOT(file->f_dentry->d_parent) )
- {
- DbgPrint("Novfs_dir_readdir: Parent is Root directory\n");
- Novfs_Get_Connected_Server_List( &list, sessionId );
- type = SERVER_LIST;
- }
- else
- {
- DbgPrint("Novfs_dir_readdir: Parent-Parent is Root directory\n");
- Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, &list, sessionId);
- type = VOLUME_LIST;
- }
-
- iLock = Novfs_lock_inode_cache( inode );
- Novfs_invalidate_inode_cache( inode );
-
- process_list(file, list, type, info, sessionId);
- }
- else
- {
- DbgPrint("Novfs_dir_readdir: Default directory\n");
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- unsigned long enumHandle=0;
-
- iLock = Novfs_lock_inode_cache( inode );
- Novfs_invalidate_inode_cache(inode);
-
- do
- {
- /*
- * Novfs_Get_Directory_List will return 0 when no error or -1 when
- * the last entry is returned. Otherwise it will return an error.
- */
- info->namelength = 0;
- status = Novfs_Get_Directory_ListEx(path, &enumHandle, &count, &pinfo, sessionId);
- DbgPrint("Novfs_dir_readdir: Novfs_Get_Directory_List return 0x%x count=%d pinfo=0x%p\n", status, count, pinfo);
- iinfo = pinfo;
- while ( (0 == status) && pinfo && count-- )
- {
- memcpy(info, pinfo, (int)((char *)&pinfo->name[pinfo->namelength]-(char *)pinfo));
- pinfo = (PENTRY_INFO)&pinfo->name[pinfo->namelength];
- name.len = info->namelength;
- name.name = info->name;
- name.hash = Novfs_internal_hash(&name);
- info->name[name.len] = '\0';
-
- DbgPrint("Novfs_dir_readdir: Got %s\n", name.name);
-
- if ( Novfs_update_entry( inode, &name, 0, info ))
- {
- Novfs_add_inode_entry(inode, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), info);
- }
- }
-
- if (iinfo)
- {
- Novfs_Free(iinfo);
- }
-
- } while ( !status );
- }
- }
- }
-
- if ( iLock )
- {
- Novfs_free_invalid_entries( inode );
- }
-
- switch ((int) file->f_pos)
- {
- case 0:
- DbgPrint("Calling filedir %llu with ino %d name .\n", file->f_pos, inode->i_ino);
- if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < 0)
- {
- break;
- }
- file->f_pos++;
- /* fallthrough */
- case 1:
- DbgPrint("Calling filedir %llu with ino %d name ..\n", file->f_pos, parent_ino(file->f_dentry));
- if (filldir(dirent, "..", 2, file->f_pos, parent_ino(file->f_dentry), DT_DIR) < 0)
- {
- break;
- }
- file->f_pos++;
- /* fallthrough */
-
- default:
- status = 0;
- inter = NULL;
-
- if ( iLock )
- {
- while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info) )
- {
- DbgPrint("Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
- if ( filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12) < 0 )
- {
- /*
- * Get the rest of the entries and put them in a fake
- * inode cache.
- */
- file->private_data = (PDIR_CACHE)Novfs_Malloc(sizeof(struct inode) + sizeof(DIR_CACHE), GFP_KERNEL);
- if (file->private_data)
- {
- struct inode *dinode = file->private_data;
- PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode));
-
- dinode->u.generic_ip = id;
-
- id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope;
- id->Flags = 0;
- INIT_LIST_HEAD( &id->DirCache );
- init_MUTEX( &id->DirCacheLock );
-
- /*
- * Copy rest of the files.
- */
- do
- {
- name.len = info->namelength;
- name.name = info->name;
- name.hash = Novfs_internal_hash( &name );
- Novfs_add_inode_entry(dinode, &name, ino, info);
- } while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info) );
- }
-
- break;
- }
- file->f_pos++;
- }
- }
-
- }
-
- if (iLock)
- {
- Novfs_unlock_inode_cache(inode);
- }
- }
-
- if (info) Novfs_Free( info );
- if (buf) Novfs_Free( buf );
- if (list) Novfs_Free( list );
-
- return(status);
-}
-
-
-/*++======================================================================*/
-int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- return(simple_sync_file(file, dentry, datasync));
-}
-
-/*++======================================================================*/
-int do_open(struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PENTRY_INFO info=NULL;
- int retCode = -ENOENT;
- session_t session;
- char *path;
- struct dentry *parent;
- struct inode *inode;
- PINODE_DATA id;
-
- inode = file->f_dentry->d_inode;
-
- if (inode && inode->u.generic_ip)
- {
- id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
- session = Scope_Get_SessionId(id->Scope);
- if (0 == session)
- {
- id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
- session = Scope_Get_SessionId(id->Scope);
- }
-
- retCode = -ENOMEM;
- info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (info)
- {
- path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER);
- if (path)
- {
- DbgPrint("do_open: %s\n", path);
-
- retCode = Novfs_Open_File(
- path,
- file->f_flags & ~O_EXCL, info,
- (unsigned long *)&file->private_data,
- session);
- DbgPrint("do_open: 0x%x 0x%x\n", retCode, file->private_data);
- if ( !retCode )
- {
- if( !Novfs_Get_File_Info(path, info, session))
- {
- update_inode(inode, info);
- }
-
- parent = dget_parent(file->f_dentry);
-
- if (parent && parent->d_inode)
- {
- struct inode *dir = parent->d_inode;
- Novfs_lock_inode_cache(dir);
- if (Novfs_update_entry(dir, &file->f_dentry->d_name, 0, info))
- {
- Novfs_add_inode_entry(dir, &file->f_dentry->d_name, inode->i_ino, info);
- }
-
- Novfs_unlock_inode_cache(dir);
- }
- dput(parent);
- }
- }
- Novfs_Free(info);
- }
- }
-
- return(retCode);
-}
-
-/*++======================================================================*/
-ssize_t Novfs_f_read(struct file *file, char *buf, size_t len, loff_t *off)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- size_t thisread, totalread=0;
- loff_t offset = *off;
- struct inode *inode;
- session_t session;
-
- if (file->f_dentry && file->f_dentry->d_inode && file->f_dentry->d_inode->u.generic_ip)
- {
- DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n", (unsigned long)file->private_data, buf, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
-
- if ( !file->private_data )
- {
- totalread = (size_t)do_open( file );
- if (totalread)
- {
- return(totalread);
- }
- }
-
- inode = file->f_dentry->d_inode;
-
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
-
- while(len > 0 && (offset < inode->i_size) )
- {
- thisread = len;
- if (Novfs_Read_File((unsigned long)file->private_data, buf, &thisread, &offset, 1, session) || !thisread)
- {
- break;
- }
- DbgPrint("Novfs_f_read thisread = 0x%x\n", thisread);
- len -= thisread;
- buf += thisread;
- offset += thisread;
- totalread += thisread;
- }
- }
- *off = offset;
- DbgPrint("Novfs_f_read return = 0x%x\n", totalread);
-
- return(totalread);
-}
-
-/*++======================================================================*/
-ssize_t Novfs_f_write(struct file *file, const char *buf, size_t len, loff_t *off)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- size_t thiswrite, totalwrite=0;
- loff_t offset = *off;
- session_t session;
- struct inode *inode;
- int status;
-
- if (file->f_dentry && file->f_dentry->d_inode && file->f_dentry->d_inode->u.generic_ip)
- {
- inode = file->f_dentry->d_inode;
-
- if ( !file->private_data )
- {
- totalwrite = (size_t)do_open( file );
- if (totalwrite)
- {
- return(totalwrite);
- }
- }
-
- DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
-
- if (file->f_flags & O_APPEND) {
- offset = inode->i_size;
- DbgPrint("Novfs_f_write appending to end %lld %.*s\n", offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
- }
-
-
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
-
- while(len > 0)
- {
- thiswrite = len;
- if ((status = Novfs_Write_File(
- (unsigned long)file->private_data,
- (unsigned char *)buf,
- &thiswrite,
- &offset,
- session)) || !thiswrite)
- {
- totalwrite = status;
- break;
- }
- DbgPrint("Novfs_f_write thiswrite = 0x%x\n", thiswrite);
- len -= thiswrite;
- buf += thiswrite;
- offset += thiswrite;
- totalwrite += thiswrite;
- if (offset > inode->i_size)
- {
- inode->i_size = offset;
- inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits;
- }
- inode->i_mtime = inode->i_atime = CURRENT_TIME;
- ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
-
- }
- }
- *off = offset;
- DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite);
-
- return(totalwrite);
-}
-
-/*++======================================================================*/
-int Novfs_f_readdir(struct file *file, void *data, filldir_t fill)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(data);
- UNUSED_VARIABLE(fill);
- return(-EISDIR);
-}
-
-/*++======================================================================*/
-int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- UNUSED_VARIABLE(inode);
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(cmd);
- UNUSED_VARIABLE(arg);
- DbgPrint("Novfs_f_ioctl: file=0x%x cmd=0x%x arg=0x%x", file, cmd, arg);
-
- return(-ENOSYS);
-}
-
-/*++======================================================================*/
-int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -EINVAL;
-
- DbgPrint("Novfs_f_mmap: file=0x%x", file);
-
- retCode = generic_file_mmap(file, vma);
-
- DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode);
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_f_open2(struct inode *inode, struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode;
-
- DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode);
- if (file->f_dentry)
- {
- DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
- }
- retCode = do_open(file);
-
- DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_f_open(struct inode *inode, struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PENTRY_INFO info=NULL;
- int retCode = -ENOENT;
- session_t session;
- char *path;
- struct dentry *parent;
- PINODE_DATA id;
-
- DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode);
- if (file->f_dentry)
- {
- DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
- }
-
- if (inode && inode->u.generic_ip)
- {
- id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
- session = Scope_Get_SessionId(id->Scope);
- if (0 == session)
- {
- id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
- session = Scope_Get_SessionId(id->Scope);
- }
-
- info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (info)
- {
- path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER);
- if (path)
- {
- DbgPrint("Novfs_f_open: %s\n", path);
-
-
- retCode = Novfs_Get_File_Info(path, info, session);
- if ( !retCode )
- {
- if ( (O_TRUNC & file->f_flags) && S_ISREG(info->mode) && info->size )
- {
- if (!Novfs_Truncate_File(path, strlen(path), session))
- {
- info->size = 0;
- }
- }
-
- /*
- * Update inode info.
- */
- update_inode(inode, info);
-
- file->private_data = NULL;
-
- parent = dget_parent(file->f_dentry);
-
- if (parent && parent->d_inode)
- {
- struct inode *dir = parent->d_inode;
- Novfs_lock_inode_cache(dir);
- if (Novfs_update_entry(dir, &file->f_dentry->d_name, 0, info))
- {
- Novfs_add_inode_entry(dir, &file->f_dentry->d_name, inode->i_ino, info);
- }
-
- Novfs_unlock_inode_cache(dir);
- }
- dput(parent);
-
- if ( S_ISDIR(info->mode) )
- {
- retCode = -EISDIR;
- }
- }
- else
- {
- if ( O_CREAT & file->f_flags )
- {
- retCode = do_open(file);
- if (file->private_data)
- {
- Novfs_f_release(file->f_dentry->d_inode, file);
- file->private_data = NULL;
- }
- }
- }
- }
- Novfs_Free(info);
- }
- }
- DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode);
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_f_flush(struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct inode *inode;
-
- UNUSED_VARIABLE(file);
- if (file->f_dentry)
- {
- inode = file->f_dentry->d_inode;
- DbgPrint("Novfs_f_flush: %.*s f_flags=0x%x f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
- }
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_f_release(struct inode *inode, struct file *file)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -EACCES;
- session_t session;
- PINODE_DATA id;
-
- DbgPrint("Novfs_f_release: path=%.*s handle=0x%x inode=0x%p\n",
- file->f_dentry->d_name.len,
- file->f_dentry->d_name.name,
- (unsigned long)file->private_data, file->f_dentry->d_inode);
-
- if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
- {
- if (file->private_data)
- {
- session = Scope_Get_SessionId(id->Scope);
- if (0 == session)
- {
- id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
- session = Scope_Get_SessionId(id->Scope);
- }
-
- //invalidate_remote_inode(file->f_dentry->d_inode);
-
- retCode = Novfs_Close_File((unsigned long)file->private_data, session);
- file->private_data = NULL;
- }
- else
- {
- retCode = 0;
- }
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(dentry);
- UNUSED_VARIABLE(datasync);
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_f_llseek(struct file *file, loff_t offset, int origin)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- DbgPrint("Novfs_f_llseek: File=0x%x Name=%.*s offset=%lld origin=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, offset, origin);
- return(generic_file_llseek(file, offset, origin));
-}
-
-/*++======================================================================*/
-int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(cmd);
- UNUSED_VARIABLE(lock);
- return(-ENOSYS);
-}
-
-/*++======================================================================*/
-int Novfs_a_readpage(struct file *file, struct page *page)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = 0;
- void *pbuf;
- struct inode *inode=NULL;
- struct dentry *dentry=NULL;
- loff_t offset;
- size_t len;
- session_t session=0;
-
- DbgPrint("Novfs_a_readpage: File=0x%x Name=%.*s Page=0x%x", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, page);
-
- dentry = file->f_dentry;
-
- if (dentry)
- {
- DbgPrint(" Dentry=0x%x Name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name);
- if (dentry->d_inode)
- {
- inode = dentry->d_inode;
- }
- }
-
-
-
- if (inode)
- {
- DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino);
-
- if (inode->u.generic_ip)
- {
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
- }
- }
-
- DbgPrint("\n");
-
- if ( !file->private_data )
- {
- retCode = (size_t)do_open( file );
- }
-
- if (file->private_data && !PageUptodate(page))
- {
- pbuf = kmap(page);
-
- offset = page->index << PAGE_CACHE_SHIFT;
- len = PAGE_CACHE_SIZE;
-
- retCode = Novfs_Read_File((unsigned long)file->private_data, pbuf, &len, &offset, 0, session);
- if ( len && (len < PAGE_CACHE_SIZE) )
- {
- memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE-len);
- }
-
- kunmap(page);
- flush_dcache_page(page);
- SetPageUptodate(page);
- }
- unlock_page(page);
-
- DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode);
- return (retCode);
-
-}
-
-/*++======================================================================*/
-int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *path, *buf;
- ENTRY_INFO info;
- unsigned long handle;
- session_t session;
- int retCode = -EACCES;
-
-
- DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name);
-
- if ( IS_ROOT(dentry) || /* Root */
- IS_ROOT(dentry->d_parent) || /* User */
- IS_ROOT(dentry->d_parent->d_parent) || /* Server */
- IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
- {
- return(-EACCES);
- }
-
- if (mode | S_IFREG)
- {
- if (dir->u.generic_ip)
- {
- session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
- }
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- retCode = Novfs_Open_File(path, nd->NDOPENFLAGS|O_RDWR, &info, &handle, session);
- if ( !retCode && handle )
- {
- Novfs_Close_File(handle, session);
- if (!Novfs_i_mknod(dir, dentry, mode | S_IFREG, 0))
- {
- if (dentry->d_inode)
- {
- ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE;
- }
- }
- }
- }
- Novfs_Free(buf);
- }
- }
- }
- return( retCode );
-}
-
-/*++======================================================================*/
-void update_inode(struct inode *Inode, PENTRY_INFO Info)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- static char dbuf[128];
-
- DbgPrint("update_inode: Inode=0x%x I_ino=%d\n", Inode, Inode->i_ino);
-
- DbgPrint("update_inode: atime=%s\n", ctime_r(&Info->atime.tv_sec, dbuf));
- DbgPrint("update_inode: ctime=%s\n", ctime_r(&Info->ctime.tv_sec, dbuf));
- DbgPrint("update_inode: mtime=%s\n", ctime_r(&Info->mtime.tv_sec, dbuf));
- DbgPrint("update_inode: size=%lld\n", Info->size);
- DbgPrint("update_inode: mode=0%o\n", Info->mode);
-
- Inode->i_mode = Info->mode;
- Inode->i_size = Info->size;
- Inode->i_atime = Info->atime;
- Inode->i_ctime = Info->ctime;
- Inode->i_mtime = Info->mtime;
- Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits);
- Inode->i_bytes = Info->size & (Inode->i_blksize - 1);
-
- DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize);
- DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits);
- DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks);
- DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes);
-}
-
-/*++======================================================================*/
-struct dentry * Novfs_i_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct dentry *retVal = ERR_PTR(-ENOENT);
- struct dentry *parent;
- PENTRY_INFO info=NULL;
- PINODE_DATA id;
- struct inode *inode=NULL;
- uid_t uid=current->euid;
- ino_t ino=0;
- struct qstr name;
-
- DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode);
-
- if (dir && (id = dir->u.generic_ip) )
- {
- retVal = 0;
- if ( IS_ROOT( dentry ))
- {
- DbgPrint("Novfs_i_lookup: Root entry=0x%x\n", Novfs_root);
- inode = Novfs_root->d_inode;
- return(0);
- }
- else
- {
- info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (info)
- {
- if ( NULL == (retVal = ERR_PTR(verify_dentry( dentry, 1 ))))
- {
- name.name = dentry->d_name.name;
- name.len = dentry->d_name.len;
- name.hash = Novfs_internal_hash(&name);
-
- if (Novfs_lock_inode_cache( dir ))
- {
- if ( !Novfs_get_entry(dir, &name, &ino, info) )
- {
- inode = ilookup(dentry->d_sb, ino);
- if ( inode )
- {
- update_inode(inode, info);
- }
- }
- Novfs_unlock_inode_cache( dir );
- }
-
- if ( !inode && ino )
- {
- uid = Scope_Get_Uid( id->Scope );
- if (Novfs_lock_inode_cache( dir ))
- {
- inode = Novfs_get_inode(dentry->d_sb, info->mode, 0, uid, ino, &name);
- if ( inode )
- {
- if ( !Novfs_get_entry(dir, &dentry->d_name, &ino, info) )
- {
- update_inode(inode, info);
- }
- }
- Novfs_unlock_inode_cache( dir );
- }
- }
- }
- }
- }
- }
-
- if ( !retVal )
- {
- dentry->d_op = &Novfs_dentry_operations;
- if (inode)
- {
- parent = dget_parent(dentry);
- Novfs_d_add(dentry->d_parent, dentry, inode, 1);
- dput(parent);
- }
- else
- {
- d_add( dentry, inode);
- }
- }
-
- if (info) Novfs_Free(info);
-
- DbgPrint("Novfs_i_lookup: inode=0x%x dentry->d_inode=0x%x return=0x%x\n", dir, dentry->d_inode, retVal);
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int Novfs_i_unlink(struct inode *dir, struct dentry *dentry)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOENT;
- struct inode *inode;
- session_t session;
- char *path, *buf;
- uint64_t t64;
-
- DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d %.*s\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name);
- DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry));
- DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", IS_ROOT(dentry->d_parent));
- DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent));
- DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent->d_parent) );
-
- if ( IS_ROOT(dentry) || /* Root */
- IS_ROOT(dentry->d_parent) || /* User */
- (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */
- IS_ROOT(dentry->d_parent->d_parent->d_parent)) ) /* Volume */
- {
- return(-EACCES);
- }
-
- inode = dentry->d_inode;
- if ( inode )
- {
- DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino);
- if (inode->u.generic_ip)
- {
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- DbgPrint("Novfs_i_unlink: path %s mode 0%o\n", path, inode->i_mode);
- if (IS_ROOT(dentry->d_parent->d_parent))
- {
- retCode = do_logout(&dentry->d_name);
- }
- else
- {
- retCode = Novfs_Delete(path, S_ISDIR(inode->i_mode), session);
- }
- if ( !retCode || IS_DEADDIR(inode))
- {
- Novfs_remove_inode_entry(dir, &dentry->d_name, 0);
- dentry->d_time = 0;
- t64 = 0;
- Scope_Set_UserSpace(&t64, &t64, &t64, &t64);
- retCode = 0;
- }
- }
- Novfs_Free(buf);
- }
- }
- }
-
- DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode);
- return (retCode);
-}
-
-/*++======================================================================*/
-int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *path, *buf;
- session_t session;
- int retCode=0;
- struct inode *inode;
- ENTRY_INFO info;
- uid_t uid;
-
- DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%o\n", dir, dir->i_ino, dentry, dentry->d_name.len, dentry->d_name.name, mode);
-
- if ( IS_ROOT(dentry) || /* Root */
- IS_ROOT(dentry->d_parent) || /* User */
- IS_ROOT(dentry->d_parent->d_parent) || /* Server */
- IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
- {
- return(-EACCES);
- }
-
- mode |= S_IFDIR;
- mode &= (S_IFMT | S_IRWXU);
- if ( dir->u.generic_ip )
- {
- session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
- }
-
- uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- DbgPrint("Novfs_i_mkdir: path %s\n", path);
- retCode = Novfs_Create(path, S_ISDIR(mode), session);
- if ( !retCode )
- {
- retCode = Novfs_Get_File_Info(path, &info, session );
- if ( !retCode )
- {
- retCode = Novfs_i_mknod(dir, dentry, mode, 0);
- inode = dentry->d_inode;
- if (inode)
- {
- update_inode(inode, &info);
- ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE;
-
- dentry->d_time = jiffies+(File_update_timeout*HZ);
-
- Novfs_lock_inode_cache(dir);
- if (Novfs_update_entry( dir, &dentry->d_name, 0, &info ))
- {
- Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, &info);
- }
- Novfs_unlock_inode_cache(dir);
- }
-
- }
- }
- }
- Novfs_Free(buf);
- }
- }
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- return(Novfs_i_unlink(inode, dentry));
-}
-
-/*++======================================================================*/
-int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct inode *inode=NULL;
- int retCode = -EACCES;
- uid_t uid;
- struct dentry *parent;
-
- if ( IS_ROOT(dentry) || /* Root */
- IS_ROOT(dentry->d_parent) || /* User */
- IS_ROOT(dentry->d_parent->d_parent) || /* Server */
- IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
- {
- return(-EACCES);
- }
-
- if ( ((PINODE_DATA)dir->u.generic_ip) )
- {
- uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
- if (mode & (S_IFREG | S_IFDIR))
- {
- inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name);
- }
- }
-
- if (inode)
- {
- ENTRY_INFO info;
-
- dentry->d_op = &Novfs_dentry_operations;
- parent = dget_parent(dentry);
- Novfs_d_add(parent, dentry, inode, 0);
- memset(&info, 0, sizeof(info));
- info.mode = inode->i_mode;
- Novfs_lock_inode_cache( dir );
- Novfs_add_inode_entry( dir, &dentry->d_name, inode->i_ino, &info);
- Novfs_unlock_inode_cache( dir );
-
- dput(parent);
-
- retCode = 0;
- }
- DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode);
- return retCode;
-}
-
-/*++======================================================================*/
-int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, struct dentry *nd)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = -ENOTEMPTY;
- char *newpath, *newbuf, *newcon;
- char *oldpath, *oldbuf, *oldcon;
- struct qstr newname, oldname;
- PENTRY_INFO info=NULL;
- int oldlen, newlen;
- session_t session;
- ino_t ino;
-
-
- if ( IS_ROOT(od) || /* Root */
- IS_ROOT(od->d_parent) || /* User */
- IS_ROOT(od->d_parent->d_parent) || /* Server */
- IS_ROOT(od->d_parent->d_parent->d_parent) ) /* Volume */
- {
- return(-EACCES);
- }
-
- DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, odir->i_ino, ndir, ndir->i_ino);
-
- oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER*2, GFP_KERNEL);
- newbuf = oldbuf+PATH_LENGTH_BUFFER;
- if ( oldbuf && newbuf )
- {
- oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER);
- newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER);
- if (oldpath && newpath)
- {
- oldlen = PATH_LENGTH_BUFFER-(int)(oldpath-oldbuf);
- newlen = PATH_LENGTH_BUFFER-(int)(newpath-newbuf);
-
- DbgPrint("Novfs_i_rename: odir=0x%x od->inode=0x%x\n", odir, od->d_inode);
- DbgPrint("Novfs_i_rename: old path %s\n", oldpath);
- DbgPrint("Novfs_i_rename: new path %s\n", newpath);
-
- /*
- * Check to see if two different servers or different volumes
- */
- newcon = strchr(newpath+1, '\\');
- oldcon = strchr(oldpath+1, '\\');
- DbgPrint("Novfs_i_rename: newcon=0x%x newpath=0x%x\n", newcon, newpath);
- DbgPrint("Novfs_i_rename: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
- retCode = -EXDEV;
- if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
- {
- newcon = strchr(newcon+1, '\\');
- oldcon = strchr(oldcon+1, '\\');
- DbgPrint("Novfs_i_rename2: newcon=0x%x newpath=0x%x\n", newcon, newpath);
- DbgPrint("Novfs_i_rename2: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
- if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
- {
- newname.name = newpath;
- newname.len = (int)(newcon-newpath);
- newname.hash = 0;
-
- oldname.name = oldpath;
- oldname.len = (int)(oldcon-oldpath);
- oldname.hash = 0;
- if ( !Novfs_d_strcmp(&newname, &oldname))
- {
-
- if ( od->d_inode && od->d_inode->u.generic_ip )
- {
-
- if (nd->d_inode && nd->d_inode->u.generic_ip)
- {
- session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
- session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
- }
-
- retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
- }
-
-
- session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
- session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
- }
- retCode = Novfs_Rename_File(
- S_ISDIR(od->d_inode->i_mode),
- oldpath,
- oldlen-1,
- newpath,
- newlen-1,
- session);
-
- if ( !retCode )
- {
- info = (PENTRY_INFO)oldbuf;
- od->d_time = 0;
- Novfs_remove_inode_entry(odir, &od->d_name, 0);
- Novfs_Get_File_Info(newpath, info, session);
- nd->d_time = jiffies+(File_update_timeout*HZ);
- if (Novfs_update_entry(ndir, &nd->d_name, 0, info))
- {
- if (nd->d_inode && nd->d_inode->i_ino)
- {
- ino = nd->d_inode->i_ino;
- }
- else
- {
- ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
- }
- Novfs_add_inode_entry(ndir, &nd->d_name, ino, info);
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (oldbuf) Novfs_Free(oldbuf);
-
- return( retCode );
-}
-
-/*++======================================================================*/
-int Novfs_i_permission(struct inode *inode, int mask)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode=0;
-
- return(retCode);
-}
-
-/*++======================================================================*/
-int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *path, *buf;
- struct inode *inode=dentry->d_inode;
- char atime_buf[32];
- char mtime_buf[32];
- char ctime_buf[32];
- unsigned int ia_valid = attr->ia_valid;
- session_t session;
- int retVal = 0;
-
- if ( IS_ROOT(dentry) || /* Root */
- IS_ROOT(dentry->d_parent) || /* User */
- IS_ROOT(dentry->d_parent->d_parent) || /* Server */
- IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
- {
- return(-EACCES);
- }
-
- if (inode && inode->u.generic_ip)
- {
- session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope);
- if (0 == session)
- {
- ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
- session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
- }
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- strcpy(atime_buf, "Unspecified");
- strcpy(mtime_buf, "Unspecified");
- strcpy(ctime_buf, "Unspecified");
- if (attr->ia_valid & ATTR_ATIME)
- {
- ctime_r(&attr->ia_atime.tv_sec, atime_buf);
- }
- if (attr->ia_valid & ATTR_MTIME)
- {
- ctime_r(&attr->ia_mtime.tv_sec, mtime_buf);
- }
- if (attr->ia_valid & ATTR_CTIME)
- {
- ctime_r(&attr->ia_ctime.tv_sec, ctime_buf);
- }
- DbgPrint("Novfs_i_setattr: %s\n" \
- " ia_valid: 0x%x\n" \
- " ia_mode: 0%o\n" \
- " ia_uid: %d\n" \
- " ia_gid: %d\n" \
- " ia_size: %lld\n" \
- " ia_atime: %s\n" \
- " ia_mtime: %s\n" \
- " ia_ctime: %s\n",
- path,
- attr->ia_valid,
- attr->ia_mode,
- attr->ia_uid,
- attr->ia_gid,
- attr->ia_size,
- atime_buf,
- mtime_buf,
- ctime_buf);
-
- if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) )
- {
- ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
-
- if (ia_valid & ATTR_SIZE)
- {
- inode->i_size = attr->ia_size;
- inode->i_blocks = (u_long)(inode->i_size >> (loff_t)inode->i_blkbits);
- inode->i_bytes = inode->i_size & (inode->i_blksize - 1);
-
- }
- if (ia_valid & ATTR_ATIME)
- inode->i_atime = attr->ia_atime;
- if (ia_valid & ATTR_MTIME)
- inode->i_mtime = attr->ia_mtime;
- if (ia_valid & ATTR_CTIME)
- inode->i_ctime = attr->ia_ctime;
- if (ia_valid & ATTR_MODE) {
- inode->i_mode = attr->ia_mode & (S_IFMT | S_IRWXU);
- }
- }
- }
- }
- Novfs_Free(buf);
- }
-
- return(retVal);
-}
-
-/*++======================================================================*/
-int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode = 0;
- char atime_buf[32];
- char mtime_buf[32];
- char ctime_buf[32];
- struct inode *inode = dentry->d_inode;
-
- ENTRY_INFO info;
- char *path, *buf;
- session_t session;
- PINODE_DATA id;
-
- if ( !IS_ROOT(dentry) &&
- !IS_ROOT(dentry->d_parent) )
- {
- session = 0;
- id = dentry->d_inode->u.generic_ip;
-
- if (id && (id->Flags & UPDATE_INODE) )
- {
- session = Scope_Get_SessionId( id->Scope );
-
- if (0 == session)
- {
- id->Scope = Scope_Get_ScopefromPath( dentry );
- session = Scope_Get_SessionId(id->Scope);
- }
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- retCode = Novfs_Get_File_Info(path, &info, session );
- if ( !retCode )
- {
- update_inode(inode, &info);
- id->Flags &= ~UPDATE_INODE;
- }
- }
- Novfs_Free(buf);
- }
- }
- }
-
- kstat->ino = inode->i_ino;
- kstat->dev = inode->i_sb->s_dev;
- kstat->mode = inode->i_mode;
- kstat->nlink = inode->i_nlink;
- kstat->uid = inode->i_uid;
- kstat->gid = inode->i_gid;
- kstat->rdev = inode->i_rdev;
- kstat->size = i_size_read(inode);
- kstat->atime = inode->i_atime;
- kstat->mtime = inode->i_mtime;
- kstat->ctime = inode->i_ctime;
- kstat->blksize = inode->i_blksize;
- kstat->blocks = inode->i_blocks;
- if (inode->i_bytes)
- {
- kstat->blocks++;
- }
- ctime_r(&kstat->atime.tv_sec, atime_buf);
- ctime_r(&kstat->mtime.tv_sec, mtime_buf);
- ctime_r(&kstat->ctime.tv_sec, ctime_buf);
-
-
- DbgPrint("Novfs_i_getattr: 0x%x <%.*s>\n" \
- " ino: %d\n" \
- " dev: 0x%x\n" \
- " mode: 0%o\n" \
- " nlink: 0x%x\n" \
- " uid: 0x%x\n" \
- " gid: 0x%x\n" \
- " rdev: 0x%x\n" \
- " size: 0x%llx\n" \
- " atime: %s\n" \
- " mtime: %s\n" \
- " ctime: %s\n" \
- " blksize: 0x%x\n" \
- " blocks: 0x%x\n",
- retCode, dentry->d_name.len, dentry->d_name.name,
- kstat->ino,
- kstat->dev,
- kstat->mode,
- kstat->nlink,
- kstat->uid,
- kstat->gid,
- kstat->rdev,
- kstat->size,
- atime_buf,
- mtime_buf,
- ctime_buf,
- kstat->blksize,
- kstat->blocks);
- return( retCode );
-}
-
-
-/*++======================================================================*/
-int Novfs_i_revalidate(struct dentry *dentry)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-
- DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, dentry->d_name.name);
-
- return(0);
-}
-
-/*++======================================================================*/
-void Novfs_read_inode(struct inode *inode)
-/*
- * Arguments:
- *
- * Returns: nothing
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment: Superblock operation
- *
- *=======================================================================-*/
-{
- DbgPrint( "Novfs_read_inode: 0x%x %d\n", inode, inode->i_ino);
-}
-
-/*++======================================================================*/
-void Novfs_write_inode(struct inode *inode)
-/*
- * Arguments:
- *
- * Returns: nothing
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment: Superblock operation
- *
- *=======================================================================-*/
-{
- DbgPrint( "Novfs_write_inode: Inode=0x%x Ino=%d\n", inode, inode->i_ino);
-}
-
-/*++======================================================================*/
-int Novfs_notify_change(struct dentry *dentry, struct iattr *attr)
-/*
- * Arguments:
- *
- * Returns: error code
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment: Superblock operation
- *
- *=======================================================================-*/
-{
- struct inode *inode = dentry->d_inode;
-
- DbgPrint( "Novfs_notify_change: Dentry=0x%x Name=%.*s Inode=0x%x Ino=%d ia_valid=0x%x\n",
- dentry, dentry->d_name.len, dentry->d_name.name,inode, inode->i_ino, attr->ia_valid);
- return(0);
-}
-
-/*++======================================================================*/
-void Novfs_clear_inode(struct inode *inode)
-/*
- * Arguments: sb - pointer to the super_block
- * buf - pointer to the statfs buffer
- *
- * Returns: 0
- *
- * Abstract: Called when statfs(2) system called.
- *
- * Notes:
- *
- * Environment: Superblock operation
- *
- *========================================================================*/
-{
- InodeCount--;
-
- if ( inode->u.generic_ip )
- {
- PINODE_DATA id=inode->u.generic_ip;
-
- DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name);
-
- Novfs_free_inode_cache(inode);
-
- down( &InodeList_lock );
- list_del( &id->IList );
- up( &InodeList_lock );
-
-
- Novfs_Free(inode->u.generic_ip);
- inode->u.generic_ip = NULL;
-
- remove_inode_hash( inode );
-
- }
- else
- {
- DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d\n", inode, inode->i_ino);
- }
-}
-
-/*++======================================================================*/
-int
-NO_TRACE
-Novfs_show_options( struct seq_file *s, struct vfsmount *m )
-/*
- * Arguments:
- *
- * Returns: 0
- *
- * Abstract: Called when /proc/mounts is read
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *buf, *path, *tmp;
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = d_path(m->mnt_root, m, buf, PATH_LENGTH_BUFFER);
- if (path)
- {
- if ( !Novfs_CurrentMount || (Novfs_CurrentMount && strcmp(Novfs_CurrentMount, path)))
- {
- DbgPrint("Novfs_show_options: %.*s %.*s %s\n", m->mnt_root->d_name.len, m->mnt_root->d_name.name,
- m->mnt_mountpoint->d_name.len, m->mnt_mountpoint->d_name.name, path);
- tmp = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - (int)(path-buf), GFP_KERNEL);
- if (tmp)
- {
- strcpy(tmp, path);
- path = Novfs_CurrentMount;
- Novfs_CurrentMount = tmp;
- Daemon_SetMountPoint( Novfs_CurrentMount );
-
- if (path)
- {
- Novfs_Free(path);
- }
- }
- }
- }
- Novfs_Free( buf );
- }
- return(0);
-}
-
-/*++======================================================================*/
-int Novfs_statfs(struct super_block *sb, struct kstatfs *buf)
-/*
- * Arguments: sb - pointer to the super_block
- * buf - pointer to the statfs buffer
- *
- * Returns: 0
- *
- * Abstract: Called when statfs(2) system called.
- *
- * Notes:
- *
- * Environment: Superblock operation
- *
- *========================================================================*/
-{
- uint64_t td, fd, te, fe;
-
- UNUSED_VARIABLE(sb);
-
- DbgPrint("Novfs_statfs:\n");
-
- td = fd = te = fe = 0;
-
- Scope_Get_UserSpace( &td, &fd, &te, &fe );
-
- DbgPrint("td=%llu\n", td);
- DbgPrint("fd=%llu\n", fd);
- DbgPrint("te=%llu\n", te);
- DbgPrint("fe=%llu\n", fd);
-
- buf->f_type = sb->s_magic;
- buf->f_bsize = sb->s_blocksize;
- buf->f_namelen = NW_MAX_PATH_LENGTH;
- buf->f_blocks = (sector_t)(td + (uint64_t)(sb->s_blocksize-1)) >> (uint64_t)sb->s_blocksize_bits;
- buf->f_bfree = (sector_t)fd >> (uint64_t)sb->s_blocksize_bits;
- buf->f_bavail = (sector_t)buf->f_bfree;
- buf->f_files = (sector_t)te;
- buf->f_ffree = (sector_t)fe;
- buf->f_frsize = sb->s_blocksize;
- if (te > 0xffffffff)
- buf->f_files = 0xffffffff;
-
- if (fe > 0xffffffff)
- buf->f_ffree = 0xffffffff;
-
-
- DbgPrint("f_type: 0x%x\n", buf->f_type);
- DbgPrint("f_bsize: %u\n", buf->f_bsize);
- DbgPrint("f_namelen: %d\n", buf->f_namelen);
- DbgPrint("f_blocks: %llu\n", buf->f_blocks);
- DbgPrint("f_bfree: %llu\n", buf->f_bfree);
- DbgPrint("f_bavail: %llu\n", buf->f_bavail);
- DbgPrint("f_files: %llu\n", buf->f_files);
- DbgPrint("f_ffree: %llu\n", buf->f_ffree);
- DbgPrint("f_frsize: %u\n", buf->f_frsize);
-
- return 0;
-}
-
-/*++======================================================================*/
-struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t Uid, ino_t ino, struct qstr *name)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *=======================================================================-*/
-{
- struct inode * inode = new_inode(sb);
-
- if (inode)
- {
- InodeCount++;
- inode->i_mode = mode;
- inode->i_uid = Uid;
- inode->i_gid = 0;
- inode->i_blksize = sb->s_blocksize;
- inode->i_blkbits = sb->s_blocksize_bits;
- inode->i_size = 0;
- inode->i_blocks = 0;
- inode->i_rdev = 0;
- inode->i_ino = (ino) ? ino: (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
- inode->i_mapping->a_ops = &Novfs_aops;
- inode->i_atime.tv_sec = 0;
- inode->i_atime.tv_nsec = 0;
- inode->i_mtime = inode->i_ctime = inode->i_atime;
-
- DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len);
-
- if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL)))
- {
- PINODE_DATA id;
- id = inode->u.generic_ip;
-
- DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id);
-
- id->Scope = NULL;
- id->Flags = 0;
- id->Inode = inode;
- INIT_LIST_HEAD( &id->DirCache );
- init_MUTEX( &id->DirCacheLock );
- down( &InodeList_lock );
-
- list_add_tail(&id->IList, &InodeList);
- up( &InodeList_lock );
-
- id->Name[0] = '\0';
-
- memcpy(id->Name, name->name, name->len);
- id->Name[name->len] = '\0';
-
- DbgPrint("Novfs_get_inode: name %s\n", id->Name);
- }
-
- insert_inode_hash(inode);
-
- switch (mode & S_IFMT) {
-
- case S_IFREG:
- inode->i_op = &Novfs_file_inode_operations;
- inode->i_fop = &Novfs_file_operations;
- break;
-
- case S_IFDIR:
- inode->i_op = &Novfs_inode_operations;
- inode->i_fop = &Novfs_dir_operations;
- inode->i_blksize = 0;
- inode->i_blkbits = 0;
- break;
-
- default:
- init_special_inode(inode, mode, dev);
- break;
- }
-
- DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size);
- DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode);
- DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize);
- DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits);
- DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks);
- DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes);
- }
-
- DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino);
- return (inode);
-}
-
-/*++======================================================================*/
-int Novfs_fill_super (struct super_block *SB, void *Data, int Silent)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct inode * inode;
- struct dentry *server, *tree;
- struct qstr name;
-/* PINODE_DATA id;
-*/
- ENTRY_INFO info;
-
- UNUSED_VARIABLE(Data);
- UNUSED_VARIABLE(Silent);
-
- SB->s_blocksize = PAGE_CACHE_SIZE;
- SB->s_blocksize_bits = PAGE_CACHE_SHIFT;
- SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL; /* Max file size */
- SB->s_op = &Novfs_ops;
- SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL);
- SB->s_magic = NOVFS_MAGIC;
-
-
- name.len = 1;
- name.name = "/";
-
- inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
- if (!inode)
- {
- return( -ENOMEM );
- }
-
- Novfs_root = d_alloc_root(inode);
-
- if (!Novfs_root)
- {
- iput(inode);
- return( -ENOMEM );
- }
- Novfs_root->d_time = jiffies+(File_update_timeout*HZ);
-
- inode->i_atime =
- inode->i_ctime =
- inode->i_mtime = CURRENT_TIME;
-
-
- SB->s_root = Novfs_root;
-
- DbgPrint( "Novfs_fill_super: root 0x%x\n", Novfs_root);
-
- if (Novfs_root)
- {
- Novfs_root->d_op = &Novfs_dentry_operations;
-
- name.name = SERVER_DIRECTORY_NAME;
- name.len = strlen(SERVER_DIRECTORY_NAME);
- name.hash = Novfs_internal_hash( &name );
-
- inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
- if (inode)
- {
- info.mode = inode->i_mode;
- info.namelength = 0;
- inode->i_size = info.size = 0;
- inode->i_uid = info.uid = 0;
- inode->i_gid = info.gid = 0;
- inode->i_atime = info.atime =
- inode->i_ctime = info.ctime =
- inode->i_mtime = info.mtime = CURRENT_TIME;
-
- server = d_alloc(Novfs_root, &name);
- if (server)
- {
- server->d_op = &Novfs_dentry_operations;
- server->d_time = 0xffffffff;
- d_add(server, inode);
- DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", SERVER_DIRECTORY_NAME, server);
- Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
- }
- }
-
- name.name = TREE_DIRECTORY_NAME;
- name.len = strlen(TREE_DIRECTORY_NAME);
- name.hash = Novfs_internal_hash( &name );
-
- inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
- if (inode)
- {
- info.mode = inode->i_mode;
- info.namelength = 0;
- inode->i_size = info.size = 0;
- inode->i_uid = info.uid = 0;
- inode->i_gid = info.gid = 0;
- inode->i_atime = info.atime =
- inode->i_ctime = info.ctime =
- inode->i_mtime = info.mtime = CURRENT_TIME;
- tree = d_alloc(Novfs_root, &name);
- if (tree)
- {
- tree->d_op = &Novfs_dentry_operations;
- tree->d_time = 0xffffffff;
-
- d_add(tree, inode);
- DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", TREE_DIRECTORY_NAME, tree);
- Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
- }
- }
- }
-
- return( 0 );
-}
-
-/*++======================================================================*/
-struct super_block *Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct super_block *sb;
- UNUSED_VARIABLE(Dev_name);
-
- sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super);
-
- DbgPrint( "Novfs_get_sb: sb=0x%x Fstype=0x%x Dev_name=%s\n", sb, Fstype, Dev_name);
-
- return (sb );
-}
-
-/*++======================================================================*/
-void Novfs_kill_sb(struct super_block *SB)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- kill_litter_super(SB);
-}
-
-/*++======================================================================*/
-ssize_t Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- ssize_t retval=0;
-
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(buf);
- UNUSED_VARIABLE(nbytes);
- UNUSED_VARIABLE(ppos);
-
- DbgPrint( "Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked());
-
- return retval;
-}
-
-/*++======================================================================*/
-ssize_t Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- ssize_t retval=0;
-
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(buf);
- UNUSED_VARIABLE(nbytes);
- UNUSED_VARIABLE(ppos);
-
- DbgPrint( "Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked());
- if (buf && nbytes)
- {
- }
-
- return(retval);
-}
-
-/*++======================================================================*/
-int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retval=0;
-
- UNUSED_VARIABLE(inode);
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(cmd);
- UNUSED_VARIABLE(arg);
-
- DbgPrint( "Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked());
-
- return(retval);
-}
-
-/*++======================================================================*/
-int __init init_novfs (void)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode;
-
-
- retCode = Init_Procfs_Interface();
-
- init_profile();
-
- if ( !retCode )
- {
- DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, NOVFS_VERSION_STRING);
- Init_Daemon_Queue();
- Scope_Init();
- retCode = register_filesystem(&Novfs_fs_type);
- if ( retCode )
- {
- Uninit_Procfs_Interface();
- Uninit_Daemon_Queue();
- Scope_Uninit();
- }
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-void __exit exit_novfs(void)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- printk( KERN_INFO "exit_novfs\n");
- Scope_Uninit();
- printk( KERN_INFO "exit_novfs after Scope_Uninit\n");
- Uninit_Daemon_Queue();
- printk( KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n");
- Uninit_Procfs_Interface();
- printk( KERN_INFO "exit_novfs Uninit_Procfs_Interface\n");
- unregister_filesystem(&Novfs_fs_type);
- printk( KERN_INFO "exit_novfs: Exit\n");
- if (Novfs_CurrentMount)
- {
- Novfs_Free(Novfs_CurrentMount);
- Novfs_CurrentMount = NULL;
- }
-}
-
-/*++======================================================================*/
-int Novfs_lock_inode_cache( struct inode *i )
-/*
- *
- * Arguments: struct inode *i - pointer to directory inode
- *
- * Returns: 0 - locked
- * -1 - not locked
- *
- * Abstract: Locks the inode cache.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- int retVal = 0;
-
- DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i);
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- down( &id->DirCacheLock );
- retVal = 1;
- }
- DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal);
- return( retVal );
-}
-
-/*++======================================================================*/
-void Novfs_unlock_inode_cache( struct inode *i )
-/*
- * Arguments: struct inode *i - pointer to directory inode
- *
- * Returns: nothing
- *
- * Abstract: Unlocks inode cache.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- up( &id->DirCacheLock );
- }
-}
-
-/*++======================================================================*/
-int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info)
-/*
- * Arguments: struct inode *i - pointer to directory inode
- *
- * Returns: 0 - item found
- * -1 - done
- *
- * Abstract: Unlocks inode cache.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *l=NULL;
- int retVal = -1;
-
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- if ( (NULL == iteration) || (NULL == *iteration) )
- {
- l = id->DirCache.next;
- }
- else
- {
- l = *iteration;
- }
-
- if (l == &id->DirCache)
- {
- l = NULL;
- }
- else
- {
- dc = list_entry(l, DIR_CACHE, list);
-
- *ino = dc->ino;
- info->type = 0;
- info->mode = dc->mode;
- info->size = dc->size;
- info->atime = dc->atime;
- info->mtime = dc->mtime;
- info->ctime = dc->ctime;
- info->namelength = dc->nameLen;
- memcpy(info->name, dc->name, dc->nameLen);
- info->name[dc->nameLen] = '\0';
- retVal = 0;
-
- l = l->next;
- }
- }
- *iteration = l;
- return( retVal );
-}
-
-/*++======================================================================*/
-int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- int retVal = -1;
- char *n="<NULL>";
- int nl=6;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- if (name && name->len)
- {
- n = (char *)name->name;
- nl = name->len;
- }
- DbgPrint("Novfs_get_entry:\n" \
- " inode: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n",
- i, nl, n, *ino);
-
- dc = Novfs_lookup_inode_cache(i, name, *ino);
- if (dc)
- {
- dc->flags |= ENTRY_VALID;
- retVal = 0;
- *ino = dc->ino;
- info->type = 0;
- info->mode = dc->mode;
- info->size = dc->size;
- info->atime = dc->atime;
- info->mtime = dc->mtime;
- info->ctime = dc->ctime;
- info->namelength = dc->nameLen;
- memcpy(info->name, dc->name, dc->nameLen);
- info->name[dc->nameLen] = '\0';
- retVal = 0;
- }
- }
- DbgPrint("Novfs_get_entry: return %d\n", retVal);
- return( retVal );
-}
-
-/*++======================================================================*/
-int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- int retVal = -1;
- char *n="<NULL>";
- int nl=6;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- if (name && name->len)
- {
- n = (char *)name->name;
- nl = name->len;
- }
- DbgPrint("Novfs_get_entry:\n" \
- " inode: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n",
- i, nl, n, *ino);
-
- dc = Novfs_lookup_inode_cache(i, name, *ino);
- if (dc)
- {
- retVal = 0;
- *ino = dc->ino;
- info->type = 0;
- info->mode = dc->mode;
- info->size = dc->size;
- info->atime = dc->atime;
- info->mtime = dc->mtime;
- info->ctime = dc->ctime;
- info->namelength = dc->nameLen;
- memcpy(info->name, dc->name, dc->nameLen);
- info->name[dc->nameLen] = '\0';
- if (EntryTime)
- {
- *EntryTime = dc->jiffies;
- }
- retVal = 0;
- }
- }
- DbgPrint("Novfs_get_entry: return %d\n", retVal);
- return( retVal );
-}
-
-/*++======================================================================*/
-int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: This routine will return the first entry on the list
- * and then remove it.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *l=NULL;
- int retVal = -1;
-
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- l = id->DirCache.next;
-
- if (l != &id->DirCache)
- {
- dc = list_entry(l, DIR_CACHE, list);
-
- *ino = dc->ino;
- info->type = 0;
- info->mode = dc->mode;
- info->size = dc->size;
- info->atime = dc->atime;
- info->mtime = dc->mtime;
- info->ctime = dc->ctime;
- info->namelength = dc->nameLen;
- memcpy(info->name, dc->name, dc->nameLen);
- info->name[dc->nameLen] = '\0';
- retVal = 0;
-
- list_del( &dc->list );
- Novfs_Free( dc );
- DCCount--;
-
- }
- }
- return( retVal );
-}
-
-/*++======================================================================*/
-void Novfs_invalidate_inode_cache( struct inode *i )
-/*
- * Arguments: struct inode *i - pointer to directory inode
- *
- * Returns: nothing
- *
- * Abstract: Marks all entries in the directory cache as invalid.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *l;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- list_for_each(l, &id->DirCache)
- {
- dc = list_entry(l, DIR_CACHE, list);
- dc->flags &= ~ENTRY_VALID;
- }
- }
-}
-
-/*++======================================================================*/
-PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino )
-/*
- * Arguments: struct inode *i - pointer to directory inode
- * struct qstr *name - pointer to name
- * ino_t - inode number
- *
- * Returns: DIR_CACHE entry if match
- * NULL - if there is no match.
- *
- * Abstract: Checks a inode directory to see if there are any enties
- * matching name or ino. If name is specified then ino is
- * not used. ino is use if name is not specified.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc, retVal=NULL;
- struct list_head *l;
- char *n="<NULL>";
- int nl=6;
- int hash=0;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- if (name && name->name)
- {
- nl = name->len;
- n = (char *)name->name;
- hash = name->hash;
- }
- DbgPrint("Novfs_lookup_inode_cache:\n" \
- " inode: 0x%p\n" \
- " name: %.*s\n" \
- " hash: 0x%x\n" \
- " len: %d\n" \
- " ino: %d\n",
- i, nl, n, hash, nl, ino);
-
- list_for_each(l, &id->DirCache)
- {
- dc = list_entry(l, DIR_CACHE, list);
- if (name)
- {
-
-/* DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \
- " ino: %d\n" \
- " hash: 0x%x\n" \
- " len: %d\n" \
- " name: %.*s\n",
- dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name);
-*/
- if ( (name->hash == dc->hash) &&
- (name->len == dc->nameLen) &&
- (0 == memcmp(name->name, dc->name, name->len)) )
- {
- retVal = dc;
- break;
- }
- }
- else
- {
- if (ino == dc->ino)
- {
- retVal = dc;
- break;
- }
- }
- }
- }
-
- DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal);
- return( retVal );
-}
-
-/*++======================================================================*/
-int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino )
-/*
- * Arguments: struct inode *i - pointer to directory inode
- * struct qstr *name - pointer to name
- * ino_t - inode number
- *
- * Returns: 0 if found
- * !0 if not found
- *
- * Abstract: Checks a inode directory to see if there are any enties
- * matching name or ino. If entry is found the valid bit
- * is set.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- int retVal = -1;
- char *n="<NULL>";
- int nl=6;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- if (name && name->len)
- {
- n = (char *)name->name;
- nl = name->len;
- }
- DbgPrint("Novfs_update_entry:\n" \
- " inode: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n",
- i, nl, n, ino);
-
- dc = Novfs_lookup_inode_cache( i, name, ino );
- if (dc)
- {
- dc->flags |= ENTRY_VALID;
- retVal = 0;
- }
- }
- return( retVal );
-}
-
-/*++======================================================================*/
-int Novfs_add_inode_entry(
- struct inode *i,
- struct qstr *name,
- ino_t ino,
- PENTRY_INFO info)
-/*
- * Arguments:
- *
- * Returns: -ENOMEM - alloc error.
- * 0 - success.
- *
- * Abstract: Added entry to directory cache.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE new;
- int retVal = -ENOMEM;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL);
- if (new)
- {
- DCCount++;
- DbgPrint("Novfs_add_inode_entry:\n" \
- " inode: 0x%p\n" \
- " id: 0x%p\n" \
- " DC: 0x%p\n" \
- " new: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n" \
- " size: %lld\n" \
- " mode: 0x%x\n",
- i, id, &id->DirCache, new, name->len, name->name, ino, info->size, info->mode);
-
- retVal = 0;
- new->flags = ENTRY_VALID;
- new->jiffies = get_jiffies_64();
- new->size = info->size;
- new->mode = info->mode;
- new->atime = info->atime;
- new->mtime = info->mtime;
- new->ctime = info->ctime;
- new->ino = ino;
- new->hash = name->hash;
- new->nameLen = name->len;
- memcpy(new->name, name->name, name->len);
- new->name[new->nameLen] = '\0';
- list_add(&new->list, &id->DirCache);
-
-/* list_for_each(l, &id->DirCache)
- {
- dc = list_entry(l, DIR_CACHE, list);
- if ( dc->hash > new->hash )
- {
- break;
- }
- }
-
- DbgPrint("Novfs_add_inode_entry: adding 0x%p to 0x%p\n", new, l);
- list_add(&new->list, l);
-*/
- }
- }
- return( retVal );
-}
-
-/*++======================================================================*/
-int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- int retVal = -1;
- char *n="<NULL>";
- int nl=6;
- char atime_buf[32];
- char mtime_buf[32];
- char ctime_buf[32];
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
-
- if (name && name->len)
- {
- n = (char *)name->name;
- nl = name->len;
- }
- ctime_r(&info->atime.tv_sec, atime_buf);
- ctime_r(&info->mtime.tv_sec, mtime_buf);
- ctime_r(&info->ctime.tv_sec, ctime_buf);
- DbgPrint("Novfs_update_entry:\n" \
- " inode: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n" \
- " size: %lld\n" \
- " atime: %s\n" \
- " mtime: %s\n" \
- " ctime: %s\n",
- i, nl, n, ino, info->size, atime_buf, mtime_buf, ctime_buf);
-
-
- dc = Novfs_lookup_inode_cache(i, name, ino);
- if (dc)
- {
- retVal = 0;
- dc->flags = ENTRY_VALID;
- dc->jiffies = get_jiffies_64();
- dc->size = info->size;
- dc->mode = info->mode;
- dc->atime = info->atime;
- dc->mtime = info->mtime;
- dc->ctime = info->ctime;
-
- ctime_r(&dc->atime.tv_sec, atime_buf);
- ctime_r(&dc->mtime.tv_sec, mtime_buf);
- ctime_r(&dc->ctime.tv_sec, ctime_buf);
- DbgPrint("Novfs_update_entry entry: 0x%x\n" \
- " flags: 0x%x\n" \
- " jiffies: %lld\n" \
- " ino: %d\n" \
- " size: %lld\n" \
- " mode: 0%o\n" \
- " atime: %s\n" \
- " mtime: %s\n" \
- " ctime: %s\n" \
- " hash: 0x%x\n" \
- " nameLen: %d\n" \
- " name: %s\n",
- dc, dc->flags, dc->jiffies, dc->ino, dc->size, dc->mode,
- atime_buf, mtime_buf, ctime_buf, dc->hash, dc->nameLen, dc->name);
- }
- }
- DbgPrint("Novfs_update_entry: return %d\n", retVal);
- return( retVal );
-}
-
-/*++======================================================================*/
-void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino)
-/*
- * Arguments:
- *
- * Returns: nothing
- *
- * Abstract: Removes entry from directory cache. You can specify a name
- * or an inode number.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- char *n="<NULL>";
- int nl=6;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- dc = Novfs_lookup_inode_cache( i, name, ino );
- if (dc)
- {
- if (name && name->name)
- {
- nl = name->len;
- n = (char *)name->name;
- }
- DbgPrint("Novfs_remove_inode_entry:\n" \
- " inode: 0x%p\n" \
- " id: 0x%p\n" \
- " DC: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n" \
- " entry: 0x%p\n" \
- " name: %.*s\n"\
- " ino: %d\n" \
- " next: 0x%p\n" \
- " prev: 0x%p\n",
- i, id, &id->DirCache, nl, n, ino, dc, dc->nameLen, dc->name, dc->ino, dc->list.next, dc->list.prev);
- list_del( &dc->list );
- Novfs_Free( dc );
- DCCount--;
-
- }
- }
-}
-
-/*++======================================================================*/
-void Novfs_free_invalid_entries( struct inode *i )
-/*
- * Arguments: struct inode *i - pointer to directory inode.
- *
- * Returns: nothing
- *
- * Abstract: Frees all invalid entries in the directory cache.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *l;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- list_for_each( l, &id->DirCache )
- {
- dc = list_entry( l, DIR_CACHE, list );
- if ( 0 == (dc->flags & ENTRY_VALID) )
- {
- DbgPrint("Novfs_free_invalid_entries:\n" \
- " inode: 0x%p\n" \
- " id: 0x%p\n" \
- " entry: 0x%p\n" \
- " name: %.*s\n" \
- " ino: %d\n",
- i, id, dc, dc->nameLen, dc->name, dc->ino);
- l = l->prev;
- list_del( &dc->list );
- Novfs_Free( dc );
- DCCount--;
- }
- }
- }
-}
-
-/*++======================================================================*/
-void Novfs_free_inode_cache( struct inode *i )
-/*
- * Arguments: struct inode *i - pointer to directory inode.
- *
- * Returns: nothing
- *
- * Abstract: Frees all entries in the inode cache.
- *
- * Notes: DirCacheLock should be held before calling this routine.
- *
- * Environment:
- *
- *========================================================================*/
-{
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *l;
-
- if ( i && (id = i->u.generic_ip) && id->DirCache.next )
- {
- list_for_each( l, &id->DirCache )
- {
- dc = list_entry( l, DIR_CACHE, list );
- l = l->prev;
- list_del( &dc->list );
- Novfs_Free( dc );
- DCCount--;
- }
- }
-}
-
-/*++======================================================================*/
-int
-NO_TRACE
-Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-#ifdef CONFIG_KDB
- struct inode *inode=NULL;
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *l;
- char atime_buf[32];
- char mtime_buf[32];
- char ctime_buf[32];
-
- if (Novfs_root)
- {
- inode = Novfs_root->d_inode;
- }
-
- if (argc > 0)
- {
- inode = (void *)simple_strtoul(argv[1], NULL, 0);
- }
-
- kdb_printf("Inode: 0x%p\n", inode);
- if (inode)
- {
- id = inode->u.generic_ip;
- kdb_printf("INODE_DATA: 0x%p\n", id);
-
- if ( id && id->DirCache.next )
- {
- list_for_each(l, &id->DirCache)
- {
- dc = list_entry(l, DIR_CACHE, list);
- ctime_r(&dc->atime.tv_sec, atime_buf);
- ctime_r(&dc->mtime.tv_sec, mtime_buf);
- ctime_r(&dc->ctime.tv_sec, ctime_buf);
-
- DbgPrint("Cache Entry: 0x%p\n" \
- " flags: 0x%x\n" \
- " jiffies: %llu\n" \
- " ino: %u\n" \
- " size: %llu\n" \
- " mode: 0%o\n" \
- " atime: %s\n" \
- " mtime: %s\n" \
- " ctime: %s\n" \
- " hash: 0x%x\n" \
- " len: %d\n" \
- " name: %s\n",
- dc, dc->flags, dc->jiffies,
- dc->ino, dc->size, dc->mode,
- atime_buf, mtime_buf, ctime_buf,
- dc->hash, dc->nameLen, dc->name);
- }
- }
- }
-#endif
- return(0);
-}
-
-/*++======================================================================*/
-void
-NO_TRACE
-Novfs_dump_inode( void *pf )
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- struct inode *inode;
- void (*pfunc)(char *Fmt, ...) = pf;
- PINODE_DATA id;
- PDIR_CACHE dc;
- struct list_head *il, *l;
- char atime_buf[32];
- char mtime_buf[32];
- char ctime_buf[32];
- unsigned long icnt=0, dccnt=0;
-
- down( &InodeList_lock );
- list_for_each(il, &InodeList)
- {
- id = list_entry(il, INODE_DATA, IList);
- inode = id->Inode;
- if (inode)
- {
- icnt++;
-
- pfunc("Inode=0x%x I_ino=%d\n", inode, inode->i_ino);
-
- pfunc(" atime=%s\n", ctime_r(&inode->i_atime.tv_sec, atime_buf));
- pfunc(" ctime=%s\n", ctime_r(&inode->i_mtime.tv_sec, atime_buf));
- pfunc(" mtime=%s\n", ctime_r(&inode->i_ctime.tv_sec, atime_buf));
- pfunc(" size=%lld\n", inode->i_size);
- pfunc(" mode=0%o\n", inode->i_mode);
- }
-
- pfunc(" INODE_DATA: 0x%p Name=%s Scope=0x%p\n", id, id->Name, id->Scope);
-
- if (id->DirCache.next )
- {
- list_for_each(l, &id->DirCache)
- {
- dccnt++;
- dc = list_entry(l, DIR_CACHE, list);
- ctime_r(&dc->atime.tv_sec, atime_buf);
- ctime_r(&dc->mtime.tv_sec, mtime_buf);
- ctime_r(&dc->ctime.tv_sec, ctime_buf);
-
- pfunc(" Cache Entry: 0x%p\n" \
- " flags: 0x%x\n" \
- " jiffies: %llu\n" \
- " ino: %u\n" \
- " size: %llu\n" \
- " mode: 0%o\n" \
- " atime: %s\n" \
- " mtime: %s\n" \
- " ctime: %s\n" \
- " hash: 0x%x\n" \
- " len: %d\n" \
- " name: %s\n",
- dc, dc->flags, dc->jiffies,
- dc->ino, dc->size, dc->mode,
- atime_buf, mtime_buf, ctime_buf,
- dc->hash, dc->nameLen, dc->name);
- }
- }
- }
- up( &InodeList_lock );
-
- pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, dccnt );
-
-}
-
-module_init(init_novfs)
-module_exit(exit_novfs)
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Novell Inc.");
-MODULE_DESCRIPTION("Novell NetWare Client for Linux");
-MODULE_VERSION( NOVFS_VERSION_STRING );
diff -uNr src.old/novfs/m src/novfs/m
--- src.old/novfs/m 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/m 1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-VERSION=`uname -r`
-
-make -C /usr/src/linux SUBDIRS=$PWD modules
-
-if [ -e novfs.ko ]
-then
- mkdir -p -m 755 /lib/modules/$VERSION/kernel/fs/novfs
- echo "copying novfs.ko to /lib/modules/$VERSION/kernel/fs/novfs"
- cp novfs.ko /lib/modules/$VERSION/kernel/fs/novfs
-fi
diff -uNr src.old/novfs/mk_novfs src/novfs/mk_novfs
--- src.old/novfs/mk_novfs 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/mk_novfs 1970-01-01 01:00:00.000000000 +0100
@@ -1,113 +0,0 @@
-#!/bin/sh
-
-RVAL=1
-TO_BUILD=1
-
-BUILD_TYPE=modules
-
-if [ $1 ]
-then
- if [ "$1" = "force" ]
- then
- FORCE=1
- else
- BUILD_TYPE=$1
- FORCE=0
- fi
-else
- FORCE=0
-fi
-
-
-if [ -d /usr/src/linux-obj/i386 ]
-then
- for i in $(ls /usr/src/linux-obj/i386)
- do
- TO_BUILD=1
- VERSION=`cat /usr/src/linux-obj/i386/$i/include/linux/version.h |grep UTS_RELEASE |awk '{printf("%s\n", substr($3, 2,length($3)-2))}'`
- NOVFS_PATH=/lib/modules/$VERSION/kernel/fs/novfs
-
- if [ -e /lib/modules/$VERSION/extra/novfs.ko ]
- then
- NOVFS_PATH=/lib/modules/$VERSION/extra
-
- else
- if [ -e /lib/modules/$VERSION/updates/novfs.ko ]
- then
- NOVFS_PATH=/lib/modules/$VERSION/updates
-
- fi
- fi
-
- if [ -d /lib/modules/$VERSION ]
- then
-
- if [ -e $NOVFS_PATH/novfs.ko ]
- then
- CUR_NOVFS_VERSION=`od --strings=8 $NOVFS_PATH/novfs.ko |grep version= |awk '{split($2,a,"="); if("version"==a[1]) printf("%s", a[2])}'`
- CUR_NOVFS_VFS_MAJOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[1])}'`
- CUR_NOVFS_VFS_MINOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[2])}'`
- CUR_NOVFS_VFS_SUB=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[3])}'`
- CUR_NOVFS_VFS_RELEASE=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"-"); printf("%d", a[2])}'`
-
- NOVFS_VFS_MAJOR=`cat Makefile |grep 'NOVFS_VFS_MAJOR =' |awk '{printf("%d", $3)}'`
- NOVFS_VFS_MINOR=`cat Makefile |grep 'NOVFS_VFS_MINOR =' |awk '{printf("%d", $3)}'`
- NOVFS_VFS_SUB=`cat Makefile |grep 'NOVFS_VFS_SUB =' |awk '{printf("%d", $3)}'`
- NOVFS_VFS_RELEASE=`cat Makefile |grep 'NOVFS_VFS_RELEASE =' |awk '{printf("%d", $3)}'`
- NOVFS_VFS_VERSION="$NOVFS_VFS_MAJOR.$NOVFS_VFS_MINOR.$NOVFS_VFS_SUB-$NOVFS_VFS_RELEASE"
-
- TO_BUILD=0
-
- if [ $NOVFS_VFS_MAJOR -gt $CUR_NOVFS_VFS_MAJOR ]
- then
- TO_BUILD=1
- else
- if [ $NOVFS_VFS_MAJOR -eq $CUR_NOVFS_VFS_MAJOR ]
- then
- if [ $NOVFS_VFS_MINOR -gt $CUR_NOVFS_VFS_MINOR ]
- then
- TO_BUILD=1
- else
- if [ $NOVFS_VFS_MINOR -eq $CUR_NOVFS_VFS_MINOR ]
- then
- if [ $NOVFS_VFS_SUB -gt $CUR_NOVFS_VFS_SUB ]
- then
- TO_BUILD=1
- else
- if [ $NOVFS_VFS_SUB -eq $CUR_NOVFS_VFS_SUB ]
- then
- if [ $NOVFS_VFS_RELEASE -gt $CUR_NOVFS_VFS_RELEASE ]
- then
- TO_BUILD=1
- fi
- fi
- fi
- fi
- fi
- fi
- fi
- fi
-
- if [ $FORCE -eq 1 ]
- then
- TO_BUILD=1;
- fi
-
- if [ $TO_BUILD -eq 1 ]
- then
- echo Building novfs.ko for $VERSION
- make -C /usr/src/linux-obj/i386/$i SUBDIRS=$PWD $BUILD_TYPE
- RVAL=$?
- if [ -e novfs.ko ]
- then
- mkdir -p -m 755 $NOVFS_PATH
- echo "copying novfs.ko to $NOVFS_PATH"
- cp novfs.ko $NOVFS_PATH
- RVAL=$?
- fi
- fi
- fi
- done
-fi
-exit $RVAL
-
diff -uNr src.old/novfs/nwcapi.c src/novfs/nwcapi.c
--- src.old/novfs/nwcapi.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/nwcapi.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,2410 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: nwcapi.c
- * Version: v1.00
- * Author: James Turner/Richard Williams
- *
- * Abstract: This module contains functions used to interface to
- * the library interface of the daemon.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-
-/*===[ Include files specific to this module ]============================*/
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/poll.h>
-#include <asm/semaphore.h>
-#include <asm/uaccess.h>
-
-#include "nwcapi.h"
-#include "nwerror.h"
-#include "commands.h"
-
-#include "vfs.h"
-
-/*===[ External data ]====================================================*/
-
-/*===[ External prototypes ]==============================================*/
-
-extern int DbgPrint( char *Fmt, ... );
-extern void mydump(int size, void *dumpptr);
-
-extern session_t Scope_Get_SessionId( void *Scope );
-extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
-
-extern int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
-
-void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
-void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
-
-/*===[ Manifest constants ]===============================================*/
-
-/*===[ Type definitions ]=================================================*/
-
-/*===[ Function prototypes ]==============================================*/
-
-/*===[ Global variables ]=================================================*/
-
-/*===[ Code ]=============================================================*/
-
-/*++======================================================================*/
-
-/*++======================================================================*/
-int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCOpenConnByName openConn, connReply;
-NwcOpenConnByName ocbn;
-u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
-char *data;
-
- cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn));
- datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME;
-
- cmd->dataLen = datalen;
- openConn = (PNwdCOpenConnByName)cmd->data;
-
- openConn->nameLen = strlen_user(ocbn.pName->pString);
- openConn->serviceLen = strlen_user(ocbn.pServiceType);
- openConn->uConnFlags = ocbn.uConnFlags;
- openConn->ConnHandle = ocbn.ConnHandle;
- data = (char *)openConn;
- data += sizeof(*openConn);
- openConn->oName = sizeof(*openConn);
-
- openConn->oServiceType = openConn->oName + openConn->nameLen;
- cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen);
- data += openConn->nameLen;
- cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- /*
- * we got reply data from the daemon
- */
- connReply = (PNwdCOpenConnByName)reply->data;
- retCode = reply->Reply.ErrorCode;
- if (!retCode)
- {
- /*
- * we got valid data.
- */
- connReply = (PNwdCOpenConnByName)reply->data;
- ocbn.RetConnHandle = connReply->newConnHandle;
- *Handle = connReply->newConnHandle;
- cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn));
- DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle);
- }
- Novfs_Free(reply);
- }
-
- Novfs_Free(cmd);
- }
-
- return((int)retCode);
-
-}
-
-/*++======================================================================*/
-int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCOpenConnByAddr openConn, connReply;
-NwcOpenConnByAddr ocba;
-NwcTranAddr tranAddr;
-u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
-char addr[MAX_ADDRESS_LENGTH];
-
- cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba));
- datalen = sizeof(*openConn);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_OPEN_CONN_BY_ADDRESS;
- cmd->dataLen = datalen;
- openConn = (PNwdCOpenConnByAddr)cmd->data;
-
- cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr));
-
- DbgPrint("NwOpenConnByAddr: tranAddr\n");
- mydump(sizeof(tranAddr), &tranAddr);
-
- openConn->TranAddr.uTransportType = tranAddr.uTransportType;
- openConn->TranAddr.uAddressLength = tranAddr.uAddressLength;
- memset(addr, 0xcc, sizeof(addr)-1);
-
- cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength);
-
- DbgPrint("NwOpenConnByAddr: addr\n");
- mydump(sizeof(addr), addr);
-
- openConn->TranAddr.oAddress = *(u_long *)(&addr[2]);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- /*
- * we got reply data from the daemon
- */
- connReply = (PNwdCOpenConnByAddr)reply->data;
- retCode = reply->Reply.ErrorCode;
- if (!retCode)
- {
- /*
- * we got valid data.
- */
- connReply = (PNwdCOpenConnByAddr)reply->data;
- ocba.ConnHandle = connReply->ConnHandle;
- *Handle = connReply->ConnHandle;
- cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba));
- DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle);
- }
- Novfs_Free(reply);
- }
-
- Novfs_Free(cmd);
- }
-
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCOpenConnByRef openConn;
-NwcOpenConnByReference ocbr;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
-
- cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr));
- datalen = sizeof(*openConn);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_OPEN_CONN_BY_REFERENCE;
- cmd->dataLen = datalen;
- openConn = (PNwdCOpenConnByRef)cmd->data;
-
- memcpy(openConn, &ocbr, sizeof(ocbr));
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- /*
- * we got reply data from the daemon
- */
- openConn = (PNwdCOpenConnByRef)reply->data;
- retCode = reply->Reply.ErrorCode;
- if (!retCode)
- {
- /*
- * we got valid data.
- */
- ocbr.ConnHandle = openConn->ConnHandle;
- *Handle = openConn->ConnHandle;
-
- cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr));
- DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle);
- }
- Novfs_Free(reply);
- }
-
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwRawSend(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-NwcRequest xRequest;
-PNwcFrag frag, cFrag, reqFrag;
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-u_long x, totalLen;
-PNwdCNCPReq ncpData;
-PNwdCNCPRep ncpReply;
-u_char *reqData;
-unsigned long actualReplyLength=0;
-
- DbgPrint("[XPLAT] Process Raw NCP Send\n");
- cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
-
- /*
- * Figure out the length of the request
- */
- frag = Novfs_Malloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL);
-
- DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
-
- if (!frag)
- return(retCode);
-
- cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag));
- totalLen = 0;
-
- cFrag = frag;
- for (x = 0; x < xRequest.uNumReplyFrags; x ++)
- {
- DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength);
- totalLen += cFrag->uLength;
- cFrag++;
- }
-
-
- DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen);
- datalen = 0;
- reqFrag = Novfs_Malloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL);
- if (!reqFrag)
- {
- Novfs_Free(frag);
- return(retCode);
- }
-
- cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag));
- cFrag = reqFrag;
- for (x = 0; x < xRequest.uNumRequestFrags; x ++)
- {
- datalen += cFrag->uLength;
- cFrag++;
- }
-
- /*
- * Allocate the cmd Request
- */
- cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData);
- DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags);
- DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen);
-
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_RAW_NCP_REQUEST;
-
- /*
- * build the NCP Request
- */
- cmd->dataLen = cmdlen - sizeof(*cmd);
- ncpData = (PNwdCNCPReq)cmd->data;
- ncpData->replyLen = totalLen;
- ncpData->requestLen = datalen;
- ncpData->ConnHandle = xRequest.ConnHandle;
- ncpData->function = xRequest.uFunction;
-
-
- reqData = ncpData->data;
- cFrag = reqFrag;
-
- for (x = 0; x < xRequest.uNumRequestFrags; x ++)
- {
- cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength);
- reqData += cFrag->uLength;
- cFrag++;
- }
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- DbgPrint("RawNCP - reply = %x\n", reply);
- DbgPrint("RawNCP - retCode = %x\n", retCode);
-
- if (reply)
- {
- /*
- * we got reply data from the daemon
- */
- ncpReply = (PNwdCNCPRep)reply->data;
- retCode = reply->Reply.ErrorCode;
-
- DbgPrint("RawNCP - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
-
- /*
- * We need to copy the reply frags to the packet.
- */
- reqData = ncpReply->data;
- cFrag = frag;
-
- totalLen = ncpReply->replyLen;
- for (x = 0; x < xRequest.uNumReplyFrags; x ++)
- {
-
- DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, cFrag->uLength);
-
- datalen = min(cFrag->uLength, totalLen);
-
- cpylen = copy_to_user(cFrag->pData, reqData, datalen);
- totalLen -= datalen;
- reqData += datalen;
- actualReplyLength += datalen;
-
- cFrag++;
- }
-
- Novfs_Free(reply);
- }
- else
- {
- retCode = -EIO;
- }
-
- Novfs_Free(cmd);
- }
- xRequest.uActualReplyLength = actualReplyLength;
- cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
-
- Novfs_Free(reqFrag);
- Novfs_Free(frag);
-
- return(retCode);
-}
-
-/*++======================================================================*/
-int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcCloseConn cc;
-PNwdCCloseConn nwdClose;
-u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
-
- datalen = sizeof(*nwdClose);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_CLOSE_CONN;
-
- nwdClose = (PNwdCCloseConn)cmd->data;
- cmd->dataLen = sizeof(*nwdClose);
- nwdClose->ConnHandle = cc.ConnHandle;
- *Handle = cc.ConnHandle;
-
- /*
- * send the request
- */
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
-
- }
-
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcCloseConn cc;
-PNwdCCloseConn nwdClose;
-u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
-
- datalen = sizeof(*nwdClose);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SYS_CLOSE_CONN;
-
- nwdClose = (PNwdCCloseConn)cmd->data;
- cmd->dataLen = sizeof(*nwdClose);
- nwdClose->ConnHandle = cc.ConnHandle;
- *Handle = cc.ConnHandle;
-
- /*
- * send the request
- */
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
-
- }
-
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwLoginIdentity(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-NwcLoginIdentity lgn, *plgn;
-int retCode = -ENOMEM;
-NclString server;
-NclString username;
-NclString password;
-u_long cpylen;
-NwcString nwcStr;
-
- cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn));
-
- DbgPrint("NwLoginIdentity:\n");
- mydump(sizeof(lgn), &lgn);
-
-
-
- cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr));
- DbgPrint("NwLoginIdentity: DomainName\n");
- mydump(sizeof(nwcStr), &nwcStr);
-
- if ( (server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
- {
- server.type = nwcStr.DataType;
- server.len = nwcStr.DataLen;
- if ( !copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len) )
- {
- DbgPrint("NwLoginIdentity: Server\n");
- mydump(server.len, server.buffer);
-
- cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
- DbgPrint("NwLoginIdentity: ObjectName\n");
- mydump(sizeof(nwcStr), &nwcStr);
-
- if ( (username.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
- {
- username.type = nwcStr.DataType;
- username.len = nwcStr.DataLen;
- if ( !copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len) )
- {
- DbgPrint("NwLoginIdentity: User\n");
- mydump(username.len, username.buffer);
-
- cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr));
- DbgPrint("NwLoginIdentity: Password\n");
- mydump(sizeof(nwcStr), &nwcStr);
-
- if ( (password.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
- {
- password.type = nwcStr.DataType;
- password.len = nwcStr.DataLen;
- if ( !copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len) )
- {
- retCode = do_login(&server, &username, &password, (u_long *)&lgn.AuthenticationId, Session);
- if (retCode)
- {
- lgn.AuthenticationId = 0;
- }
-
- plgn = (NwcLoginIdentity *)pdata->reqData;
- cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId));
-
- }
- memset(password.buffer, 0, password.len);
- Novfs_Free(password.buffer);
- }
- }
- memset(username.buffer, 0, username.len);
- Novfs_Free(username.buffer);
- }
- }
- Novfs_Free(server.buffer);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int NwAuthConnWithId(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-NwcAuthenticateWithId pauth;
-PNwdCAuthenticateWithId pDauth;
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- datalen = sizeof(*pDauth);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID;
-
-
- cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth));
-
- pDauth = (PNwdCAuthenticateWithId)cmd->data;
- cmd->dataLen = datalen;
- pDauth->AuthenticationId = pauth.AuthenticationId;
- pDauth->ConnHandle = pauth.ConnHandle;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int NwLicenseConn(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcLicenseConn lisc;
-PNwdCLicenseConn pDLisc;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- datalen = sizeof(*pDLisc);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_LICENSE_CONN;
-
-
- cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc));
-
- pDLisc = (PNwdCLicenseConn)cmd->data;
- cmd->dataLen = datalen;
- pDLisc->ConnHandle = lisc.ConnHandle;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-}
-
-
-/*++======================================================================*/
-int NwLogoutIdentity(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcLogoutIdentity logout;
-PNwdCLogoutIdentity pDLogout;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- datalen = sizeof(*pDLogout);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_LOGOUT_IDENTITY;
-
- cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout));
-
- pDLogout = (PNwdCLogoutIdentity)cmd->data;
- cmd->dataLen = datalen;
- pDLogout->AuthenticationId = logout.AuthenticationId;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-int NwUnlicenseConn(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCUnlicenseConn pUconn;
-NwcUnlicenseConn ulc;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
-
- cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc));
- datalen = sizeof(*pUconn);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_UNLICENSE_CONN;
- cmd->dataLen = datalen;
- pUconn = (PNwdCUnlicenseConn)cmd->data;
-
- pUconn->ConnHandle = ulc.ConnHandle;
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- /*
- * we got reply data from the daemon
- */
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
-
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-
-/*++======================================================================*/
-int NwUnAuthenticate(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcUnauthenticate auth;
-PNwdCUnauthenticate pDAuth;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- datalen = sizeof(*pDAuth);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN;
-
- cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth));
-
- pDAuth = (PNwdCUnauthenticate)cmd->data;
- cmd->dataLen = datalen;
- pDAuth->AuthenticationId = auth.AuthenticationId;
- pDAuth->ConnHandle = auth.ConnHandle;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-
-/*++======================================================================*/
-int NwGetConnInfo(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcGetConnInfo connInfo;
-PNwdCGetConnInfo pDConnInfo;
-u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
-
- cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo));
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_GET_CONN_INFO;
-
- pDConnInfo = (PNwdCGetConnInfo)cmd->data;
-
- pDConnInfo->ConnHandle = connInfo.ConnHandle;
- pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
- pDConnInfo->uInfoLength = connInfo.uInfoLength;
- cmd->dataLen = sizeof(*pDConnInfo);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- GetConnData(&connInfo, cmd, reply);
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
-
- }
-
- return(retCode);
-
-}
-
-
-/*++======================================================================*/
-int NwSetConnInfo(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcSetConnInfo connInfo;
-PNwdCSetConnInfo pDConnInfo;
-u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
-
- cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo));
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SET_CONN_INFO;
-
- pDConnInfo = (PNwdCSetConnInfo)cmd->data;
-
- pDConnInfo->ConnHandle = connInfo.ConnHandle;
- pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
- pDConnInfo->uInfoLength = connInfo.uInfoLength;
- cmd->dataLen = sizeof(*pDConnInfo);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
-
- }
-
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwGetIdentityInfo(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcGetIdentityInfo qidInfo, *gId;
-PNwdCGetIdentityInfo idInfo;
-NwcString xferStr;
-char *str;
-u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
-
- cmdlen = sizeof(*cmd) + sizeof(*idInfo);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo));
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_GET_IDENTITY_INFO;
-
- idInfo = (PNwdCGetIdentityInfo)cmd->data;
-
- idInfo->AuthenticationId = qidInfo.AuthenticationId;
- cmd->dataLen = sizeof(*idInfo);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
-
- if (!reply->Reply.ErrorCode)
- {
- /*
- * Save the return info to the user structure.
- */
- gId = pdata->reqData;
- idInfo = (PNwdCGetIdentityInfo)reply->data;
- cpylen = copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId));
- cpylen = copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType));
- cpylen = copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags));
- cpylen = copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType));
- cpylen = copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType));
-
- cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(NwcString));
- str = (char *)((char *)reply->data + idInfo->pDomainNameOffset);
- cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen);
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
- xferStr.DataLen = idInfo->domainLen;
- cpylen = copy_to_user(gId->pDomainName, &xferStr, sizeof(NwcString));
-
-
- cpylen = copy_from_user(&xferStr, gId->pObjectName, sizeof(NwcString));
- str = (char *)((char *)reply->data + idInfo->pObjectNameOffset);
- cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen);
- xferStr.DataLen = idInfo->objectLen - 1;
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
- cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(NwcString));
- }
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
-
- }
-
- return(retCode);
-}
-
-/*++======================================================================*/
-int NwScanConnInfo(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcScanConnInfo connInfo, *rInfo;
-PNwdCScanConnInfo pDConnInfo;
-u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
-u_char *localData;
-
- cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo));
-
- cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SCAN_CONN_INFO;
-
- pDConnInfo = (PNwdCScanConnInfo)cmd->data;
-
- DbgPrint("NwScanConnInfo: Input Data\n");
- DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex);
- DbgPrint("connInfo.uConnectionReference = 0x%X\n", connInfo.uConnectionReference);
- DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", connInfo.uScanInfoLevel);
- DbgPrint("connInfo.uScanInfoLen = 0x%X\n", connInfo.uScanInfoLen);
- DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", connInfo.uReturnInfoLength);
- DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", connInfo.uReturnInfoLevel);
- DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags);
-
-
- pDConnInfo->uScanIndex = connInfo.uScanIndex;
- pDConnInfo->uConnectionReference = connInfo.uConnectionReference;
- pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel;
- pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen;
- pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength;
- pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel;
- pDConnInfo->uScanFlags = connInfo.uScanFlags;
-
- if (pDConnInfo->uScanInfoLen)
- {
- localData = (u_char *)pDConnInfo;
- pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo);
- localData += pDConnInfo->uScanConnInfoOffset;
- cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen);
- }
- else
- {
- pDConnInfo->uScanConnInfoOffset = 0;
- }
-
-
- cmd->dataLen = sizeof(*pDConnInfo);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- DbgPrint("NwScanConnInfo: Reply recieved\n");
- DbgPrint(" NextIndex = %x\n", connInfo.uScanIndex);
- DbgPrint(" ErrorCode = %x\n", reply->Reply.ErrorCode);
- DbgPrint(" data = %x\n", reply->data);
-
- pDConnInfo = (PNwdCScanConnInfo)reply->data;
- retCode = (u_long)reply->Reply.ErrorCode;
- if (!retCode)
- {
- GetUserData(&connInfo, cmd, reply);
- rInfo = (NwcScanConnInfo *)pdata->repData;
- cpylen = copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex));
- cpylen = copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference));
- }
- else
- {
- u_long x;
-
- x = 0;
- rInfo = (NwcScanConnInfo *)pdata->reqData;
- cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference));
- }
-
- Novfs_Free(reply);
- }
- else
- {
- retCode = -EIO;
- }
- Novfs_Free(cmd);
-
- }
-
- return(retCode);
-}
-
-/*++======================================================================*/
-void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
-/*
- * Abstract: Copies the user data out of the scan conn info call.
- *
- *========================================================================*/
-
-{
-u_long uLevel;
-PNwdCScanConnInfo pDConnInfo;
-
-u_char *srcData = NULL;
-u_long dataLen = 0, cpylen;
-
-
- pDConnInfo = (PNwdCScanConnInfo)reply->data;
- uLevel = pDConnInfo->uReturnInfoLevel;
- DbgPrint("[GetUserData] uLevel = %d, reply = 0x%X, reply->data = 0x%X\n", uLevel, reply, reply->data);
-
- switch(uLevel)
- {
- case NWC_CONN_INFO_RETURN_ALL:
- case NWC_CONN_INFO_TRAN_ADDR:
- case NWC_CONN_INFO_NDS_STATE:
- case NWC_CONN_INFO_MAX_PACKET_SIZE:
- case NWC_CONN_INFO_LICENSE_STATE:
- case NWC_CONN_INFO_PUBLIC_STATE:
- case NWC_CONN_INFO_SERVICE_TYPE:
- case NWC_CONN_INFO_DISTANCE:
- case NWC_CONN_INFO_SERVER_VERSION:
- case NWC_CONN_INFO_AUTH_ID:
- case NWC_CONN_INFO_SUSPENDED:
- case NWC_CONN_INFO_WORKGROUP_ID:
- case NWC_CONN_INFO_SECURITY_STATE:
- case NWC_CONN_INFO_CONN_NUMBER:
- case NWC_CONN_INFO_USER_ID:
- case NWC_CONN_INFO_BCAST_STATE:
- case NWC_CONN_INFO_CONN_REF:
- case NWC_CONN_INFO_AUTH_STATE:
- case NWC_CONN_INFO_TREE_NAME:
- case NWC_CONN_INFO_SERVER_NAME:
- case NWC_CONN_INFO_VERSION:
- srcData = (u_char *)pDConnInfo;
- srcData += pDConnInfo->uReturnConnInfoOffset;
- dataLen = pDConnInfo->uReturnInfoLength;
- break;
-
- case NWC_CONN_INFO_RETURN_NONE:
- case NWC_CONN_INFO_TREE_NAME_UNICODE:
- case NWC_CONN_INFO_SERVER_NAME_UNICODE:
- case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
- case NWC_CONN_INFO_ALTERNATE_ADDR:
- case NWC_CONN_INFO_SERVER_GUID:
- default:
- break;
- }
-
- if (srcData && dataLen)
- {
- DbgPrint("Copy Data in GetUserData 0x%X -> 0x%X :: 0x%X\n",
- srcData, connInfo->pReturnConnInfo, dataLen);
- cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
- }
-
- return;
-}
-
-/*++======================================================================*/
-void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
-/*
- * Abstract: Copies the user data out of the scan conn info call.
- *
- *========================================================================*/
-
-{
-u_long uLevel;
-PNwdCGetConnInfo pDConnInfo;
-
-u_char *srcData = NULL;
-u_long dataLen = 0, cpylen;
-
-
- pDConnInfo = (PNwdCGetConnInfo)cmd->data;
- uLevel = pDConnInfo->uInfoLevel;
-
- switch(uLevel)
- {
- case NWC_CONN_INFO_RETURN_ALL:
- srcData = (u_char *)reply->data;
- dataLen = reply->dataLen;
- break;
-
- case NWC_CONN_INFO_RETURN_NONE:
- dataLen = 0;
- break;
-
- case NWC_CONN_INFO_TRAN_ADDR:
- {
- u_char *dstData = connInfo->pConnInfo;
- NwcTranAddr tranAddr;
-
- srcData = (u_char *)reply->data;
-
- cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr));
- tranAddr.uTransportType = ((PNwdTranAddr)srcData)->uTransportType;
- tranAddr.uAddressLength = ((PNwdTranAddr)srcData)->uAddressLength;
- cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
- cpylen = copy_to_user(tranAddr.puAddress, ((PNwdTranAddr)srcData)->Buffer, ((PNwdTranAddr)srcData)->uAddressLength);
- dataLen=0;
- break;
- }
- case NWC_CONN_INFO_NDS_STATE:
- case NWC_CONN_INFO_MAX_PACKET_SIZE:
- case NWC_CONN_INFO_LICENSE_STATE:
- case NWC_CONN_INFO_PUBLIC_STATE:
- case NWC_CONN_INFO_SERVICE_TYPE:
- case NWC_CONN_INFO_DISTANCE:
- case NWC_CONN_INFO_SERVER_VERSION:
- case NWC_CONN_INFO_AUTH_ID:
- case NWC_CONN_INFO_SUSPENDED:
- case NWC_CONN_INFO_WORKGROUP_ID:
- case NWC_CONN_INFO_SECURITY_STATE:
- case NWC_CONN_INFO_CONN_NUMBER:
- case NWC_CONN_INFO_USER_ID:
- case NWC_CONN_INFO_BCAST_STATE:
- case NWC_CONN_INFO_CONN_REF:
- case NWC_CONN_INFO_AUTH_STATE:
- case NWC_CONN_INFO_VERSION:
- case NWC_CONN_INFO_SERVER_NAME:
- case NWC_CONN_INFO_TREE_NAME:
- srcData = (u_char *)reply->data;
- dataLen = reply->dataLen;
- break;
-
- case NWC_CONN_INFO_TREE_NAME_UNICODE:
- case NWC_CONN_INFO_SERVER_NAME_UNICODE:
- break;
-
- case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
- break;
-
- case NWC_CONN_INFO_ALTERNATE_ADDR:
- break;
-
- case NWC_CONN_INFO_SERVER_GUID:
- break;
-
- default:
- break;
- }
-
- if (srcData && dataLen)
- {
- cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength);
- }
-
- return;
-}
-
-/*++======================================================================*/
-int NwGetDaemonVersion(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCGetRequesterVersion pDVersion;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- datalen = sizeof(*pDVersion);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_GET_REQUESTER_VERSION;
- cmdlen = sizeof(*cmd);
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- pDVersion = (PNwdCGetRequesterVersion)reply->data;
- cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion));
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-
-/*++======================================================================*/
-int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCGetPreferredDsTree pDGetTree;
-NwcGetPreferredDsTree xplatCall, *p;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-u_char *dPtr;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetPreferredDsTree));
- datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength;
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE;
- cmdlen = sizeof(*cmd);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- if (!retCode)
- {
- pDGetTree = (PNwdCGetPreferredDsTree)reply->data;
- dPtr = reply->data + pDGetTree->DsTreeNameOffset;
- p = (NwcGetPreferredDsTree *)pdata->reqData;
-
- DbgPrint("NwcGetPreferredDSTree: Reply recieved\n");
- DbgPrint(" TreeLen = %x\n", pDGetTree->uTreeLength);
- DbgPrint(" TreeName = %s\n", dPtr);
-
- cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4);
- cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength);
- }
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-PNwdCSetPreferredDsTree pDSetTree;
-NwcSetPreferredDsTree xplatCall;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-u_char *dPtr;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPreferredDsTree));
- datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength;
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE;
-
- pDSetTree = (PNwdCSetPreferredDsTree)cmd->data;
- pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree);
- pDSetTree->uTreeLength = xplatCall.uTreeLength;
-
- dPtr = cmd->data + sizeof(*pDSetTree);
- cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength);
-
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-
-/*++======================================================================*/
-int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcSetDefaultNameContext xplatCall;
-PNwdCSetDefaultNameContext pDSet;
-u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-u_char *dPtr;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetDefaultNameContext));
- datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength;
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT;
- cmd->dataLen = sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + xplatCall.uNameLength;
-
- pDSet = (PNwdCSetDefaultNameContext)cmd->data;
- dPtr = cmd->data;
-
- pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext);
- pDSet->uTreeLength = xplatCall.uTreeLength;
- pDSet->NameContextOffset = pDSet->TreeOffset+xplatCall.uTreeLength;
- pDSet->uNameLength = xplatCall.uNameLength;
-
- cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
- cpylen = copy_from_user(dPtr+pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength);
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcGetDefaultNameContext xplatCall;
-PNwdCGetDefaultNameContext pGet;
-char *dPtr;
-int retCode = -ENOMEM;
-u_long cmdlen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetDefaultNameContext));
- cmdlen = sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT;
- cmd->dataLen = sizeof(NwdCGetDefaultNameContext)+xplatCall.uTreeLength;
-
- pGet = (PNwdCGetDefaultNameContext)cmd->data;
- dPtr = cmd->data;
-
- pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext);
- pGet->uTreeLength = xplatCall.uTreeLength;
-
- cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
- dPtr[pGet->TreeOffset+pGet->uTreeLength] = 0;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- retCode = reply->Reply.ErrorCode;
- if (!retCode)
- {
- pGet = (PNwdCGetDefaultNameContext)reply->data;
-
- DbgPrint("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", retCode, pGet->uNameLength, xplatCall.uNameLength);
- if (xplatCall.uNameLength < pGet->uNameLength)
- {
- pGet->uNameLength = xplatCall.uNameLength;
- retCode = NWE_BUFFER_OVERFLOW;
- }
- dPtr = (char *)pGet + pGet->NameContextOffset;
- cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength);
- }
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(retCode);
-
-}
-
-/*++======================================================================*/
-int NwQueryFeature(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- NwcQueryFeature xpCall;
- int status = SUCCESS;
- u_long cpylen;
-
- cpylen = copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature));
- switch (xpCall.Feature)
- {
- case NWC_FEAT_NDS:
- case NWC_FEAT_NDS_MTREE:
- case NWC_FEAT_PRN_CAPTURE:
- case NWC_FEAT_NDS_RESOLVE:
-
- status = NWE_REQUESTER_FAILURE;
-
- }
- return( status );
-}
-
-/*++======================================================================*/
-int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcGetTreeMonitoredConnRef xplatCall, *p;
-PNwdCGetTreeMonitoredConnRef pDConnRef;
-char *dPtr;
-u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetTreeMonitoredConnRef));
- datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen;
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF;
-
- pDConnRef = (PNwdCGetTreeMonitoredConnRef)cmd->data;
- pDConnRef->TreeName.boffset = sizeof(*pDConnRef);
- pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen;
- pDConnRef->TreeName.type = xplatCall.pTreeName->DataType;
-
- dPtr = cmd->data + sizeof(*pDConnRef);
- cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len);
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- pDConnRef = (PNwdCGetTreeMonitoredConnRef)reply->data;
- dPtr = reply->data + pDConnRef->TreeName.boffset;
- p = (NwcGetTreeMonitoredConnRef *)pdata->reqData;
- cpylen = copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4);
-
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
-
- }
-
- return(status);
-}
-
-/*++======================================================================*/
-int NwcEnumIdentities(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcEnumerateIdentities xplatCall, *eId;
-PNwdCEnumerateIdentities pEnum;
-NwcString xferStr;
-char *str;
-u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcEnumerateIdentities));
- datalen = sizeof(*pEnum);
- cmdlen = datalen + sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES;
-
- DbgPrint("NwcEnumIdentities: Send Request\n");
- DbgPrint(" iterator = %x\n", xplatCall.Iterator);
- DbgPrint(" cmdlen = %d\n", cmdlen);
-
- pEnum = (PNwdCEnumerateIdentities)cmd->data;
- pEnum->Iterator = xplatCall.Iterator;
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- status = reply->Reply.ErrorCode;
-
- eId = pdata->repData;
- pEnum = (PNwdCEnumerateIdentities)reply->data;
- cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator));
- DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", pEnum->AuthenticationId);
- cpylen = copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId));
- cpylen = copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType));
- cpylen = copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags));
- cpylen = copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType));
- cpylen = copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType));
-
- if (!status)
- {
- cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(NwcString));
- str = (char *)((char *)reply->data + pEnum->domainNameOffset);
- DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", str);
- cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen);
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
- xferStr.DataLen = pEnum->domainNameLen - 1;
- cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(NwcString));
-
-
- cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(NwcString));
- str = (char *)((char *)reply->data + pEnum->objectNameOffset);
- DbgPrint("[XPLAT NWCAPI] Found User %s\n", str);
- cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen);
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
- xferStr.DataLen = pEnum->objectNameLen - 1;
- cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(NwcString));
- }
-
- Novfs_Free(reply);
-
- }
- Novfs_Free(cmd);
-
- }
- return(status);
-}
-
-/*++======================================================================*/
-int NwcChangeAuthKey(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Change the password on the server
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcChangeKey xplatCall;
-PNwdCChangeKey pNewKey;
-NwcString xferStr;
-char *str;
-u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey));
-
- datalen = sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
- + xplatCall.pNewPassword->DataLen + xplatCall.pVerifyPassword->DataLen;
-
- cmdlen = sizeof(*cmd) + datalen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- pNewKey = (PNwdCChangeKey)cmd->data;
- cmd->dataLen = datalen;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_CHANGE_KEY;
-
- pNewKey->NameType = xplatCall.NameType;
- pNewKey->ObjectType = xplatCall.ObjectType;
- pNewKey->AuthType = xplatCall.AuthType;
- str = (char *)pNewKey;
-
- /*
- * Get the tree name
- */
- str += sizeof(*pNewKey);
- cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
- pNewKey->domainNameOffset = sizeof(*pNewKey);
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->domainNameLen = xferStr.DataLen;
-
- /*
- * Get the User Name
- */
- str += pNewKey->domainNameLen;
- cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
- pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->objectNameLen = xferStr.DataLen;
-
- /*
- * Get the New Password
- */
- str += pNewKey->objectNameLen;
- cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(NwcString));
- pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->newPasswordLen = xferStr.DataLen;
-
- /*
- * Get the Verify Password
- */
- str += pNewKey->newPasswordLen;
- cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
- pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen;
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->verifyPasswordLen = xferStr.DataLen;
-
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- memset(cmd, 0, cmdlen);
-
- Novfs_Free(cmd);
- }
-
- return(status);
-}
-
-/*++======================================================================*/
-int NwcSetPrimaryConn(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Set the primary connection Id
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcSetPrimaryConnection xplatCall;
-PNwdCSetPrimaryConnection pConn;
-u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPrimaryConnection));
-
- datalen = sizeof(NwdCSetPrimaryConnection);
- cmdlen = sizeof(*cmd) + datalen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- pConn = (PNwdCSetPrimaryConnection)cmd->data;
- cmd->dataLen = datalen;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SET_PRIMARY_CONN;
- pConn->ConnHandle = xplatCall.ConnHandle;
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
-
- Novfs_Free(cmd);
- }
-
- return(status);
-}
-
-/*++======================================================================*/
-int NwcGetPrimaryConn(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Get the Primary connection
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-XPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long status = -ENOMEM, cmdlen, replylen, cpylen;
-
-
- cmdlen = (u_long)(&((PXPLAT_CALL_REQUEST)0)->data);
-
- cmd.dataLen = 0;
- cmd.Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd.Command.SequenceNumber = 0;
- cmd.Command.SessionId = Session;
- cmd.NwcCommand = NWC_GET_PRIMARY_CONN;
-
- status = Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- if (!status)
- {
- cpylen = copy_to_user(pdata->repData, reply->data, sizeof(u_long));
- }
-
- Novfs_Free(reply);
- }
-
- return(status);
-}
-
-
-/*++======================================================================*/
-int NwcSetMapDrive(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Get the Primary connection
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long status = 0, datalen, cmdlen, replylen, cpylen;
-NwcMapDriveEx symInfo;
-
- DbgPrint("Call to NwcSetMapDrive\n");
- cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
- cmdlen = sizeof(*cmd);
- datalen = sizeof(symInfo) + symInfo.dirPathOffsetLength + symInfo.linkOffsetLength;
-
- DbgPrint(" cmdlen = %d\n", cmdlen);
- DbgPrint(" dataLen = %d\n", datalen);
- DbgPrint(" symInfo.dirPathOffsetLength = %d\n", symInfo.dirPathOffsetLength);
- DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength);
- DbgPrint(" pdata->datalen = %d\n", pdata->reqLen);
-
- mydump(sizeof(symInfo), &symInfo);
-
- cmdlen += datalen;
-
-
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->dataLen = datalen;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_MAP_DRIVE;
-
- cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(status);
-
-}
-
-/*++======================================================================*/
-int NwcUnMapDrive(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Get the Primary connection
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long status = 0, datalen, cmdlen, replylen, cpylen;
-NwcUnmapDriveEx symInfo;
-
- DbgPrint("Call to NwcUnMapDrive\n");
-
- cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
- cmdlen = sizeof(*cmd);
- datalen = sizeof(symInfo) + symInfo.linkLen;
-
- cmdlen += datalen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->dataLen = datalen;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_UNMAP_DRIVE;
-
- cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
-
- return(status);
-}
-
-
-/*++======================================================================*/
-int NwcEnumerateDrives(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Get the Primary connection
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long status = 0, cmdlen, replylen, cpylen;
-u_long offset;
-char *cp;
-
- DbgPrint("Call to NwcEnumerateDrives\n");
-
- cmdlen = sizeof(*cmd);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
- cmd->dataLen = 0;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_ENUMERATE_DRIVES;
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- DbgPrint("Status Code = 0x%X\n", status);
- if (!status)
- {
- offset = sizeof(u_long);
- cp = reply->data;
- replylen = ((PNwcGetMappedDrives)pdata->repData)->MapBuffLen;
- cpylen = copy_to_user(pdata->repData, cp, offset);
- cp += offset;
- cpylen = copy_to_user(((PNwcGetMappedDrives)pdata->repData)->MapBuffer, cp, min(replylen - offset, reply->dataLen - offset));
- }
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
-
- return(status);
-}
-
-
-/*++======================================================================*/
-int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Get the Primary connection
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-u_long status = 0x8866, cmdlen, replylen, cpylen;
-NwcGetBroadcastNotification msg;
-PNwdCGetBroadcastNotification dmsg;
-
- cmdlen = sizeof(*cmd) + sizeof(*dmsg);
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
- if (cmd)
- {
-
- cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg));
- cmd->dataLen = sizeof(*dmsg);
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
-
- cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE;
- dmsg = (PNwdCGetBroadcastNotification)cmd->data;
- dmsg->uConnReference = msg.uConnReference;
-
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- DbgPrint("Status Code = 0x%X\n", status);
- if (!status)
- {
- /* we have a message so copy it to the user buffer */
- cpylen = copy_to_user(pdata->repData, reply->data, min(pdata->repLen, reply->dataLen));
- }
- else
- {
- msg.messageLen = 0;
- msg.message[0] = 0;
- cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg));
- }
-
- Novfs_Free(reply);
- }
- Novfs_Free(cmd);
- }
- return(status);
-
-}
-
-
-int NwdSetKeyValue(PXPLAT pdata, session_t Session)
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcSetKey xplatCall;
-PNwdCSetKey pNewKey;
-NwcString cstrObjectName, cstrPassword;
-char *str;
-u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey));
- cpylen = copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(NwcString));
- cpylen = copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(NwcString));
-
- datalen = sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen;
-
- cmdlen = sizeof(*cmd) + datalen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- pNewKey = (PNwdCSetKey)cmd->data;
- cmd->dataLen = datalen;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_SET_KEY;
-
- pNewKey->ObjectType = xplatCall.ObjectType;
- pNewKey->AuthenticationId = xplatCall.AuthenticationId;
- pNewKey->ConnHandle = xplatCall.ConnHandle;
- str = (char *)pNewKey;
-
- /*
- * Get the User Name
- */
- str += sizeof(NwdCSetKey);
- cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen);
-
- str +=
- pNewKey->objectNameLen = cstrObjectName.DataLen;
- pNewKey->objectNameOffset = sizeof(NwdCSetKey);
-
- /*
- * Get the Verify Password
- */
- cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen);
-
- pNewKey->newPasswordLen = cstrPassword.DataLen;
- pNewKey->newPasswordOffset = pNewKey->objectNameOffset+pNewKey->objectNameLen;
-
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- memset(cmd, 0, cmdlen);
- Novfs_Free(cmd);
- }
-
- return(status);
-}
-
-/*++======================================================================*/
-int NwdVerifyKeyValue(PXPLAT pdata, session_t Session)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract: Change the password on the server
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-PXPLAT_CALL_REQUEST cmd;
-PXPLAT_CALL_REPLY reply;
-NwcVerifyKey xplatCall;
-PNwdCVerifyKey pNewKey;
-NwcString xferStr;
-char *str;
-u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-
- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey));
-
- datalen = sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
- + xplatCall.pVerifyPassword->DataLen;
-
- cmdlen = sizeof(*cmd) + datalen;
- cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
-
- if (cmd)
- {
- pNewKey = (PNwdCVerifyKey)cmd->data;
- cmd->dataLen = datalen;
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_VERIFY_KEY;
-
- pNewKey->NameType = xplatCall.NameType;
- pNewKey->ObjectType = xplatCall.ObjectType;
- pNewKey->AuthType = xplatCall.AuthType;
- str = (char *)pNewKey;
-
- /*
- * Get the tree name
- */
- str += sizeof(*pNewKey);
- cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
- pNewKey->domainNameOffset = sizeof(*pNewKey);
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->domainNameLen = xferStr.DataLen;
-
- /*
- * Get the User Name
- */
- str += pNewKey->domainNameLen;
- cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
- pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->objectNameLen = xferStr.DataLen;
-
- /*
- * Get the Verify Password
- */
- str += pNewKey->objectNameLen;
- cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
- pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
- pNewKey->verifyPasswordLen = xferStr.DataLen;
-
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply)
- {
- status = reply->Reply.ErrorCode;
- Novfs_Free(reply);
- }
- memset(cmd, 0, cmdlen);
- Novfs_Free(cmd);
- }
-
- return(status);
-}
diff -uNr src.old/novfs/proc.c src/novfs/proc.c
--- src.old/novfs/proc.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/proc.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,339 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: proc.c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module contains functions that create the
- * interface to the proc filesystem.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
-
-/*===[ Include files specific to this module ]============================*/
-#include "vfs.h"
-
-/*===[ External data ]====================================================*/
-extern char *Novfs_CurrentMount;
-
-/*===[ External prototypes ]==============================================*/
-extern int DbgPrint( char *Fmt, ... );
-
-extern ssize_t
-Daemon_Receive_Reply(struct file *file, const char *buf, size_t nbytes, loff_t *ppos);
-
-extern ssize_t
-Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
-
-extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-
-extern int Daemon_Library_close(struct inode *inode, struct file *file);
-extern int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-extern int Daemon_Library_open(struct inode *inode, struct file *file);
-extern ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
-extern ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
-extern loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
-
-extern int Daemon_Open_Control(struct inode *Inode, struct file *File);
-extern int Daemon_Close_Control(struct inode *Inode, struct file *File);
-
-extern int Daemon_getversion( char *Buf, int Length );
-
-/*===[ Manifest constants ]===============================================*/
-
-/*===[ Type definitions ]=================================================*/
-
-/*===[ Function prototypes ]==============================================*/
-ssize_t
-Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
-
-ssize_t
-Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
-
-int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-
-int Init_Procfs_Interface( void );
-void Uninit_Procfs_Interface( void );
-
-/*===[ Global variables ]=================================================*/
-struct proc_dir_entry *Novfs_Procfs_dir, *Novfs_Control, *Novfs_Library, *Novfs_Version;
-static struct file_operations Daemon_proc_fops;
-static struct file_operations Library_proc_fops;
-
-/*===[ Code ]=============================================================*/
-
-/*++======================================================================*/
-int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *buf, tbuf[48];
- int len=0, i;
-
- if ( !off )
- {
- buf = page+off;
- *start = buf;
- len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING);
- i = Daemon_getversion(tbuf, sizeof(tbuf));
- if ((i > 0) && i < (count-len))
- {
- len += sprintf(buf+len, "Novfsd Version=%s\n", tbuf);
- }
-
- if (Novfs_CurrentMount)
- {
- i = strlen(Novfs_CurrentMount);
- if ((i > 0) && i < (count-len))
- {
- len += sprintf(buf+len, "Novfs mount=%s\n", Novfs_CurrentMount);
- }
- }
- DbgPrint("Novfs_Get_Version:\n%s\n", buf);
- }
- *eof = 1;
- return(len);
-}
-
-/*++======================================================================*/
-ssize_t
-Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- ssize_t retval=0;
-
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(buf);
- UNUSED_VARIABLE(nbytes);
- UNUSED_VARIABLE(ppos);
-
- DbgPrint( "Novfs_User_proc_read: kernel_locked 0x%x\n", kernel_locked());
-
- return retval;
-}
-/*++======================================================================*/
-ssize_t
-Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- ssize_t retval=0;
-
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(ppos);
-
- DbgPrint( "Novfs_User_proc_write: kernel_locked 0x%x\n", kernel_locked());
- if (buf && nbytes)
- {
- }
-
- return(retval);
-}
-
-/*++======================================================================*/
-int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retval=-ENOSYS;
-
- UNUSED_VARIABLE(inode);
- UNUSED_VARIABLE(file);
- UNUSED_VARIABLE(cmd);
- UNUSED_VARIABLE(arg);
-
- DbgPrint( "Novfs_User_proc_ioctl: kernel_locked 0x%x\n", kernel_locked());
-
- return(retval);
-}
-
-/*++======================================================================*/
-int Init_Procfs_Interface( void )
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- int retCode=0;
-
- Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL);
- if ( Novfs_Procfs_dir )
- {
- Novfs_Procfs_dir->owner = THIS_MODULE;
-
- Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir);
-
- if ( Novfs_Control )
- {
- Novfs_Control->owner = THIS_MODULE;
- Novfs_Control->size = 0;
- memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, sizeof(struct file_operations));
-
- /*
- * Setup our functions
- */
- Daemon_proc_fops.owner = THIS_MODULE;
- Daemon_proc_fops.open = Daemon_Open_Control;
- Daemon_proc_fops.release = Daemon_Close_Control;
- Daemon_proc_fops.read = Daemon_Send_Command;
- Daemon_proc_fops.write = Daemon_Receive_Reply;
- Daemon_proc_fops.ioctl = Daemon_ioctl;
-
- Novfs_Control->proc_fops = &Daemon_proc_fops;
- }
- else
- {
- remove_proc_entry(MODULE_NAME, NULL);
- return(-ENOENT);
- }
-
- Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir);
- if ( Novfs_Library )
- {
- Novfs_Library->owner = THIS_MODULE;
- Novfs_Library->size = 0;
-
- /*
- * Setup our file functions
- */
- memcpy(&Library_proc_fops, Novfs_Library->proc_fops, sizeof(struct file_operations));
- Library_proc_fops.owner = THIS_MODULE;
- Library_proc_fops.open = Daemon_Library_open;
- Library_proc_fops.release = Daemon_Library_close;
- Library_proc_fops.read = Daemon_Library_read;
- Library_proc_fops.write = Daemon_Library_write;
- Library_proc_fops.llseek = Daemon_Library_llseek;
- Library_proc_fops.ioctl = Daemon_Library_ioctl;
- Novfs_Library->proc_fops = &Library_proc_fops;
- }
- else
- {
- remove_proc_entry("Control", Novfs_Procfs_dir);
- remove_proc_entry(MODULE_NAME, NULL);
- return(-ENOENT);
- }
-
- Novfs_Version = create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, Novfs_Get_Version, NULL);
- if ( Novfs_Version )
- {
- Novfs_Version->owner = THIS_MODULE;
- Novfs_Version->size = 0;
- }
- else
- {
- remove_proc_entry("Library", Novfs_Procfs_dir);
- remove_proc_entry("Control", Novfs_Procfs_dir);
- remove_proc_entry(MODULE_NAME, NULL);
- retCode = -ENOENT;
- }
- }
- else
- {
- retCode = -ENOENT;
- }
- return(retCode);
-}
-
-/*++======================================================================*/
-void Uninit_Procfs_Interface( void )
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
-
- DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n");
- remove_proc_entry("Version", Novfs_Procfs_dir);
-
- DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n");
- remove_proc_entry("Control", Novfs_Procfs_dir);
-
- DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n");
- remove_proc_entry("Library", Novfs_Procfs_dir);
-
- DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", MODULE_NAME);
- remove_proc_entry(MODULE_NAME, NULL);
-
- DbgPrint("Uninit_Procfs_Interface done\n");
-}
diff -uNr src.old/novfs/profile.c src/novfs/profile.c
--- src.old/novfs/profile.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/profile.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,1201 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: profile.c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module contains a debugging code for
- * the novfs VFS.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/sched.h>
-#include <asm/uaccess.h>
-#include <linux/vmalloc.h>
-#include <linux/time.h>
-
-#include <linux/profile.h>
-#include <linux/notifier.h>
-
-/*===[ Include files specific to this module ]============================*/
-#include "vfs.h"
-
-/*===[ External data ]====================================================*/
-extern struct dentry *Novfs_root;
-extern struct proc_dir_entry *Novfs_Procfs_dir;
-extern unsigned long File_update_timeout;
-
-/*===[ External prototypes ]==============================================*/
-extern void Scope_Dump_Tasklist( void );
-extern void Scope_Dump_Scopetable( void );
-extern void Daemon_Dumpque( void );
-extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
-extern int Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-extern void Novfs_dump_inode( void *pf );
-extern int Daemon_SendDebugCmd ( char *Command );
-
-
-/*===[ Manifest constants ]===============================================*/
-#define DBGBUFFERSIZE (1024*1024*32)
-
-/*===[ Type definitions ]=================================================*/
-typedef void daemon_command_t;
-
-typedef struct _SYMBOL_TABLE {
- void *address;
- char *name;
-} SYMBOL_TABLE, *PSYMBOL_TABLE;
-
-struct local_rtc_time {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
-};
-
-/*===[ Function prototypes ]==============================================*/
-int profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) __attribute__((__no_instrument_function__));
-int init_profile( void );
-
-char *ctime_r(time_t *clock, char *buf);
-int LocalPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
-int DbgPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
-
-void __cyg_profile_func_enter (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)) ;
-void __cyg_profile_func_exit (void *this_fn, void *call_site) __attribute__((__no_instrument_function__));
-void doline(unsigned char *b, unsigned char *p, unsigned char *l) __attribute__((__no_instrument_function__));
-void mydump(int size, void *dumpptr) __attribute__((__no_instrument_function__));
-void GregorianDay(struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
-void to_tm(int tim, struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
-char *ctime_r(time_t *clock, char *buf) __attribute__((__no_instrument_function__));
-int profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-int profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-int profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-int profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-int profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-int profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs);
-
-void *Novfs_Malloc( size_t size, int flags ) __attribute__((__no_instrument_function__));
-void Novfs_Free( const void *p ) __attribute__((__no_instrument_function__));
-
-int profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs) __attribute__((__no_instrument_function__));
-void profile_dump_memorylist( void *pf );
-
-static ssize_t User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
-static ssize_t User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
-static int proc_read_DbgBuffer(char *page, char **start,
- off_t off, int count,
- int *eof, void *data) __attribute__((__no_instrument_function__));
-
-void profile_dump_dt(struct dentry *parent, void *pf );
-ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off);
-ssize_t profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off);
-ssize_t profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off);
-
-/*===[ Global variables ]=================================================*/
-char *DbgPrintBuffer=NULL;
-char DbgPrintOn=0;
-char DbgSyslogOn=0;
-char DbgProfileOn=0;
-char DbgDaemonLogOn=0;
-unsigned long DbgPrintBufferOffset=0;
-unsigned long DbgPrintBufferReadOffset=0;
-unsigned long DbgPrintBufferSize = DBGBUFFERSIZE;
-
-int Indent = 0;
-char IndentString[] = " ";
-
-static struct file_operations Dbg_proc_file_operations;
-static struct file_operations dentry_proc_file_ops;
-static struct file_operations inode_proc_file_ops;
-static struct file_operations memory_proc_file_ops;
-
-static struct proc_dir_entry *dbg_dir, *dbg_file;
-static struct proc_dir_entry *dentry_file;
-static struct proc_dir_entry *inode_file;
-static struct proc_dir_entry *memory_file;
-
-static struct notifier_block taskexit_nb;
-
-
-DECLARE_MUTEX(LocalPrint_lock);
-spinlock_t Syslog_lock = SPIN_LOCK_UNLOCKED;
-
-#include "profile_funcs.h"
-
-
-/*===[ Code ]=============================================================*/
-int
-profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data)
-{
- struct task_struct *task = (struct task_struct *)data;
-
- DbgPrint("profile_task_exit_callback: task 0x%p %u exiting %s\n", task, task->pid, task->comm);
- return(0);
-}
-
-int init_profile( void )
-{
- int retCode = 0;
-
- if ( DbgPrintBuffer )
- {
- if (Novfs_Procfs_dir)
- {
- dbg_dir = Novfs_Procfs_dir;
- }
- else
- {
- dbg_dir = proc_mkdir(MODULE_NAME, NULL);
- }
-
- if( dbg_dir )
- {
- dbg_dir->owner = THIS_MODULE;
- dbg_file = create_proc_read_entry("Debug",
- 0600,
- dbg_dir,
- proc_read_DbgBuffer,
- NULL);
- if ( dbg_file )
- {
- dbg_file->owner = THIS_MODULE;
- dbg_file->size = DBGBUFFERSIZE;
- memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, sizeof(struct file_operations));
- Dbg_proc_file_operations.read = User_proc_read_DbgBuffer;
- Dbg_proc_file_operations.write = User_proc_write_DbgBuffer;
- dbg_file->proc_fops = &Dbg_proc_file_operations;
- }
- else
- {
- remove_proc_entry(MODULE_NAME, NULL);
- vfree( DbgPrintBuffer );
- DbgPrintBuffer = NULL;
- }
-
- inode_file = create_proc_entry("inode",
- 0600,
- dbg_dir);
- if ( inode_file )
- {
- inode_file->owner = THIS_MODULE;
- inode_file->size = 0;
- memcpy(&inode_proc_file_ops, inode_file->proc_fops, sizeof(struct file_operations));
- inode_proc_file_ops.owner = THIS_MODULE;
- inode_proc_file_ops.read = profile_inode_read;
- inode_file->proc_fops = &inode_proc_file_ops;
- }
-
- dentry_file = create_proc_entry("dentry",
- 0600,
- dbg_dir);
- if ( dentry_file )
- {
- dentry_file->owner = THIS_MODULE;
- dentry_file->size = 0;
- memcpy(&dentry_proc_file_ops, dentry_file->proc_fops, sizeof(struct file_operations));
- dentry_proc_file_ops.owner = THIS_MODULE;
- dentry_proc_file_ops.read = profile_dentry_read;
- dentry_file->proc_fops = &dentry_proc_file_ops;
- }
-
- memory_file = create_proc_entry("memory",
- 0600,
- dbg_dir);
- if ( memory_file )
- {
- memory_file->owner = THIS_MODULE;
- memory_file->size = 0;
- memcpy(&memory_proc_file_ops, memory_file->proc_fops, sizeof(struct file_operations));
- memory_proc_file_ops.owner = THIS_MODULE;
- memory_proc_file_ops.read = profile_memory_read;
- memory_file->proc_fops = &memory_proc_file_ops;
- }
-
- }
- else
- {
- vfree( DbgPrintBuffer );
- DbgPrintBuffer = NULL;
- }
- }
- return( retCode );
-}
-
-/*
-void uninit_profile()
-{
- if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
- if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
- if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
- if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
-
- if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))
- {
- DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
- remove_proc_entry( MODULE_NAME, NULL );
- }
-}
-*/
-
-static
-ssize_t
-User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos)
-{
- ssize_t retval=nbytes;
- u_char *lbuf, *p;
- int i;
- u_long cpylen;
-
-
- UNUSED_VARIABLE( *ppos );
-
- lbuf = Novfs_Malloc(nbytes+1, GFP_KERNEL);
- if (lbuf)
- {
- cpylen = copy_from_user(lbuf, buf, nbytes);
-
- lbuf[nbytes] = 0;
- DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf);
-
- for (i=0; lbuf[i] && lbuf[i] != '\n'; i++) ;
-
- if ( '\n' == lbuf[i] )
- {
- lbuf[i] = '\0';
- }
-
- if ( !strcmp("on", lbuf))
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- DbgPrintOn = 1;
- }
- else if ( !strcmp("off", lbuf))
- {
- DbgPrintOn = 0;
- }
- else if ( !strcmp("reset", lbuf))
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- }
- else if ( NULL != (p = strchr(lbuf, ' ')))
- {
- *p++ = '\0';
- if ( !strcmp("syslog", lbuf))
- {
-
- if (!strcmp("on", p))
- {
- DbgSyslogOn = 1;
- }
- else if (!strcmp("off", p))
- {
- DbgSyslogOn = 0;
- }
- }
- else if ( !strcmp("profile", lbuf))
- {
-
- if (!strcmp("on", p))
- {
- DbgProfileOn = 1;
- }
- else if (!strcmp("off", p))
- {
- DbgProfileOn = 0;
- }
- }
- else if ( !strcmp("daemonlog", lbuf))
- {
-
- if (!strcmp("on", p))
- {
- DbgDaemonLogOn = 1;
- }
- else if (!strcmp("off", p))
- {
- DbgDaemonLogOn = 0;
- }
- }
- else if ( !strcmp("novfsd", lbuf))
- {
- Daemon_SendDebugCmd( p );
- }
- else if ( !strcmp("file_update_timeout", lbuf))
- {
- File_update_timeout = simple_strtoul(p, NULL, 0);
- }
- }
- Novfs_Free(lbuf);
- }
-
- return (retval);
-}
-
-static
-ssize_t
-User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-
-{
- ssize_t retval=0;
- size_t count;
-
- UNUSED_VARIABLE( *ppos );
-
- if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset))
- {
-
- if (count > nbytes)
- {
- count = nbytes;
- }
-
- count -= copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], count);
-
- if (count == 0)
- {
- if (retval == 0)
- retval = -EFAULT;
- }
- else
- {
- DbgPrintBufferReadOffset += count;
- if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- }
- retval = count;
- }
- }
-
- return retval;
-}
-
-static
-int
-proc_read_DbgBuffer(char *page, char **start,
- off_t off, int count,
- int *eof, void *data)
-{
- int len;
- static char bufd[512];
-
- UNUSED_VARIABLE(start);
- UNUSED_VARIABLE(eof);
- UNUSED_VARIABLE(data);
-
- sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n",
- off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset);
- printk(bufd);
-
- len = DbgPrintBufferOffset - DbgPrintBufferReadOffset;
-
- if ((int)(DbgPrintBufferOffset-DbgPrintBufferReadOffset) > count)
- {
- len = count;
- }
-
- if (len)
- {
- memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len);
- DbgPrintBufferReadOffset += len;
- }
-
-
- if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- }
-
- sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: return %d\n", len);
- printk(bufd);
-
- return len;
-}
-
-#define DBG_BUFFER_SIZE (2*1024)
-
-int
-LocalPrint( char *Fmt, ... )
-{
- int len=0;
- va_list args;
-
- if (DbgPrintBuffer)
- {
- va_start(args, Fmt);
- len += vsnprintf(DbgPrintBuffer+DbgPrintBufferOffset, DbgPrintBufferSize-DbgPrintBufferOffset, Fmt, args);
- DbgPrintBufferOffset += len;
- }
-
- return(len);
-}
-
-
-int
-DbgPrint( char *Fmt, ... )
-{
- char *buf;
- int len=0;
- unsigned long offset;
- va_list args;
-
- if ( (DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn )
- {
- buf = kmalloc( DBG_BUFFER_SIZE, GFP_KERNEL );
-
- if (buf)
- {
- va_start(args, Fmt);
- len = sprintf(buf, "[%d] ", current->pid);
-
- len += vsnprintf(buf+len, DBG_BUFFER_SIZE-len, Fmt, args);
- if ( -1 == len )
- {
- len = DBG_BUFFER_SIZE-1;
- buf[len] = '\0';
- }
- /*
- len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts);
- len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args);
- */
-
- if (len)
- {
- if (DbgSyslogOn)
- {
- spin_lock( &Syslog_lock );
- printk("<6>%s", buf);
- spin_unlock( &Syslog_lock );
- }
-
- if ( DbgPrintBuffer && DbgPrintOn )
- {
- if ((DbgPrintBufferOffset+len) > DbgPrintBufferSize)
- {
- offset = DbgPrintBufferOffset;
- DbgPrintBufferOffset = 0;
- memset(&DbgPrintBuffer[offset], 0, DbgPrintBufferSize-offset);
- }
-
- mb();
-
- if ((DbgPrintBufferOffset+len) < DbgPrintBufferSize)
- {
- DbgPrintBufferOffset += len;
- offset = DbgPrintBufferOffset-len;
- memcpy(&DbgPrintBuffer[offset], buf, len+1);
- }
- }
- }
- kfree(buf);
- }
- }
-
- return(len);
-}
-
-void
-__cyg_profile_func_enter (void *this_fn, void *call_site)
-{
- PSYMBOL_TABLE sym;
- struct timespec ts;
-
-
- if ((void *)init_novfs == this_fn)
- {
- DbgPrintBuffer = vmalloc(DBGBUFFERSIZE);
- taskexit_nb.notifier_call = profile_task_exit_callback;
-
-#ifdef CONFIG_KDB
- kdb_register("novfs_tl", profile_dump_tasklist, "", "Dumps task list", 0);
- kdb_register("novfs_st", profile_dump_scopetable, "", "Dumps the novfs scope table", 0);
- kdb_register("novfs_dque", profile_dump_daemonque, "", "Dumps the novfs daemon que", 0);
- kdb_register("novfs_db", profile_dump_DbgBuffer, "[-r] [-e size] [-i]", "Dumps the novfs DbgBuffer", 0);
- kdb_register("novfs_den", profile_dump_DentryTree, "[dentry]", "Dumps a Dentry tree", 0);
- kdb_register("novfs_ic", Novfs_dump_inode_cache, "[inode]", "Dumps a Inode Cache", 0);
- kdb_register("novfs_inode", profile_dump_inode, "", "Dump allocated Inodes", 0);
- kdb_register("novfs_mem", profile_dump_memorylist_dbg, "", "Dumps allocated memory", 0);
-#endif
- }
- else if (exit_novfs == this_fn)
- {
- if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
- if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
- if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
- if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
-
- if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))
- {
- printk( KERN_INFO "Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
- remove_proc_entry( MODULE_NAME, NULL );
- }
- }
-
- if (DbgProfileOn)
- {
- sym = SymbolTable;
- while (sym->address)
- {
- if (this_fn == sym->address )
- {
- ts = current_kernel_time();
- DbgPrint("[%ld:lu]%sS %s (0x%p 0x%p)\n", ts.tv_sec, ts.tv_nsec, &IndentString[sizeof(IndentString)-Indent-1], sym->name, this_fn, call_site);
-
- Indent++;
- if (Indent > (int)(sizeof(IndentString)-1))
- Indent--;
-
- break;
- }
- sym++;
- }
- }
-}
-
-void
-__cyg_profile_func_exit (void *this_fn, void *call_site)
-{
- PSYMBOL_TABLE sym;
- struct timespec ts;
-
- if (exit_novfs == this_fn)
- {
- if (DbgPrintBuffer) vfree( DbgPrintBuffer );
- DbgPrintBuffer = NULL;
-
-#ifdef CONFIG_KDB
- kdb_unregister("novfs_tl");
- kdb_unregister("novfs_st");
- kdb_unregister("novfs_dque");
- kdb_unregister("novfs_db");
- kdb_unregister("novfs_den");
- kdb_unregister("novfs_ic");
- kdb_unregister("novfs_inode");
- kdb_unregister("novfs_mem");
-#endif
- return;
- }
-
- if (DbgProfileOn)
- {
- sym = SymbolTable;
- while (sym->address)
- {
- if (this_fn == sym->address )
- {
- Indent--;
- if (Indent < 0)
- Indent = 0;
-
- ts = current_kernel_time();
- DbgPrint("[%ld:lu]%sR %s (0x%p)\n", ts.tv_sec, ts.tv_nsec, &IndentString[sizeof(IndentString)-Indent-1], sym->name, call_site);
- break;
- }
- sym++;
- }
- }
-}
-
-void
-doline(unsigned char *b, unsigned char *e, unsigned char *l)
-{
- *b++ = ' ';
- while (l < e) {
- if ((*l < ' ') || (*l > '~'))
- {
- *b++ = '.';
- *b = '\0';
- }
- else
- {
- b += sprintf(b, "%c", *l);
- }
- l++;
- }
-}
-
-void
-mydump(int size, void *dumpptr)
-{
- unsigned char *ptr = (unsigned char *)dumpptr;
- unsigned char *line=0, buf[80], *bptr=buf;
- int i;
-
- if ( DbgPrintBuffer )
- {
- if (size)
- {
- for (i=0; i < size; i++)
- {
- if (0 == (i % 16))
- {
- if (line)
- {
- doline(bptr, ptr, line);
- DbgPrint("%s\n", buf);
- bptr = buf;
- }
- bptr += sprintf(bptr, "0x%p: ", ptr);
- line = ptr;
- }
- bptr += sprintf(bptr, "%02x ", *ptr++);
- }
- doline(bptr, ptr, line);
- DbgPrint("%s\n", buf);
- }
- }
-}
-
-#define FEBRUARY 2
-#define STARTOFTIME 1970
-#define SECDAY 86400L
-#define SECYR (SECDAY * 365)
-#define leapyear(year) ((year) % 4 == 0)
-#define days_in_year(a) (leapyear(a) ? 366 : 365)
-#define days_in_month(a) (month_days[(a) - 1])
-
-static int month_days[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/*
- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
- */
-void
-GregorianDay(struct local_rtc_time * tm)
-{
- int leapsToDate;
- int lastYear;
- int day;
- int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-
- lastYear=tm->tm_year-1;
-
- /*
- * Number of leap corrections to apply up to end of last year
- */
- leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
-
- /*
- * This year is a leap year if it is divisible by 4 except when it is
- * divisible by 100 unless it is divisible by 400
- *
- * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
- */
- if((tm->tm_year%4==0) &&
- ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
- (tm->tm_mon>2))
- {
- /*
- * We are past Feb. 29 in a leap year
- */
- day=1;
- }
- else
- {
- day=0;
- }
-
- day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
- tm->tm_mday;
-
- tm->tm_wday=day%7;
-}
-
-void
-to_tm(int tim, struct local_rtc_time * tm)
-{
- register int i;
- register long hms, day;
-
- day = tim / SECDAY;
- hms = tim % SECDAY;
-
- /* Hours, minutes, seconds are easy */
- tm->tm_hour = hms / 3600;
- tm->tm_min = (hms % 3600) / 60;
- tm->tm_sec = (hms % 3600) % 60;
-
- /* Number of years in days */
- for (i = STARTOFTIME; day >= days_in_year(i); i++)
- day -= days_in_year(i);
- tm->tm_year = i;
-
- /* Number of months in days left */
- if (leapyear(tm->tm_year))
- days_in_month(FEBRUARY) = 29;
- for (i = 1; day >= days_in_month(i); i++)
- day -= days_in_month(i);
- days_in_month(FEBRUARY) = 28;
- tm->tm_mon = i;
-
- /* Days are what is left over (+1) from all that. */
- tm->tm_mday = day + 1;
-
- /*
- * Determine the day of week
- */
- GregorianDay(tm);
-}
-
-char *
-ctime_r(time_t *clock, char *buf)
-{
- struct local_rtc_time tm;
- static char *DAYOFWEEK[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- static char *MONTHOFYEAR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- to_tm(*clock, &tm);
-
- sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], MONTHOFYEAR[tm.tm_mon-1], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year);
- return(buf);
-}
-
-
-#ifdef CONFIG_KDB
-
-int
-NO_TRACE
-profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- Scope_Dump_Tasklist();
- return( 0 );
-}
-
-int
-NO_TRACE
-profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- Scope_Dump_Scopetable();
- return( 0 );
-}
-
-int
-NO_TRACE
-profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- Daemon_Dumpque();
- return( 0 );
-}
-
-int
-NO_TRACE
-profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- unsigned long offset = DbgPrintBufferReadOffset;
- if (argc > 0)
- {
- if (!strcmp("-r", argv[1]))
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- }
- else if (!strcmp("-e", argv[1]) && (argc > 1))
- {
- offset = simple_strtoul(argv[2], NULL, 0);
- if (offset && offset < DbgPrintBufferOffset)
- {
- offset = DbgPrintBufferOffset - offset;
- }
- else
- {
- offset = DbgPrintBufferOffset;
- }
- }
- else if (!strcmp("-i", argv[1]))
- {
- kdb_printf("DbgPrintBuffer =0x%p\n", DbgPrintBuffer);
- kdb_printf("DbgPrintBufferOffset =0x%lx\n", DbgPrintBufferOffset);
- kdb_printf("DbgPrintBufferSize =0x%lx\n", DbgPrintBufferSize);
- offset = DbgPrintBufferOffset;
-
- }
- }
- while (DbgPrintBufferOffset > offset)
- {
- kdb_printf("%c", DbgPrintBuffer[offset++]);
- }
- return( 0 );
-}
-
-int
-NO_TRACE
-profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- struct dentry *parent=Novfs_root;
-
- if (argc > 0)
- {
- parent = (void *)simple_strtoul(argv[1], NULL, 0);
- }
-
- if (parent)
- {
- profile_dump_dt(parent, kdb_printf );
- }
-
- return(0);
-}
-
-
-int
-NO_TRACE
-profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- Novfs_dump_inode( kdb_printf );
- return( 0 );
-}
-
-#endif /* CONFIG_KDB */
-
-typedef struct memory_header
-{
- struct list_head list;
- void *caller;
- size_t size;
-} MEMORY_LIST, *PMEMORY_LIST;
-
-spinlock_t Malloc_Lock = SPIN_LOCK_UNLOCKED;
-LIST_HEAD( Memory_List );
-
-void *Novfs_Malloc( size_t size, int flags )
-{
- void *p=NULL;
- PMEMORY_LIST mh;
-
- mh = kmalloc(size + sizeof(MEMORY_LIST), flags);
- if (mh)
- {
- mh->caller = __builtin_return_address(0);
- mh->size = size;
- spin_lock(&Malloc_Lock);
- list_add(&mh->list, &Memory_List);
- spin_unlock(&Malloc_Lock);
- p = (char *)mh+sizeof(MEMORY_LIST);
- /*DbgPrint("Novfs_Malloc: 0x%p 0x%p %d\n", p, mh->caller, size);
- */
- }
- return(p);
-}
-
-void Novfs_Free( const void *p )
-{
- PMEMORY_LIST mh;
-
- if (p)
- {
- /*DbgPrint("Novfs_Free: 0x%p 0x%p\n", p, __builtin_return_address(0));
- */
- mh = (PMEMORY_LIST)((char *)p-sizeof(MEMORY_LIST));
-
- spin_lock(&Malloc_Lock);
- list_del(&mh->list);
- spin_unlock(&Malloc_Lock);
- kfree(mh);
- }
-}
-
-
-int
-NO_TRACE
-profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
-#ifdef CONFIG_KDB
- profile_dump_memorylist(kdb_printf);
-#endif /* CONFIG_KDB */
-
- return( 0 );
-}
-
-void
-NO_TRACE
-profile_dump_memorylist( void *pf )
-{
- void (*pfunc)(char *Fmt, ...) = pf;
-
- PMEMORY_LIST mh;
- struct list_head *l;
-
- size_t total=0;
- int count=0;
-
- spin_lock( &Malloc_Lock );
-
- list_for_each( l, &Memory_List )
- {
- mh = list_entry(l, MEMORY_LIST, list);
- pfunc("0x%p 0x%p 0x%p %d\n", mh, (char *)mh+sizeof(MEMORY_LIST), mh->caller, mh->size);
- count++;
- total += mh->size;
- }
- spin_unlock( &Malloc_Lock );
-
- pfunc("Blocks=%d Total=%d\n", count, total);
-}
-
-void
-NO_TRACE
-profile_dump_dt(struct dentry *parent, void *pf )
-{
- void (*pfunc)(char *Fmt, ...) = pf;
- struct l {
- struct l *next;
- struct dentry *dentry;
- } *l, *n, *start;
- struct list_head *p;
- struct dentry *d;
- char *buf, *path, *sd;
- char inode_number[16];
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
-
- if( NULL == buf )
- {
- return;
- }
-
- if (parent)
- {
- pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, parent->d_name.name);
- if (parent->d_subdirs.next == &parent->d_subdirs)
- {
- pfunc("No children...\n");
- }
- else
- {
- start = Novfs_Malloc(sizeof(*start), GFP_KERNEL);
- if (start)
- {
- start->next = NULL;
- start->dentry = parent;
- l = start;
- while(l)
- {
- p = l->dentry->d_subdirs.next;
- while(p != &l->dentry->d_subdirs)
- {
- d = list_entry(p, struct dentry, D_CHILD);
- p = p->next;
-
- if (d->d_subdirs.next != &d->d_subdirs)
- {
- n = Novfs_Malloc(sizeof(*n), GFP_KERNEL);
- if (n)
- {
- n->next = l->next;
- l->next = n;
- n->dentry = d;
- }
- }
- else
- {
- path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
- if (path)
- {
- pfunc("1-0x%p %s\n" \
- " d_name: %.*s\n" \
- " d_parent: 0x%p\n" \
- " d_count: %d\n" \
- " d_flags: 0x%x\n" \
- " d_subdirs: 0x%p\n" \
- " d_inode: 0x%p\n",
- d, path, d->d_name.len, d->d_name.name, d->d_parent,
- atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, d->d_inode);
- }
- }
- }
- l = l->next;
- }
- l = start;
- while(l)
- {
- d=l->dentry;
- path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
- if (path)
- {
- sd = " (None)";
- if (&d->d_subdirs != d->d_subdirs.next)
- {
- sd = "";
- }
- inode_number[0] = '\0';
- if (d->d_inode)
- {
- sprintf(inode_number, " (%lu)", d->d_inode->i_ino);
- }
- pfunc("0x%p %s\n" \
- " d_parent: 0x%p\n" \
- " d_count: %d\n" \
- " d_flags: 0x%x\n" \
- " d_subdirs: 0x%p%s\n" \
- " d_inode: 0x%p%s\n",
- d, path, d->d_parent,
- atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, sd, d->d_inode, inode_number);
- }
-
- n = l;
- l = l->next;
- Novfs_Free(n);
- }
- }
- }
- }
-
- Novfs_Free(buf);
-
-}
-
-/*int profile_inode_open(struct inode *inode, struct file *file)
-{
-
-}
-
-int profile_inode_close(struct inode *inode, struct file *file)
-{
-}
-*/
-ssize_t profile_common_read( char *buf, size_t len, loff_t *off )
-{
- ssize_t retval=0;
- size_t count;
- unsigned long offset = *off;
-
- if (0 != (count = DbgPrintBufferOffset - offset))
- {
- if (count > len)
- {
- count = len;
- }
-
- count -= copy_to_user(buf, &DbgPrintBuffer[offset], count);
-
- if (count == 0)
- {
- retval = -EFAULT;
- }
- else
- {
- *off += (loff_t)count;
- retval = count;
- }
- }
- return retval;
-
-}
-
-//ssize_t NO_TRACE profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
-ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
-{
- ssize_t retval=0;
- unsigned long offset = *off;
- static char save_DbgPrintOn;
-
- if (offset == 0)
- {
- down(&LocalPrint_lock);
- save_DbgPrintOn = DbgPrintOn;
- DbgPrintOn = 0;
-
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- Novfs_dump_inode( LocalPrint );
- }
-
- retval = profile_common_read(buf, len, off);
-
- if ( 0 == retval)
- {
- DbgPrintOn = save_DbgPrintOn;
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
-
- up(&LocalPrint_lock);
- }
-
- return retval;
-
-}
-
-ssize_t NO_TRACE profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off)
-{
- ssize_t retval=0;
- unsigned long offset = *off;
- static char save_DbgPrintOn;
-
- if (offset == 0)
- {
- down(&LocalPrint_lock);
- save_DbgPrintOn = DbgPrintOn;
- DbgPrintOn = 0;
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- profile_dump_dt(Novfs_root, LocalPrint);
- }
-
- retval = profile_common_read(buf, len, off);
-
- if ( 0 == retval)
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- DbgPrintOn = save_DbgPrintOn;
-
- up(&LocalPrint_lock);
- }
-
- return retval;
-
-}
-
-ssize_t NO_TRACE profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off)
-{
- ssize_t retval=0;
- unsigned long offset = *off;
- static char save_DbgPrintOn;
-
- if (offset == 0)
- {
- down(&LocalPrint_lock);
- save_DbgPrintOn = DbgPrintOn;
- DbgPrintOn = 0;
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- profile_dump_memorylist( LocalPrint );
- }
-
- retval = profile_common_read(buf, len, off);
-
- if ( 0 == retval)
- {
- DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
- DbgPrintOn = save_DbgPrintOn;
-
- up(&LocalPrint_lock);
- }
-
- return retval;
-
-}
diff -uNr src.old/novfs/profile_funcs.h src/novfs/profile_funcs.h
--- src.old/novfs/profile_funcs.h 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/profile_funcs.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,419 +0,0 @@
-extern void Daemon_Added_Resource( void );
-extern void Daemon_Close_Control( void );
-extern void Daemon_CreateSessionId( void );
-extern void Daemon_DestroySessionId( void );
-extern void Daemon_Dumpque( void );
-extern void Daemon_Get_UserSpace( void );
-extern void Daemon_Library_close( void );
-extern void Daemon_Library_ioctl( void );
-extern void Daemon_Library_open( void );
-extern void Daemon_Library_read( void );
-extern void Daemon_Library_write( void );
-extern void Daemon_Login( void );
-extern void Daemon_Logout( void );
-extern void Daemon_Open_Control( void );
-extern void Daemon_Poll( void );
-extern void Daemon_Receive_Reply( void );
-extern void Daemon_Remove_Resource( void );
-extern void Daemon_Send_Command( void );
-extern void Daemon_SetMountPoint( void );
-extern void Daemon_Timer( void );
-extern void Daemon_getpwuid( void );
-extern void Daemon_getversion( void );
-extern void Daemon_ioctl( void );
-extern void GetConnData( void );
-extern void GetUserData( void );
-extern void Init_Daemon_Queue( void );
-extern void Init_Procfs_Interface( void );
-extern void Novfs_Add_to_Root( void );
-extern void Novfs_Add_to_Root2( void );
-extern void Novfs_Close_File( void );
-extern void Novfs_Close_Stream( void );
-extern void Novfs_Control_ioctl( void );
-extern void Novfs_Control_read( void );
-extern void Novfs_Control_write( void );
-extern void Novfs_Create( void );
-extern void Novfs_Delete( void );
-extern void Novfs_Find_Name_In_List( void );
-extern void Novfs_Get_Connected_Server_List( void );
-extern void Novfs_Get_Directory_List( void );
-extern void Novfs_Get_Directory_ListEx( void );
-extern void Novfs_Get_File_Info( void );
-extern void Novfs_Get_File_Info2( void );
-extern void Novfs_Get_Server_Volume_List( void );
-extern void Novfs_Get_Version( void );
-extern void Novfs_Open_File( void );
-extern void Novfs_Read_File( void );
-extern void Novfs_Read_Stream( void );
-extern void Novfs_Remove_from_Root( void );
-extern void Novfs_Rename_File( void );
-extern void Novfs_Set_Attr( void );
-extern void Novfs_Truncate_File( void );
-extern void Novfs_User_proc_ioctl( void );
-extern void Novfs_User_proc_read( void );
-extern void Novfs_User_proc_write( void );
-extern void Novfs_Verify_Server_Name( void );
-extern void Novfs_Verify_Volume_Name( void );
-extern void Novfs_Write_File( void );
-extern void Novfs_Write_File2( void );
-extern void Novfs_Write_Stream( void );
-extern void Novfs_a_readpage( void );
-extern void Novfs_add_inode_entry( void );
-extern void Novfs_clear_inode( void );
-extern void Novfs_d_add( void );
-extern void Novfs_d_compare( void );
-extern void Novfs_d_delete( void );
-extern void Novfs_d_hash( void );
-extern void Novfs_d_iput( void );
-extern void Novfs_d_lookup( void );
-extern void Novfs_d_release( void );
-extern void Novfs_d_revalidate( void );
-extern void Novfs_d_strcmp( void );
-extern void Novfs_dget_path( void );
-extern void Novfs_dir_fsync( void );
-extern void Novfs_dir_lseek( void );
-extern void Novfs_dir_open( void );
-extern void Novfs_dir_read( void );
-extern void Novfs_dir_readdir( void );
-extern void Novfs_dir_release( void );
-extern void Novfs_enumerate_inode_cache( void );
-extern void Novfs_f_flush( void );
-extern void Novfs_f_fsync( void );
-extern void Novfs_f_ioctl( void );
-extern void Novfs_f_llseek( void );
-extern void Novfs_f_lock( void );
-extern void Novfs_f_mmap( void );
-extern void Novfs_f_open( void );
-extern void Novfs_f_read( void );
-extern void Novfs_f_readdir( void );
-extern void Novfs_f_release( void );
-extern void Novfs_f_write( void );
-extern void Novfs_fill_super( void );
-extern void Novfs_free_inode_cache( void );
-extern void Novfs_free_invalid_entries( void );
-extern void Novfs_get_alltrees( void );
-extern void Novfs_get_entry( void );
-extern void Novfs_get_entry_time( void );
-extern void Novfs_get_inode( void );
-extern void Novfs_get_remove_entry( void );
-extern void Novfs_get_sb( void );
-extern void Novfs_i_create( void );
-extern void Novfs_i_getattr( void );
-extern void Novfs_i_lookup( void );
-extern void Novfs_i_mkdir( void );
-extern void Novfs_i_mknod( void );
-extern void Novfs_i_permission( void );
-extern void Novfs_i_rename( void );
-extern void Novfs_i_revalidate( void );
-extern void Novfs_i_rmdir( void );
-extern void Novfs_i_setattr( void );
-extern void Novfs_i_unlink( void );
-extern void Novfs_internal_hash( void );
-extern void Novfs_invalidate_inode_cache( void );
-extern void Novfs_kill_sb( void );
-extern void Novfs_lock_inode_cache( void );
-extern void Novfs_lookup_inode_cache( void );
-extern void Novfs_lookup_validate( void );
-extern void Novfs_notify_change( void );
-extern void Novfs_read_inode( void );
-extern void Novfs_remove_inode_entry( void );
-extern void Novfs_show_options( void );
-extern void Novfs_statfs( void );
-extern void Novfs_tree_read( void );
-extern void Novfs_unlock_inode_cache( void );
-extern void Novfs_update_entry( void );
-extern void Novfs_verify_file( void );
-extern void Novfs_write_inode( void );
-extern void NwAuthConnWithId( void );
-extern void NwConnClose( void );
-extern void NwGetConnInfo( void );
-extern void NwGetDaemonVersion( void );
-extern void NwGetIdentityInfo( void );
-extern void NwLicenseConn( void );
-extern void NwLoginIdentity( void );
-extern void NwLogoutIdentity( void );
-extern void NwOpenConnByAddr( void );
-extern void NwOpenConnByName( void );
-extern void NwOpenConnByRef( void );
-extern void NwQueryFeature( void );
-extern void NwRawSend( void );
-extern void NwScanConnInfo( void );
-extern void NwSetConnInfo( void );
-extern void NwSysConnClose( void );
-extern void NwUnAuthenticate( void );
-extern void NwUnlicenseConn( void );
-extern void NwcChangeAuthKey( void );
-extern void NwcEnumIdentities( void );
-extern void NwcEnumerateDrives( void );
-extern void NwcGetBroadcastMessage( void );
-extern void NwcGetDefaultNameCtx( void );
-extern void NwcGetPreferredDSTree( void );
-extern void NwcGetPrimaryConn( void );
-extern void NwcGetTreeMonitoredConn( void );
-extern void NwcSetDefaultNameCtx( void );
-extern void NwcSetMapDrive( void );
-extern void NwcSetPreferredDSTree( void );
-extern void NwcSetPrimaryConn( void );
-extern void NwcUnMapDrive( void );
-extern void NwdConvertLocalHandle( void );
-extern void NwdConvertNetwareHandle( void );
-extern void NwdGetMountPath( void );
-extern void NwdSetKeyValue( void );
-extern void NwdSetMapDrive( void );
-extern void NwdUnMapDrive( void );
-extern void NwdVerifyKeyValue( void );
-extern void Queue_Daemon_Command( void );
-extern void Queue_get( void );
-extern void Queue_put( void );
-extern void RemoveDriveMaps( void );
-extern void Scope_Cleanup( void );
-extern void Scope_Cleanup_Thread( void );
-extern void Scope_Dump_Scopetable( void );
-extern void Scope_Dump_Tasklist( void );
-extern void Scope_Find_Scope( void );
-extern void Scope_Get_Hash( void );
-extern void Scope_Get_ScopeUsers( void );
-extern void Scope_Get_ScopefromName( void );
-extern void Scope_Get_ScopefromPath( void );
-extern void Scope_Get_SessionId( void );
-extern void Scope_Get_Uid( void );
-extern void Scope_Get_UserName( void );
-extern void Scope_Get_UserSpace( void );
-extern void Scope_Init( void );
-extern void Scope_Lookup( void );
-extern void Scope_Search4Scope( void );
-extern void Scope_Set_UserSpace( void );
-extern void Scope_Timer_Function( void );
-extern void Scope_Uninit( void );
-extern void Scope_Validate_Scope( void );
-extern void Uninit_Daemon_Queue( void );
-extern void Uninit_Procfs_Interface( void );
-extern void add_to_list( void );
-extern void begin_directory_enumerate( void );
-extern void directory_enumerate( void );
-extern void directory_enumerate_ex( void );
-extern void do_login( void );
-extern void do_logout( void );
-extern void end_directory_enumerate( void );
-extern void exit_novfs( void );
-extern void find_queue( void );
-extern void get_next_queue( void );
-extern void init_novfs( void );
-extern void local_unlink( void );
-extern void process_list( void );
-extern void update_inode( void );
-extern void verify_dentry( void );
-
-SYMBOL_TABLE SymbolTable[] = {
- {Scope_Get_UserSpace, "Scope_Get_UserSpace"},
- {NwLoginIdentity, "NwLoginIdentity"},
- {Novfs_d_revalidate, "Novfs_d_revalidate"},
- {Daemon_SetMountPoint, "Daemon_SetMountPoint"},
- {Scope_Get_Hash, "Scope_Get_Hash"},
- {Queue_get, "Queue_get"},
- {Queue_Daemon_Command, "Queue_Daemon_Command"},
- {Novfs_dir_fsync, "Novfs_dir_fsync"},
- {Novfs_Read_File, "Novfs_Read_File"},
- {Daemon_Library_close, "Daemon_Library_close"},
- {NwRawSend, "NwRawSend"},
- {Novfs_get_inode, "Novfs_get_inode"},
- {Novfs_Remove_from_Root, "Novfs_Remove_from_Root"},
- {Novfs_Find_Name_In_List, "Novfs_Find_Name_In_List"},
- {Scope_Get_SessionId, "Scope_Get_SessionId"},
- {NwOpenConnByAddr, "NwOpenConnByAddr"},
- {Novfs_read_inode, "Novfs_read_inode"},
- {Novfs_Truncate_File, "Novfs_Truncate_File"},
- {Daemon_Login, "Daemon_Login"},
- {Scope_Get_ScopefromPath, "Scope_Get_ScopefromPath"},
- {NwcGetTreeMonitoredConn, "NwcGetTreeMonitoredConn"},
- {Novfs_write_inode, "Novfs_write_inode"},
- {Scope_Lookup, "Scope_Lookup"},
- {NwQueryFeature, "NwQueryFeature"},
- {Novfs_get_entry_time, "Novfs_get_entry_time"},
- {Novfs_Control_write, "Novfs_Control_write"},
- {Scope_Get_Uid, "Scope_Get_Uid"},
- {NwSysConnClose, "NwSysConnClose"},
- {NwConnClose, "NwConnClose"},
- {Novfs_get_entry, "Novfs_get_entry"},
- {Novfs_Rename_File, "Novfs_Rename_File"},
- {NwdConvertLocalHandle, "NwdConvertLocalHandle"},
- {Novfs_dir_lseek, "Novfs_dir_lseek"},
- {Scope_Get_ScopefromName, "Scope_Get_ScopefromName"},
- {NwcGetPrimaryConn, "NwcGetPrimaryConn"},
- {Novfs_d_strcmp, "Novfs_d_strcmp"},
- {Daemon_Library_ioctl, "Daemon_Library_ioctl"},
- {end_directory_enumerate, "end_directory_enumerate"},
- {directory_enumerate, "directory_enumerate"},
- {begin_directory_enumerate, "begin_directory_enumerate"},
- {NwdGetMountPath, "NwdGetMountPath"},
- {NwAuthConnWithId, "NwAuthConnWithId"},
- {Novfs_Set_Attr, "Novfs_Set_Attr"},
- {Daemon_getversion, "Daemon_getversion"},
- {Scope_Dump_Scopetable, "Scope_Dump_Scopetable"},
- {NwcSetMapDrive, "NwcSetMapDrive"},
- {Novfs_lookup_inode_cache, "Novfs_lookup_inode_cache"},
- {Novfs_i_mkdir, "Novfs_i_mkdir"},
- {Novfs_free_invalid_entries, "Novfs_free_invalid_entries"},
- {Novfs_dump_inode_cache, "Novfs_dump_inode_cache"},
- {Novfs_Write_Stream, "Novfs_Write_Stream"},
- {Novfs_Verify_Server_Name, "Novfs_Verify_Server_Name"},
- {GetConnData, "GetConnData"},
- {Uninit_Procfs_Interface, "Uninit_Procfs_Interface"},
- {Scope_Validate_Scope, "Scope_Validate_Scope"},
- {Scope_Timer_Function, "Scope_Timer_Function"},
- {Novfs_i_setattr, "Novfs_i_setattr"},
- {Novfs_i_mknod, "Novfs_i_mknod"},
- {Novfs_Verify_Volume_Name, "Novfs_Verify_Volume_Name"},
- {Novfs_Close_Stream, "Novfs_Close_Stream"},
- {Novfs_Add_to_Root, "Novfs_Add_to_Root"},
- {Init_Procfs_Interface, "Init_Procfs_Interface"},
- {Novfs_dump_inode, "Novfs_dump_inode"},
- {Novfs_Get_Directory_List, "Novfs_Get_Directory_List"},
- {Novfs_Get_Connected_Server_List, "Novfs_Get_Connected_Server_List"},
- {Daemon_Logout, "Daemon_Logout"},
- {do_logout, "do_logout"},
- {Scope_Search4Scope, "Scope_Search4Scope"},
- {NwdUnMapDrive, "NwdUnMapDrive"},
- {Novfs_Control_read, "Novfs_Control_read"},
- {Scope_Cleanup_Thread, "Scope_Cleanup_Thread"},
- {Novfs_invalidate_inode_cache, "Novfs_invalidate_inode_cache"},
- {Novfs_f_flush, "Novfs_f_flush"},
- {Novfs_enumerate_inode_cache, "Novfs_enumerate_inode_cache"},
- {Novfs_d_compare, "Novfs_d_compare"},
- {Daemon_Library_write, "Daemon_Library_write"},
- {GetUserData, "GetUserData"},
- {Daemon_Remove_Resource, "Daemon_Remove_Resource"},
- {Scope_Set_UserSpace, "Scope_Set_UserSpace"},
- {Novfs_get_alltrees, "Novfs_get_alltrees"},
- {Daemon_Get_UserSpace, "Daemon_Get_UserSpace"},
- {Uninit_Daemon_Queue, "Uninit_Daemon_Queue"},
- {NwcChangeAuthKey, "NwcChangeAuthKey"},
- {NwLicenseConn, "NwLicenseConn"},
- {Init_Daemon_Queue, "Init_Daemon_Queue"},
- {Novfs_tree_read, "Novfs_tree_read"},
- {Novfs_f_llseek, "Novfs_f_llseek"},
- {find_queue, "find_queue"},
- {Scope_Find_Scope, "Scope_Find_Scope"},
- {Novfs_lookup_validate, "Novfs_lookup_validate"},
- {Novfs_d_hash, "Novfs_d_hash"},
- {Novfs_a_readpage, "Novfs_a_readpage"},
- {Novfs_Create, "Novfs_Create"},
- {Novfs_Close_File, "Novfs_Close_File"},
- {Daemon_getpwuid, "Daemon_getpwuid"},
- {Daemon_CreateSessionId, "Daemon_CreateSessionId"},
- {Scope_dget_path, "Scope_dget_path"},
- {NwcSetDefaultNameCtx, "NwcSetDefaultNameCtx"},
- {NwcGetDefaultNameCtx, "NwcGetDefaultNameCtx"},
- {NwUnAuthenticate, "NwUnAuthenticate"},
- {Novfs_i_getattr, "Novfs_i_getattr"},
- {Novfs_get_remove_entry, "Novfs_get_remove_entry"},
- {Novfs_f_ioctl, "Novfs_f_ioctl"},
- {Scope_Get_ScopeUsers, "Scope_Get_ScopeUsers"},
- {Scope_Dump_Tasklist, "Scope_Dump_Tasklist"},
- {NwOpenConnByRef, "NwOpenConnByRef"},
- {Novfs_unlock_inode_cache, "Novfs_unlock_inode_cache"},
- {Novfs_lock_inode_cache, "Novfs_lock_inode_cache"},
- {Daemon_DestroySessionId, "Daemon_DestroySessionId"},
- {do_login, "do_login"},
- {Novfs_free_inode_cache, "Novfs_free_inode_cache"},
- {Novfs_Read_Stream, "Novfs_Read_Stream"},
- {Daemon_Library_read, "Daemon_Library_read"},
- {NwdSetMapDrive, "NwdSetMapDrive"},
- {Novfs_internal_hash, "Novfs_internal_hash"},
- {Daemon_Receive_Reply, "Daemon_Receive_Reply"},
- {Daemon_Library_open, "Daemon_Library_open"},
- {get_next_queue, "get_next_queue"},
- {exit_novfs, "exit_novfs"},
- {NwcGetBroadcastMessage, "NwcGetBroadcastMessage"},
- {Novfs_d_lookup, "Novfs_d_lookup"},
- {Novfs_clear_inode, "Novfs_clear_inode"},
- {Daemon_Open_Control, "Daemon_Open_Control"},
- {NwdConvertNetwareHandle, "NwdConvertNetwareHandle"},
- {NwcUnMapDrive, "NwcUnMapDrive"},
- {Novfs_notify_change, "Novfs_notify_change"},
- {Novfs_dir_release, "Novfs_dir_release"},
- {directory_enumerate_ex, "directory_enumerate_ex"},
- {RemoveDriveMaps, "RemoveDriveMaps"},
- {NwOpenConnByName, "NwOpenConnByName"},
- {Novfs_verify_file, "Novfs_verify_file"},
- {Novfs_statfs, "Novfs_statfs"},
- {Novfs_f_write, "Novfs_f_write"},
- {Novfs_Get_File_Info, "Novfs_Get_File_Info"},
- {Novfs_Delete, "Novfs_Delete"},
- {update_inode, "update_inode"},
- {NwcSetPreferredDSTree, "NwcSetPreferredDSTree"},
- {NwcGetPreferredDSTree, "NwcGetPreferredDSTree"},
- {Novfs_update_entry, "Novfs_update_entry"},
- {Novfs_kill_sb, "Novfs_kill_sb"},
- {Daemon_ioctl, "Daemon_ioctl"},
- {Scope_Get_UserName, "Scope_Get_UserName"},
- {NwcEnumerateDrives, "NwcEnumerateDrives"},
- {Novfs_i_revalidate, "Novfs_i_revalidate"},
- {Novfs_f_release, "Novfs_f_release"},
- {Novfs_f_read, "Novfs_f_read"},
- {Novfs_d_delete, "Novfs_d_delete"},
- {Novfs_Write_File, "Novfs_Write_File"},
- {Novfs_User_proc_ioctl, "Novfs_User_proc_ioctl"},
- {Novfs_Get_File_Info2, "Novfs_Get_File_Info2"},
- {NwdSetKeyValue, "NwdSetKeyValue"},
- {Novfs_remove_inode_entry, "Novfs_remove_inode_entry"},
- {Novfs_i_rename, "Novfs_i_rename"},
- {Novfs_f_open, "Novfs_f_open"},
- {Novfs_d_iput, "Novfs_d_iput"},
- {Novfs_Get_Directory_ListEx, "Novfs_Get_Directory_ListEx"},
- {Daemon_Timer, "Daemon_Timer"},
- {Daemon_Close_Control, "Daemon_Close_Control"},
- {verify_dentry, "verify_dentry"},
- {process_list, "process_list"},
- {local_unlink, "local_unlink"},
- {init_novfs, "init_novfs"},
- {NwUnlicenseConn, "NwUnlicenseConn"},
- {NwGetConnInfo, "NwGetConnInfo"},
- {Novfs_i_permission, "Novfs_i_permission"},
- {Novfs_dir_read, "Novfs_dir_read"},
- {NwcSetPrimaryConn, "NwcSetPrimaryConn"},
- {Novfs_f_lock, "Novfs_f_lock"},
- {Novfs_dir_readdir, "Novfs_dir_readdir"},
- {Novfs_dir_open, "Novfs_dir_open"},
- {Queue_put, "Queue_put"},
- {NwLogoutIdentity, "NwLogoutIdentity"},
- {NwGetIdentityInfo, "NwGetIdentityInfo"},
- {Novfs_i_rmdir, "Novfs_i_rmdir"},
- {Novfs_i_create, "Novfs_i_create"},
- {Novfs_f_mmap, "Novfs_f_mmap"},
- {Novfs_Write_File2, "Novfs_Write_File2"},
- {Novfs_User_proc_read, "Novfs_User_proc_read"},
- {Novfs_show_options, "Novfs_show_options"},
- {Novfs_add_inode_entry, "Novfs_add_inode_entry"},
- {Novfs_Open_File, "Novfs_Open_File"},
- {Novfs_Get_Version, "Novfs_Get_Version"},
- {Daemon_Poll, "Daemon_Poll"},
- {add_to_list, "add_to_list"},
- {Scope_Init, "Scope_Init"},
- {Scope_Cleanup, "Scope_Cleanup"},
- {NwSetConnInfo, "NwSetConnInfo"},
- {Novfs_i_unlink, "Novfs_i_unlink"},
- {Novfs_get_sb, "Novfs_get_sb"},
- {Novfs_f_readdir, "Novfs_f_readdir"},
- {Novfs_f_fsync, "Novfs_f_fsync"},
- {Novfs_d_release, "Novfs_d_release"},
- {Novfs_User_proc_write, "Novfs_User_proc_write"},
- {Daemon_Send_Command, "Daemon_Send_Command"},
- {Daemon_Dumpque, "Daemon_Dumpque"},
- {NwcEnumIdentities, "NwcEnumIdentities"},
- {NwGetDaemonVersion, "NwGetDaemonVersion"},
- {Novfs_i_lookup, "Novfs_i_lookup"},
- {Novfs_fill_super, "Novfs_fill_super"},
- {Novfs_Get_Server_Volume_List, "Novfs_Get_Server_Volume_List"},
- {Novfs_Add_to_Root2, "Novfs_Add_to_Root2"},
- {Daemon_SendDebugCmd, "Daemon_SendDebugCmd"},
- {Daemon_Added_Resource, "Daemon_Added_Resource"},
- {Scope_Uninit, "Scope_Uninit"},
- {NwdVerifyKeyValue, "NwdVerifyKeyValue"},
- {NwScanConnInfo, "NwScanConnInfo"},
- {Novfs_dget_path, "Novfs_dget_path"},
- {Novfs_d_add, "Novfs_d_add"},
- {Novfs_Control_ioctl, "Novfs_Control_ioctl"},
- // Terminate the table
- {NULL, NULL}
-};
diff -uNr src.old/novfs/scope.c src/novfs/scope.c
--- src.old/novfs/scope.c 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/scope.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,1210 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: scope.c
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: This module contains functions used to scope
- * users.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-
-/*===[ Include files specific to Linux ]==================================*/
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kthread.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/sched.h>
-#include <linux/personality.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/synclink.h>
-#include <linux/smp_lock.h>
-#include <asm/semaphore.h>
-#include <linux/security.h>
-#include <linux/syscalls.h>
-
-/*===[ Include files specific to this module ]============================*/
-#include "vfs.h"
-#define LEADER signal->leader
-
-/*===[ External data ]====================================================*/
-
-/*===[ External prototypes ]==============================================*/
-extern int DbgPrint( char *Fmt, ... );
-extern int Daemon_CreateSessionId( uint64_t *SessionId );
-extern int Daemon_DestroySessionId( uint64_t SessionId );
-extern int Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
-extern int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
-
-extern int Novfs_Remove_from_Root(char *);
-extern int Novfs_Add_to_Root(char *);
-
-/*===[ Manifest constants ]===============================================*/
-#define CLEANUP_INTERVAL 10
-#define MAX_USERNAME_LENGTH 32
-
-/*===[ Type definitions ]=================================================*/
-typedef struct _SCOPE_LIST_
-{
- struct list_head ScopeList;
- scope_t ScopeId;
- session_t SessionId;
- pid_t ScopePid;
- task_t *ScopeTask;
- unsigned long ScopeHash;
- uid_t ScopeUid;
- uint64_t ScopeUSize;
- uint64_t ScopeUFree;
- uint64_t ScopeUTEnties;
- uint64_t ScopeUAEnties;
- int ScopeUserNameLength;
- unsigned char ScopeUserName[MAX_USERNAME_LENGTH];
-} SCOPE_LIST, *PSCOPE_LIST;
-
-/*===[ Function prototypes ]==============================================*/
-void Scope_Init( void );
-void Scope_Uninit( void );
-
-PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked );
-PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create );
-unsigned long Scope_Get_Hash( PSCOPE_LIST Scope );
-uid_t Scope_Get_Uid( PSCOPE_LIST Scope );
-int Scope_Validate_Scope( PSCOPE_LIST Scope );
-char *Scope_Get_UserName( PSCOPE_LIST Scope );
-session_t Scope_Get_SessionId( PSCOPE_LIST Scope );
-PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name );
-int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
-int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
-
-char *Scope_Get_ScopeUsers( void );
-void *Scope_Lookup( void );
-
-void Scope_Timer_Function(unsigned long Context);
-int Scope_Cleanup_Thread(void *Args);
-void Scope_Cleanup( void );
-char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
-void Scope_Dump_Tasklist( void );
-void Scope_Dump_Scopetable( void );
-
-/*===[ Global variables ]=================================================*/
-struct list_head Scope_List;
-struct semaphore Scope_Lock;
-struct semaphore Scope_Thread_Delay;
-int Scope_Thread_Terminate=0;
-struct semaphore Scope_Delay_Event;
-struct timer_list Scope_Timer;
-unsigned long Scope_Hash_Val=1;
-
-/*===[ Code ]=============================================================*/
-
-/*++======================================================================*/
-void Scope_Init( void )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- INIT_LIST_HEAD( &Scope_List );
- init_MUTEX( &Scope_Lock );
- init_MUTEX_LOCKED( &Scope_Thread_Delay );
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
- kernel_thread( Scope_Cleanup_Thread, NULL, 0 );
-#else
- kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST");
-#endif
-}
-
-/*++======================================================================*/
-void Scope_Uninit( void )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- Scope_Thread_Terminate = 1;
-
- up(&Scope_Thread_Delay);
-
- mb();
- while( Scope_Thread_Terminate )
- {
- yield();
- }
- printk( KERN_INFO "Scope_Uninit: Exit\n");
-
-}
-
-/*++======================================================================*/
-PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope, rscope=NULL;
- struct list_head *sl;
- int offset;
-
- DbgPrint("Scope_Search4Scope: 0x%llx 0x%x 0x%x\n", Id, Session, Locked);
-
- if ( Session )
- {
- offset = (int)(&((PSCOPE_LIST)0)->SessionId);
- }
- else
- {
- offset = (int)(&((PSCOPE_LIST)0)->ScopeId);
- }
-
- if ( !Locked )
- {
- down( &Scope_Lock );
- }
-
- sl = Scope_List.next;
- DbgPrint("Scope_Search4Scope: 0x%x\n", sl);
- while (sl != &Scope_List)
- {
- scope = list_entry(sl, SCOPE_LIST, ScopeList);
-
- if ( Id == *(session_t *)((char *)scope+offset) )
- {
- rscope = scope;
- break;
- }
-
- sl = sl->next;
- }
-
- if ( !Locked )
- {
- up( &Scope_Lock );
- }
-
- DbgPrint("Scope_Search4Scope: return 0x%x\n", rscope);
- return( rscope );
-}
-
-/*++======================================================================*/
-PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope=NULL, pscope=NULL;
- task_t *task;
- scope_t scopeId;
- int addscope=0;
-
- task = current;
-
- DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
-
- scopeId = task->euid;
-
- scope = Scope_Search4Scope( scopeId, FALSE, FALSE );
-
- if ( !scope && Create )
- {
- scope = Novfs_Malloc( sizeof(*pscope), GFP_KERNEL );
- if ( scope )
- {
- scope->ScopeId = scopeId;
- scope->SessionId = 0;
- scope->ScopePid = task->pid;
- scope->ScopeTask = task;
- scope->ScopeHash = 0;
- scope->ScopeUid = task->euid;
- scope->ScopeUserName[0] = '\0';
-
- if ( !Daemon_CreateSessionId( &scope->SessionId ) )
- {
- DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
- memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName));
- scope->ScopeUserNameLength = 0;
- Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), scope->ScopeUserName);
- scope->ScopeUserNameLength = strlen(scope->ScopeUserName);
- addscope = 1;
- }
-
- scope->ScopeHash = Scope_Hash_Val++;
- DbgPrint("Scope_Find_Scope: Adding 0x%x\n" \
- " ScopeId: 0x%llx\n" \
- " SessionId: 0x%llx\n" \
- " ScopePid: %d\n" \
- " ScopeTask: 0x%x\n" \
- " ScopeHash: %d\n" \
- " ScopeUid: %d\n" \
- " ScopeUserNameLength: %d\n" \
- " ScopeUserName: %s\n",
- scope,
- scope->ScopeId,
- scope->SessionId,
- scope->ScopePid,
- scope->ScopeTask,
- scope->ScopeHash,
- scope->ScopeUid,
- scope->ScopeUserNameLength,
- scope->ScopeUserName);
-
- if ( scope->SessionId )
- {
- down( &Scope_Lock );
- list_add(&scope->ScopeList, &Scope_List);
- up( &Scope_Lock );
- }
- else
- {
- Novfs_Free(scope);
- scope = NULL;
- }
- }
-
- if (addscope)
- {
- Novfs_Add_to_Root( scope->ScopeUserName );
- }
- }
-
- return(scope);
-}
-
-/*++======================================================================*/
-unsigned long Scope_Get_Hash( PSCOPE_LIST Scope )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- unsigned long hash=0;
-
- if ( NULL == Scope)
- {
- Scope = Scope_Find_Scope( TRUE );
- }
-
- if ( Scope && Scope_Validate_Scope( Scope ))
- {
- hash = Scope->ScopeHash;
- }
- return( hash );
-}
-
-/*++======================================================================*/
-uid_t Scope_Get_Uid( PSCOPE_LIST Scope )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- uid_t uid=0;
-
- if ( NULL == Scope)
- {
- Scope = Scope_Find_Scope( TRUE );
- }
-
- if ( Scope && Scope_Validate_Scope( Scope ))
- {
- uid = Scope->ScopeUid;
- }
- return( uid );
-}
-
-/*++======================================================================*/
-int Scope_Validate_Scope( PSCOPE_LIST Scope )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST s;
- struct list_head *sl;
- int retVal = 0;
-
- DbgPrint("Scope_Validate_Scope: 0x%x\n", Scope);
-
- down( &Scope_Lock );
-
- sl = Scope_List.next;
- while (sl != &Scope_List)
- {
- s = list_entry(sl, SCOPE_LIST, ScopeList);
-
- if ( s == Scope )
- {
- retVal = 1;
- break;
- }
-
- sl = sl->next;
- }
-
- up( &Scope_Lock );
-
- return( retVal );
-}
-
-/*++======================================================================*/
-char *Scope_Get_UserName( PSCOPE_LIST Scope )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *name=NULL;
-
- if ( !Scope )
- {
- Scope = Scope_Find_Scope( TRUE );
- }
-
- if ( Scope && Scope_Validate_Scope( Scope ))
- {
- name = Scope->ScopeUserName;
- }
- return( name );
-}
-
-/*++======================================================================*/
-session_t Scope_Get_SessionId( PSCOPE_LIST Scope )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- session_t sessionId=0;
-
- DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope);
- if ( !Scope )
- {
- Scope = Scope_Find_Scope( TRUE );
- }
-
- if ( Scope && Scope_Validate_Scope( Scope ))
- {
- sessionId = Scope->SessionId;
- }
- DbgPrint("Scope_Get_SessionId: return 0x%llx\n", sessionId);
- return( sessionId );
-}
-
-/*++======================================================================*/
-PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope, rscope=NULL;
- struct list_head *sl;
-
- DbgPrint("Scope_Get_ScopefromName: %.*s\n", Name->len, Name->name);
-
- down( &Scope_Lock );
-
- sl = Scope_List.next;
- while (sl != &Scope_List)
- {
- scope = list_entry(sl, SCOPE_LIST, ScopeList);
-
- if ( (Name->len == scope->ScopeUserNameLength) &&
- (0 == strncmp(scope->ScopeUserName, Name->name, Name->len)) )
- {
- rscope = scope;
- break;
- }
-
- sl = sl->next;
- }
-
- up( &Scope_Lock );
-
- return( rscope );
-}
-
-/*++======================================================================*/
-int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope;
- int retVal=0;
-
- scope = Scope_Find_Scope( TRUE );
-
- if ( scope )
- {
- if (TotalSize) scope->ScopeUSize = *TotalSize;
- if (Free) scope->ScopeUFree = *Free;
- if (TotalEnties) scope->ScopeUTEnties = *TotalEnties;
- if (FreeEnties) scope->ScopeUAEnties = *FreeEnties;
- }
-
-
- return( retVal );
-}
-
-/*++======================================================================*/
-int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope;
- int retVal=0;
-
- uint64_t td, fd, te, fe;
-
- scope = Scope_Find_Scope( TRUE );
-
- td = fd = te = fe = 0;
- if ( scope )
- {
-
- retVal = Daemon_Get_UserSpace(scope->SessionId, &td, &fd, &te, &fe);
-
- scope->ScopeUSize = td;
- scope->ScopeUFree = fd;
- scope->ScopeUTEnties = te;
- scope->ScopeUAEnties = fe;
- }
-
- if (TotalSize) *TotalSize = td;
- if (Free) *Free = fd;
- if (TotalEnties) *TotalEnties = te;
- if (FreeEnties) *FreeEnties = fe;
-
- return( retVal );
-}
-
-/*++======================================================================*/
-PSCOPE_LIST Scope_Get_ScopefromPath( struct dentry *Dentry )
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope=NULL;
- char *buf, *path, *cp;
- struct qstr name;
-
- buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
- if (buf)
- {
- path = Scope_dget_path( Dentry, buf, PATH_LENGTH_BUFFER, 0 );
- if (path)
- {
- DbgPrint("Scope_Get_ScopefromPath: %s\n", path );
-
- if (*path == '/') path++;
-
- cp = path;
- if ( *cp )
- {
- while ( *cp && (*cp != '/') ) cp++;
-
- *cp = '\0';
- name.hash = 0;
- name.len = (int)(cp-path);
- name.name = path;
- scope = Scope_Get_ScopefromName( &name );
- }
- }
- Novfs_Free(buf);
- }
-
- return( scope );
-}
-
-/*++======================================================================*/
-char *add_to_list(char *Name, char *List, char *EndOfList)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- while (*Name && (List < EndOfList) )
- {
- *List++ = *Name++;
- }
-
- if (List < EndOfList)
- {
- *List++ = '\0';
- }
- return(List);
-}
-
-/*++======================================================================*/
-char *Scope_Get_ScopeUsers()
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope;
- struct list_head *sl;
- int asize=8*MAX_USERNAME_LENGTH;
- char *list, *cp, *ep;
-
- DbgPrint("Scope_Get_ScopeUsers\n");
-
- do /* Copy list until done or out of memory */
- {
- list = Novfs_Malloc(asize, GFP_KERNEL);
-
- DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list);
- if (list)
- {
- cp = list;
- ep = cp+asize;
-
- /*
- * Add the tree and server entries
- */
- cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep);
- cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep);
-
- down( &Scope_Lock );
-
- sl = Scope_List.next;
- while ( (sl != &Scope_List) && (cp < ep) )
- {
- scope = list_entry(sl, SCOPE_LIST, ScopeList);
-
- DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", scope, scope->ScopeUserName);
-
- cp = add_to_list(scope->ScopeUserName, cp, ep);
-
- sl = sl->next;
- }
-
- up( &Scope_Lock );
-
- if (cp < ep)
- {
- *cp++ = '\0';
- asize = 0;
- }
- else /* Allocation was to small, up size */
- {
- asize *= 4;
- Novfs_Free(list);
- list=NULL;
- }
- }
- else /* if allocation fails return an empty list */
- {
- break;
- }
- } while ( !list ); /* List was to small try again */
-
- return( list );
-}
-
-/*++======================================================================*/
-void *Scope_Lookup()
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope;
-
- scope = Scope_Find_Scope( TRUE );
- return( scope );
-}
-
-/*++======================================================================*/
-void
-NO_TRACE
-Scope_Timer_Function(unsigned long Context)
-/*
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- up(&Scope_Thread_Delay);
-}
-
-/*++======================================================================*/
-int Scope_Cleanup_Thread(void *Args)
-/*
- *
- * Arguments:
- *
- * Returns:
- *
- * Abstract:
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope, rscope;
- struct list_head *sl, cleanup;
- task_t *task;
-
- DbgPrint( "Scope_Cleanup_Thread: %d\n", current->pid);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
- lock_kernel();
- snprintf(current->comm, 16, "novfs_ST");
- unlock_kernel();
- sys_close(0);
- sys_close(1);
- sys_close(2);
-#endif
-
- /*
- * Setup and start que timer
- */
- init_timer( &Scope_Timer );
-
- for ( ;; )
- {
- DbgPrint( "Scope_Cleanup_Thread: looping\n");
- if ( Scope_Thread_Terminate )
- {
- break;
- }
-
- /*
- * Check scope list for any terminated processes
- */
- down( &Scope_Lock );
-
- sl = Scope_List.next;
- INIT_LIST_HEAD( &cleanup );
-
- while (sl != &Scope_List)
- {
- scope = list_entry(sl, SCOPE_LIST, ScopeList);
- sl = sl->next;
-
- rscope = NULL;
- read_lock(&tasklist_lock);
- for_each_process(task)
- {
- if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) )
- {
- rscope = scope;
- break;
- }
- }
- read_unlock(&tasklist_lock);
- if ( !rscope )
- {
- list_move( &scope->ScopeList, &cleanup );
- DbgPrint("Scope_Cleanup_Thread: Scope=0x%x\n", rscope);
- }
- }
-
- up(&Scope_Lock);
-
- sl = cleanup.next;
- while ( sl != &cleanup )
- {
- scope = list_entry(sl, SCOPE_LIST, ScopeList);
- sl = sl->next;
-
- DbgPrint("Scope_Cleanup_Thread: Removing 0x%x\n" \
- " ScopeId: 0x%llx\n" \
- " SessionId: 0x%llx\n" \
- " ScopePid: %d\n" \
- " ScopeTask: 0x%x\n" \
- " ScopeHash: %d\n" \
- " ScopeUid: %d\n" \
- " ScopeUserName: %s\n",
- scope,
- scope->ScopeId,
- scope->SessionId,
- scope->ScopePid,
- scope->ScopeTask,
- scope->ScopeHash,
- scope->ScopeUid,
- scope->ScopeUserName);
- if ( !Scope_Search4Scope(scope->SessionId, TRUE, FALSE) )
- {
- Novfs_Remove_from_Root( scope->ScopeUserName );
- Daemon_DestroySessionId( scope->SessionId );
- }
- Novfs_Free( scope );
- }
-
- Scope_Timer.expires = jiffies + HZ*CLEANUP_INTERVAL;
- Scope_Timer.data = (unsigned long)0;
- Scope_Timer.function = Scope_Timer_Function;
- add_timer(&Scope_Timer);
- DbgPrint( "Scope_Cleanup_Thread: sleeping\n");
-
- if (down_interruptible( &Scope_Thread_Delay ))
- {
- break;
- }
- del_timer(&Scope_Timer);
- }
- Scope_Thread_Terminate = 0;
-
- printk( KERN_INFO "Scope_Cleanup_Thread: Exit\n");
- DbgPrint( "Scope_Cleanup_Thread: Exit\n");
- return(0);
-}
-
-/*++======================================================================*/
-void Scope_Cleanup( void )
-/*
- *
- * Arguments: None
- *
- * Returns: Nothing
- *
- * Abstract: Removes all knows scopes.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- PSCOPE_LIST scope;
- struct list_head *sl;
-
- DbgPrint( "Scope_Cleanup:\n");
-
- /*
- * Check scope list for any terminated processes
- */
- down( &Scope_Lock );
-
- sl = Scope_List.next;
-
- while (sl != &Scope_List)
- {
- scope = list_entry( sl, SCOPE_LIST, ScopeList );
- sl = sl->next;
-
- list_del( &scope->ScopeList );
-
- DbgPrint("Scope_Cleanup: Removing 0x%x\n" \
- " ScopeId: 0x%llx\n" \
- " SessionId: 0x%llx\n" \
- " ScopePid: %d\n" \
- " ScopeTask: 0x%x\n" \
- " ScopeHash: %d\n" \
- " ScopeUid: %d\n" \
- " ScopeUserName: %s\n",
- scope,
- scope->ScopeId,
- scope->SessionId,
- scope->ScopePid,
- scope->ScopeTask,
- scope->ScopeHash,
- scope->ScopeUid,
- scope->ScopeUserName);
- if ( !Scope_Search4Scope( scope->SessionId, TRUE, TRUE ) )
- {
- Novfs_Remove_from_Root( scope->ScopeUserName );
- Daemon_DestroySessionId( scope->SessionId );
- }
- Novfs_Free( scope );
- }
-
- up(&Scope_Lock);
-
-}
-
-/*++======================================================================*/
-char *
-NO_TRACE
-Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags)
-/*
- * Arguments: struct dentry *Dentry - starting entry
- * char *Buf - pointer to memory buffer
- * unsigned int Buflen - size of memory buffer
- *
- * Returns: pointer to path.
- *
- * Abstract: Walks the dentry chain building a path.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- char *retval=&Buf[Buflen];
- struct dentry *p=Dentry;
- int len;
-
- *(--retval) = '\0';
- Buflen--;
-
-/*
- if (!IS_ROOT(p))
- {
- while (Buflen && !IS_ROOT(p))
- {
- if (Buflen > p->d_name.len)
- {
- retval -= p->d_name.len;
- Buflen -= p->d_name.len;
- memcpy(retval, p->d_name.name, p->d_name.len);
- *(--retval) = '/';
- Buflen--;
- p = p->d_parent;
- }
- else
- {
- retval = NULL;
- break;
- }
- }
- }
- if (Flags)
- {
- len = strlen(p->d_sb->s_type->name);
- if (Buflen-len > 0)
- {
- retval -= len;
- Buflen -= len;
- memcpy(retval, p->d_sb->s_type->name, len);
- *(--retval) = '/';
- Buflen--;
- }
- }
- else
- {
- *(--retval) = '/';
- Buflen--;
- }
-*/
- do
- {
- if (Buflen > p->d_name.len)
- {
- retval -= p->d_name.len;
- Buflen -= p->d_name.len;
- memcpy(retval, p->d_name.name, p->d_name.len);
- *(--retval) = '/';
- Buflen--;
- p = p->d_parent;
- }
- else
- {
- retval = NULL;
- break;
- }
- } while (!IS_ROOT(p));
-
- if (IS_ROOT(Dentry))
- {
- retval++;
- }
-
- if (Flags)
- {
- len = strlen(p->d_sb->s_type->name);
- if (Buflen-len > 0)
- {
- retval -= len;
- Buflen -= len;
- memcpy(retval, p->d_sb->s_type->name, len);
- *(--retval) = '/';
- Buflen--;
- }
- }
-
- return(retval);
-}
-
-void Scope_Dump_Tasklist( void )
-{
-#ifdef OLD_DEBUG_KERNEL
- task_t *task;
- struct files_struct *fs;
- int i, open_files=0;
- static char buf[1024];
- char *path;
-
-
- for_each_process(task)
- {
- kdb_printf("Task List:\n" \
- " Task: 0x%p\n" \
- " pid: %d\n" \
- " tgid: %d\n" \
- " uid: %d %d %d %d\n" \
- " gid: %d\n" \
- " parent: 0x%p\n" \
- " comm: %s\n" \
- " user: 0x%p\n" \
- " real_parent: 0x%p\n" \
- " parent_exec_id: 0x%x\n" \
- " self_exec_id: 0x%x\n" \
- " did_exec: 0x%x\n" \
- " signal: 0x%p\n" \
- " thread_info: 0x%p\n" \
- " security: 0x%p\n",
- task,
- task->pid,
- task->tgid,
- task->uid,task->euid,task->suid,task->fsuid,
- task->gid,
- task->parent,
- task->comm,
- task->user,
- task->real_parent,
- task->parent_exec_id,
- task->self_exec_id,
- task->did_exec,
- task->signal,
- task->thread_info,
- task->security);
-
- fs = task->files;
- kdb_printf(" File List: 0x%p\n", fs);
- if (fs)
- {
- open_files = fs->max_fds;
- kdb_printf(" Max fds: %d\n", open_files);
- for (i = 0; i<open_files; i++)
- {
- struct file *f = fs->fd[i];
- if (f && (f->f_dentry))
- {
- path = Scope_dget_path(f->f_dentry, buf, sizeof(buf), 1);
- if ( !path )
- {
- path = buf;
- memcpy(path, f->f_dentry->d_name.name, f->f_dentry->d_name.len);
- path[f->f_dentry->d_name.len] = '\0';
- }
- kdb_printf(" file(%d): 0x%p\n" \
- " f_dentry: 0x%p\n" \
- " d_name: %s\n" \
- " d_count: %d\n" \
- " d_inode: 0x%p\n",
- i, f, f->f_dentry, path,
- atomic_read(&f->f_dentry->d_count),
- f->f_dentry->d_inode);
- }
- }
- }
- }
-#endif
-}
-
-void Scope_Dump_Scopetable( void )
-{
-#ifdef CONFIG_KDB
- PSCOPE_LIST scope;
- struct list_head *sl;
-
- sl = Scope_List.next;
- while (sl != &Scope_List)
- {
- scope = list_entry(sl, SCOPE_LIST, ScopeList);
- sl = sl->next;
- kdb_printf("Scope List:\n" \
- " Scope: 0x%p\n" \
- " ScopeId: 0x%llx\n" \
- " SessionId: 0x%llx\n" \
- " ScopePid: %u\n" \
- " ScopeTask: 0x%p\n" \
- " ScopeHash: 0x%lx\n" \
- " ScopeUid: %ld\n" \
- " ScopeUserName: %s\n",
- scope,
- scope->ScopeId,
- scope->SessionId,
- scope->ScopePid,
- scope->ScopeTask,
- scope->ScopeHash,
- (long)scope->ScopeUid,
- scope->ScopeUserName);
-
- }
-
-#endif
-}
diff -uNr src.old/novfs/vfs.h src/novfs/vfs.h
--- src.old/novfs/vfs.h 2006-07-11 21:24:18.000000000 +0200
+++ src/novfs/vfs.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,276 +0,0 @@
-/*++========================================================================
- * Program Name: Novell NCP Redirector for Linux
- * File Name: vfs.h
- * Version: v1.00
- * Author: James Turner
- *
- * Abstract: Include module for novfs.
- * Notes:
- * Revision History:
- *
- *
- * Copyright (C) 2005 Novell, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *======================================================================--*/
-#ifndef __STDC_VERSION__
-#define __STDC_VERSION__ 0L
-#endif
-
-/*===[ Include files specific to Linux ]==================================*/
-#ifdef CONFIG_KDB
-#include <linux/kdb.h>
-#include <linux/kdbprivate.h>
-
-#endif /* CONFIG_KDB */
-
-#include <linux/version.h>
-#include <linux/namei.h>
-
-/*===[ Include files specific to this module ]============================*/
-
-/*===[ External data ]====================================================*/
-extern int Novfs_Version_Major;
-extern int Novfs_Version_Minor;
-extern int Novfs_Version_Sub;
-extern int Novfs_Version_Release;
-
-/*===[ External prototypes ]==============================================*/
-extern void *Novfs_Malloc( size_t, int );
-extern void Novfs_Free( const void * );
-
-
-/*===[ Manifest constants ]===============================================*/
-#define NOVFS_MAGIC 0x4e574653
-#define MODULE_NAME "novfs"
-
-#define UNUSED_VARIABLE(a) (a) = (a)
-
-#define TREE_DIRECTORY_NAME ".Trees"
-#define SERVER_DIRECTORY_NAME ".Servers"
-
-#define PATH_LENGTH_BUFFER PATH_MAX
-#define NW_MAX_PATH_LENGTH 255
-
-#define IOC_LOGIN 0x4a540000
-#define IOC_LOGOUT 0x4a540001
-#define IOC_XPLAT 0x4a540002
-#define IOC_SESSION 0x4a540003
-#define IOC_DEBUGPRINT 0x4a540004
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
-#define D_CHILD d_u.d_child
-#else
-#define D_CHILD d_child
-#endif
-
-/*
- * NetWare file attributes
- */
-
-#define NW_ATTRIBUTE_NORMAL 0x00
-#define NW_ATTRIBUTE_READ_ONLY 0x01
-#define NW_ATTRIBUTE_HIDDEN 0x02
-#define NW_ATTRIBUTE_SYSTEM 0x04
-#define NW_ATTRIBUTE_EXECUTE_ONLY 0x08
-#define NW_ATTRIBUTE_DIRECTORY 0x10
-#define NW_ATTRIBUTE_ARCHIVE 0x20
-#define NW_ATTRIBUTE_EXECUTE 0x40
-#define NW_ATTRIBUTE_SHAREABLE 0x80
-
-/*
- * Define READ/WRITE flag for DATA_LIST
- */
-#define DLREAD 0
-#define DLWRITE 1
-
-/*
- * Define list type
- */
-#define USER_LIST 1
-#define SERVER_LIST 2
-#define VOLUME_LIST 3
-
-/*
- * Define flags used in for inodes
- */
-#define USER_INODE 1
-#define UPDATE_INODE 2
-
-/*
- * Define flags for directory cache flags
- */
-#define ENTRY_VALID 0x00000001
-
-#ifdef INTENT_MAGIC
-#define NDOPENFLAGS intent.it_flags
-#else
-#define NDOPENFLAGS intent.open.flags
-#endif
-
-/*
- * daemon_command_t flags values
- */
-#define INTERRUPTIBLE 1
-
-#define NO_TRACE __attribute__((__no_instrument_function__))
-
-#ifndef NOVFS_VFS_MAJOR
-#define NOVFS_VFS_MAJOR 0
-#endif
-
-#ifndef NOVFS_VFS_MINOR
-#define NOVFS_VFS_MINOR 0
-#endif
-
-#ifndef NOVFS_VFS_SUB
-#define NOVFS_VFS_SUB 0
-#endif
-
-#ifndef NOVFS_VFS_RELEASE
-#define NOVFS_VFS_RELEASE 0
-#endif
-
-#define VALUE_TO_STR( value ) #value
-#define DEFINE_TO_STR(value) VALUE_TO_STR(value)
-
-
-#define NOVFS_VERSION_STRING \
- DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \
- DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \
- DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \
- DEFINE_TO_STR(NOVFS_VFS_RELEASE)
-
-/*===[ Type definitions ]=================================================*/
-typedef struct _ENTRY_INFO
-{
- int type;
- umode_t mode;
- uid_t uid;
- gid_t gid;
- loff_t size;
- struct timespec atime;
- struct timespec mtime;
- struct timespec ctime;
- int namelength;
- unsigned char name[1];
-} ENTRY_INFO, *PENTRY_INFO;
-
-typedef struct _STRING_
-{
- int Length;
- unsigned char *Data;
-} STRING, *PSTRING;
-
-typedef struct _LOGIN_
-{
- STRING Server;
- STRING UserName;
- STRING Password;
-} LOGIN, *PLOGIN;
-
-typedef struct _LOGOUT_
-{
- STRING Server;
-} LOGOUT, *PLOGOUT;
-
-typedef uint64_t scope_t;
-typedef uint64_t session_t;
-
-typedef struct _DIR_CACHE_
-{
- struct list_head list;
- int flags;
- u64 jiffies;
- ino_t ino;
- loff_t size;
- umode_t mode;
- struct timespec atime;
- struct timespec mtime;
- struct timespec ctime;
- unsigned long hash;
- int nameLen;
- char name[1];
-} DIR_CACHE, *PDIR_CACHE;
-
-typedef struct _INODE_DATA_
-{
- void *Scope;
- unsigned long Flags;
- struct list_head IList;
- struct inode *Inode;
- struct list_head DirCache;
- struct semaphore DirCacheLock;
- char Name[1]; /* Needs to be last entry */
-} INODE_DATA, *PINODE_DATA;
-
-typedef struct _DATA_LIST_
-{
- void *page;
- void *offset;
- int len;
- int rwflag;
-} DATA_LIST, *PDATA_LIST;
-
-typedef struct _XPLAT_
-{
- int xfunction;
- unsigned long reqLen;
- void *reqData;
- unsigned long repLen;
- void *repData;
-
-} XPLAT, *PXPLAT;
-
-
-/*===[ Function prototypes ]==============================================*/
-
-extern int DbgPrint( char *Fmt, ... );
-extern char *ctime_r(time_t *clock, char *buf);
-
-
-/*++======================================================================*/
-static inline unsigned long InterlockedIncrement( unsigned long *p )
-/*
- *
- * Arguments: unsigned long *p - pointer to value.
- *
- * Returns: unsigned long - value prior to increment.
- *
- * Abstract: The value of *p is incremented and the value of *p before
- * it was incremented is returned. This is an atomic operation.
- *
- * Notes:
- *
- * Environment:
- *
- *========================================================================*/
-{
- unsigned long x = 1;
-
- mb();
-
-#if defined(__i386) || defined(__i386__)
- __asm__ __volatile__(
- " lock xadd %0,(%2)"
- : "+r"(x), "=m"(p)
- : "r"(p), "m"(p)
- : "memory");
-
-#else
- x = *p++;
-#endif
- return( x );
-}
diff -uNr src.old/src/Makefile src/src/Makefile
--- src.old/src/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ src/src/Makefile 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,58 @@
+##*++======================================================================
+## Program Name: Novell NCP Redirector for Linux
+## File Name: Makefile
+## Version: v1.01
+## Author: James Turner
+##
+## Abstract: This is used to generate the novfs module
+## Notes:
+## Revision History:
+## 6/10/2005 - Added lines for SuSE
+##
+## Copyright (C) 2005 Novell, Inc.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##=====================================================================--*/
+
+#
+# Makefile for the Novell NetWare Client for Linux filesystem.
+#
+NOVFS_VFS_MAJOR = 2
+NOVFS_VFS_MINOR = 0
+NOVFS_VFS_SUB = 0
+NOVFS_VFS_RELEASE = 0
+
+# Remove # from the following line for debug version
+EXTRA_CFLAGS += -finstrument-functions
+EXTRA_CFLAGS += -g
+EXTRA_CFLAGS += -I.
+EXTRA_CFLAGS += -I$(obj)/../include
+EXTRA_CFLAGS += -I$(obj)/../../include
+EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR)
+EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR)
+EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB)
+EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH)
+EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE)
+
+
+obj-m := novfs.o
+
+novfs-y := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o
+
+all:
+ make -C /usr/src/linux SUBDIRS=`pwd` modules
+
+clean:
+ make -C /usr/src/linux SUBDIRS=`pwd` modules clean
diff -uNr src.old/src/blank.c src/src/blank.c
--- src.old/src/blank.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/blank.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,61 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: .c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module
+ *
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+
+/*===[ Include files specific to this module ]============================*/
+
+/*===[ External data ]====================================================*/
+
+/*===[ External prototypes ]==============================================*/
+
+/*===[ Manifest constants ]===============================================*/
+
+/*===[ Type definitions ]=================================================*/
+
+/*===[ Function prototypes ]==============================================*/
+
+/*===[ Global variables ]=================================================*/
+
+/*===[ Code ]=============================================================*/
+
+/*++======================================================================*/
+Function
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
diff -uNr src.old/src/daemon.c src/src/daemon.c
--- src.old/src/daemon.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/daemon.c 2006-10-16 15:08:23.000000000 +0200
@@ -0,0 +1,2863 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: daemon.c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module contains all the functions necessary
+ * for sending commands to our daemon module.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include <linux/time.h>
+
+
+/*===[ Include files specific to this module ]============================*/
+#include "vfs.h"
+#include "nwcapi.h"
+#include "commands.h"
+#include "nwerror.h"
+
+/*===[ External data ]====================================================*/
+extern char *Novfs_CurrentMount;
+
+/*===[ External prototypes ]==============================================*/
+extern int DbgPrint( char *Fmt, ... );
+extern void mydump(int size, void *dumpptr);
+
+extern char *Scope_Get_UserName( void *Scope );
+extern void *Scope_Lookup( void );
+extern session_t Scope_Get_SessionId( void *Scope );
+extern void Scope_Cleanup( void );
+
+extern int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
+extern int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+extern int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
+
+extern int Novfs_Add_to_Root(char *);
+
+/*
+ * profile.c functions
+ */
+extern uint64_t get_nanosecond_time( void );
+
+/*
+ * nwcapi.c functions
+ */
+extern int NwAuthConnWithId(PXPLAT pdata, session_t Session);
+extern int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
+extern int NwGetConnInfo(PXPLAT pdata, session_t Session);
+extern int NwSetConnInfo(PXPLAT pdata, session_t Session);
+extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session);
+extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session);
+extern int NwLicenseConn(PXPLAT pdata, session_t Session);
+extern int NwLoginIdentity(PXPLAT pdata, session_t Session);
+extern int NwLogoutIdentity(PXPLAT pdata, session_t Session);
+extern int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session);
+extern int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session);
+extern int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session);
+extern int NwQueryFeature(PXPLAT pdata, session_t Session);
+extern int NwRawSend(PXPLAT pdata, session_t Session);
+extern int NwScanConnInfo(PXPLAT pdata, session_t Session);
+extern int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
+extern int NwUnAuthenticate(PXPLAT pdata, session_t Session);
+extern int NwUnlicenseConn(PXPLAT pdata, session_t Session);
+extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session);
+extern int NwcEnumIdentities(PXPLAT pdata, session_t Session);
+extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session);
+extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session);
+extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session);
+extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session);
+extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session);
+extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session);
+extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session);
+extern int NwcSetMapDrive(PXPLAT pdata, session_t Session);
+extern int NwcUnMapDrive(PXPLAT pdata, session_t Session);
+extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session);
+extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session);
+extern int NwdSetKeyValue(PXPLAT pdata, session_t Session);
+extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session);
+
+/*===[ Manifest constants ]===============================================*/
+#define QUEUE_SENDING 0
+#define QUEUE_WAITING 1
+#define QUEUE_TIMEOUT 2
+#define QUEUE_ACKED 3
+#define QUEUE_DONE 4
+
+#define TIMEOUT_VALUE 10
+
+#define DH_TYPE_UNDEFINED 0
+#define DH_TYPE_STREAM 1
+#define DH_TYPE_CONNECTION 2
+
+/*===[ Type definitions ]=================================================*/
+typedef struct _DAEMON_QUEUE
+{
+ struct list_head list; /* Must be first entry */
+ spinlock_t lock; /* Used to control access to list */
+ struct semaphore semaphore; /* Used to signal when data is available */
+} daemon_queue_t;
+
+typedef struct _DAEMON_COMMAND
+{
+ struct list_head list; /* Must be first entry */
+ atomic_t reference;
+ u_long status;
+ u_long flags;
+ struct semaphore semaphore;
+ u_long sequence;
+ struct timer_list timer;
+ void *request;
+ u_long reqlen;
+ void *data;
+ int datalen;
+ void *reply;
+ u_long replen;
+} daemon_command_t;
+
+
+typedef struct _DAEMON_HANDLE_
+{
+ struct list_head list;
+ rwlock_t lock;
+ session_t session;
+} daemon_handle_t;
+
+typedef struct _DAEMON_RESOURCE_
+{
+ struct list_head list;
+ int type;
+ u_long connection;
+ u_char handle[6];
+ mode_t mode;
+ loff_t size;
+} daemon_resource_t;
+
+typedef struct _DRIVE_MAP_
+{
+ struct list_head list; /* Must be first item */
+ session_t session;
+ u_long hash;
+ int namelen;
+ char name[1];
+} drive_map_t;
+
+/*===[ Function prototypes ]==============================================*/
+int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size);
+int Daemon_Close_Control(struct inode *Inode, struct file *File);
+int Daemon_CreateSessionId( uint64_t *SessionId );
+int Daemon_DestroySessionId( uint64_t SessionId );
+void Daemon_Dumpque( void );
+int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
+int Daemon_Library_close(struct inode *inode, struct file *file);
+int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
+int Daemon_Library_open(struct inode *inode, struct file *file);
+ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
+ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
+loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
+int Daemon_Login(PLOGIN Login, session_t Session);
+int Daemon_Logout(PLOGOUT Logout, session_t Session);
+int Daemon_Open_Control(struct inode *Inode, struct file *File);
+uint Daemon_Poll(struct file *file, struct poll_table_struct *poll_table);
+ssize_t Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle);
+
+ssize_t Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
+int Daemon_SetMountPoint( char *Path );
+void Daemon_Timer(u_long data);
+int Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
+int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
+void Init_Daemon_Queue( void );
+int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
+void Queue_get(daemon_command_t *que);
+void Queue_put(daemon_command_t *que);
+void Uninit_Daemon_Queue( void );
+int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
+int do_logout( struct qstr *Server, session_t Session );
+daemon_command_t *find_queue(u_long sequence);
+daemon_command_t *get_next_queue(int Set_Queue_Waiting);
+int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle);
+int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle);
+int NwdGetMountPath(PXPLAT pdata);
+int NwdSetMapDrive(PXPLAT pdata, session_t Session);
+int NwdUnMapDrive(PXPLAT pdata, session_t Session);
+void RemoveDriveMaps( void );
+int local_unlink(const char *pathname);
+
+/*===[ Global variables ]=================================================*/
+daemon_queue_t Daemon_Queue;
+
+static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue);
+
+u_long Sequence = 0;
+atomic_t Daemon_Open_Count=ATOMIC_INIT(0);
+
+u_long Daemon_Command_Timeout = TIMEOUT_VALUE;
+
+DECLARE_MUTEX ( DriveMapLock );
+LIST_HEAD( DriveMapList );
+
+int MaxIoSize=PAGE_SIZE;
+
+/*===[ Code ]=============================================================*/
+
+/*++======================================================================*/
+void Init_Daemon_Queue()
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ INIT_LIST_HEAD(&Daemon_Queue.list);
+ spin_lock_init(&Daemon_Queue.lock);
+ init_MUTEX_LOCKED(&Daemon_Queue.semaphore);
+}
+
+/*++======================================================================*/
+void Uninit_Daemon_Queue( void )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ /* Does nothing for now but we maybe should clear the queue. */
+}
+
+/*++======================================================================*/
+void
+NO_TRACE
+Daemon_Timer(u_long data)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que = (daemon_command_t *)data;
+
+ if ( QUEUE_ACKED != que->status )
+ {
+ que->status = QUEUE_TIMEOUT;
+ }
+ up(&que->semaphore);
+}
+
+/*++======================================================================*/
+int Queue_Daemon_Command(
+ void *request,
+ u_long reqlen,
+ void *data,
+ int dlen,
+ void **reply,
+ u_long *replen,
+ int interruptible)
+/*
+ *
+ * Arguments: void *request - pointer to the request that is to be sent. Needs to be kernel memory.
+ * int reqlen - length of the request.
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+ int retCode = 0;
+ uint64_t ts1, ts2;
+
+ ts1 = get_nanosecond_time();
+
+ DbgPrint( "Queue_Daemon_Command: 0x%x %d\n", request, reqlen);
+
+ if (atomic_read(&Daemon_Open_Count))
+ {
+
+ que = (daemon_command_t *)Novfs_Malloc(sizeof(*que), GFP_KERNEL);
+
+ DbgPrint( "Queue_Daemon_Command: que=0x%x\n", que);
+ if (que)
+ {
+ atomic_set( &que->reference, 0 );
+ que->status = QUEUE_SENDING;
+ que->flags = 0;
+
+ init_MUTEX_LOCKED(&que->semaphore);
+
+ DbgPrint( "Queue_Daemon_Command: semaphore inited que=0x%x\n", que);
+
+ que->sequence = InterlockedIncrement(&Sequence);
+
+ DbgPrint( "Queue_Daemon_Command: sequence=0x%x\n", que->sequence);
+
+ ((PCOMMAND_REQUEST_HEADER)request)->SequenceNumber = que->sequence;
+
+ /*
+ * Setup and start que timer
+ */
+ init_timer(&que->timer);
+ que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout);
+ que->timer.data = (u_long)que;
+ que->timer.function = Daemon_Timer;
+ add_timer(&que->timer);
+
+ DbgPrint( "Queue_Daemon_Command: timer started que=0x%x\n", que);
+
+ /*
+ * Setup request
+ */
+ que->request = request;
+ que->reqlen = reqlen;
+ que->data = data;
+ que->datalen = dlen;
+ que->reply = NULL;
+ que->replen = 0;
+
+ DbgPrint( "Queue_Daemon_Command: setting up que=0x%x\n", que);
+
+ /*
+ * Added entry to queue.
+ */
+ DbgPrint( "Queue_Daemon_Command: Daemon_Queue locked\n");
+
+ /*
+ * Check to see if interruptible and set flags.
+ */
+ if (interruptible)
+ {
+ que->flags |= INTERRUPTIBLE;
+ }
+
+ Queue_get( que );
+
+ spin_lock(&Daemon_Queue.lock);
+ list_add_tail(&que->list, &Daemon_Queue.list);
+ spin_unlock(&Daemon_Queue.lock);
+
+ DbgPrint( "Queue_Daemon_Command: 0x%x added to Daemon_Queue\n", que);
+ /*
+ * Signal that there is data to be read
+ */
+ up(&Daemon_Queue.semaphore);
+
+ /*
+ * Give a change to the other processes.
+ */
+ yield();
+
+ DbgPrint( "Queue_Daemon_Command: calling down 0x%x\n", CURRENT_TIME);
+
+ /*
+ * Block waiting for reply or timeout
+ */
+ down(&que->semaphore);
+
+ DbgPrint( "Queue_Daemon_Command: after down 0x%x\n", CURRENT_TIME);
+
+ if ( QUEUE_ACKED == que->status )
+ {
+ que->status = QUEUE_WAITING;
+ mod_timer(&que->timer, jiffies + (HZ * 2 * Daemon_Command_Timeout));
+ DbgPrint( "Queue_Daemon_Command: mod_timer 0x%x\n", CURRENT_TIME);
+ if (interruptible)
+ {
+ retCode = down_interruptible(&que->semaphore);
+ }
+ else
+ {
+ down(&que->semaphore);
+ }
+ DbgPrint( "Queue_Daemon_Command: after down2 0x%x\n", CURRENT_TIME);
+ }
+
+ DbgPrint( "Queue_Daemon_Command: after down 0x%d 0x%x\n", retCode, CURRENT_TIME);
+ /*
+ * Delete timer
+ */
+ del_timer(&que->timer);
+
+ /*
+ * Check for timeout
+ */
+ if ((QUEUE_TIMEOUT == que->status) && (NULL == que->reply) )
+ {
+ DbgPrint( "Queue_Daemon_Command: Timeout\n");
+ retCode = -ETIME;
+ }
+ *reply = que->reply;
+ *replen = que->replen;
+
+ /*
+ * Remove item from queue
+ */
+ Queue_put( que );
+
+ }
+ else /* Error case with no memory */
+ {
+ retCode = -ENOMEM;
+ *reply = NULL;
+ *replen = 0;
+ }
+ }
+ else
+ {
+ retCode = -EIO;
+ *reply = NULL;
+ *replen = 0;
+
+ }
+ ts2 = get_nanosecond_time();
+ ts2 = ts2-ts1;
+
+ DbgPrint( "Queue_Daemon_Command: %llu retCode=%d \n", ts2, retCode);
+ return(retCode);
+}
+
+/*++======================================================================*/
+void Queue_get(daemon_command_t *Que)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference));
+ atomic_inc( &Que->reference );
+}
+
+/*++======================================================================*/
+void Queue_put(daemon_command_t *Que)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+
+ DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference));
+ spin_lock(&Daemon_Queue.lock);
+
+ if ( atomic_dec_and_test( &Que->reference ))
+ {
+ /*
+ * Remove item from queue
+ */
+ list_del(&Que->list);
+ spin_unlock(&Daemon_Queue.lock);
+
+ /*
+ * Free item memory
+ */
+ Novfs_Free(Que);
+ }
+ else
+ {
+ spin_unlock(&Daemon_Queue.lock);
+ }
+}
+
+/*++======================================================================*/
+daemon_command_t *get_next_queue(int Set_Queue_Waiting)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+
+ DbgPrint( "get_next_queue: que=0x%p\n", Daemon_Queue.list.next);
+
+ spin_lock(&Daemon_Queue.lock);
+ que = (daemon_command_t *)Daemon_Queue.list.next;
+
+ while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && ( que->status != QUEUE_SENDING ) )
+ {
+ que = (daemon_command_t *)que->list.next;
+ }
+
+ if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list) || (que->status != QUEUE_SENDING))
+ {
+ que = NULL;
+ }
+ else if (Set_Queue_Waiting)
+ {
+ que->status = QUEUE_WAITING;
+ }
+
+ if (que)
+ {
+ atomic_inc( &que->reference );
+ }
+
+ spin_unlock(&Daemon_Queue.lock);
+
+ DbgPrint( "get_next_queue: return=0x%x\n", que);
+ return(que);
+}
+
+/*++======================================================================*/
+daemon_command_t *find_queue(u_long sequence)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+
+ DbgPrint( "find_queue: 0x%x\n", sequence);
+
+ spin_lock(&Daemon_Queue.lock);
+ que = (daemon_command_t *)Daemon_Queue.list.next;
+
+
+ while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->sequence != sequence))
+ {
+ que = (daemon_command_t *)que->list.next;
+ }
+
+ if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list.next) || (que->sequence != sequence))
+ {
+ que = NULL;
+ }
+
+ if (que)
+ {
+ atomic_inc( &que->reference );
+ }
+
+ spin_unlock(&Daemon_Queue.lock);
+
+ DbgPrint( "find_queue: return 0x%p\n", que);
+ return(que);
+}
+/*++======================================================================*/
+int Daemon_Open_Control(struct inode *Inode, struct file *File)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
+ atomic_inc(&Daemon_Open_Count);
+
+ return(0);
+}
+
+/*++======================================================================*/
+int Daemon_Close_Control(struct inode *Inode, struct file *File)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+
+ DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
+
+ if (atomic_dec_and_test(&Daemon_Open_Count))
+ {
+ /*
+ * Signal any pending que itmes.
+ */
+
+ spin_lock(&Daemon_Queue.lock);
+ que = (daemon_command_t *)Daemon_Queue.list.next;
+
+ while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->status != QUEUE_DONE))
+ {
+ que->status = QUEUE_TIMEOUT;
+ up(&que->semaphore);
+
+ que = (daemon_command_t *)que->list.next;
+ }
+ spin_unlock(&Daemon_Queue.lock);
+
+ RemoveDriveMaps();
+
+ Scope_Cleanup();
+ }
+
+ return(0);
+}
+
+/*++======================================================================*/
+ssize_t
+Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+ size_t retValue = 0;
+ int Finished=0;
+ PDATA_LIST dlist;
+ int i, dcnt, bcnt, ccnt, error;
+ char *vadr;
+ u_long cpylen;
+
+ DbgPrint( "Daemon_Send_Command: %u %lld\n", len, *off);
+ if (len > MaxIoSize)
+ {
+ MaxIoSize = len;
+ }
+
+ while ( !Finished )
+ {
+ que = get_next_queue(1);
+ DbgPrint( "Daemon_Send_Command: 0x%x\n", que);
+ if (que)
+ {
+ retValue = que->reqlen;
+ if (retValue > len)
+ {
+ retValue = len;
+ }
+ if (retValue > 0x80)
+ mydump(0x80, que->request);
+ else
+ mydump(retValue, que->request);
+
+ cpylen = copy_to_user(buf, que->request, retValue);
+ if (que->datalen && (retValue < len))
+ {
+ buf += retValue;
+ dlist = que->data;
+ dcnt = que->datalen;
+ for (i=0; i<dcnt; i++, dlist++)
+ {
+ if ( DLREAD == dlist->rwflag )
+ {
+ bcnt = dlist->len;
+ DbgPrint("Daemon_Send_Command%d: page=0x%x offset=0x%x len=%d\n", i, dlist->page, dlist->offset, dlist->len);
+ if ((bcnt + retValue) <= len)
+ {
+ void *km_adr=NULL;
+
+ if (dlist->page)
+ {
+ km_adr = kmap(dlist->page);
+ vadr = km_adr;
+ vadr += (u_int)dlist->offset;
+ }
+ else
+ {
+ vadr = dlist->offset;
+ }
+
+ ccnt = copy_to_user(buf, vadr, bcnt);
+
+ if ( km_adr )
+ {
+ kunmap(dlist->page);
+ }
+
+ DbgPrint("Daemon_Send_Command: Copy %d from 0x%x to 0x%x.\n", bcnt, vadr, buf);
+ if (bcnt > 0x80)
+ mydump(0x80, vadr);
+ else
+ mydump(bcnt, vadr);
+
+ retValue += bcnt;
+ buf += bcnt;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ Queue_put( que );
+ break;
+ }
+
+ if (O_NONBLOCK & file->f_flags)
+ {
+ retValue = -EAGAIN;
+ break;
+ }
+ else
+ {
+ if ((error = down_interruptible(&Daemon_Queue.semaphore)))
+ {
+ DbgPrint( "Daemon_Send_Command: after down_interruptible error...%d\n", error);
+ retValue = -EINTR;
+ break;
+ }
+ DbgPrint( "Daemon_Send_Command: after down_interruptible\n");
+ }
+ }
+
+ *off = *off;
+
+ DbgPrint( "Daemon_Send_Command: return 0x%x\n", retValue);
+
+ return(retValue);
+}
+
+/*++======================================================================*/
+ssize_t
+Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+ size_t retValue = 0;
+ void *reply;
+ u_long sequence, cpylen;
+
+ PDATA_LIST dlist;
+ char *vadr;
+ int i;
+
+ DbgPrint( "Daemon_Receive_Reply: buf=0x%x nbytes=%d ppos=%llx\n", buf, nbytes, *ppos);
+
+ /*
+ * Get sequence number from reply buffer
+ */
+
+ cpylen = copy_from_user(&sequence, buf, sizeof(sequence));
+
+ /*
+ * Find item based on sequence number
+ */
+ que = find_queue(sequence);
+
+ DbgPrint( "Daemon_Receive_Reply: 0x%x 0x%x %d\n", sequence, que, nbytes);
+ if (que)
+ {
+ do
+ {
+ retValue = nbytes;
+ /*
+ * Ack packet from novfsd. Remove timer and
+ * return
+ */
+ if (nbytes == sizeof(sequence))
+ {
+ que->status = QUEUE_ACKED;
+ break;
+ }
+
+ /*
+ * Set status that packet is done.
+ */
+ que->status = QUEUE_DONE;
+
+ if ( NULL != (dlist = que->data) )
+ {
+ int thiscopy, left=nbytes;
+ retValue = 0;
+
+
+ DbgPrint( "Daemon_Receive_Reply: dlist=0x%x count=%d\n", dlist, que->datalen);
+ for (i=0; (i < que->datalen) && (retValue < nbytes); i++, dlist++)
+ {
+ DbgPrint( "Daemon_Receive_Reply:\n" \
+ " dlist[%d].page: 0x%x\n" \
+ " dlist[%d].offset: 0x%x\n" \
+ " dlist[%d].len: 0x%x\n" \
+ " dlist[%d].rwflag: 0x%x\n",
+ i, dlist->page,
+ i, dlist->offset,
+ i, dlist->len,
+ i, dlist->rwflag);
+
+ if (DLWRITE == dlist->rwflag)
+ {
+ void *km_adr=NULL;
+
+ if (dlist->page)
+ {
+ km_adr = kmap(dlist->page);
+ vadr = km_adr;
+ vadr += (u_int)dlist->offset;
+ }
+ else
+ {
+ vadr = dlist->offset;
+ }
+
+ thiscopy = dlist->len;
+ if (thiscopy > left)
+ {
+ thiscopy = left;
+ dlist->len = left;
+ }
+ cpylen = copy_from_user(vadr, buf, thiscopy);
+
+ if ( km_adr )
+ {
+ kunmap(dlist->page);
+ }
+
+ left -= thiscopy;
+ retValue += thiscopy;
+ buf += thiscopy;
+ }
+ }
+ que->replen = retValue;
+ }
+ else
+ {
+ reply = Novfs_Malloc(nbytes, GFP_KERNEL);
+ DbgPrint( "Daemon_Receive_Reply: reply=0x%x\n", reply);
+ if (reply)
+ {
+ retValue = nbytes;
+ que->reply = reply;
+ que->replen = nbytes;
+
+ retValue -= copy_from_user(reply, buf, retValue);
+ if (retValue > 0x80)
+ mydump(0x80, reply);
+ else
+ mydump(retValue, reply);
+
+
+ }
+ else
+ {
+ retValue = -ENOMEM;
+ }
+ }
+ } while (0);
+ up(&que->semaphore);
+ Queue_put( que );
+ }
+
+ DbgPrint( "Daemon_Receive_Reply: return 0x%x\n", retValue);
+
+ return(retValue);
+}
+
+/*++======================================================================*/
+int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PLOGIN_USER_REQUEST cmd;
+ PLOGIN_USER_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen, datalen;
+ u_char *data;
+
+ datalen = Server->len+Username->len+Password->len;
+ cmdlen = sizeof(*cmd) + datalen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ data = (u_char *)cmd + sizeof(*cmd);
+ cmd->Command.CommandType = VFS_COMMAND_LOGIN_USER;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+
+ cmd->srvNameType = Server->type;
+ cmd->serverLength = Server->len;
+ cmd->serverOffset = (u_long)(data-(u_char *)cmd);
+ memcpy(data, Server->buffer, Server->len);
+ data += Server->len;
+
+ cmd->usrNameType = Username->type;
+ cmd->userNameLength = Username->len;
+ cmd->userNameOffset = (u_long)(data-(u_char *)cmd);
+ memcpy(data, Username->buffer, Username->len);
+ data += Username->len;
+
+ cmd->pwdNameType = Password->type;
+ cmd->passwordLength = Password->len;
+ cmd->passwordOffset = (u_long)(data-(u_char *)cmd);
+ memcpy(data, Password->buffer, Password->len);
+ data += Password->len;
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = reply->Reply.ErrorCode;
+ }
+ else
+ {
+ retCode = 0;
+ if (lgnId)
+ {
+ *lgnId = reply->loginIdentity;
+ }
+ }
+ Novfs_Free(reply);
+ }
+ memset(cmd, 0, cmdlen);
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+
+}
+
+/*++======================================================================*/
+int do_logout( struct qstr *Server, session_t Session )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PLOGOUT_REQUEST cmd;
+ PLOGOUT_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen;
+
+ cmdlen = (int)(&((PLOGOUT_REQUEST)0)->Name) + Server->len;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_LOGOUT_USER;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+
+ cmd->Length = Server->len;
+ memcpy(cmd->Name, Server->name, Server->len);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+
+}
+
+/*++======================================================================*/
+int Daemon_getpwuid( uid_t uid, int unamelen, char *uname )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ GETPWUID_REQUEST cmd;
+ PGETPWUID_REPLY reply;
+ u_long replylen=0;
+ int retCode;
+
+ cmd.Command.CommandType = VFS_COMMAND_GETPWUD;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = 0;
+ cmd.uid = uid;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ else
+ {
+ retCode = 0;
+ memset(uname, 0, unamelen);
+ replylen = replylen - (int)(&((PGETPWUID_REPLY)0)->UserName);
+ if (replylen)
+ {
+ if (replylen > unamelen)
+ {
+ retCode = -EINVAL;
+ replylen = unamelen-1;
+ }
+ memcpy(uname, reply->UserName, replylen);
+ }
+ }
+ Novfs_Free(reply);
+ }
+ return( retCode );
+
+}
+
+/*++======================================================================*/
+int Daemon_getversion( char *Buf, int Length )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ GET_VERSION_REQUEST cmd;
+ PGET_VERSION_REPLY reply;
+ u_long replylen=0;
+ int retVal=0;
+
+ cmd.Command.CommandType = VFS_COMMAND_GET_VERSION;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = 0;
+
+ Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retVal = -EIO;
+ }
+ else
+ {
+ retVal = replylen - (int)(&((PGET_VERSION_REPLY)0)->Version);
+ if (retVal < Length)
+ {
+ memcpy(Buf, reply->Version, retVal);
+ Buf[retVal] = '\0';
+ }
+ }
+ Novfs_Free(reply);
+ }
+ return( retVal );
+
+}
+
+/*++======================================================================*/
+int Daemon_Login(PLOGIN Login, session_t Session)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOMEM;
+ LOGIN lLogin;
+ NclString server;
+ NclString username;
+ NclString password;
+
+ if ( !copy_from_user(&lLogin, Login, sizeof(lLogin)))
+ {
+ if ( (server.buffer = Novfs_Malloc(lLogin.Server.Length, GFP_KERNEL)) )
+ {
+ server.len = lLogin.Server.Length;
+ server.type = NWC_STRING_TYPE_ASCII;
+ if ( !copy_from_user((void *)server.buffer, lLogin.Server.Data, server.len) )
+ {
+ if ( (username.buffer = Novfs_Malloc(lLogin.UserName.Length, GFP_KERNEL)) )
+ {
+ username.len = lLogin.UserName.Length;
+ username.type = NWC_STRING_TYPE_ASCII;
+ if ( !copy_from_user((void *)username.buffer, lLogin.UserName.Data, username.len) )
+ {
+ if ( (password.buffer = Novfs_Malloc(lLogin.Password.Length, GFP_KERNEL)) )
+ {
+ password.len = lLogin.Password.Length;
+ password.type = NWC_STRING_TYPE_ASCII;
+ if ( !copy_from_user((void *)password.buffer, lLogin.Password.Data, password.len) )
+ {
+ retCode = do_login(&server, &username, &password, NULL, Session);
+ if ( !retCode )
+ {
+ char *username;
+ username = Scope_Get_UserName( NULL );
+ if (username)
+ {
+ Novfs_Add_to_Root( username );
+ }
+ }
+ }
+ memset(password.buffer, 0, password.len);
+ Novfs_Free(password.buffer);
+ }
+ }
+ memset(username.buffer, 0, username.len);
+ Novfs_Free(username.buffer);
+ }
+ }
+ Novfs_Free(server.buffer);
+ }
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Daemon_Logout(PLOGOUT Logout, session_t Session)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ LOGOUT lLogout;
+ struct qstr server;
+ int retCode=0;
+
+ if ( !copy_from_user(&lLogout, Logout, sizeof(lLogout)))
+ {
+ if ( (server.name = Novfs_Malloc(lLogout.Server.Length, GFP_KERNEL)) )
+ {
+ server.len = lLogout.Server.Length;
+ if ( !copy_from_user((void *)server.name, lLogout.Server.Data, server.len) )
+ {
+ retCode = do_logout( &server, Session );
+ }
+ Novfs_Free(server.name);
+ }
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Daemon_CreateSessionId( uint64_t *SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ CREATE_CONTEXT_REQUEST cmd;
+ PCREATE_CONTEXT_REPLY reply;
+ u_long replylen=0;
+ int retCode=0;
+
+ DbgPrint("Daemon_CreateSessionId: %d\n", current->pid);
+
+ cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = 0;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ if ( !reply->Reply.ErrorCode && replylen > sizeof(COMMAND_REPLY_HEADER))
+ {
+ *SessionId = reply->SessionId;
+ retCode = 0;
+ }
+ else
+ {
+ *SessionId = 0;
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId);
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Daemon_DestroySessionId( uint64_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DESTROY_CONTEXT_REQUEST cmd;
+ PDESTROY_CONTEXT_REPLY reply;
+ u_long replylen=0;
+ int retCode=0;
+
+ DbgPrint("Daemon_DestroySessionId: 0x%llx\n", SessionId);
+
+ cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ if ( !reply->Reply.ErrorCode )
+ {
+ drive_map_t *dm;
+ struct list_head *list;
+
+ retCode = 0;
+
+ /*
+ * When destroying the session check to see if there are any
+ * mapped drives. If there are then remove them.
+ */
+ down( &DriveMapLock );
+ list_for_each( list, &DriveMapList )
+ {
+ dm = list_entry( list, drive_map_t, list );
+ if ( SessionId == dm->session)
+ {
+ local_unlink( dm->name );
+ list = list->prev;
+ list_del( &dm->list );
+ Novfs_Free( dm );
+ }
+
+ }
+ up( &DriveMapLock );
+
+ }
+ else
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ GET_USER_SPACE_REQUEST cmd;
+ PGET_USER_SPACE_REPLY reply;
+ u_long replylen=0;
+ int retCode=0;
+
+ DbgPrint("Daemon_Get_UserSpace: 0x%llx\n", SessionId);
+
+ cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ if ( !reply->Reply.ErrorCode )
+ {
+
+ DbgPrint("TotalSpace: %llu\n", reply->TotalSpace);
+ DbgPrint("FreeSpace: %llu\n", reply->FreeSpace);
+ DbgPrint("TotalEnties: %llu\n", reply->TotalEnties);
+ DbgPrint("FreeEnties: %llu\n", reply->FreeEnties);
+
+ if (TotalSize) *TotalSize = reply->TotalSpace;
+ if (Free) *Free = reply->FreeSpace;
+ if (TotalEnties) *TotalEnties = reply->TotalEnties;
+ if (FreeEnties) *FreeEnties = reply->FreeEnties;
+ retCode = 0;
+ }
+ else
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Daemon_SetMountPoint ( char *Path )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSET_MOUNT_PATH_REQUEST cmd;
+ PSET_MOUNT_PATH_REPLY reply;
+ u_long replylen, cmdlen;
+ int retCode = -ENOMEM;
+
+ DbgPrint("Daemon_SetMountPoint: %s\n", Path);
+
+ replylen = strlen(Path);
+
+ cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen;
+
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if ( cmd )
+ {
+ cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = 0;
+ cmd->PathLength = replylen;
+
+ strcpy(cmd->Path, Path);
+
+ replylen = 0;
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ if ( !reply->Reply.ErrorCode )
+ {
+ retCode = 0;
+ }
+ else
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Daemon_SendDebugCmd ( char *Command )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DEBUG_REQUEST cmd;
+ PDEBUG_REPLY reply;
+ DEBUG_REPLY lreply;
+ u_long replylen, cmdlen;
+ DATA_LIST dlist[2];
+
+ int retCode = -ENOMEM;
+
+ DbgPrint("Daemon_SendDebugCmd: %s\n", Command);
+
+ dlist[0].page = NULL;
+ dlist[0].offset = (char *)Command;
+ dlist[0].len = strlen(Command);
+ dlist[0].rwflag = DLREAD;
+
+ dlist[1].page = NULL;
+ dlist[1].offset = (char *)&lreply;
+ dlist[1].len = sizeof(lreply);
+ dlist[1].rwflag = DLWRITE;
+
+ cmdlen = (int)(&((PDEBUG_REQUEST)0)->dbgcmd);
+
+ cmd.Command.CommandType = VFS_COMMAND_DBG;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = 0;
+ cmd.cmdlen = strlen(Command);
+
+ replylen = 0;
+
+ retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ Novfs_Free(reply);
+ }
+ if (0 == retCode)
+ {
+ retCode = lreply.Reply.ErrorCode;
+ }
+
+ return(retCode);
+}
+
+/*++======================================================================*/
+int
+NO_TRACE
+Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOSYS;
+ u_long cpylen;
+
+
+ switch (cmd)
+ {
+ case IOC_LOGIN:
+ {
+ retCode = Daemon_Login((PLOGIN)arg, Scope_Get_SessionId( NULL ));
+ break;
+ }
+
+ case IOC_LOGOUT:
+ {
+ retCode = Daemon_Logout((PLOGOUT)arg, Scope_Get_SessionId( NULL ));
+ break;
+ }
+ case IOC_DEBUGPRINT:
+ {
+ struct Ioctl_Debug {
+ int length;
+ char *data;
+ } io;
+ char *buf;
+ io.length = 0;
+ cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
+ if (io.length)
+ {
+ buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
+ if (buf)
+ {
+ buf[0] = 0;
+ cpylen = copy_from_user(buf, io.data, io.length);
+ buf[io.length] = '\0';
+ DbgPrint("%s", buf);
+ Novfs_Free(buf);
+ retCode = 0;
+ }
+ }
+ break;
+ }
+
+ case IOC_XPLAT:
+ {
+ XPLAT data;
+
+ cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
+ retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
+
+ switch(data.xfunction)
+ {
+ case NWC_GET_MOUNT_PATH:
+ DbgPrint("[Daemon_ioctl] Call NwdGetMountPath\n");
+ retCode = NwdGetMountPath( &data );
+ break;
+ }
+
+ DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
+ break;
+ }
+
+ }
+ return (retCode);
+}
+
+/*++======================================================================*/
+int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_resource_t *resource;
+ int retVal = NWE_OUT_OF_HEAP_SPACE;
+
+ if (FHandle)
+ DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u_long *)&FHandle[2], Mode, Size);
+ else
+ DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x\n", DHandle, Type, CHandle);
+
+ resource = Novfs_Malloc(sizeof(daemon_resource_t), GFP_KERNEL);
+ if (resource)
+ {
+ resource->type = Type;
+ resource->connection = CHandle;
+ if (FHandle)
+ {
+ memcpy( resource->handle, FHandle, sizeof(resource->handle) );
+ }
+ else
+ {
+ memset( resource->handle, 0, sizeof(resource->handle) );
+ }
+ resource->mode = Mode;
+ resource->size = Size;
+ write_lock( &DHandle->lock );
+ list_add( &resource->list, &DHandle->list );
+ write_unlock( &DHandle->lock );
+ DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource);
+ retVal = 0;
+ }
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_resource_t *resource;
+ struct list_head *l;
+ int retVal = -ENOMEM;
+
+ DbgPrint("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x\n", DHandle, Type, CHandle, FHandle);
+
+ write_lock( &DHandle->lock );
+
+ list_for_each( l, &DHandle->list )
+ {
+ resource = list_entry( l, daemon_resource_t, list );
+
+ if ( (Type == resource->type) &&
+ (resource->connection == CHandle) )
+ {
+ DbgPrint("Daemon_Remove_Resource: Found resource=0x%p\n", resource);
+ l = l->prev;
+ list_del( &resource->list );
+ Novfs_Free( resource );
+ break;
+ }
+ }
+
+ write_unlock( &DHandle->lock );
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int Daemon_Library_open(struct inode *inode, struct file *file)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = -ENOMEM;
+ daemon_handle_t *dh;
+
+ DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file);
+
+ if ((dh = Novfs_Malloc(sizeof(daemon_handle_t), GFP_KERNEL)))
+ {
+ file->private_data = dh;
+ INIT_LIST_HEAD( &dh->list);
+ rwlock_init( &dh->lock );
+ dh->session = Scope_Get_SessionId( NULL );
+ retVal = 0;
+ }
+ return(retVal);
+}
+
+/*++======================================================================*/
+int Daemon_Library_close(struct inode *inode, struct file *file)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_handle_t *dh;
+ daemon_resource_t *resource;
+ struct list_head *l;
+
+ char commanddata[sizeof(XPLAT_CALL_REQUEST)+sizeof(NwdCCloseConn)];
+ PXPLAT_CALL_REQUEST cmd;
+ PXPLAT_CALL_REPLY reply;
+ PNwdCCloseConn nwdClose;
+ u_long cmdlen, replylen;
+
+ DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file);
+ if (file->private_data)
+ {
+ dh = (daemon_handle_t *)file->private_data;
+
+ list_for_each( l, &dh->list )
+ {
+ resource = list_entry( l, daemon_resource_t, list );
+
+ if (DH_TYPE_STREAM == resource->type)
+ {
+ Novfs_Close_Stream( resource->connection, resource->handle, dh->session );
+ }
+ else if (DH_TYPE_CONNECTION == resource->type)
+ {
+ cmd = (PXPLAT_CALL_REQUEST)commanddata;
+ cmdlen = offsetof(XPLAT_CALL_REQUEST, data) + sizeof(NwdCCloseConn);
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = dh->session;
+ cmd->NwcCommand = NWC_CLOSE_CONN;
+
+ cmd->dataLen = sizeof(NwdCCloseConn);
+ nwdClose = (PNwdCCloseConn)cmd->data;
+ nwdClose->ConnHandle = resource->connection;
+
+ Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+ if (reply)
+ {
+ Novfs_Free(reply);
+ }
+ }
+ l = l->prev;
+ list_del( &resource->list );
+ Novfs_Free( resource );
+ }
+ Novfs_Free(dh);
+ file->private_data = NULL;
+ }
+
+ return(0);
+}
+
+/*++======================================================================*/
+ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_handle_t *dh;
+ daemon_resource_t *resource;
+
+ size_t thisread, totalread=0;
+ loff_t offset = *off;
+
+ DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n", file, len, *off);
+
+ if (file->private_data)
+ {
+ dh = file->private_data;
+ read_lock( &dh->lock );
+ if (&dh->list != dh->list.next)
+ {
+ resource = list_entry( dh->list.next, daemon_resource_t, list );
+
+ if (DH_TYPE_STREAM == resource->type)
+ {
+ while( len > 0 && (offset < resource->size) )
+ {
+ thisread = len;
+ if (Novfs_Read_Stream(resource->connection,
+ resource->handle,
+ buf, &thisread,
+ &offset, 1,
+ dh->session) || !thisread)
+ {
+ break;
+ }
+ len -= thisread;
+ buf += thisread;
+ offset += thisread;
+ totalread += thisread;
+ }
+ }
+ }
+ read_unlock( &dh->lock );
+ }
+ *off = offset;
+ DbgPrint("Daemon_Library_read return = 0x%x\n", totalread);
+ return(totalread);
+}
+
+/*++======================================================================*/
+ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_handle_t *dh;
+ daemon_resource_t *resource;
+
+ size_t thiswrite, totalwrite=-EINVAL;
+ loff_t offset = *off;
+ int status;
+
+ DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n", file, len, *off);
+
+ if (file->private_data)
+ {
+ dh = file->private_data;
+ write_lock( &dh->lock );
+ if (&dh->list != dh->list.next)
+ {
+ resource = list_entry( dh->list.next, daemon_resource_t, list );
+
+ if ( (DH_TYPE_STREAM == resource->type) && (len >= 0) )
+ {
+ totalwrite = 0;
+ do
+ {
+ thiswrite = len;
+ status = Novfs_Write_Stream(resource->connection,
+ resource->handle,
+ (PVOID)buf,
+ &thiswrite,
+ &offset,
+ dh->session);
+ if ( status || !thiswrite )
+ {
+ /*
+ * If len is zero then the file will have just been
+ * truncated to offset. Update size.
+ */
+ if ( !status && !len )
+ {
+ resource->size = offset;
+ }
+ totalwrite = status;
+ break;
+ }
+ len -= thiswrite;
+ buf += thiswrite;
+ offset += thiswrite;
+ totalwrite += thiswrite;
+ if (offset > resource->size)
+ {
+ resource->size = offset;
+ }
+ } while(len > 0);
+ }
+ }
+ write_unlock( &dh->lock );
+ }
+ *off = offset;
+ DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite);
+
+ return(totalwrite);
+}
+
+/*++======================================================================*/
+loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_handle_t *dh;
+ daemon_resource_t *resource;
+
+ loff_t retVal = -EINVAL;
+
+ DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", file, offset, origin);
+
+ if (file->private_data)
+ {
+ dh = file->private_data;
+ read_lock( &dh->lock );
+ if (&dh->list != dh->list.next)
+ {
+ resource = list_entry( dh->list.next, daemon_resource_t, list );
+
+ if (DH_TYPE_STREAM == resource->type)
+ {
+ switch (origin) {
+ case 2:
+ offset += resource->size;
+ break;
+ case 1:
+ offset += file->f_pos;
+ }
+ if (offset >= 0) {
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_version = 0;
+ }
+ retVal = offset;
+ }
+ }
+ }
+ read_unlock( &dh->lock );
+ }
+
+ DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal);
+
+ return retVal;
+}
+
+/*++======================================================================*/
+int
+NO_TRACE
+Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOSYS;
+ daemon_handle_t *dh;
+ u_long handle=0, cpylen;
+
+
+ dh = file->private_data;
+
+ DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%x dh=0x%p\n", file, cmd, arg, dh);
+
+ if (dh)
+ {
+
+ switch (cmd)
+ {
+ case IOC_LOGIN:
+ {
+ retCode = Daemon_Login((PLOGIN)arg, dh->session);
+ break;
+ }
+
+ case IOC_LOGOUT:
+ {
+ retCode = Daemon_Logout((PLOGOUT)arg, dh->session);
+ break;
+ }
+
+ case IOC_DEBUGPRINT:
+ {
+ struct Ioctl_Debug {
+ int length;
+ char *data;
+ } io;
+ char *buf;
+ io.length = 0;
+ cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
+ if (io.length)
+ {
+ buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
+ if (buf)
+ {
+ buf[0] = 0;
+ cpylen = copy_from_user(buf, io.data, io.length);
+ buf[io.length] = '\0';
+ DbgPrint("%s", buf);
+ Novfs_Free(buf);
+ retCode = 0;
+ }
+ }
+ break;
+ }
+
+ case IOC_XPLAT:
+ {
+ XPLAT data;
+
+ cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
+ retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
+
+ switch(data.xfunction)
+ {
+ case NWC_OPEN_CONN_BY_NAME:
+ DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n");
+ retCode = NwOpenConnByName(&data, &handle, dh->session);
+ if ( !retCode )
+ {
+ Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
+ }
+ break;
+
+ case NWC_OPEN_CONN_BY_ADDRESS:
+ DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n");
+ retCode = NwOpenConnByAddr(&data, &handle, dh->session);
+ if ( !retCode )
+ {
+ Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
+ }
+ break;
+
+ case NWC_OPEN_CONN_BY_REFERENCE:
+
+ DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n");
+ retCode = NwOpenConnByRef(&data, &handle, dh->session);
+ if ( !retCode )
+ {
+ Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
+ }
+ break;
+
+ case NWC_SYS_CLOSE_CONN:
+ DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n");
+ retCode = NwSysConnClose(&data, &handle, dh->session);
+ Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
+ break;
+
+ case NWC_CLOSE_CONN:
+ DbgPrint("[VFS XPLAT] Call NwCloseConn\n");
+ retCode = NwConnClose(&data, &handle, dh->session);
+ Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
+ break;
+
+ case NWC_LOGIN_IDENTITY:
+ DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n");
+ retCode = NwLoginIdentity(&data, dh->session);
+ break;
+
+ case NWC_RAW_NCP_REQUEST:
+ DbgPrint("[VFS XPLAT] Send Raw NCP Request\n");
+ retCode = NwRawSend(&data, dh->session);
+ break;
+
+ case NWC_AUTHENTICATE_CONN_WITH_ID:
+ DbgPrint("[VFS XPLAT] Authenticate Conn With ID\n");
+ retCode = NwAuthConnWithId(&data, dh->session);
+ break;
+
+ case NWC_UNAUTHENTICATE_CONN:
+ DbgPrint("[VFS XPLAT] UnAuthenticate Conn With ID\n");
+ retCode = NwUnAuthenticate(&data, dh->session);
+ break;
+
+ case NWC_LICENSE_CONN:
+ DbgPrint("Call NwLicenseConn\n");
+ retCode = NwLicenseConn(&data, dh->session);
+ break;
+
+ case NWC_LOGOUT_IDENTITY:
+ DbgPrint("[VFS XPLAT] Call NwLogoutIdentity\n");
+ retCode = NwLogoutIdentity(&data, dh->session);
+ break;
+
+ case NWC_UNLICENSE_CONN:
+ DbgPrint("[VFS XPLAT] Call NwUnlicense\n");
+ retCode = NwUnlicenseConn(&data, dh->session);
+ break;
+
+ case NWC_GET_CONN_INFO:
+ DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
+ retCode = NwGetConnInfo(&data, dh->session);
+ break;
+
+ case NWC_SET_CONN_INFO:
+ DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
+ retCode = NwSetConnInfo(&data, dh->session);
+ break;
+
+ case NWC_SCAN_CONN_INFO:
+ DbgPrint("[VFS XPLAT] Call NwScanConnInfo\n");
+ retCode = NwScanConnInfo(&data, dh->session);
+ break;
+
+
+ case NWC_GET_IDENTITY_INFO:
+ DbgPrint("[VFS XPLAT] Call NwGetIdentityInfo\n");
+ retCode = NwGetIdentityInfo(&data, dh->session);
+ break;
+
+ case NWC_GET_REQUESTER_VERSION:
+ DbgPrint("[VFS XPLAT] Call NwGetDaemonVersion\n");
+ retCode = NwGetDaemonVersion(&data, dh->session);
+ break;
+
+ case NWC_GET_PREFERRED_DS_TREE:
+ DbgPrint("[VFS XPLAT] Call NwcGetPreferredDsTree\n");
+ retCode = NwcGetPreferredDSTree(&data, dh->session);
+ break;
+
+ case NWC_SET_PREFERRED_DS_TREE:
+ DbgPrint("[VFS XPLAT] Call NwcSetPreferredDsTree\n");
+ retCode = NwcSetPreferredDSTree(&data, dh->session);
+ break;
+
+ case NWC_GET_DEFAULT_NAME_CONTEXT:
+ DbgPrint("[VFS XPLAT] Call NwcGetDefaultNameContext\n");
+ retCode = NwcGetDefaultNameCtx(&data, dh->session);
+ break;
+
+ case NWC_SET_DEFAULT_NAME_CONTEXT:
+ DbgPrint("[VFS XPLAT] Call NwcSetDefaultNameContext\n");
+ retCode = NwcSetDefaultNameCtx(&data, dh->session);
+ break;
+
+ case NWC_QUERY_FEATURE:
+ DbgPrint("[VFS XPLAT] Call NwQueryFeature\n");
+ retCode = NwQueryFeature(&data, dh->session);
+ break;
+
+
+ case NWC_GET_TREE_MONITORED_CONN_REF:
+ DbgPrint("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n");
+ retCode = NwcGetTreeMonitoredConn(&data, dh->session);
+ break;
+
+ case NWC_ENUMERATE_IDENTITIES:
+ DbgPrint("[VFS XPLAT] Call NwcEnumerateIdentities\n");
+ retCode = NwcEnumIdentities(&data, dh->session);
+ break;
+
+ case NWC_CHANGE_KEY:
+ DbgPrint("[VFS XPLAT] Call NwcChangeAuthKey\n");
+ retCode = NwcChangeAuthKey(&data, dh->session);
+ break;
+
+ case NWC_CONVERT_LOCAL_HANDLE:
+ DbgPrint("[VFS XPLAT] Call NwdConvertLocalHandle\n");
+ retCode = NwdConvertLocalHandle(&data, dh);
+ break;
+
+ case NWC_CONVERT_NETWARE_HANDLE:
+ DbgPrint("[VFS XPLAT] Call NwdConvertNetwareHandle\n");
+ retCode = NwdConvertNetwareHandle(&data, dh);
+ break;
+
+ case NWC_SET_PRIMARY_CONN:
+ DbgPrint("[VFS XPLAT] Call NwcSetPrimaryConn\n");
+ retCode = NwcSetPrimaryConn(&data, dh->session);
+ break;
+
+ case NWC_GET_PRIMARY_CONN:
+ DbgPrint("[VFS XPLAT] Call NwcGetPrimaryConn\n");
+ retCode = NwcGetPrimaryConn(&data, dh->session);
+ break;
+
+ case NWC_MAP_DRIVE:
+ DbgPrint("[VFS XPLAT] Call NwcMapDrive\n");
+ retCode = NwdSetMapDrive(&data, dh->session);
+ break;
+
+ case NWC_UNMAP_DRIVE:
+ DbgPrint("[VFS XPLAT] Call NwcUnMapDrive\n");
+ retCode = NwdUnMapDrive(&data, dh->session);
+ break;
+
+ case NWC_ENUMERATE_DRIVES:
+ DbgPrint("[VFS XPLAT] Call NwcEnumerateDrives\n");
+ retCode = NwcEnumerateDrives(&data, dh->session);
+ break;
+
+ case NWC_GET_MOUNT_PATH:
+ DbgPrint("[VFS XPLAT] Call NwdGetMountPath\n");
+ retCode = NwdGetMountPath( &data );
+ break;
+
+ case NWC_GET_BROADCAST_MESSAGE:
+ DbgPrint("[VSF XPLAT Call NwdGetBroadcastMessage\n");
+ retCode = NwcGetBroadcastMessage(&data, dh->session);
+ break;
+
+ case NWC_SET_KEY:
+ DbgPrint("[VSF XPLAT Call NwdSetKey\n");
+ retCode = NwdSetKeyValue(&data, dh->session);
+ break;
+
+ case NWC_VERIFY_KEY:
+ DbgPrint("[VSF XPLAT Call NwdVerifyKey\n");
+ retCode = NwdVerifyKeyValue(&data, dh->session);
+ break;
+
+ case NWC_RAW_NCP_REQUEST_ALL:
+ case NWC_NDS_RESOLVE_NAME_TO_ID:
+ case NWC_FRAGMENT_REQUEST:
+ case NWC_GET_CONFIGURED_NSPS:
+ default:
+ break;
+
+ }
+
+ DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
+ break;
+ }
+ }
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ daemon_command_t *que;
+ unsigned int mask = POLLOUT | POLLWRNORM;
+
+ que = get_next_queue(0);
+ if (que)
+ {
+ mask |= (POLLIN | POLLRDNORM);
+ }
+ else
+ {
+
+ }
+ return(mask);
+}
+
+
+void Daemon_Dumpque( void )
+{
+#ifdef CONFIG_KDB
+ daemon_command_t *que;
+
+ que = (daemon_command_t *)Daemon_Queue.list.next;
+
+ while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next))
+ {
+ kdb_printf("DaemonQue:\n" \
+ " Que: 0x%p\n" \
+ " status: 0x%lx\n" \
+ " flags: 0x%lx\n" \
+ " semaphore: 0x%x\n" \
+ " sequence: 0x%lx\n" \
+ " timer: 0x%lx\n" \
+ " request: 0x%p\n" \
+ " reqlen: %ld\n" \
+ " data: 0x%p\n" \
+ " datalen: %d\n" \
+ " reply: 0x%p\n" \
+ " replen: %ld\n",
+ que,
+ que->status,
+ que->flags,
+ atomic_read(&que->semaphore.count),
+ que->sequence,
+ que->timer.expires,
+ que->request,
+ que->reqlen,
+ que->data,
+ que->datalen,
+ que->reply,
+ que->replen);
+ que = (daemon_command_t *)que->list.next;
+ }
+#endif
+}
+
+/*++======================================================================*/
+int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal;
+ NwcConvertNetWareHandle nh;
+ u_long cpylen;
+
+ DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle);
+
+ cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle));
+
+ retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, nh.ConnHandle, nh.NetWareHandle, nh.uAccessMode, nh.uFileSize);
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = NWE_REQUESTER_FAILURE;
+ daemon_resource_t *resource;
+ NwcConvertLocalHandle lh;
+ struct list_head *l;
+ u_long cpylen;
+
+ DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle);
+
+ read_lock( &DHandle->lock );
+
+ list_for_each( l, &DHandle->list )
+ {
+ resource = list_entry( l, daemon_resource_t, list );
+
+ if ( DH_TYPE_STREAM == resource->type )
+ {
+ lh.uConnReference = resource->connection;
+
+ memcpy(lh.NwFileHandle, resource->handle, sizeof(resource->handle));
+ if (pdata->repLen >= sizeof(NwcConvertLocalHandle))
+ {
+ cpylen = copy_to_user(pdata->repData, &lh, sizeof(NwcConvertLocalHandle));
+ retVal = 0;
+ }
+ else
+ {
+ retVal = NWE_BUFFER_OVERFLOW;
+ }
+ break;
+ }
+ }
+
+ read_unlock( &DHandle->lock );
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int NwdGetMountPath(PXPLAT pdata)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = NWE_REQUESTER_FAILURE;
+ int len;
+ u_long cpylen;
+ NwcGetMountPath mp;
+
+ cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen);
+
+ if ( Novfs_CurrentMount )
+ {
+
+ len = strlen(Novfs_CurrentMount)+1;
+ if ( (len > mp.MountPathLen) && mp.pMountPath)
+ {
+ retVal = NWE_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ if (mp.pMountPath)
+ {
+ cpylen = copy_to_user(mp.pMountPath, Novfs_CurrentMount, len);
+ }
+ retVal = 0;
+ }
+
+ mp.MountPathLen = len;
+
+ if (pdata->repData && (pdata->repLen >= sizeof(mp)) )
+ {
+ cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp));
+ }
+ }
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int NwdSetMapDrive(PXPLAT pdata, session_t Session)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal;
+ u_long cpylen;
+
+ retVal = NwcSetMapDrive(pdata, Session);
+ if ( !retVal )
+ {
+ NwcMapDriveEx symInfo;
+ char *path;
+ drive_map_t *drivemap, *dm;
+ struct list_head *list;
+
+ cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+ drivemap = Novfs_Malloc( sizeof(drive_map_t)+symInfo.linkOffsetLength, GFP_KERNEL );
+ if (drivemap)
+ {
+ path = (char *)pdata->reqData;
+ path += symInfo.linkOffset;
+ cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength);
+
+ drivemap->session = Session;
+ drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength-1);
+ drivemap->namelen = symInfo.linkOffsetLength-1;
+ DbgPrint( "NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name);
+
+ dm = (drive_map_t *)&DriveMapList.next;
+
+ down( &DriveMapLock );
+
+ list_for_each( list, &DriveMapList )
+ {
+ dm = list_entry( list, drive_map_t, list );
+ DbgPrint( "NwdSetMapDrive: dm=0x%p\n" \
+ " hash: 0x%x\n" \
+ " namelen: %d\n" \
+ " name: %s\n",
+ dm, dm->hash, dm->namelen, dm->name);
+
+ if (drivemap->hash == dm->hash)
+ {
+ if ( 0 == strcmp(dm->name, drivemap->name))
+ {
+ dm = NULL;
+ break;
+ }
+ }
+ else if (drivemap->hash < dm->hash)
+ {
+ break;
+ }
+ }
+
+ if (dm)
+ {
+ if ( (dm == (drive_map_t *)&DriveMapList) ||
+ (dm->hash < drivemap->hash) )
+ {
+ list_add( &drivemap->list, &dm->list);
+ }
+ else
+ {
+ list_add_tail( &drivemap->list, &dm->list);
+ }
+ }
+ else
+ {
+ Novfs_Free( drivemap );
+ }
+ up( &DriveMapLock );
+ }
+ }
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int NwdUnMapDrive(PXPLAT pdata, session_t Session)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = NWE_REQUESTER_FAILURE;
+ u_long cpylen;
+
+ retVal = NwcUnMapDrive(pdata, Session);
+ if ( !retVal )
+ {
+ NwcUnmapDriveEx symInfo;
+ char *path;
+ drive_map_t *dm;
+ struct list_head *list;
+ u_long hash;
+
+
+ cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+ path = Novfs_Malloc( symInfo.linkLen, GFP_KERNEL );
+ if (path)
+ {
+ cpylen = copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen);
+
+ hash = full_name_hash(path, symInfo.linkLen-1);
+ DbgPrint( "NwdUnMapDrive: hash=0x%x path=%s\n", hash, path);
+
+ dm = NULL;
+
+ down( &DriveMapLock );
+
+ list_for_each( list, &DriveMapList )
+ {
+ dm = list_entry( list, drive_map_t, list );
+ DbgPrint( "NwdUnMapDrive: dm=0x%p %s\n" \
+ " hash: 0x%x\n" \
+ " namelen: %d\n",
+ dm, dm->name, dm->hash, dm->namelen);
+
+ if (hash == dm->hash)
+ {
+ if ( 0 == strcmp(dm->name, path))
+ {
+ break;
+ }
+ }
+ else if (hash < dm->hash)
+ {
+ dm = NULL;
+ break;
+ }
+ }
+
+ if (dm)
+ {
+ DbgPrint( "NwdUnMapDrive: Remove dm=0x%p %s\n" \
+ " hash: 0x%x\n" \
+ " namelen: %d\n",
+ dm, dm->name, dm->hash, dm->namelen);
+ list_del( &dm->list );
+ Novfs_Free( dm );
+ }
+
+ up( &DriveMapLock );
+ }
+ }
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+void RemoveDriveMaps( void )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ drive_map_t *dm;
+ struct list_head *list;
+
+ down( &DriveMapLock );
+ list_for_each( list, &DriveMapList )
+ {
+ dm = list_entry( list, drive_map_t, list );
+
+ DbgPrint( "RemoveDriveMap: dm=0x%p\n" \
+ " hash: 0x%x\n" \
+ " namelen: %d\n" \
+ " name: %s\n",
+ dm, dm->hash, dm->namelen, dm->name);
+ local_unlink( dm->name );
+ list = list->prev;
+ list_del( &dm->list );
+ Novfs_Free( dm );
+ }
+ up( &DriveMapLock );
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+/*++======================================================================*/
+int local_unlink(const char *pathname)
+{
+ int error;
+ struct dentry *dentry;
+ struct nameidata nd;
+ struct inode *inode = NULL;
+
+ DbgPrint("local_unlink: %s\n", pathname);
+ error = path_lookup(pathname, LOOKUP_PARENT, &nd);
+ DbgPrint("local_unlink: path_lookup %d\n", error);
+ if ( !error )
+ {
+ error = -EISDIR;
+ if (nd.last_type == LAST_NORM)
+ {
+ mutex_lock(&nd.dentry->d_inode->i_mutex);
+ dentry = lookup_create( &nd, 1);
+ DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
+
+ error = PTR_ERR(dentry);
+ if (!IS_ERR(dentry))
+ {
+ if (nd.last.name[nd.last.len])
+ {
+ error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
+ }
+ else
+ {
+ inode = dentry->d_inode;
+ if (inode)
+ {
+ atomic_inc(&inode->i_count);
+ }
+ error = vfs_unlink(nd.dentry->d_inode, dentry);
+ DbgPrint("local_unlink: vfs_unlink %d\n", error);
+ }
+ dput(dentry);
+ }
+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
+
+ }
+ path_release(&nd);
+ }
+
+ if (inode)
+ {
+ iput(inode); /* truncate the inode here */
+ }
+
+ DbgPrint("local_unlink: error=%d\n", error);
+ return error;
+}
+
+#else
+/*++======================================================================*/
+int local_unlink(const char *pathname)
+{
+ int error;
+ struct dentry *dentry;
+ struct nameidata nd;
+ struct inode *inode = NULL;
+
+ DbgPrint("local_unlink: %s\n", pathname);
+ error = path_lookup(pathname, LOOKUP_PARENT, &nd);
+ DbgPrint("local_unlink: path_lookup %d\n", error);
+ if ( !error )
+ {
+ error = -EISDIR;
+ if (nd.last_type == LAST_NORM)
+ {
+ down(&nd.dentry->d_inode->i_sem);
+ dentry = lookup_one_len(&nd.last, nd.dentry, sizeof(nd.last));
+ DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
+
+ error = PTR_ERR(dentry);
+ if (!IS_ERR(dentry))
+ {
+ if (nd.last.name[nd.last.len])
+ {
+ error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
+ }
+ else
+ {
+ inode = dentry->d_inode;
+ if (inode)
+ {
+ atomic_inc(&inode->i_count);
+ }
+ error = vfs_unlink(nd.dentry->d_inode, dentry);
+ DbgPrint("local_unlink: vfs_unlink %d\n", error);
+ }
+ dput(dentry);
+ }
+ up(&nd.dentry->d_inode->i_sem);
+ }
+ path_release(&nd);
+ }
+
+ if (inode)
+ {
+ iput(inode); /* truncate the inode here */
+ }
+
+ DbgPrint("local_unlink: error=%d\n", error);
+ return error;
+}
+#endif
diff -uNr src.old/src/file.c src/src/file.c
--- src.old/src/file.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/file.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,2318 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: file.c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module contains functions for accessing
+ * files through the daemon.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/dcache.h>
+#include <linux/pagemap.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+
+/*===[ Include files specific to this module ]============================*/
+#include "commands.h"
+#include "nwerror.h"
+#include "vfs.h"
+
+/*===[ External data ]====================================================*/
+extern struct dentry_operations Novfs_dentry_operations;
+extern int MaxIoSize;
+
+
+/*===[ External prototypes ]==============================================*/
+extern int DbgPrint( char *Fmt, ... );
+extern void mydump(int size, void *dumpptr);
+extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
+extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid);
+
+extern void *Scope_Lookup( void );
+
+/*===[ Manifest constants ]===============================================*/
+
+/*===[ Type definitions ]=================================================*/
+
+/*===[ Function prototypes ]==============================================*/
+
+int Novfs_verify_file( struct qstr *Path, session_t SessionId );
+int Novfs_get_alltrees(struct dentry *parent);
+ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off);
+
+int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId );
+int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, session_t SessionId );
+int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List );
+int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId );
+int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId );
+int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId );
+int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
+int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
+int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId );
+int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId );
+int Novfs_Close_File( u_long Handle, session_t SessionId );
+int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId);
+int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+int Novfs_Write_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId);
+int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
+int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
+int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId );
+int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId );
+int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId );
+int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId );
+int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId );
+
+/*===[ Global variables ]=================================================*/
+static struct file_operations Novfs_tree_operations = {
+ read: Novfs_tree_read,
+};
+
+/*
+ * StripTrailingDots was added because some apps will
+ * try and create a file name with a trailing dot. NetWare
+ * doesn't like this and will return an error.
+ */
+u_char StripTrailingDots=1;
+
+/*===[ Code ]=============================================================*/
+
+/*++======================================================================*/
+int Novfs_verify_file( struct qstr *Path, scope_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PVERIFY_FILE_REPLY reply=NULL;
+ u_long replylen=0;
+ PVERIFY_FILE_REQUEST cmd;
+ int cmdlen;
+ int retCode=0;
+
+ cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + Path->len;
+ cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+ cmd->pathLen = Path->len;
+ memcpy(cmd->path, Path->name, Path->len);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ DbgPrint("Novfs_verify_file: reply\n");
+ mydump(replylen, reply);
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -ENOENT;
+ }
+ else
+ {
+ retCode = 0;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_get_alltrees(struct dentry *parent)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ u_char *p;
+ PCOMMAND_REPLY_HEADER reply=NULL;
+ u_long replylen=0;
+ COMMAND_REQUEST_HEADER cmd;
+ int retCode;
+ struct dentry *entry;
+ struct qstr name;
+ struct inode *inode;
+
+ cmd.CommandType = 0;
+ cmd.SequenceNumber = 0;
+ cmd.SessionId = 0x1234;
+
+ DbgPrint( "Novfs_get_alltrees:\n");
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ DbgPrint( "Novfs_get_alltrees: relpy=0x%x replylen=%d\n", reply, replylen);
+ if (reply)
+ {
+ mydump(replylen, reply);
+ if ( !reply->ErrorCode && (replylen > sizeof(COMMAND_REPLY_HEADER)))
+ {
+ p = (char *)reply+8;
+ while (*p)
+ {
+ DbgPrint( "Novfs_get_alltrees: %s\n",p);
+ name.len = strlen(p);
+ name.name = p;
+ name.hash = full_name_hash(name.name, name.len);
+ entry = d_lookup(parent, &name);
+ if ( NULL == entry )
+ {
+ DbgPrint( "Novfs_get_alltrees: adding %s\n",p);
+ entry = d_alloc(parent, &name);
+ if (entry)
+ {
+ entry->d_op = &Novfs_dentry_operations;
+ inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0);
+ if (inode)
+ {
+ inode->i_fop = &Novfs_tree_operations;
+ d_add(entry, inode);
+ }
+ }
+ }
+ p += (name.len+1);
+ }
+ }
+ Novfs_Free(reply);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ if (file->f_pos != 0)
+ {
+ return(0);
+ }
+ if (copy_to_user(buf, "Tree\n", 5))
+ {
+ return(0);
+ }
+ return(5);
+}
+
+/*++======================================================================*/
+int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ GET_CONNECTED_SERVER_LIST_REQUEST req;
+ PGET_CONNECTED_SERVER_LIST_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode=0;
+
+ *ServerList = NULL;
+
+ req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST;
+ req.Command.SessionId = SessionId;
+
+ retCode = Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ DbgPrint("Novfs_Get_Connected_Server_List: reply\n");
+ replylen -= sizeof(COMMAND_REPLY_HEADER);
+ if ( !reply->Reply.ErrorCode && replylen )
+ {
+ memcpy(reply, reply->List, replylen);
+ *ServerList = (u_char *)reply;
+ retCode = 0;
+ }
+ else
+ {
+ Novfs_Free(reply);
+ retCode = -ENOENT;
+ }
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, scope_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PGET_SERVER_VOLUME_LIST_REQUEST req;
+ PGET_SERVER_VOLUME_LIST_REPLY reply=NULL;
+ u_long replylen=0, reqlen;
+ int retCode;
+
+ *VolumeList = NULL;
+ reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST)+Server->len;
+ req = Novfs_Malloc(reqlen, GFP_KERNEL);
+ if (req)
+ {
+ req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST;
+ req->Length = Server->len;
+ memcpy(req->Name, Server->name, Server->len);
+ req->Command.SessionId = SessionId;
+
+ retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if ( reply )
+ {
+ DbgPrint("Novfs_Get_Server_Volume_List: reply\n");
+ mydump(replylen, reply);
+ replylen -= sizeof(COMMAND_REPLY_HEADER);
+
+ if ( !reply->Reply.ErrorCode && replylen )
+ {
+ memcpy(reply, reply->List, replylen);
+ *VolumeList = (u_char *)reply;
+ retCode = 0;
+ }
+ else
+ {
+ Novfs_Free(reply);
+ retCode = -ENOENT;
+ }
+ }
+ Novfs_Free(req);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int len;
+ int retCode = 0;
+
+ while (*List)
+ {
+ len = strlen(List);
+ if ((len == Name->len) && !strncmp(Name->name, List, len))
+ {
+ retCode = 1;
+ break;
+ }
+ List += (len+1);
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ u_char *list;
+ int retCode = 0;
+
+ DbgPrint("Novfs_Verify_Server_Name: %.*s\n", Server->len, Server->name);
+
+ list = NULL;
+ Novfs_Get_Connected_Server_List( &list, SessionId );
+
+ if (list)
+ {
+ retCode = Novfs_Find_Name_In_List( Server, list );
+ Novfs_Free(list);
+ }
+ DbgPrint("Novfs_Verify_Server_Name: %d\n", retCode);
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId )
+/*
+ *
+ * Arguments: Server - Server name.
+ * Volume - Volume name to check for.
+ *
+ * Returns: zero - not found.
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ u_char *list;
+ int retCode = 0;
+ u_char *name;
+ int namelen;
+ struct qstr path;
+
+ list = NULL;
+ namelen = Server->len+Volume->len+2;
+ name = Novfs_Malloc(namelen, GFP_KERNEL);
+
+ if (name)
+ {
+ name[0] = '\\';
+ memcpy(&name[1], Server->name, Server->len);
+ name[1+Server->len] = '\\';
+ memcpy(&name[2+Server->len], Volume->name, Volume->len);
+ path.len = namelen;
+ path.name = name;
+
+ if (Novfs_verify_file(&path, SessionId))
+ {
+ retCode = 0;
+ }
+ else
+ {
+ retCode = 1;
+ }
+
+ Novfs_Free(name);
+ }
+ else
+ {
+
+ Novfs_Get_Server_Volume_List( Server, &list, SessionId );
+
+ if (list)
+ {
+ retCode = Novfs_Find_Name_In_List( Volume, list );
+ Novfs_Free(list);
+ }
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PVERIFY_FILE_REPLY reply=NULL;
+ u_long replylen=0;
+ PVERIFY_FILE_REQUEST cmd;
+ int cmdlen;
+ int retCode=-ENOENT;
+ int pathlen;
+
+ DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
+
+ Info->mode = S_IFDIR | 0700;
+ Info->uid = current->uid;
+ Info->gid = current->gid;
+ Info->size = 0;
+ Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
+
+ if (Path && *Path)
+ {
+ pathlen = strlen(Path);
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[pathlen-1]) pathlen--;
+ }
+ cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + pathlen;
+ cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+ cmd->pathLen = pathlen;
+ memcpy(cmd->path, Path, cmd->pathLen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+
+ if ( reply->Reply.ErrorCode )
+ {
+ retCode = -ENOENT;
+ }
+ else
+ {
+ Info->type = 3;
+ Info->mode = S_IRWXU;
+
+ if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
+ {
+ Info->mode |= S_IFDIR;
+ }
+ else
+ {
+ Info->mode |= S_IFREG;
+ }
+
+ if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
+ {
+ Info->mode &= ~(S_IWUSR);
+ }
+
+ Info->uid = current->euid;
+ Info->gid = current->egid;
+ Info->size = reply->fileSize;
+ Info->atime.tv_sec = reply->lastAccessTime;
+ Info->atime.tv_nsec = 0;
+ Info->mtime.tv_sec = reply->modifyTime;
+ Info->mtime.tv_nsec = 0;
+ Info->ctime.tv_sec = reply->createTime;
+ Info->ctime.tv_nsec = 0;
+ DbgPrint("Novfs_Get_File_Info: replylen=%d sizeof(VERIFY_FILE_REPLY)=%d\n", replylen, sizeof(VERIFY_FILE_REPLY));
+ if (replylen > sizeof(VERIFY_FILE_REPLY))
+ {
+ long *lp = &reply->fileMode;
+ lp++;
+ DbgPrint("Novfs_Get_File_Info: extra data 0x%x\n", *lp);
+ Info->mtime.tv_nsec = *lp;
+ }
+ retCode = 0;
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ }
+
+ DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Get_File_Info2( u_char *Path, PENTRY_INFO Info, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PVERIFY_FILE_REPLY reply=NULL;
+ u_long replylen=0;
+ PVERIFY_FILE_REQUEST cmd;
+ int cmdlen;
+ struct qstr server = {0}, volume = {0};
+ u_char *p;
+ int i;
+ int retCode=-ENOENT;
+ p = Path;
+
+ DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
+
+ Info->mode = S_IFDIR | 0700;
+ Info->uid = current->uid;
+ Info->gid = current->gid;
+ Info->size = 0;
+ Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
+
+ if ('\\' == *p)
+ {
+ p++;
+ }
+ server.name = p;
+
+ for(i=0; *p && ('\\' != *p); i++, p++);
+ server.len = i;
+ if (*p)
+ {
+ if ('\\' == *p)
+ {
+ p++;
+ }
+ volume.name = p;
+ for(i=0; *p && ('\\' != *p); i++, p++);
+ if (i)
+ {
+ volume.len = i;
+ if (*p)
+ {
+ if ('\\' == *p)
+ {
+ p++;
+ }
+ if (*p)
+ {
+ cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + strlen(Path);
+ cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+ cmd->pathLen = strlen(Path);
+ memcpy(cmd->path, Path, cmd->pathLen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+
+ if ( reply->Reply.ErrorCode )
+ {
+ retCode = -ENOENT;
+ }
+ else
+ {
+ Info->type = 3;
+ Info->mode = S_IRWXU;
+
+ if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
+ {
+ Info->mode |= S_IFDIR;
+ }
+ else
+ {
+ Info->mode |= S_IFREG;
+ }
+
+ if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
+ {
+ Info->mode &= ~(S_IWUSR);
+ }
+
+ Info->uid = current->euid;
+ Info->gid = current->egid;
+ Info->size = reply->fileSize;
+ Info->atime.tv_sec = reply->lastAccessTime;
+ Info->atime.tv_nsec = 0;
+ Info->mtime.tv_sec = reply->modifyTime;
+ Info->mtime.tv_nsec = 0;
+ Info->ctime.tv_sec = reply->createTime;
+ Info->ctime.tv_nsec = 0;
+ retCode = 0;
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ }
+ }
+ }
+ if (('\0' == *p) && volume.len)
+ {
+ if ( Novfs_Verify_Volume_Name( &server, &volume, SessionId ) )
+ {
+ retCode = 0;
+ Info->type = 2;
+ }
+ }
+ }
+ if (server.len && !volume.len)
+ {
+ if ( Novfs_Verify_Server_Name( &server, SessionId ) )
+ {
+ retCode = 0;
+ Info->type = 1;
+ }
+ }
+ DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
+ return(retCode);
+}
+
+/*++======================================================================*/
+int begin_directory_enumerate( u_char *Path, int PathLen, u_long *EnumHandle, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd;
+ PBEGIN_ENUMERATE_DIRECTORY_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode, cmdlen;
+
+ *EnumHandle = 0;
+
+ cmdlen = (int)(&((PBEGIN_ENUMERATE_DIRECTORY_REQUEST)0)->path) + PathLen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_START_ENUMERATE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+
+ cmd->pathLen = PathLen;
+ memcpy(cmd->path, Path, PathLen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+/*
+ * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0);
+ */
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ else
+ {
+ *EnumHandle = reply->enumerateHandle;
+ retCode = 0;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int end_directory_enumerate( u_long EnumHandle, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ END_ENUMERATE_DIRECTORY_REQUEST cmd;
+ PEND_ENUMERATE_DIRECTORY_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode;
+
+
+ cmd.Command.CommandType = VFS_COMMAND_END_ENUMERATE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.enumerateHandle = EnumHandle;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
+ if (reply)
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int directory_enumerate( u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ENUMERATE_DIRECTORY_REQUEST cmd;
+ PENUMERATE_DIRECTORY_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode;
+
+
+ cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.enumerateHandle = *EnumHandle;
+ cmd.pathLen = 0;
+ cmd.path[0] = '\0';
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ /*
+ * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
+ * error but there could still be valid data.
+ */
+ if ( !reply->Reply.ErrorCode ||
+ ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
+ (reply->nameLen > 0)) )
+ {
+ Info->type = 3;
+ Info->mode = S_IRWXU;
+
+ if (reply->mode & NW_ATTRIBUTE_DIRECTORY)
+ {
+ Info->mode |= S_IFDIR;
+ Info->mode |= S_IXUSR;
+ }
+ else
+ {
+ Info->mode |= S_IFREG;
+ }
+
+ if (reply->mode & NW_ATTRIBUTE_READ_ONLY)
+ {
+ Info->mode &= ~(S_IWUSR);
+ }
+
+ if (reply->mode & NW_ATTRIBUTE_EXECUTE)
+ {
+ Info->mode |= S_IXUSR;
+ }
+
+ Info->uid = current->uid;
+ Info->gid = current->gid;
+ Info->size = reply->size;
+ Info->atime.tv_sec = reply->lastAccessTime;
+ Info->atime.tv_nsec = 0;
+ Info->mtime.tv_sec = reply->modifyTime;
+ Info->mtime.tv_nsec = 0;
+ Info->ctime.tv_sec = reply->createTime;
+ Info->ctime.tv_nsec = 0;
+ Info->namelength = reply->nameLen;
+ memcpy(Info->name, reply->name, reply->nameLen);
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -1; /* Eof of data */
+ }
+ *EnumHandle = reply->enumerateHandle;
+ }
+ else
+ {
+ retCode = -ENODATA;
+ }
+ Novfs_Free(reply);
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int directory_enumerate_ex( u_long *EnumHandle, session_t SessionId, int *Count, PENTRY_INFO *PInfo, int Interrupt)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ENUMERATE_DIRECTORY_EX_REQUEST cmd;
+ PENUMERATE_DIRECTORY_EX_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode=0;
+ PENTRY_INFO info;
+ PENUMERATE_DIRECTORY_EX_DATA data;
+ int isize;
+
+ if (PInfo)
+ {
+ *PInfo = NULL;
+ }
+ *Count = 0;
+
+ cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY_EX;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.enumerateHandle = *EnumHandle;
+ cmd.pathLen = 0;
+ cmd.path[0] = '\0';
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, Interrupt);
+
+ if (reply)
+ {
+ retCode = 0;
+ /*
+ * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
+ * error but there could still be valid data.
+ */
+
+ if ( !reply->Reply.ErrorCode ||
+ ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
+ (reply->enumCount > 0)) )
+ {
+ DbgPrint("directory_enumerate_ex: isize=%d\n", replylen);
+ data = (PENUMERATE_DIRECTORY_EX_DATA)((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY));
+ isize = replylen -
+ sizeof(PENUMERATE_DIRECTORY_EX_REPLY) -
+ reply->enumCount * (int)(&((PENUMERATE_DIRECTORY_EX_DATA)0)->name);
+ isize += (reply->enumCount * (int)(&((PENTRY_INFO)0)->name));
+
+ if (PInfo)
+ {
+ *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL);
+ if ( *PInfo )
+ {
+ DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info);
+ *Count = reply->enumCount;
+ do
+ {
+ DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data);
+
+ info->type = 3;
+ info->mode = S_IRWXU;
+
+ if (data->mode & NW_ATTRIBUTE_DIRECTORY)
+ {
+ info->mode |= S_IFDIR;
+ info->mode |= S_IXUSR;
+ }
+ else
+ {
+ info->mode |= S_IFREG;
+ }
+
+ if (data->mode & NW_ATTRIBUTE_READ_ONLY)
+ {
+ info->mode &= ~(S_IWUSR);
+ }
+
+ if (data->mode & NW_ATTRIBUTE_EXECUTE)
+ {
+ info->mode |= S_IXUSR;
+ }
+
+ info->uid = current->euid;
+ info->gid = current->egid;
+ info->size = data->size;
+ info->atime.tv_sec = data->lastAccessTime;
+ info->atime.tv_nsec = 0;
+ info->mtime.tv_sec = data->modifyTime;
+ info->mtime.tv_nsec = 0;
+ info->ctime.tv_sec = data->createTime;
+ info->ctime.tv_nsec = 0;
+ info->namelength = data->nameLen;
+ memcpy(info->name, data->name, data->nameLen);
+ data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen];
+ replylen = (int)((char *)&info->name[info->namelength] - (char *)info);
+ DbgPrint("directory_enumerate_ex3: info=0x%p\n", info);
+ mydump(replylen, info);
+
+ info = (PENTRY_INFO)&info->name[info->namelength];
+
+ } while (--reply->enumCount);
+ }
+ }
+
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -1; /* Eof of data */
+ }
+ *EnumHandle = reply->enumerateHandle;
+ }
+ else
+ {
+ retCode = -ENODATA;
+ }
+ Novfs_Free(reply);
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOENT;
+
+ if ( -1 == *EnumHandle)
+ {
+ return( -ENODATA );
+ }
+
+ if ( 0 == *EnumHandle )
+ {
+ retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
+ }
+
+ if ( *EnumHandle )
+ {
+ retCode = directory_enumerate( EnumHandle, Info, SessionId );
+ if (retCode)
+ {
+ end_directory_enumerate( *EnumHandle, SessionId );
+ if ( -1 == retCode )
+ {
+ retCode = 0;
+ *EnumHandle = -1;
+ }
+ }
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOENT;
+
+ if (Count) *Count = 0;
+ if (Info) *Info = NULL;
+
+ if ( -1 == *EnumHandle)
+ {
+ return( -ENODATA );
+ }
+
+ if ( 0 == *EnumHandle )
+ {
+ retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
+ }
+
+ if ( *EnumHandle )
+ {
+ retCode = directory_enumerate_ex( EnumHandle, SessionId, Count, Info, INTERRUPTIBLE );
+ if (retCode)
+ {
+ end_directory_enumerate( *EnumHandle, SessionId );
+ if ( -1 == retCode )
+ {
+ retCode = 0;
+ *EnumHandle = -1;
+ }
+ }
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ POPEN_FILE_REQUEST cmd;
+ POPEN_FILE_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen, pathlen;
+
+ pathlen = strlen(Path);
+
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[pathlen-1]) pathlen--;
+ }
+
+ *Handle = 0;
+
+ cmdlen = (int)(&((POPEN_FILE_REQUEST)0)->path) + pathlen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_OPEN_FILE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+
+ cmd->access = 0;
+
+ if ( !(Flags & O_WRONLY) || (Flags & O_RDWR))
+ {
+ cmd->access |= NWD_ACCESS_READ;
+ }
+
+ if ((Flags & O_WRONLY) || (Flags & O_RDWR))
+ {
+ cmd->access |= NWD_ACCESS_WRITE;
+ }
+
+ switch (Flags & (O_CREAT | O_EXCL | O_TRUNC))
+ {
+ case O_CREAT:
+ cmd->disp = NWD_DISP_OPEN_ALWAYS;
+ break;
+
+ case O_CREAT | O_EXCL:
+ cmd->disp = NWD_DISP_CREATE_NEW;
+ break;
+
+ case O_TRUNC:
+ cmd->disp = NWD_DISP_CREATE_ALWAYS;
+ break;
+
+ case O_CREAT | O_TRUNC:
+ cmd->disp = NWD_DISP_CREATE_ALWAYS;
+ break;
+
+ case O_CREAT | O_EXCL | O_TRUNC:
+ cmd->disp = NWD_DISP_CREATE_NEW;
+ break;
+
+ default:
+ cmd->disp = NWD_DISP_OPEN_EXISTING;
+ break;
+ }
+
+ cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE;
+
+ cmd->pathLen = pathlen;
+ memcpy(cmd->path, Path, pathlen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ if( NWE_OBJECT_EXISTS == reply->Reply.ErrorCode)
+ {
+ retCode = -EEXIST;
+ }
+ else if( NWE_ACCESS_DENIED == reply->Reply.ErrorCode)
+ {
+ retCode = -EACCES;
+ }
+ else
+ {
+ retCode = -ENOENT;
+ }
+ }
+ else
+ {
+ *Handle = reply->handle;
+ retCode = 0;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PCREATE_FILE_REQUEST cmd;
+ PCREATE_FILE_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen, pathlen;
+
+ pathlen = strlen(Path);
+
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[pathlen-1]) pathlen--;
+ }
+
+ cmdlen = (int)(&((PCREATE_FILE_REQUEST)0)->path) + pathlen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_CREATE_FILE;
+ if (DirectoryFlag)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_CREATE_DIRECOTRY;
+ }
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+
+ cmd->pathlength = pathlen;
+ memcpy(cmd->path, Path, pathlen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Close_File( u_long Handle, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ CLOSE_FILE_REQUEST cmd;
+ PCLOSE_FILE_REPLY reply;
+ u_long replylen=0;
+ int retCode;
+
+ cmd.Command.CommandType = VFS_COMMAND_CLOSE_FILE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.handle = Handle;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
+ if (reply)
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ return( retCode );
+}
+/*++======================================================================*/
+int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ READ_FILE_REQUEST cmd;
+ PREAD_FILE_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode = 0;
+ size_t len;
+
+ len = *Bytes;
+ *Bytes = 0;
+
+ if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MaxIoSize)
+ {
+ len = MaxIoSize - (int)(&((PREAD_FILE_REPLY)0)->data);
+ len = (len/PAGE_SIZE)*PAGE_SIZE;
+ }
+
+ cmd.Command.CommandType = VFS_COMMAND_READ_FILE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.handle = Handle;
+ cmd.len = len;
+ cmd.offset = *Offset;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
+
+ if (!retCode)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ else
+ {
+ replylen -= (int)(&((PREAD_FILE_REPLY)0)->data);
+ if (replylen > 0)
+ {
+ replylen -= copy_to_user(Buffer, reply->data, replylen);
+ *Bytes = replylen;
+ }
+ }
+ }
+
+ if ( reply )
+ {
+ Novfs_Free(reply);
+ }
+
+ DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ READ_FILE_REQUEST cmd;
+ PREAD_FILE_REPLY reply=NULL;
+ READ_FILE_REPLY lreply;
+ u_long replylen=0;
+ int retCode = 0;
+ size_t len;
+
+ len = *Bytes;
+ *Bytes = 0;
+
+ DbgPrint("Novfs_Read_File_Pages: Handle=0x%x Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%llx\n",
+ Handle, DList, DList_Cnt, len, *Offset, SessionId);
+
+ cmd.Command.CommandType = VFS_COMMAND_READ_FILE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.handle = Handle;
+ cmd.len = len;
+ cmd.offset = *Offset;
+
+ /*
+ * Dlst first entry is reserved for reply header.
+ */
+ DList[0].page = NULL;
+ DList[0].offset = &lreply;
+ DList[0].len = (int)(&((PREAD_FILE_REPLY)0)->data);
+ DList[0].rwflag = DLWRITE;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), DList, DList_Cnt, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ DbgPrint("Novfs_Read_File_Pages: Queue_Daemon_Command 0x%x\n", retCode);
+
+ if (!retCode)
+ {
+ if (reply)
+ {
+ memcpy(&lreply, reply, sizeof(lreply));
+ }
+
+ if (lreply.Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ *Bytes = replylen - (int)(&((PREAD_FILE_REPLY)0)->data);
+ }
+
+ if ( reply )
+ {
+ Novfs_Free(reply);
+ }
+
+ DbgPrint("Novfs_Read_File: retCode=0x%x\n", retCode);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ WRITE_FILE_REQUEST cmd;
+ PWRITE_FILE_REPLY reply=NULL;
+ unsigned long replylen=0;
+ int retCode=0, cmdlen;
+ size_t len;
+
+ unsigned long boff;
+ struct page **pages;
+ DATA_LIST *dlist;
+ int res=0, npage, i;
+ WRITE_FILE_REPLY lreply;
+
+
+ len = *Bytes;
+ cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data);
+
+ *Bytes = 0;
+
+ memset(&lreply, 0, sizeof(lreply));
+
+ DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
+
+ if ( (cmdlen+len) > MaxIoSize)
+ {
+ len = MaxIoSize-cmdlen;
+ len = (len/PAGE_SIZE)*PAGE_SIZE;
+ }
+ cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+ cmd.handle = Handle;
+ cmd.len = len;
+ cmd.offset = *Offset;
+
+ DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
+
+ npage = (((unsigned long)Buffer & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+
+ dlist = Novfs_Malloc(sizeof(DATA_LIST)*(npage+1), GFP_KERNEL);
+ if (NULL == dlist)
+ {
+ return(-ENOMEM);
+ }
+
+ pages = Novfs_Malloc(sizeof(struct page *)*npage, GFP_KERNEL);
+
+ if (NULL == pages)
+ {
+ Novfs_Free(dlist);
+ return(-ENOMEM);
+ }
+
+ down_read(&current->mm->mmap_sem);
+
+ res = get_user_pages(
+ current,
+ current->mm,
+ (unsigned long)Buffer,
+ npage,
+ 0, /* read type */
+ 0, /* don't force */
+ pages,
+ NULL);
+
+ up_read(&current->mm->mmap_sem);
+
+ DbgPrint("Novfs_Write_File res=%d\n", res);
+
+ if ( res > 0 )
+ {
+ boff = (unsigned long)Buffer & ~PAGE_MASK;
+
+ flush_dcache_page(pages[0]);
+ dlist[0].page = pages[0];
+ dlist[0].offset = (char *)boff;
+ dlist[0].len = PAGE_SIZE - boff;
+ dlist[0].rwflag = DLREAD;
+
+ if (dlist[0].len > len)
+ {
+ dlist[0].len = len;
+ }
+
+ DbgPrint("Novfs_Write_File0: page=0x%x offset=0x%p len=%d\n", dlist[0].page, dlist[0].offset, dlist[0].len);
+
+ boff = dlist[0].len;
+
+ DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff);
+
+ for (i=1; (i < res) && (boff < len); i++)
+ {
+ flush_dcache_page(pages[i]);
+
+ dlist[i].page = pages[i];
+ dlist[i].offset = NULL;
+ dlist[i].len = len-boff;
+ if (dlist[i].len > PAGE_SIZE)
+ {
+ dlist[i].len = PAGE_SIZE;
+ }
+ dlist[i].rwflag = DLREAD;
+
+ boff += dlist[i].len;
+ DbgPrint("Novfs_Write_File%d: page=0x%x offset=0x%p len=%d\n", i, dlist[i].page, dlist[i].offset, dlist[i].len);
+ }
+
+ dlist[i].page = NULL;
+ dlist[i].offset = &lreply;
+ dlist[i].len = sizeof(lreply);
+ dlist[i].rwflag = DLWRITE;
+ res++;
+
+ DbgPrint("Novfs_Write_File Buffer=0x%x boff=0x%x len=%d\n", Buffer, boff, len);
+
+ retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, res, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ }
+ else
+ {
+ char *kdata;
+
+ res = 0;
+
+ kdata = Novfs_Malloc(len, GFP_KERNEL);
+ if (kdata)
+ {
+ len -= copy_from_user(kdata, Buffer, len);
+ dlist[0].page = NULL;
+ dlist[0].offset = kdata;
+ dlist[0].len = len;
+ dlist[0].rwflag = DLREAD;
+
+ dlist[1].page = NULL;
+ dlist[1].offset = &lreply;
+ dlist[1].len = sizeof(lreply);
+ dlist[1].rwflag = DLWRITE;
+
+ retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ Novfs_Free(kdata);
+ }
+ }
+
+ DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%x\n", retCode, reply);
+
+ if ( !retCode )
+ {
+ switch (lreply.Reply.ErrorCode)
+ {
+ case 0:
+ *Bytes = (size_t)lreply.bytesWritten;
+ retCode = 0;
+ break;
+
+ case NWE_INSUFFICIENT_SPACE:
+ retCode = -ENOSPC;
+ break;
+
+ case NWE_ACCESS_DENIED:
+ retCode = -EACCES;
+ break;
+
+ default:
+ retCode = -EIO;
+ break;
+ }
+ }
+
+ if ( res )
+ {
+ for (i=0; i<res; i++)
+ {
+ if (dlist[i].page)
+ {
+ page_cache_release(dlist[i].page);
+ }
+ }
+ }
+
+ Novfs_Free(pages);
+ Novfs_Free(dlist);
+
+ DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Write_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ WRITE_FILE_REQUEST cmd;
+ WRITE_FILE_REPLY lreply;
+ PWRITE_FILE_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode=0, cmdlen;
+ size_t len;
+
+ DbgPrint("Novfs_Write_Pages: Handle=0x%x Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%llx\n",
+ Handle, DList, DList_Cnt, Bytes, Offset, SessionId);
+
+ DList[0].page = NULL;
+ DList[0].offset = &lreply;
+ DList[0].len = sizeof(lreply);
+ DList[0].rwflag = DLWRITE;
+
+ len = Bytes;
+ cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data);
+
+ if (len)
+ {
+ cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.handle = Handle;
+ cmd.len = len;
+ cmd.offset = Offset;
+
+ retCode = Queue_Daemon_Command(&cmd, cmdlen, DList, DList_Cnt, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (!retCode)
+ {
+ if (reply)
+ {
+ memcpy(&lreply, reply, sizeof(lreply));
+ }
+ switch (lreply.Reply.ErrorCode)
+ {
+ case 0:
+ retCode = 0;
+ break;
+
+ case NWE_INSUFFICIENT_SPACE:
+ retCode = -ENOSPC;
+ break;
+
+ case NWE_ACCESS_DENIED:
+ retCode = -EACCES;
+ break;
+
+ default:
+ retCode = -EIO;
+ break;
+ }
+ }
+ if ( reply )
+ {
+ Novfs_Free(reply);
+ }
+ }
+ DbgPrint("Novfs_Write_Pages retCode=0x%x\n", retCode);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ READ_STREAM_REQUEST cmd;
+ PREAD_STREAM_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode = 0;
+ size_t len;
+
+ len = *Bytes;
+ *Bytes = 0;
+
+ if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MaxIoSize)
+ {
+ len = MaxIoSize - (int)(&((PREAD_FILE_REPLY)0)->data);
+ len = (len/PAGE_SIZE)*PAGE_SIZE;
+ }
+
+ cmd.Command.CommandType = VFS_COMMAND_READ_STREAM;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.connection = ConnHandle;
+ memcpy( cmd.handle, Handle, sizeof(cmd.handle));
+ cmd.len = len;
+ cmd.offset = *Offset;
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
+
+ if ( reply )
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ else
+ {
+ replylen -= (int)(&((PREAD_STREAM_REPLY)0)->data);
+ if (replylen > 0)
+ {
+ if (User)
+ {
+ replylen -= copy_to_user(Buffer, reply->data, replylen);
+ }
+ else
+ {
+ memcpy(Buffer, reply->data, replylen);
+ }
+
+ *Bytes = replylen;
+ }
+ }
+ Novfs_Free(reply);
+ }
+
+ DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PWRITE_STREAM_REQUEST cmd;
+ PWRITE_STREAM_REPLY reply=NULL;
+ u_long replylen=0;
+ int retCode=0, cmdlen;
+ size_t len;
+
+ len = *Bytes;
+ cmdlen = len+(int)(&((PWRITE_STREAM_REQUEST)0)->data);
+ *Bytes = 0;
+
+ if (cmdlen > MaxIoSize)
+ {
+ cmdlen = MaxIoSize;
+ len = cmdlen - (int)(&((PWRITE_STREAM_REQUEST)0)->data);
+ }
+
+ DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len);
+
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ if (Buffer && len)
+ {
+ len -= copy_from_user(cmd->data, Buffer, len);
+ }
+
+ DbgPrint("Novfs_Write_Stream len=%d\n", len);
+
+ cmd->Command.CommandType = VFS_COMMAND_WRITE_STREAM;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+
+ cmd->connection = ConnHandle;
+ memcpy(cmd->handle, Handle, sizeof(cmd->handle));
+ cmd->len = len;
+ cmd->offset = *Offset;
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ switch (reply->Reply.ErrorCode)
+ {
+ case 0:
+ retCode = 0;
+ break;
+
+ case NWE_INSUFFICIENT_SPACE:
+ retCode = -ENOSPC;
+ break;
+
+ case NWE_ACCESS_DENIED:
+ retCode = -EACCES;
+ break;
+
+ default:
+ retCode = -EIO;
+ break;
+ }
+ DbgPrint("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", reply->bytesWritten);
+ *Bytes = reply->bytesWritten;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ CLOSE_STREAM_REQUEST cmd;
+ PCLOSE_STREAM_REPLY reply;
+ u_long replylen=0;
+ int retCode;
+
+ cmd.Command.CommandType = VFS_COMMAND_CLOSE_STREAM;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.connection = ConnHandle;
+ memcpy(cmd.handle, Handle, sizeof(cmd.handle));
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
+ if (reply)
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PDELETE_FILE_REQUEST cmd;
+ PDELETE_FILE_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen, pathlen;
+
+ pathlen = strlen(Path);
+
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[pathlen-1]) pathlen--;
+ }
+
+ cmdlen = (int)(&((PDELETE_FILE_REQUEST)0)->path) + pathlen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_DELETE_FILE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+
+ cmd->isDirectory = DirectoryFlag;
+ cmd->pathlength = pathlen;
+ memcpy(cmd->path, Path, pathlen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) /* Access Denied Error */
+ {
+ retCode = -EACCES;
+ }
+ else
+ {
+ retCode = -EIO;
+ }
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PTRUNCATE_FILE_REQUEST cmd;
+ PTRUNCATE_FILE_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen;
+
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[PathLen-1]) PathLen--;
+ }
+ cmdlen = (int)(&((PTRUNCATE_FILE_REQUEST)0)->path) + PathLen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_TRUNCATE_FILE;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+
+ cmd->pathLen = PathLen;
+ memcpy(cmd->path, Path, PathLen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ RENAME_FILE_REQUEST cmd;
+ PRENAME_FILE_REPLY reply;
+ u_long replylen=0;
+ int retCode;
+
+ DbgPrint("Novfs_Rename_File:\n" \
+ " DirectoryFlag: %d\n" \
+ " OldName: %.*s\n" \
+ " NewName: %.*s\n" \
+ " SessionId: 0x%llx\n",
+ DirectoryFlag,
+ OldLen, OldName,
+ NewLen, NewName,
+ SessionId );
+
+ cmd.Command.CommandType = VFS_COMMAND_RENAME_FILE;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = SessionId;
+
+ cmd.directoryFlag = DirectoryFlag;
+
+ if (StripTrailingDots)
+ {
+ if ('.' == OldName[OldLen-1]) OldLen--;
+ if ('.' == NewName[NewLen-1]) NewLen--;
+ }
+
+ cmd.newnameLen = NewLen;
+ memcpy(cmd.newname, NewName, NewLen);
+
+ cmd.oldnameLen = OldLen;
+ memcpy(cmd.oldname, OldName, OldLen);
+
+ retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = 0;
+ if (reply->Reply.ErrorCode)
+ {
+ retCode = -ENOENT;
+ }
+ Novfs_Free(reply);
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSET_FILE_INFO_REQUEST cmd;
+ PSET_FILE_INFO_REPLY reply;
+ u_long replylen=0;
+ int retCode, cmdlen, pathlen;
+
+ pathlen = strlen(Path);
+
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[pathlen-1]) pathlen--;
+ }
+
+ cmdlen = (int)(&((PSET_FILE_INFO_REQUEST)0)->path) + pathlen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_SET_FILE_INFO;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+ cmd->fileInfo.ia_valid = Attr->ia_valid;
+ cmd->fileInfo.ia_mode = Attr->ia_mode;
+ cmd->fileInfo.ia_uid = Attr->ia_uid;
+ cmd->fileInfo.ia_gid = Attr->ia_uid;
+ cmd->fileInfo.ia_size = Attr->ia_size;
+ cmd->fileInfo.ia_atime = Attr->ia_atime.tv_sec;
+ cmd->fileInfo.ia_mtime = Attr->ia_mtime.tv_sec;;
+ cmd->fileInfo.ia_ctime = Attr->ia_ctime.tv_sec;;
+/*
+ cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags;
+*/
+ cmd->fileInfo.ia_attr_flags = 0;
+
+ cmd->pathlength = pathlen;
+ memcpy(cmd->path, Path, pathlen);
+
+ retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ switch( reply->Reply.ErrorCode )
+ {
+ case 0:
+ retCode = 0;
+ break;
+
+ case NWE_PARAM_INVALID:
+ retCode = -EINVAL;
+ break;
+
+ default:
+ retCode = -EIO;
+ break;
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PGET_CACHE_FLAG_REQUEST cmd;
+ PGET_CACHE_FLAG_REPLY reply=NULL;
+ u_long replylen=0;
+ int cmdlen;
+ int retCode = 0;
+ int pathlen;
+
+ DbgPrint("Novfs_Get_File_Cache_Flag: Path = %s\n", Path);
+
+ if (Path && *Path)
+ {
+ pathlen = strlen(Path);
+ if (StripTrailingDots)
+ {
+ if ('.' == Path[pathlen-1]) pathlen--;
+ }
+ cmdlen = (int)(&((PGET_CACHE_FLAG_REQUEST)0)->path) + pathlen;
+ cmd = (PGET_CACHE_FLAG_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_GET_CACHE_FLAG;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = SessionId;
+ cmd->pathLen = pathlen;
+ memcpy(cmd->path, Path, cmd->pathLen);
+
+ Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+
+ if ( !reply->Reply.ErrorCode )
+ {
+ retCode = reply->CacheFlag;
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ }
+
+ DbgPrint("Novfs_Get_File_Cache_Flag: return %d\n", retCode);
+ return(retCode);
+}
diff -uNr src.old/src/inode.c src/src/inode.c
--- src.old/src/inode.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/inode.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,5236 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: inode.c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module contains functions used to control
+ * access to the Linux file system.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/dcache.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/unistd.h>
+#include <linux/backing-dev.h>
+#include <asm/statfs.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
+#include <linux/statfs.h>
+#include <linux/pagevec.h>
+#include <linux/writeback.h>
+#include <linux/backing-dev.h>
+
+/*===[ Include files specific to this module ]============================*/
+#include "vfs.h"
+
+/*===[ External data ]====================================================*/
+extern int MaxIoSize;
+
+/*===[ External prototypes ]==============================================*/
+extern int DbgPrint( char *Fmt, ... );
+extern int LocalPrint( char *Fmt, ... );
+
+extern int Init_Procfs_Interface( void );
+extern void Uninit_Procfs_Interface( void );
+extern void mydump(int size, void *dumpptr);
+
+/*
+ * Daemon.c functions
+ */
+extern void Init_Daemon_Queue( void );
+extern void Uninit_Daemon_Queue( void );
+extern int do_logout( struct qstr *Server );
+extern int Daemon_SetMountPoint( char *Path );
+
+/*
+ * file.c functions
+ */
+extern int Novfs_verify_file( struct qstr *Path, session_t SessionId );
+extern int Novfs_get_alltrees(struct dentry *parent);
+extern int Novfs_Get_Connected_Server_List( unsigned char **ServerList, session_t SessionId );
+extern int Novfs_Get_Server_Volume_List( struct qstr *Server, unsigned char **VolumeList, session_t SessionId );
+extern int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId );
+extern int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId );
+extern int Novfs_Get_File_Info( unsigned char *Path, PENTRY_INFO Info, session_t SessionId );
+extern int Novfs_Get_Directory_List( unsigned char *Path, unsigned long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
+extern int Novfs_Get_Directory_ListEx( unsigned char *Path, unsigned long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
+extern int Novfs_Open_File( unsigned char *Path, int Flags, PENTRY_INFO Info, unsigned long *Handle, session_t SessionId );
+extern int Novfs_Create( unsigned char *Path, int DirectoryFlag, session_t SessionId );
+extern int Novfs_Close_File( unsigned long Handle, session_t SessionId );
+extern int Novfs_Read_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+extern int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId);
+extern int Novfs_Write_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+extern int Novfs_Write_Pages( unsigned long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId);
+extern int Novfs_Delete( unsigned char *Path, int DirectoryFlag, session_t SessionId );
+extern int Novfs_Truncate_File( unsigned char *Path, int PathLen, session_t SessionId );
+extern int Novfs_Rename_File( int DirectoryFlag, unsigned char *OldName, int OldLen, unsigned char *NewName, int NewLen, session_t SessionId );
+extern int Novfs_Set_Attr( unsigned char *Path, struct iattr *Attr, session_t SessionId );
+extern int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId );
+
+/*
+ * scope.c functions
+ */
+extern void Scope_Init( void );
+extern void Scope_Uninit( void );
+extern void *Scope_Lookup( void );
+extern unsigned long Scope_Get_Hash( void *);
+extern uid_t Scope_Get_Uid( void *);
+extern session_t Scope_Get_SessionId( void *Scope );
+extern void *Scope_Get_ScopefromName( struct qstr *Name );
+extern void *Scope_Get_ScopefromPath( struct dentry *Dentry );
+extern char *Scope_Get_ScopeUsers( void );
+extern int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+extern int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
+
+/*
+ * profile.c functions
+ */
+extern int init_profile( void );
+extern void uninit_profile( void );
+
+/*===[ Manifest constants ]===============================================*/
+#define FILE_UPDATE_TIMEOUT 2
+
+/*===[ Type definitions ]=================================================*/
+
+/*===[ Function prototypes ]==============================================*/
+int Novfs_Remove_from_Root(char *RemoveName);
+int Novfs_Add_to_Root(char *);
+char *Novfs_dget_path( struct dentry *d, char *path, unsigned int pathlen );
+int verify_dentry(struct dentry *dentry, int Flags);
+int invalidate_dentry(struct dentry *parent);
+struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name);
+int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add);
+int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2);
+struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name);
+unsigned long Novfs_internal_hash (struct qstr *name);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+ int Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data, struct vfsmount *Mnt);
+#else
+ struct super_block * Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data);
+#endif
+
+void Novfs_kill_sb(struct super_block *SB);
+int Novfs_fill_super (struct super_block *SB, void *Data, int Silent);
+
+/*
+ * Declared dentry_operations
+ */
+int Novfs_d_revalidate(struct dentry *, struct nameidata *);
+int Novfs_d_hash (struct dentry *, struct qstr *);
+int Novfs_d_compare (struct dentry *, struct qstr *, struct qstr *);
+int Novfs_d_delete(struct dentry *dentry);
+void Novfs_d_release(struct dentry *dentry);
+void Novfs_d_iput(struct dentry *dentry, struct inode *inode);
+
+/*
+ * Declared directory operations
+ */
+int Novfs_dir_open(struct inode *inode, struct file *file);
+int Novfs_dir_release(struct inode *inode, struct file *file);
+loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin);
+int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off);
+void addtodentry( struct dentry *Parent, unsigned char *List, int Level );
+int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, ino_t ino, unsigned ftype);
+int Novfs_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
+int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync);
+
+/*
+ * Declared address space operations
+ */
+int Novfs_a_writepage(struct page* page, struct writeback_control *wbc);
+int Novfs_a_writepages(struct address_space *mapping, struct writeback_control *wbc);
+int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to);
+int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to);
+int Novfs_a_readpage(struct file *file, struct page *page);
+int Novfs_a_readpages(struct file *file, struct address_space *mapping, struct list_head *page_lst, unsigned nr_pages);
+ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb,
+ const struct iovec *iov,
+ loff_t offset,
+ unsigned long nr_segs);
+
+/*
+ * Declared file_operations
+ */
+ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *);
+ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *);
+int Novfs_f_readdir(struct file *, void *, filldir_t);
+int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma);
+int Novfs_f_open(struct inode *, struct file *);
+int Novfs_f_flush(struct file *);
+int Novfs_f_release(struct inode *, struct file *);
+int Novfs_f_fsync(struct file *, struct dentry *, int datasync);
+int Novfs_f_lock(struct file *, int, struct file_lock *);
+
+/*
+ * Declared inode_operations
+ */
+int Novfs_i_create(struct inode *,struct dentry *,int, struct nameidata *);
+struct dentry * Novfs_i_lookup(struct inode *,struct dentry *, struct nameidata *);
+int Novfs_i_mkdir(struct inode *,struct dentry *,int);
+int Novfs_i_unlink(struct inode *dir, struct dentry *dentry);
+int Novfs_i_rmdir(struct inode *,struct dentry *);
+int Novfs_i_mknod(struct inode *,struct dentry *,int,dev_t);
+int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
+int Novfs_i_permission(struct inode *inode, int mask);
+int Novfs_i_setattr(struct dentry *, struct iattr *);
+int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *);
+int Novfs_i_revalidate(struct dentry *dentry);
+
+void update_inode(struct inode *Inode, PENTRY_INFO Info);
+
+/*
+ * Declared super_operations
+ */
+void Novfs_read_inode(struct inode *inode);
+void Novfs_write_inode(struct inode *inode);
+int Novfs_notify_change(struct dentry *dentry, struct iattr *attr);
+void Novfs_clear_inode(struct inode *inode);
+int Novfs_show_options( struct seq_file *s, struct vfsmount *m );
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+ int Novfs_statfs(struct dentry *de, struct kstatfs *buf);
+#else
+ int Novfs_statfs(struct super_block *sb, struct kstatfs *buf);
+#endif
+
+/*
+ * Declared control interface functions
+ */
+ssize_t
+Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+
+ssize_t
+Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos);
+
+int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+
+int __init init_novfs(void);
+void __exit exit_novfs(void);
+
+int Novfs_lock_inode_cache( struct inode *i );
+void Novfs_unlock_inode_cache( struct inode *i );
+int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info);
+int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info);
+int Novfs_get_entry_by_pos( struct inode *i, loff_t pos, ino_t *ino, PENTRY_INFO info);
+int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime);
+int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info);
+void Novfs_invalidate_inode_cache( struct inode *i );
+PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino );
+int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino );
+int Novfs_add_inode_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
+int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
+void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino);
+void Novfs_free_invalid_entries( struct inode *i );
+void Novfs_free_inode_cache( struct inode *i );
+
+/*===[ Global variables ]=================================================*/
+struct dentry_operations Novfs_dentry_operations = {
+ .d_revalidate = Novfs_d_revalidate,
+ .d_hash = Novfs_d_hash,
+ .d_compare = Novfs_d_compare,
+ .d_delete = Novfs_d_delete,
+ .d_release = Novfs_d_release,
+ .d_iput = Novfs_d_iput,
+};
+
+struct file_operations Novfs_dir_operations = {
+ .owner = THIS_MODULE,
+ .open = Novfs_dir_open,
+ .release = Novfs_dir_release,
+ .llseek = Novfs_dir_lseek,
+ .read = Novfs_dir_read,
+ .readdir = Novfs_dir_readdir,
+ .fsync = Novfs_dir_fsync,
+};
+
+static struct file_operations Novfs_file_operations = {
+ .owner = THIS_MODULE,
+ .read = Novfs_f_read,
+ .write = Novfs_f_write,
+ .readdir = Novfs_f_readdir,
+ .ioctl = Novfs_f_ioctl,
+ .mmap = Novfs_f_mmap,
+ .open = Novfs_f_open,
+ .flush = Novfs_f_flush,
+ .release = Novfs_f_release,
+ .fsync = Novfs_f_fsync,
+ .llseek = generic_file_llseek,
+};
+
+static struct address_space_operations Novfs_aops = {
+ .readpage = Novfs_a_readpage,
+ .readpages = Novfs_a_readpages,
+ .writepage = Novfs_a_writepage,
+ .writepages = Novfs_a_writepages,
+ .prepare_write = Novfs_a_prepare_write,
+ .commit_write = Novfs_a_commit_write,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+ .direct_IO = Novfs_a_direct_IO,
+};
+
+static struct inode_operations Novfs_inode_operations = {
+ .create = Novfs_i_create,
+ .lookup = Novfs_i_lookup,
+ .unlink = Novfs_i_unlink,
+ .mkdir = Novfs_i_mkdir,
+ .rmdir = Novfs_i_rmdir,
+ .mknod = Novfs_i_mknod,
+ .rename = Novfs_i_rename,
+ .setattr = Novfs_i_setattr,
+ .getattr = Novfs_i_getattr,
+};
+
+static struct inode_operations Novfs_file_inode_operations = {
+ .setattr = Novfs_i_setattr,
+ .getattr = Novfs_i_getattr,
+};
+
+static struct super_operations Novfs_ops = {
+ .read_inode = Novfs_read_inode,
+ .statfs = Novfs_statfs,
+ .clear_inode = Novfs_clear_inode,
+ .drop_inode = generic_delete_inode,
+ .show_options = Novfs_show_options,
+
+};
+
+/* Not currently used
+static struct file_operations Novfs_Control_operations = {
+ .read = Novfs_Control_read,
+ .write = Novfs_Control_write,
+ .ioctl = Novfs_Control_ioctl,
+};
+*/
+
+ino_t Novfs_Inode_Number=1;
+
+static struct file_system_type Novfs_fs_type = {
+ .name = "novfs",
+ .get_sb = Novfs_get_sb,
+ .kill_sb = Novfs_kill_sb,
+ .owner = THIS_MODULE,
+};
+
+struct dentry *Novfs_root=NULL;
+
+int Novfs_Version_Major=NOVFS_VFS_MAJOR;
+int Novfs_Version_Minor=NOVFS_VFS_MINOR;
+int Novfs_Version_Sub=NOVFS_VFS_SUB;
+int Novfs_Version_Release=NOVFS_VFS_RELEASE;
+
+char *Novfs_CurrentMount=NULL;
+
+DECLARE_MUTEX(InodeList_lock);
+
+LIST_HEAD(InodeList);
+
+unsigned long InodeCount=0, DCCount=0;
+unsigned long File_update_timeout=FILE_UPDATE_TIMEOUT;
+int PageCache=1;
+
+/*===[ Code ]=============================================================*/
+static __inline__ void PRINT_DENTRY(const char *s, struct dentry *d)
+{
+ DbgPrint("%s: 0x%x\n", s, d);
+ DbgPrint(" d_count: 0x%x\n", d->d_count);
+ DbgPrint(" d_lock: 0x%x\n", d->d_lock);
+ DbgPrint(" d_inode: 0x%x\n", d->d_inode);
+ DbgPrint(" d_lru: 0x%x\n" \
+ " next: 0x%x\n" \
+ " prev: 0x%x\n", &d->d_lru, d->d_lru.next, d->d_lru.prev);
+ DbgPrint(" d_child: 0x%x\n" \
+ " next: 0x%x\n" \
+ " prev: 0x%x\n", &d->D_CHILD, d->D_CHILD.next, d->D_CHILD.prev);
+ DbgPrint(" d_subdirs: 0x%x\n" \
+ " next: 0x%x\n" \
+ " prev: 0x%x\n", &d->d_subdirs, d->d_subdirs.next, d->d_subdirs.prev);
+ DbgPrint(" d_alias: 0x%x\n" \
+ " next: 0x%x\n" \
+ " prev: 0x%x\n", &d->d_alias, d->d_alias.next, d->d_alias.prev);
+ DbgPrint(" d_time: 0x%x\n", d->d_time);
+ DbgPrint(" d_op: 0x%x\n", d->d_op);
+ DbgPrint(" d_sb: 0x%x\n", d->d_sb);
+ DbgPrint(" d_flags: 0x%x\n", d->d_flags);
+ DbgPrint(" d_mounted: 0x%x\n", d->d_mounted);
+ DbgPrint(" d_fsdata: 0x%x\n", d->d_fsdata);
+/* DbgPrint(" d_cookie: 0x%x\n", d->d_cookie); */
+ DbgPrint(" d_parent: 0x%x\n", d->d_parent);
+ DbgPrint(" d_name: 0x%x %.*s\n", &d->d_name, d->d_name.len, d->d_name.name);
+ DbgPrint(" name: 0x%x\n" \
+ " len: %d\n" \
+ " hash: 0x%x\n", d->d_name.name, d->d_name.len, d->d_name.hash);
+ DbgPrint(" d_hash: 0x%x\n" \
+ " next: 0x%x\n" \
+ " pprev: 0x%x\n", d->d_hash, d->d_hash.next, d->d_hash.pprev);
+}
+
+/*++======================================================================*/
+int Novfs_Remove_from_Root(char *RemoveName)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct qstr name;
+ struct dentry *dentry;
+ struct inode *dir;
+
+ DbgPrint( "Novfs_Remove_from_Root: %s\n", RemoveName);
+ name.len = strlen(RemoveName);
+ name.name = RemoveName;
+ Novfs_d_hash(Novfs_root, &name);
+
+ dentry = d_lookup( Novfs_root, &name);
+ if (dentry)
+ {
+ if (dentry->d_inode && dentry->d_inode->u.generic_ip)
+ {
+ ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL;
+ }
+ dput(dentry);
+ }
+
+
+ dir = Novfs_root->d_inode;
+
+ Novfs_lock_inode_cache( dir );
+ Novfs_remove_inode_entry( dir, &name, 0);
+ Novfs_unlock_inode_cache( dir );
+
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_Add_to_Root(char *AddName)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct qstr name;
+ struct inode *dir;
+ ENTRY_INFO info;
+ ino_t ino;
+
+ DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
+ name.len = strlen(AddName);
+ name.name = AddName;
+ Novfs_d_hash(Novfs_root, &name);
+
+ dir = Novfs_root->d_inode;
+
+ Novfs_lock_inode_cache( dir );
+
+ ino = 0;
+
+ if ( !Novfs_lookup_inode_cache(dir, &name, 0))
+ {
+ info.mode = S_IFDIR | 0700;
+ info.size = 0;
+ info.atime = info.ctime = info.mtime = CURRENT_TIME;
+
+ ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+ Novfs_add_inode_entry( dir, &name, ino, &info);
+ }
+
+ Novfs_unlock_inode_cache( dir );
+
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_Add_to_Root2(char *AddName)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct dentry *entry;
+ struct qstr name;
+ struct inode *inode;
+ void *scope;
+
+ DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
+ name.len = strlen(AddName);
+ name.name = AddName;
+
+ Novfs_d_hash(Novfs_root, &name);
+
+ entry = Novfs_d_lookup(Novfs_root, &name);
+ DbgPrint( "Novfs_Add_to_Root: Novfs_d_lookup 0x%x\n", entry);
+ if ( NULL == entry )
+ {
+ scope = Scope_Lookup();
+
+ entry = d_alloc(Novfs_root, &name);
+ DbgPrint( "Novfs_Add_to_Root: d_alloc 0x%x\n", entry );
+ if (entry)
+ {
+ entry->d_op = &Novfs_dentry_operations;
+ entry->d_time = jiffies+(File_update_timeout*HZ);
+ /*
+ * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name );
+ */
+ inode = Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name);
+ DbgPrint( "Novfs_Add_to_Root: Inode=0x%x\n", inode);
+ if (inode)
+ {
+ inode->i_atime =
+ inode->i_ctime =
+ inode->i_mtime = CURRENT_TIME;
+ if ( !Novfs_d_add(Novfs_root, entry, inode, 1))
+ {
+ if (inode->u.generic_ip)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE;
+ }
+ PRINT_DENTRY("After Novfs_d_add", entry);
+ }
+ else
+ {
+ dput(entry);
+ iput(inode);
+ }
+ }
+ }
+ }
+ else
+ {
+ dput(entry);
+ PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry);
+ }
+ return(0);
+}
+
+/*++======================================================================*/
+char *Novfs_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen)
+/*
+ * Arguments: struct dentry *Dentry - starting entry
+ * char *Buf - pointer to memory buffer
+ * unsigned int Buflen - size of memory buffer
+ *
+ * Returns: pointer to path.
+ *
+ * Abstract: Walks the dentry chain building a path.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *retval=&Buf[Buflen];
+ struct dentry *p=Dentry;
+
+ *(--retval) = '\0';
+ Buflen--;
+
+ if (!IS_ROOT(p) && !IS_ROOT(p->d_parent))
+ {
+ while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent))
+ {
+ if (Buflen > p->d_name.len)
+ {
+ retval -= p->d_name.len;
+ Buflen -= p->d_name.len;
+ memcpy(retval, p->d_name.name, p->d_name.len);
+ *(--retval) = '\\';
+ Buflen--;
+ p = p->d_parent;
+ }
+ else
+ {
+ retval = NULL;
+ break;
+ }
+ }
+ }
+ else
+ {
+ *(--retval) = '\\';
+ }
+
+
+
+if (retval) DbgPrint("Novfs_dget_path: %s\n", retval);
+ return(retval);
+}
+
+/*++======================================================================*/
+int verify_dentry( struct dentry *dentry, int Flags )
+/*
+ * Arguments: struct dentry *dentry - entry to verify
+ *
+ * Returns: zero - Inode cache has been updated. If not in the cache
+ * then file doesn't exist.
+ * !zero - Error
+ *
+ * Abstract: This routine will verify if the file that dentry is pointing
+ * at exist and if it does it will put it in the inode cache of
+ * the parent.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = -ENOENT;
+ struct inode *dir;
+ PENTRY_INFO info=NULL;
+ PINODE_DATA id;
+ session_t session;
+ char *path, *list=NULL, *cp;
+ ino_t ino;
+ struct qstr name;
+ int iLock=0;
+ struct dentry *parent=NULL;
+ u64 ctime;
+ struct inode *inode;
+
+ if ( IS_ROOT(dentry) )
+ {
+ DbgPrint("verify_dentry: Root entry\n");
+ return( 0 );
+ }
+
+ if ( dentry && dentry->d_parent &&
+ (dir = dentry->d_parent->d_inode) &&
+ (id = dir->u.generic_ip) )
+ {
+ parent = dget_parent(dentry);
+
+ info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
+
+ if (info)
+ {
+ if (Novfs_lock_inode_cache( dir ))
+ {
+ name.len = dentry->d_name.len;
+ name.name = dentry->d_name.name;
+ name.hash = Novfs_internal_hash( &name );
+ if ( !Novfs_get_entry_time(dir, &name, &ino, info, &ctime))
+ {
+ inode = dentry->d_inode;
+ if ( inode &&
+ ( (inode->i_size != info->size) ||
+ (inode->i_mtime.tv_sec != info->mtime.tv_sec) ||
+ (inode->i_mtime.tv_nsec != info->mtime.tv_nsec) ))
+ {
+ /*
+ * Values don't match so update.
+ */
+ ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
+ }
+
+ ctime = get_jiffies_64() - ctime;
+ if ( Flags || ctime < (u64)(File_update_timeout*HZ) )
+ {
+ retVal = 0;
+ Novfs_unlock_inode_cache(dir);
+ dput(parent);
+ Novfs_Free(info);
+ return(0);
+ }
+ }
+ Novfs_unlock_inode_cache(dir);
+ }
+
+ if ( IS_ROOT(dentry->d_parent) )
+ {
+ session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name));
+ }
+ else
+ {
+ session = Scope_Get_SessionId( id->Scope );
+ }
+
+ if ( !session )
+ {
+ id->Scope = Scope_Get_ScopefromPath(dentry);
+ session = Scope_Get_SessionId( id->Scope );
+ }
+
+ ino = 0;
+ retVal = 0;
+
+ if ( IS_ROOT(dentry->d_parent) )
+ {
+ DbgPrint("verify_dentry: parent is Root directory\n");
+ list = Scope_Get_ScopeUsers();
+
+ iLock = Novfs_lock_inode_cache( dir );
+ Novfs_invalidate_inode_cache( dir );
+
+ if ( list )
+ {
+ cp = list;
+ while (*cp)
+ {
+ name.name = cp;
+ name.len = strlen(cp);
+ name.hash = Novfs_internal_hash( &name );
+ cp += (name.len+1);
+ ino = 0;
+ if ( Novfs_get_entry( dir, &name, &ino, info ) )
+ {
+ info->mode = S_IFDIR | 0700;
+ info->size = 0;
+ info->atime = info->ctime = info->mtime = CURRENT_TIME;
+ ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+ Novfs_add_inode_entry(dir, &name, ino, info);
+ }
+ }
+ }
+ Novfs_free_invalid_entries( dir );
+ }
+ else
+ {
+
+ path = Novfs_dget_path(dentry, info->name, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ if (dentry->d_name.len <= NW_MAX_PATH_LENGTH)
+ {
+ name.hash = Novfs_internal_hash(&dentry->d_name);
+ name.len = dentry->d_name.len;
+ name.name = dentry->d_name.name;
+
+
+
+ retVal = Novfs_Get_File_Info( path, info, session );
+ if ( 0 == retVal)
+ {
+ dentry->d_time = jiffies+(File_update_timeout*HZ);
+ iLock = Novfs_lock_inode_cache( dir );
+ if ( Novfs_update_entry( dir, &name, 0, info ) )
+ {
+ if (dentry->d_inode)
+ {
+ ino = dentry->d_inode->i_ino;
+ }
+ else
+ {
+ ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+ }
+ Novfs_add_inode_entry( dir, &name, ino, info);
+ }
+ if ( dentry->d_inode )
+ {
+ update_inode(dentry->d_inode, info);
+ id->Flags &= ~UPDATE_INODE;
+
+ dentry->d_inode->i_flags &= ~S_DEAD;
+ if (dentry->d_inode->u.generic_ip)
+ {
+ ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope;
+ }
+ }
+ }
+ else if (-EINTR != retVal)
+ {
+ retVal = 0;
+ iLock = Novfs_lock_inode_cache( dir );
+ Novfs_remove_inode_entry( dir, &name, 0 );
+ if ( dentry->d_inode && !(dentry->d_inode->i_flags & S_DEAD) )
+ {
+ dentry->d_inode->i_flags |= S_DEAD;
+ dentry->d_inode->i_size = 0;
+ dentry->d_inode->i_atime.tv_sec =
+ dentry->d_inode->i_atime.tv_nsec =
+ dentry->d_inode->i_ctime.tv_sec =
+ dentry->d_inode->i_ctime.tv_nsec =
+ dentry->d_inode->i_mtime.tv_sec =
+ dentry->d_inode->i_mtime.tv_nsec = 0;
+ dentry->d_inode->i_blocks = 0;
+ d_delete(dentry); /* Remove from cache */
+ }
+ }
+ }
+ else
+ {
+ retVal = -ENAMETOOLONG;
+ }
+ }
+ }
+ }
+ else
+ {
+ retVal = -ENOMEM;
+ }
+ if (iLock)
+ {
+ Novfs_unlock_inode_cache( dir );
+ }
+ dput(parent);
+ }
+
+ if (list) Novfs_Free(list);
+ if (info) Novfs_Free(info);
+
+ DbgPrint("verify_dentry: return=0x%x\n", retVal);
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ return( d_lookup( Parent, Name));
+}
+
+/*++======================================================================*/
+int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ void *scope;
+ PINODE_DATA id=NULL;
+
+ char *path, *buf;
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, i->i_ino, path);
+ }
+ Novfs_Free(buf);
+ }
+
+ if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip)
+ {
+ id = (PINODE_DATA)Parent->d_inode->u.generic_ip;
+ }
+
+ if (id && id->Scope)
+ {
+ scope = id->Scope;
+ }
+ else
+ {
+ scope = Scope_Get_ScopefromPath( d );
+ }
+
+ ((PINODE_DATA)i->u.generic_ip)->Scope = scope;
+
+ d->d_time = jiffies+(File_update_timeout*HZ);
+ if (a)
+ {
+ d_add(d, i);
+ }
+ else
+ {
+ d_instantiate(d, i);
+ }
+
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+/*
+ * Arguments: struct dentry *dentry - pointer to dentry to revalidate.
+ * struct nameidata *nd - pointer to nameidata.
+ *
+ * Returns: zero - dentry is not valid.
+ * !zero - valid entry
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = 0;
+ struct inode *dir;
+ PINODE_DATA id;
+ struct qstr name;
+
+ UNUSED_VARIABLE( nd );
+
+ DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" \
+ " d_count: %d\n" \
+ " d_inode: 0x%p\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
+
+ if (IS_ROOT( dentry ))
+ {
+ retCode = 1;
+ }
+ else
+ {
+ if ( dentry->d_inode &&
+ dentry->d_parent &&
+ (dir = dentry->d_parent->d_inode) &&
+ (id = dir->u.generic_ip) )
+ {
+ /*
+ * Check timer to see if in valid time limit
+ */
+ if (jiffies > dentry->d_time)
+ {
+ /*
+ * Revalidate entry
+ */
+ name.len = dentry->d_name.len;
+ name.name = dentry->d_name.name;
+ name.hash = Novfs_internal_hash(&dentry->d_name);
+ dentry->d_time = 0;
+
+ if ( 0 == verify_dentry( dentry, 0 ))
+ {
+ if (Novfs_lock_inode_cache( dir ))
+ {
+ if (Novfs_lookup_inode_cache( dir, &name, 0))
+ {
+ dentry->d_time = jiffies + (File_update_timeout*HZ);
+ retCode = 1;
+ }
+ Novfs_unlock_inode_cache( dir );
+ }
+ }
+ }
+ else
+ {
+ retCode = 1;
+ }
+ }
+ }
+
+
+ if ( ( 0 == retCode ) && dentry->d_inode )
+ {
+ /*
+ * Entry has become invalid
+ */
+/* dput(dentry);
+*/
+ }
+
+ DbgPrint("Novfs_d_revalidate: return 0x%x\n", retCode);
+
+ return(retCode);
+}
+
+/*++======================================================================*/
+unsigned long Novfs_internal_hash (struct qstr *name)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ unsigned long hash = 0;
+ unsigned int len = name->len;
+ unsigned char *c = (unsigned char *)name->name;
+
+ while(len--)
+ {
+ /*
+ * Lower case values for the hash.
+ */
+ hash = partial_name_hash(tolower(*c++), hash);
+ }
+
+ return(hash);
+}
+
+/*++======================================================================*/
+int Novfs_d_hash (struct dentry *dentry, struct qstr *name)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ UNUSED_VARIABLE( dentry );
+
+ DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name);
+
+ name->hash = Novfs_internal_hash( name );
+
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = 1;
+ unsigned char *str1, *str2;
+ unsigned int len;
+
+ DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, s2->len, s2->name);
+
+ if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash) )
+ {
+ len = s1->len;
+ str1 = (unsigned char *)s1->name;
+ str2 = (unsigned char *)s2->name;
+ for ( retCode = 0; len-- ; str1++, str2++ )
+ {
+ if (*str1 != *str2)
+ {
+ if (tolower(*str1) != tolower(*str2))
+ {
+ retCode = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode);
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_d_compare (struct dentry *parent, struct qstr *s1, struct qstr *s2)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode;
+
+ retCode = Novfs_d_strcmp(s1, s2);
+
+ DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode);
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_d_delete(struct dentry *dentry)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = 0;
+
+ DbgPrint("Novfs_d_delete: 0x%p %.*s\n" \
+ " d_count: %d\n" \
+ " d_inode: 0x%p\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
+
+ if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD))
+ {
+ retVal = 1;
+ }
+
+ dentry->d_time = 0;
+
+ return( retVal );
+}
+
+/*++======================================================================*/
+void Novfs_d_release(struct dentry *dentry)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DbgPrint("Novfs_d_release: 0x%x %.*s\n", dentry, dentry->d_name.len, dentry->d_name.name);
+}
+
+/*++======================================================================*/
+void Novfs_d_iput(struct dentry *dentry, struct inode *inode)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DbgPrint("Novfs_d_iput: Inode=0x%x Ino=%d Dentry=0x%x Name=%.*s\n",
+ inode, inode->i_ino, dentry, dentry->d_name.len, dentry->d_name.name);
+
+ iput(inode);
+
+}
+/*++======================================================================*/
+int Novfs_dir_open(struct inode *dir, struct file *file)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *path, *buf;
+
+
+ DbgPrint("Novfs_dir_open: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ DbgPrint("Novfs_dir_open: path %s\n", path);
+ }
+ Novfs_Free(buf);
+ }
+ file->private_data = NULL;
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_dir_release(struct inode *dir, struct file *file)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct inode *inode;
+
+ DbgPrint("Novfs_dir_release: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+ if (file->private_data)
+ {
+ inode = file->private_data;
+ Novfs_free_inode_cache( inode );
+ Novfs_Free(file->private_data);
+ }
+
+ return(0);
+}
+
+/*++======================================================================*/
+loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ return(default_llseek(file, offset, origin));
+}
+
+/*++======================================================================*/
+int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+/*
+ int rlen = 0;
+
+ DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off);
+
+ if (0 == *off)
+ {
+ rlen = 8;
+ rlen -= copy_to_user(buf, "Testing\n", 8);
+ *off += rlen;
+ }
+ return(rlen);
+*/
+ return(generic_read_dir(file, buf, len, off));
+}
+
+/*++======================================================================*/
+void process_list(struct file *File, char *List, int Type, PENTRY_INFO Info, session_t SessionId)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ unsigned char *path, *buf=NULL, *cp;
+ struct inode *dir = File->f_dentry->d_inode;
+ struct qstr name;
+ ino_t ino=0;
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ path = buf;
+ if (buf)
+ {
+ path = Novfs_dget_path(File->f_dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ strcpy(buf, path);
+ }
+ path = buf+strlen(buf);
+ *path++ = '\\';
+ }
+
+ if ( List )
+ {
+ cp = List;
+ while (*cp)
+ {
+ name.name = cp;
+ name.len = strlen(cp);
+ name.hash = Novfs_internal_hash( &name );
+ cp += (name.len+1);
+
+ Info->mode = S_IFDIR | 0700;
+ Info->size = 0;
+ Info->atime = Info->ctime = Info->mtime = CURRENT_TIME;
+
+ if ( (USER_LIST != Type) && buf && ((int)(path-buf)+name.len < PATH_LENGTH_BUFFER) )
+ {
+ strcpy(path, name.name);
+ Novfs_Get_File_Info(buf, Info, SessionId);
+ }
+
+ if ( Novfs_update_entry( dir, &name, ino, Info ) )
+ {
+ Novfs_add_inode_entry(dir, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), Info);
+ }
+ }
+ }
+
+ if (buf) Novfs_Free(buf);
+
+}
+
+/*++======================================================================*/
+int Novfs_dir_readdir(struct file * file, void * dirent, filldir_t filldir)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ unsigned char *path, *buf=NULL;
+ unsigned char *list=NULL;
+ PENTRY_INFO info=NULL, pinfo, iinfo;
+ int count;
+
+ int status = -ENOMEM;
+ struct inode *inode;
+ session_t sessionId;
+ uid_t uid;
+ struct qstr name;
+ struct list_head *inter;
+ ino_t ino;
+ int iLock=0;
+ int type = 0;
+
+ DbgPrint("Novfs_dir_readdir(%s): dentry path %.*s 0x%x\n", current->comm, file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_dentry->d_fsdata);
+
+ inode = file->f_dentry->d_inode;
+
+ info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (info)
+ {
+ if (!file->private_data)
+ {
+ if ( inode && inode->u.generic_ip )
+ {
+ sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ if (0 == sessionId)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry);
+ sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+ uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+ else
+ {
+ sessionId = 0;
+ uid = current->euid;
+ }
+
+ if ( IS_ROOT(file->f_dentry) || /* Root */
+ IS_ROOT(file->f_dentry->d_parent) || /* User */
+ IS_ROOT(file->f_dentry->d_parent->d_parent) ) /* Server */
+ {
+ if ( IS_ROOT(file->f_dentry) )
+ {
+ DbgPrint("Novfs_dir_readdir: Root directory\n");
+ list = Scope_Get_ScopeUsers();
+ type = USER_LIST;
+
+ }
+ else if ( IS_ROOT(file->f_dentry->d_parent) )
+ {
+ DbgPrint("Novfs_dir_readdir: Parent is Root directory\n");
+ Novfs_Get_Connected_Server_List( &list, sessionId );
+ type = SERVER_LIST;
+ }
+ else
+ {
+ DbgPrint("Novfs_dir_readdir: Parent-Parent is Root directory\n");
+ Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, &list, sessionId);
+ type = VOLUME_LIST;
+ }
+
+ iLock = Novfs_lock_inode_cache( inode );
+ Novfs_invalidate_inode_cache( inode );
+
+ process_list(file, list, type, info, sessionId);
+ }
+ else
+ {
+ DbgPrint("Novfs_dir_readdir: Default directory\n");
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ unsigned long enumHandle=0;
+
+ iLock = Novfs_lock_inode_cache( inode );
+ Novfs_invalidate_inode_cache(inode);
+ do
+ {
+ /*
+ * Novfs_Get_Directory_List will return 0 when no error or -1 when
+ * the last entry is returned. Otherwise it will return an error.
+ */
+ info->namelength = 0;
+ status = Novfs_Get_Directory_ListEx(path, &enumHandle, &count, &pinfo, sessionId);
+ DbgPrint("Novfs_dir_readdir: Novfs_Get_Directory_List return 0x%x count=%d pinfo=0x%p\n", status, count, pinfo);
+ iinfo = pinfo;
+ while ( (0 == status) && pinfo && count-- )
+ {
+ memcpy(info, pinfo, (int)((char *)&pinfo->name[pinfo->namelength]-(char *)pinfo));
+ pinfo = (PENTRY_INFO)&pinfo->name[pinfo->namelength];
+ name.len = info->namelength;
+ name.name = info->name;
+ name.hash = Novfs_internal_hash(&name);
+ info->name[name.len] = '\0';
+
+ DbgPrint("Novfs_dir_readdir: Got %s\n", name.name);
+
+ if ( Novfs_update_entry( inode, &name, 0, info ))
+ {
+ Novfs_add_inode_entry(inode, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), info);
+ }
+ }
+
+ if (iinfo)
+ {
+ Novfs_Free(iinfo);
+ }
+
+ }
+ while ( !status );
+ }
+ }
+ }
+
+ file->private_data = (PDIR_CACHE)Novfs_Malloc(sizeof(struct inode) + sizeof(DIR_CACHE), GFP_KERNEL);
+ if (file->private_data)
+ {
+ struct inode *dinode = file->private_data;
+ PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode));
+
+ dinode->u.generic_ip = id;
+
+ id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope;
+ id->Flags = 0;
+ INIT_LIST_HEAD( &id->DirCache );
+ init_MUTEX( &id->DirCacheLock );
+
+ inter = NULL;
+ /*
+ * Copy rest of the files.
+ */
+ while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info))
+ {
+ DbgPrint("Novfs_dir_readdir : BEGIN Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
+ name.len = info->namelength;
+ name.name = info->name;
+ name.hash = Novfs_internal_hash( &name );
+ Novfs_add_inode_entry(dinode, &name, ino, info);
+ DbgPrint("Novfs_dir_readdir : END Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
+ }
+ file->private_data = dinode;
+ }
+
+ if ( iLock )
+ {
+ Novfs_free_invalid_entries( inode );
+ }
+ }
+
+ switch ((int) file->f_pos)
+ {
+ case 0:
+ DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d name .\n", file->f_pos, inode->i_ino);
+ if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < 0)
+ {
+ break;
+ }
+ file->f_pos++;
+ /* fallthrough */
+ case 1:
+ DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d name ..\n", file->f_pos, parent_ino(file->f_dentry));
+ if (filldir(dirent, "..", 2, file->f_pos, parent_ino(file->f_dentry), DT_DIR) < 0)
+ {
+ break;
+ }
+ file->f_pos++;
+ /* fallthrough */
+ }
+
+ status = 0;
+ inter = NULL;
+
+ if(!Novfs_get_entry_by_pos(file->private_data, file->f_pos, &ino, info))
+ {
+ DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
+ filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12);
+ }
+ file->f_pos++;
+
+ if (iLock)
+ {
+ Novfs_unlock_inode_cache(inode);
+ }
+ }
+
+ if (info) Novfs_Free( info );
+ if (buf) Novfs_Free( buf );
+ if (list) Novfs_Free( list );
+
+ return(status);
+}
+
+
+/*++======================================================================*/
+int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ return(simple_sync_file(file, dentry, datasync));
+}
+
+
+/*++======================================================================*/
+ssize_t Novfs_f_read(struct file *file, char *buf, size_t len, loff_t *off)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ size_t thisread, totalread=0;
+ loff_t offset = *off;
+ struct inode *inode;
+ session_t session;
+ PINODE_DATA id;
+
+ if ( file->f_dentry &&
+ (inode = file->f_dentry->d_inode) &&
+ (id = (PINODE_DATA)inode->u.generic_ip))
+ {
+
+ DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n",
+ (unsigned long)file->private_data,
+ buf, len, offset,
+ file->f_dentry->d_name.len,
+ file->f_dentry->d_name.name);
+
+ if ( PageCache &&
+ !(file->f_flags & O_DIRECT) &&
+ id->CacheFlag )
+ {
+ totalread = generic_file_read(file, buf, len, off);
+ }
+ else
+ {
+ session = Scope_Get_SessionId(id->Scope);
+ if (0 == session)
+ {
+ id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(id->Scope);
+ }
+
+ while(len > 0 && (offset < i_size_read(inode)) )
+ {
+ thisread = len;
+ if (Novfs_Read_File((unsigned long)file->private_data, buf, &thisread, &offset, session) || !thisread)
+ {
+ break;
+ }
+ DbgPrint("Novfs_f_read thisread = 0x%x\n", thisread);
+ len -= thisread;
+ buf += thisread;
+ offset += thisread;
+ totalread += thisread;
+ }
+ *off = offset;
+ }
+ }
+ DbgPrint("Novfs_f_read return = 0x%x\n", totalread);
+
+ return(totalread);
+}
+
+/*++======================================================================*/
+ssize_t Novfs_f_write(struct file *file, const char *buf, size_t len, loff_t *off)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ssize_t thiswrite, totalwrite=0;
+ loff_t offset = *off;
+ session_t session;
+ struct inode *inode;
+ int status;
+ PINODE_DATA id;
+
+ if ( file->f_dentry &&
+ (inode = file->f_dentry->d_inode) &&
+ (id = file->f_dentry->d_inode->u.generic_ip) )
+ {
+ DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+
+ if ( PageCache &&
+ !(file->f_flags & O_DIRECT) &&
+ id->CacheFlag )
+ {
+ totalwrite = generic_file_write(file, buf, len, off);
+ }
+ else
+ {
+ if (file->f_flags & O_APPEND)
+ {
+ offset = i_size_read(inode);
+ DbgPrint("Novfs_f_write appending to end %lld %.*s\n", offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+ }
+
+ session = Scope_Get_SessionId(id->Scope);
+ if (0 == session)
+ {
+ id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(id->Scope);
+ }
+
+ while(len > 0)
+ {
+ thiswrite = len;
+ if ((status = Novfs_Write_File(
+ (unsigned long)file->private_data,
+ (unsigned char *)buf,
+ &thiswrite,
+ &offset,
+ session)) || !thiswrite)
+ {
+ totalwrite = status;
+ break;
+ }
+ DbgPrint("Novfs_f_write thiswrite = 0x%x\n", thiswrite);
+ len -= thiswrite;
+ buf += thiswrite;
+ offset += thiswrite;
+ totalwrite += thiswrite;
+ if (offset > i_size_read(inode))
+ {
+ i_size_write(inode, offset);
+ inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits;
+ }
+ inode->i_mtime = inode->i_atime = CURRENT_TIME;
+ id->Flags |= UPDATE_INODE;
+
+ }
+ *off = offset;
+ }
+ }
+ DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite);
+
+ return(totalwrite);
+}
+
+/*++======================================================================*/
+int Novfs_f_readdir(struct file *file, void *data, filldir_t fill)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(data);
+ UNUSED_VARIABLE(fill);
+ return(-EISDIR);
+}
+
+/*++======================================================================*/
+int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ UNUSED_VARIABLE(inode);
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(cmd);
+ UNUSED_VARIABLE(arg);
+ DbgPrint("Novfs_f_ioctl: file=0x%x cmd=0x%x arg=0x%x", file, cmd, arg);
+
+ return(-ENOSYS);
+}
+
+/*++======================================================================*/
+int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -EINVAL;
+
+ DbgPrint("Novfs_f_mmap: file=0x%x", file);
+
+ retCode = generic_file_mmap(file, vma);
+
+ DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode);
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_f_open(struct inode *inode, struct file *file)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PENTRY_INFO info=NULL;
+ int retCode = -ENOENT;
+ session_t session;
+ char *path;
+ struct dentry *parent;
+ ino_t ino;
+ PINODE_DATA id;
+
+ DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode);
+ if (file->f_dentry)
+ {
+ DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
+ }
+
+ if (inode && inode->u.generic_ip)
+ {
+ id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
+ session = Scope_Get_SessionId(id->Scope);
+ if (0 == session)
+ {
+ id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(id->Scope);
+ }
+
+ info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (info)
+ {
+ path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ DbgPrint("Novfs_f_open: %s\n", path);
+ retCode = Novfs_Open_File(
+ path,
+ file->f_flags & ~O_EXCL, info,
+ (unsigned long *)&file->private_data,
+ session);
+ if ( !retCode )
+ {
+ /*
+ *update_inode(inode, &info);
+ */
+ id->FileHandle = (unsigned long)file->private_data;
+ id->CacheFlag = Novfs_Get_File_Cache_Flag( path, session );
+
+ if( !Novfs_Get_File_Info(path, info, session))
+ {
+ update_inode(inode, info);
+ }
+
+ parent = dget_parent(file->f_dentry);
+
+ if (parent && parent->d_inode)
+ {
+ struct inode *dir = parent->d_inode;
+ Novfs_lock_inode_cache(dir);
+ ino = 0;
+ if (Novfs_get_entry(dir, &file->f_dentry->d_name, &ino, info))
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
+ }
+
+ Novfs_unlock_inode_cache(dir);
+ }
+ dput(parent);
+ }
+ }
+ Novfs_Free(info);
+ }
+ }
+ DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode);
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_f_flush(struct file *file)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct inode *inode;
+
+ if (file->f_dentry)
+ {
+ if( (file->f_flags & O_ACCMODE) != O_RDONLY)
+ {
+ inode = file->f_dentry->d_inode;
+ DbgPrint("Novfs_f_flush: %.*s f_flags=0x%x f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
+ filemap_fdatawrite( file->f_dentry->d_inode->i_mapping );
+ }
+ }
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_f_release(struct inode *inode, struct file *file)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -EACCES;
+ session_t session;
+ PINODE_DATA id;
+
+ DbgPrint("Novfs_f_release: path=%.*s handle=%x\n",
+ file->f_dentry->d_name.len,
+ file->f_dentry->d_name.name,
+ (unsigned long)file->private_data);
+
+ if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
+ {
+ session = Scope_Get_SessionId(id->Scope);
+ if (0 == session)
+ {
+ id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(id->Scope);
+ }
+
+ //invalidate_remote_inode(file->f_dentry->d_inode);
+
+ retCode = Novfs_Close_File((unsigned long)file->private_data, session);
+ id->FileHandle = 0;
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(dentry);
+ UNUSED_VARIABLE(datasync);
+ return(0);
+}
+
+/*++======================================================================*/
+int Novfs_f_llseek(struct file *file, loff_t offset, int origin)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ DbgPrint("Novfs_f_llseek: File=0x%x Name=%.*s offset=%lld origin=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, offset, origin);
+ return(generic_file_llseek(file, offset, origin));
+}
+
+/*++======================================================================*/
+int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(cmd);
+ UNUSED_VARIABLE(lock);
+ return(-ENOSYS);
+}
+/*++======================================================================*/
+static void Novfs_copy_cache_pages(struct address_space *mapping,
+ struct list_head *pages, int bytes_read, char *data,
+ struct pagevec *plru_pvec)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct page *page;
+ char *target;
+
+ while (bytes_read > 0) {
+ if (list_empty(pages))
+ break;
+
+ page = list_entry(pages->prev, struct page, lru);
+ list_del(&page->lru);
+
+ if (add_to_page_cache(page, mapping, page->index,
+ GFP_KERNEL)) {
+ page_cache_release(page);
+ data += PAGE_CACHE_SIZE;
+ bytes_read -= PAGE_CACHE_SIZE;
+ continue;
+ }
+
+ target = kmap_atomic(page,KM_USER0);
+
+ if (PAGE_CACHE_SIZE > bytes_read) {
+ memcpy(target, data, bytes_read);
+ /* zero the tail end of this partial page */
+ memset(target + bytes_read, 0,
+ PAGE_CACHE_SIZE - bytes_read);
+ bytes_read = 0;
+ } else {
+ memcpy(target, data, PAGE_CACHE_SIZE);
+ bytes_read -= PAGE_CACHE_SIZE;
+ }
+ kunmap_atomic(target, KM_USER0);
+
+ flush_dcache_page(page);
+ SetPageUptodate(page);
+ unlock_page(page);
+ if (!pagevec_add(plru_pvec, page))
+ __pagevec_lru_add(plru_pvec);
+ data += PAGE_CACHE_SIZE;
+ }
+ return;
+}
+
+/*++======================================================================*/
+int Novfs_a_writepage(struct page* page, struct writeback_control *wbc)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -EFAULT;
+ struct inode *inode = page->mapping->host;
+ PINODE_DATA id = inode->u.generic_ip;
+ loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT);
+ session_t session=0;
+ DATA_LIST dlst[2];
+ size_t len = PAGE_CACHE_SIZE;
+
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+
+ page_cache_get(page);
+
+ pos = ((loff_t)page->index << PAGE_CACHE_SHIFT);
+
+ /*
+ * Leave first dlst entry for reply header.
+ */
+ dlst[1].page = page;
+ dlst[1].offset = NULL;
+ dlst[1].len = len;
+ dlst[1].rwflag = DLREAD;
+
+ /*
+ * Check size so we don't write pass end of file.
+ */
+ if ((pos + (loff_t)len) > i_size_read(inode))
+ {
+ len = (size_t)(i_size_read(inode) - pos);
+ }
+
+ retCode = Novfs_Write_Pages( id->FileHandle, dlst, 2, len, pos, session);
+ if ( !retCode )
+ {
+ SetPageUptodate(page);
+ }
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_a_writepages(struct address_space *mapping, struct writeback_control *wbc)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = 0;
+ struct inode *inode=mapping->host;
+ session_t session=0;
+ unsigned long fh=0;
+
+ int max_page_lookup = MaxIoSize/PAGE_CACHE_SIZE;
+
+ PDATA_LIST dlist, dlptr;
+ struct page **pages;
+
+ int dlist_idx, i=0;
+ pgoff_t index, next_index=0;
+ loff_t pos=0;
+ size_t tsize;
+
+ DbgPrint("Novfs_a_writepages: mapping=0x%p wbc=0x%p\n", mapping, wbc);
+
+ if (inode)
+ {
+ DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino);
+
+ if (inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ fh = ((PINODE_DATA)inode->u.generic_ip)->FileHandle;
+ }
+ }
+
+ dlist = Novfs_Malloc( sizeof(DATA_LIST) * max_page_lookup, GFP_KERNEL);
+ pages = Novfs_Malloc( sizeof(struct page *) * max_page_lookup, GFP_KERNEL);
+
+ if ( fh && dlist && pages )
+ {
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
+ int done = 0;
+ int nr_pages=0;
+ int scanned = 0;
+
+ if (wbc->nonblocking && bdi_write_congested(bdi))
+ {
+ wbc->encountered_congestion = 1;
+ return 0;
+ }
+
+ if (wbc->sync_mode == WB_SYNC_NONE)
+ {
+ index = mapping->writeback_index; /* Start from prev offset */
+ }
+ else
+ {
+ index = 0; /* whole-file sweep */
+ scanned = 1;
+ }
+
+ next_index = index;
+
+ while (!done && (wbc->nr_to_write > 0))
+ {
+ dlist_idx = 0;
+ dlptr = &dlist[1];
+
+ DbgPrint("Novfs_a_writepages1: nr_pages=%d\n", nr_pages);
+ if ( !nr_pages )
+ {
+ memset(pages, 0, sizeof(struct page *)*max_page_lookup);
+
+ AS_TREE_LOCK(&mapping->tree_lock);
+
+ /*
+ * Need to ask for one less then max_page_lookup or we
+ * will overflow the request buffer. This also frees
+ * the first entry for the reply buffer.
+ */
+ nr_pages = radix_tree_gang_lookup_tag(&mapping->page_tree,
+ (void **)pages, index, max_page_lookup-1, PAGECACHE_TAG_DIRTY);
+
+ DbgPrint("Novfs_a_writepages2: nr_pages=%d\n", nr_pages);
+
+
+ for (i = 0; i < nr_pages; i++)
+ {
+ page_cache_get(pages[i]);
+ }
+
+ AS_TREE_UNLOCK(&mapping->tree_lock);
+
+ if (nr_pages)
+ {
+ index = pages[nr_pages - 1]->index + 1;
+ pos = (loff_t)pages[0]->index << PAGE_CACHE_SHIFT;
+ }
+
+ if ( !nr_pages )
+ {
+ if ( scanned )
+ {
+ index = 0;
+ scanned = 0;
+ continue;
+ }
+ done = 1;
+ }
+ else
+ {
+ next_index = pages[0]->index;
+ i = 0;
+ }
+ }
+ else
+ {
+ if (pages[i])
+ {
+ pos = (loff_t)pages[i]->index << PAGE_CACHE_SHIFT;
+ }
+ }
+
+
+ for ( ; i < nr_pages ; i++)
+ {
+ struct page *page = pages[i];
+
+ /*
+ * At this point we hold neither mapping->tree_lock nor
+ * lock on the page itself: the page may be truncated or
+ * invalidated (changing page->mapping to NULL), or even
+ * swizzled back from swapper_space to tmpfs file
+ * mapping
+ */
+
+ DbgPrint("Novfs_a_writepages: pos=0x%llx index=%d page->index=%d next_index=%d\n", pos, index, page->index, next_index);
+
+ if (page->index != next_index)
+ {
+ next_index = page->index;
+ break;
+ }
+ next_index = page->index+1;
+
+ lock_page(page);
+
+ if (wbc->sync_mode != WB_SYNC_NONE)
+ wait_on_page_writeback(page);
+
+ if (page->mapping != mapping || PageWriteback(page) ||
+ !clear_page_dirty_for_io(page))
+ {
+ unlock_page(page);
+ continue;
+ }
+
+ dlptr[dlist_idx].page = page;
+ dlptr[dlist_idx].offset = NULL;
+ dlptr[dlist_idx].len = PAGE_CACHE_SIZE;
+ dlptr[dlist_idx].rwflag = DLREAD;
+ dlist_idx++;
+ DbgPrint("Novfs_a_writepages: Add page=0x%p index=0x%lx\n", page, page->index);
+ }
+
+ DbgPrint("Novfs_a_writepages: dlist_idx=%d\n", dlist_idx);
+ if ( dlist_idx )
+ {
+ tsize = dlist_idx * PAGE_CACHE_SIZE;
+ /*
+ * Check size so we don't write pass end of file.
+ */
+ if ((pos + tsize) > i_size_read(inode))
+ {
+ tsize = (size_t)(i_size_read(inode) - pos);
+ }
+
+ retCode = Novfs_Write_Pages(fh, dlist, dlist_idx+1, tsize, pos, session);
+ switch (retCode)
+ {
+ case 0:
+ wbc->nr_to_write -= dlist_idx;
+ break;
+
+ case -ENOSPC:
+ set_bit(AS_ENOSPC, &mapping->flags);
+ done = 1;
+ break;
+
+ default:
+ set_bit(AS_EIO, &mapping->flags);
+ done = 1;
+ break;
+ }
+
+ do
+ {
+ unlock_page((struct page *)dlptr[dlist_idx-1].page);
+ page_cache_release((struct page *)dlptr[dlist_idx-1].page);
+ DbgPrint("Novfs_a_writepages: release page=0x%p index=0x%lx\n", dlptr[dlist_idx-1].page, ((struct page *)dlptr[dlist_idx-1].page)->index);
+ if ( !retCode )
+ {
+ wbc->nr_to_write--;
+ }
+ } while( --dlist_idx );
+ }
+
+ if ( i >= nr_pages )
+ {
+ nr_pages = 0;
+ }
+ }
+
+ mapping->writeback_index = index;
+
+ }
+ else
+ {
+ set_bit(AS_EIO, &mapping->flags);
+ }
+ if (dlist) Novfs_Free(dlist);
+ if (pages) Novfs_Free(pages);
+
+ DbgPrint("Novfs_a_writepage: retCode=%d\n", retCode);
+ return (0);
+
+}
+
+/*++======================================================================*/
+int Novfs_a_readpage(struct file *file, struct page *page)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = 0;
+ void *pbuf;
+ struct inode *inode=NULL;
+ struct dentry *dentry=NULL;
+ loff_t offset;
+ size_t len;
+ session_t session=0;
+
+ DbgPrint("Novfs_a_readpage: File=0x%x Name=%.*s Page=0x%x", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, page);
+
+ dentry = file->f_dentry;
+
+ if (dentry)
+ {
+ DbgPrint(" Dentry=0x%x Name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name);
+ if (dentry->d_inode)
+ {
+ inode = dentry->d_inode;
+ }
+ }
+
+
+
+ if (inode)
+ {
+ DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino);
+
+ if (inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+ }
+ }
+
+ DbgPrint("\n");
+
+
+ if (!PageUptodate(page))
+ {
+ DATA_LIST dlst[2];
+
+ offset = page->index << PAGE_CACHE_SHIFT;
+ len = PAGE_CACHE_SIZE;
+
+ /*
+ * Save the first entry for the reply header.
+ */
+ dlst[1].page = page;
+ dlst[1].offset = NULL;
+ dlst[1].len = PAGE_CACHE_SIZE;
+ dlst[1].rwflag = DLWRITE;
+
+ retCode = Novfs_Read_Pages((unsigned long)file->private_data, dlst, 2, &len, &offset, session);
+ if ( len && (len < PAGE_CACHE_SIZE) )
+ {
+ pbuf = kmap_atomic(page, KM_USER0);
+ memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE-len);
+ kunmap_atomic(pbuf, KM_USER0);
+ }
+
+ flush_dcache_page(page);
+ SetPageUptodate(page);
+ }
+ unlock_page(page);
+
+ DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode);
+ return (retCode);
+
+}
+
+/*++======================================================================*/
+int Novfs_a_readpages(struct file *file, struct address_space *mapping, struct list_head *page_lst, unsigned nr_pages)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = 0;
+ struct inode *inode=NULL;
+ struct dentry *dentry=NULL;
+ session_t session=0;
+ loff_t offset;
+ size_t len;
+
+ unsigned page_idx;
+ struct pagevec lru_pvec;
+ pgoff_t next_index;
+
+ char *rbuf, done=0;
+
+ DbgPrint("Novfs_a_readpages: File=0x%p Name=%.*s Pages=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, nr_pages);
+
+ dentry = file->f_dentry;
+
+ if (dentry)
+ {
+ DbgPrint(" Dentry=0x%x Name=%.*s\n", dentry, dentry->d_name.len, dentry->d_name.name);
+ if (dentry->d_inode)
+ {
+ inode = dentry->d_inode;
+ }
+ }
+
+ if (inode)
+ {
+ DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino);
+
+ if (inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+ }
+ }
+
+ rbuf = (char *)Novfs_Malloc(MaxIoSize, GFP_KERNEL);
+ if (rbuf)
+ {
+ pagevec_init(&lru_pvec, 0);
+ for (page_idx = 0; page_idx < nr_pages && !done; )
+ {
+ struct page *page, *tpage;
+
+ if (list_empty(page_lst))
+ break;
+
+ page = list_entry(page_lst->prev, struct page, lru);
+
+ next_index = page->index;
+ offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+ len = 0;
+
+ /*
+ * Count number of contiguous pages.
+ */
+ list_for_each_entry_reverse(tpage, page_lst, lru)
+ {
+ if ( (next_index != tpage->index) ||
+ (len >= MaxIoSize-PAGE_SIZE) )
+ {
+ break;
+ }
+ len += PAGE_SIZE;
+ next_index++;
+ }
+
+ if ( len && !done )
+ {
+ DATA_LIST dllst[2];
+
+ dllst[1].page = NULL;
+ dllst[1].offset = rbuf;
+ dllst[1].len = len;
+ dllst[1].rwflag = DLWRITE;
+
+ if ( !Novfs_Read_Pages((unsigned long)file->private_data, dllst, 2, &len, &offset, session))
+ {
+ Novfs_copy_cache_pages(mapping, page_lst, len, rbuf, &lru_pvec);
+ page_idx += len >> PAGE_CACHE_SHIFT;
+ if ((int)(len & PAGE_CACHE_MASK) != len)
+ {
+ page_idx++;
+ }
+ }
+ else
+ {
+ done = 1;
+ }
+ }
+ }
+
+ /*
+ * Free any remaining pages.
+ */
+ while ( !list_empty(page_lst) )
+ {
+ struct page *page = list_entry(page_lst->prev, struct page, lru);
+
+ list_del(&page->lru);
+ page_cache_release(page);
+ }
+
+ pagevec_lru_add(&lru_pvec);
+ Novfs_Free( rbuf );
+ }
+ else
+ {
+ retCode = -ENOMEM;
+ }
+
+ DbgPrint("Novfs_a_readpages: retCode=%d\n", retCode);
+ return (retCode);
+
+}
+
+/*++======================================================================*/
+int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = 0;
+ loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+ size_t len=PAGE_CACHE_SIZE;
+ session_t session=0;
+ DATA_LIST dllst[2];
+ struct inode *inode = file->f_dentry->d_inode;
+
+ DbgPrint("Novfs_a_prepare_write: File=0x%x Page=0x%x offset=0x%llx From=%u To=%u filesize=%lld\n", file, page, offset, from, to, i_size_read(file->f_dentry->d_inode));
+ if (!PageUptodate(page))
+ {
+ /*
+ * Check to see if whole page
+ */
+ if((to==PAGE_CACHE_SIZE) && (from == 0))
+ {
+ SetPageUptodate(page);
+ }
+
+ /*
+ * Check to see if we can read page.
+ */
+ else if((file->f_flags & O_ACCMODE) != O_WRONLY)
+ {
+ /*
+ * Get session.
+ */
+ if (file->f_dentry && file->f_dentry->d_inode)
+ {
+ if (file->f_dentry->d_inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+ }
+ }
+
+ page_cache_get(page);
+
+ len = i_size_read(inode) - offset;
+ if (len > PAGE_CACHE_SIZE)
+ {
+ len = PAGE_CACHE_SIZE;
+ }
+
+ if( len )
+ {
+ /*
+ * Read page from server.
+ */
+
+ dllst[1].page = page;
+ dllst[1].offset = 0;
+ dllst[1].len = len;
+ dllst[1].rwflag = DLWRITE;
+
+ Novfs_Read_Pages((unsigned long)file->private_data, dllst, 2, &len, &offset, session);
+ /*
+ * Zero unnsed page.
+ */
+ }
+
+ if (len < PAGE_CACHE_SIZE)
+ {
+ char *adr = kmap_atomic(page, KM_USER0);
+ memset(adr+len, 0, PAGE_CACHE_SIZE-len);
+ kunmap_atomic(adr, KM_USER0);
+ }
+ }
+ else
+ {
+ /*
+ * Zero section of memory that not going to be used.
+ */
+ char *adr = kmap_atomic(page, KM_USER0);
+ memset(adr, 0, from);
+ memset(adr + to, 0, PAGE_CACHE_SIZE - to);
+ kunmap_atomic(adr, KM_USER0);
+
+ DbgPrint("Novfs_a_prepare_write: memset 0x%p\n", adr);
+ }
+ flush_dcache_page(page);
+ SetPageUptodate(page);
+ }
+
+// DbgPrint("Novfs_a_prepare_write: return %d\n", retVal);
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+
+{
+ int retCode = 0;
+ struct inode *inode = page->mapping->host;
+ loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ session_t session=0;
+ PINODE_DATA id;
+ DATA_LIST dlst[1];
+ size_t len = to - offset;
+
+ DbgPrint("Novfs_a_commit_write: File=0x%p Page=0x%p offset=0x%x To=%u filesize=%lld\n", file, page, offset, to, i_size_read(file->f_dentry->d_inode));
+ if (file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
+ {
+ session = Scope_Get_SessionId(id->Scope);
+ if (0 == session)
+ {
+ id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+ session = Scope_Get_SessionId(id->Scope);
+ }
+
+ if (pos > inode->i_size)
+ {
+ i_size_write(inode, pos);
+ }
+
+ if (!PageUptodate(page))
+ {
+ pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
+
+ if (to < offset)
+ {
+ return( retCode );
+ }
+ dlst[0].page = page;
+ dlst[0].offset = (void *)offset;
+ dlst[0].len = len;
+ dlst[0].rwflag = DLREAD;
+
+ retCode = Novfs_Write_Pages( id->FileHandle, dlst, 1, len, pos, session);
+
+ } else {
+ set_page_dirty(page);
+ }
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb,
+ const struct iovec *iov,
+ loff_t offset,
+ unsigned long nr_segs)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes: This is a dummy function so that we can allow a file
+ * to get the direct IO flag set. Novfs_f_read and
+ * Novfs_f_write will do the work. Maybe not the best
+ * way to do but it was the easiest to implement.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ return( -EIO );
+}
+
+/*++======================================================================*/
+int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *path, *buf;
+ ENTRY_INFO info;
+ unsigned long handle;
+ session_t session;
+ int retCode = -EACCES;
+
+
+ DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name);
+
+ if ( IS_ROOT(dentry) || /* Root */
+ IS_ROOT(dentry->d_parent) || /* User */
+ IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+ IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+ {
+ return(-EACCES);
+ }
+
+ if (mode | S_IFREG)
+ {
+ if (dir->u.generic_ip)
+ {
+ session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
+ }
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ retCode = Novfs_Open_File(path, nd->NDOPENFLAGS|O_RDWR, &info, &handle, session);
+ if ( !retCode && handle )
+ {
+ Novfs_Close_File(handle, session);
+ if (!Novfs_i_mknod(dir, dentry, mode | S_IFREG, 0))
+ {
+ if (dentry->d_inode)
+ {
+ ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE;
+ }
+ }
+ }
+ }
+ Novfs_Free(buf);
+ }
+ }
+ }
+ return( retCode );
+}
+
+/*++======================================================================*/
+void update_inode(struct inode *Inode, PENTRY_INFO Info)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ static char dbuf[128];
+
+ DbgPrint("update_inode: Inode=0x%x I_ino=%d\n", Inode, Inode->i_ino);
+
+ DbgPrint("update_inode: atime=%s\n", ctime_r(&Info->atime.tv_sec, dbuf));
+ DbgPrint("update_inode: ctime=%s\n", ctime_r(&Info->ctime.tv_sec, dbuf));
+ DbgPrint("update_inode: mtime=%s %d\n", ctime_r(&Info->mtime.tv_sec, dbuf), Info->mtime.tv_nsec);
+ DbgPrint("update_inode: size=%lld\n", Info->size);
+ DbgPrint("update_inode: mode=0%o\n", Info->mode);
+
+ if ( Inode &&
+ ( (Inode->i_size != Info->size) ||
+ (Inode->i_mtime.tv_sec != Info->mtime.tv_sec) ||
+ (Inode->i_mtime.tv_nsec != Info->mtime.tv_nsec) ))
+ {
+ DbgPrint("update_inode: calling invalidate_remote_inode sz %d %d\n", Inode->i_size, Info->size);
+ DbgPrint("update_inode: calling invalidate_remote_inode sec %d %d\n", Inode->i_mtime.tv_sec, Info->mtime.tv_sec);
+ DbgPrint("update_inode: calling invalidate_remote_inode ns %d %d\n", Inode->i_mtime.tv_nsec, Info->mtime.tv_nsec);
+ invalidate_remote_inode( Inode );
+ }
+
+ Inode->i_mode = Info->mode;
+ Inode->i_size = Info->size;
+ Inode->i_atime = Info->atime;
+ Inode->i_ctime = Info->ctime;
+ Inode->i_mtime = Info->mtime;
+
+ if (Inode->i_size && Inode->i_blksize)
+ {
+ Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits);
+ Inode->i_bytes = Info->size & (Inode->i_blksize - 1);
+
+ DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize);
+ DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits);
+ DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks);
+ DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes);
+ }
+}
+
+/*++======================================================================*/
+struct dentry * Novfs_i_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct dentry *retVal = ERR_PTR(-ENOENT);
+ struct dentry *parent;
+ PENTRY_INFO info=NULL;
+ PINODE_DATA id;
+ struct inode *inode=NULL;
+ uid_t uid=current->euid;
+ ino_t ino=0;
+ struct qstr name;
+
+ DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode);
+
+ if (dir && (id = dir->u.generic_ip) )
+ {
+ retVal = 0;
+ if ( IS_ROOT( dentry ))
+ {
+ DbgPrint("Novfs_i_lookup: Root entry=0x%x\n", Novfs_root);
+ inode = Novfs_root->d_inode;
+ return(0);
+ }
+ else
+ {
+ info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (info)
+ {
+ if ( NULL == (retVal = ERR_PTR(verify_dentry( dentry, 1 ))))
+ {
+ name.name = dentry->d_name.name;
+ name.len = dentry->d_name.len;
+ name.hash = Novfs_internal_hash(&name);
+
+ if (Novfs_lock_inode_cache( dir ))
+ {
+ if ( !Novfs_get_entry(dir, &name, &ino, info) )
+ {
+ inode = ilookup(dentry->d_sb, ino);
+ if ( inode )
+ {
+ update_inode(inode, info);
+ }
+ }
+ Novfs_unlock_inode_cache( dir );
+ }
+
+ if ( !inode && ino )
+ {
+ uid = Scope_Get_Uid( id->Scope );
+ if (Novfs_lock_inode_cache( dir ))
+ {
+ inode = Novfs_get_inode(dentry->d_sb, info->mode, 0, uid, ino, &name);
+ if ( inode )
+ {
+ if ( !Novfs_get_entry(dir, &dentry->d_name, &ino, info) )
+ {
+ update_inode(inode, info);
+ }
+ }
+ Novfs_unlock_inode_cache( dir );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( !retVal )
+ {
+ dentry->d_op = &Novfs_dentry_operations;
+ if (inode)
+ {
+ parent = dget_parent(dentry);
+ Novfs_d_add(dentry->d_parent, dentry, inode, 1);
+ dput(parent);
+ }
+ else
+ {
+ d_add( dentry, inode);
+ }
+ }
+
+ if (info) Novfs_Free(info);
+
+ DbgPrint("Novfs_i_lookup: inode=0x%x dentry->d_inode=0x%x return=0x%x\n", dir, dentry->d_inode, retVal);
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int Novfs_i_unlink(struct inode *dir, struct dentry *dentry)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOENT;
+ struct inode *inode;
+ session_t session;
+ char *path, *buf;
+ uint64_t t64;
+
+ DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d %.*s\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name);
+ DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry));
+ DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", IS_ROOT(dentry->d_parent));
+ DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent));
+ DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent->d_parent) );
+
+ if ( IS_ROOT(dentry) || /* Root */
+ IS_ROOT(dentry->d_parent) || /* User */
+ (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */
+ IS_ROOT(dentry->d_parent->d_parent->d_parent)) ) /* Volume */
+ {
+ return(-EACCES);
+ }
+
+ inode = dentry->d_inode;
+ if ( inode )
+ {
+ DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino);
+ if (inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ DbgPrint("Novfs_i_unlink: path %s mode 0%o\n", path, inode->i_mode);
+ if (IS_ROOT(dentry->d_parent->d_parent))
+ {
+ retCode = do_logout(&dentry->d_name);
+ }
+ else
+ {
+ retCode = Novfs_Delete(path, S_ISDIR(inode->i_mode), session);
+ }
+ if ( !retCode || IS_DEADDIR(inode))
+ {
+ Novfs_remove_inode_entry(dir, &dentry->d_name, 0);
+ dentry->d_time = 0;
+ t64 = 0;
+ Scope_Set_UserSpace(&t64, &t64, &t64, &t64);
+ retCode = 0;
+ }
+ }
+ Novfs_Free(buf);
+ }
+ }
+ }
+
+ DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode);
+ return (retCode);
+}
+
+/*++======================================================================*/
+int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *path, *buf;
+ session_t session;
+ int retCode=0;
+ struct inode *inode;
+ ENTRY_INFO info;
+ uid_t uid;
+
+ DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%o\n", dir, dir->i_ino, dentry, dentry->d_name.len, dentry->d_name.name, mode);
+
+ if ( IS_ROOT(dentry) || /* Root */
+ IS_ROOT(dentry->d_parent) || /* User */
+ IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+ IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+ {
+ return(-EACCES);
+ }
+
+ mode |= S_IFDIR;
+ mode &= (S_IFMT | S_IRWXU);
+ if ( dir->u.generic_ip )
+ {
+ session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
+ }
+
+ uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ DbgPrint("Novfs_i_mkdir: path %s\n", path);
+ retCode = Novfs_Create(path, S_ISDIR(mode), session);
+ if ( !retCode )
+ {
+ retCode = Novfs_Get_File_Info(path, &info, session );
+ if ( !retCode )
+ {
+ retCode = Novfs_i_mknod(dir, dentry, mode, 0);
+ inode = dentry->d_inode;
+ if (inode)
+ {
+ update_inode(inode, &info);
+ ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE;
+
+ dentry->d_time = jiffies+(File_update_timeout*HZ);
+
+ Novfs_lock_inode_cache(dir);
+ if (Novfs_update_entry( dir, &dentry->d_name, 0, &info ))
+ {
+ Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, &info);
+ }
+ Novfs_unlock_inode_cache(dir);
+ }
+
+ }
+ }
+ }
+ Novfs_Free(buf);
+ }
+ }
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ return(Novfs_i_unlink(inode, dentry));
+}
+
+/*++======================================================================*/
+int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct inode *inode=NULL;
+ int retCode = -EACCES;
+ uid_t uid;
+ struct dentry *parent;
+
+ if ( IS_ROOT(dentry) || /* Root */
+ IS_ROOT(dentry->d_parent) || /* User */
+ IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+ IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+ {
+ return(-EACCES);
+ }
+
+ if ( ((PINODE_DATA)dir->u.generic_ip) )
+ {
+ uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+ if (mode & (S_IFREG | S_IFDIR))
+ {
+ inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name);
+ }
+ }
+
+ if (inode)
+ {
+ ENTRY_INFO info;
+
+ dentry->d_op = &Novfs_dentry_operations;
+ parent = dget_parent(dentry);
+ Novfs_d_add(parent, dentry, inode, 0);
+ memset(&info, 0, sizeof(info));
+ info.mode = inode->i_mode;
+ Novfs_lock_inode_cache( dir );
+ Novfs_add_inode_entry( dir, &dentry->d_name, inode->i_ino, &info);
+ Novfs_unlock_inode_cache( dir );
+
+ dput(parent);
+
+ retCode = 0;
+ }
+ DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode);
+ return retCode;
+}
+
+/*++======================================================================*/
+int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, struct dentry *nd)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = -ENOTEMPTY;
+ char *newpath, *newbuf, *newcon;
+ char *oldpath, *oldbuf, *oldcon;
+ struct qstr newname, oldname;
+ PENTRY_INFO info=NULL;
+ int oldlen, newlen;
+ session_t session;
+ ino_t ino;
+
+
+ if ( IS_ROOT(od) || /* Root */
+ IS_ROOT(od->d_parent) || /* User */
+ IS_ROOT(od->d_parent->d_parent) || /* Server */
+ IS_ROOT(od->d_parent->d_parent->d_parent) ) /* Volume */
+ {
+ return(-EACCES);
+ }
+
+ DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, odir->i_ino, ndir, ndir->i_ino);
+
+ oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER*2, GFP_KERNEL);
+ newbuf = oldbuf+PATH_LENGTH_BUFFER;
+ if ( oldbuf && newbuf )
+ {
+ oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER);
+ newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER);
+ if (oldpath && newpath)
+ {
+ oldlen = PATH_LENGTH_BUFFER-(int)(oldpath-oldbuf);
+ newlen = PATH_LENGTH_BUFFER-(int)(newpath-newbuf);
+
+ DbgPrint("Novfs_i_rename: odir=0x%x od->inode=0x%x\n", odir, od->d_inode);
+ DbgPrint("Novfs_i_rename: old path %s\n", oldpath);
+ DbgPrint("Novfs_i_rename: new path %s\n", newpath);
+
+ /*
+ * Check to see if two different servers or different volumes
+ */
+ newcon = strchr(newpath+1, '\\');
+ oldcon = strchr(oldpath+1, '\\');
+ DbgPrint("Novfs_i_rename: newcon=0x%x newpath=0x%x\n", newcon, newpath);
+ DbgPrint("Novfs_i_rename: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
+ retCode = -EXDEV;
+ if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
+ {
+ newcon = strchr(newcon+1, '\\');
+ oldcon = strchr(oldcon+1, '\\');
+ DbgPrint("Novfs_i_rename2: newcon=0x%x newpath=0x%x\n", newcon, newpath);
+ DbgPrint("Novfs_i_rename2: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
+ if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
+ {
+ newname.name = newpath;
+ newname.len = (int)(newcon-newpath);
+ newname.hash = 0;
+
+ oldname.name = oldpath;
+ oldname.len = (int)(oldcon-oldpath);
+ oldname.hash = 0;
+ if ( !Novfs_d_strcmp(&newname, &oldname))
+ {
+
+ if ( od->d_inode && od->d_inode->u.generic_ip )
+ {
+
+ if (nd->d_inode && nd->d_inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
+ session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+ }
+
+ retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
+ }
+
+
+ session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
+ session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+ }
+ retCode = Novfs_Rename_File(
+ S_ISDIR(od->d_inode->i_mode),
+ oldpath,
+ oldlen-1,
+ newpath,
+ newlen-1,
+ session);
+
+ if ( !retCode )
+ {
+ info = (PENTRY_INFO)oldbuf;
+ od->d_time = 0;
+ Novfs_remove_inode_entry(odir, &od->d_name, 0);
+ Novfs_Get_File_Info(newpath, info, session);
+ nd->d_time = jiffies+(File_update_timeout*HZ);
+ if (Novfs_update_entry(ndir, &nd->d_name, 0, info))
+ {
+ if (nd->d_inode && nd->d_inode->i_ino)
+ {
+ ino = nd->d_inode->i_ino;
+ }
+ else
+ {
+ ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+ }
+ Novfs_add_inode_entry(ndir, &nd->d_name, ino, info);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (oldbuf) Novfs_Free(oldbuf);
+
+ return( retCode );
+}
+
+/*++======================================================================*/
+int Novfs_i_permission(struct inode *inode, int mask)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode=0;
+
+ return(retCode);
+}
+
+/*++======================================================================*/
+int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *path, *buf;
+ struct inode *inode=dentry->d_inode;
+ char atime_buf[32];
+ char mtime_buf[32];
+ char ctime_buf[32];
+ unsigned int ia_valid = attr->ia_valid;
+ session_t session;
+ int retVal = 0;
+
+ if ( IS_ROOT(dentry) || /* Root */
+ IS_ROOT(dentry->d_parent) || /* User */
+ IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+ IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+ {
+ return(-EACCES);
+ }
+
+ if (inode && inode->u.generic_ip)
+ {
+ session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope);
+ if (0 == session)
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+ session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+ }
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ strcpy(atime_buf, "Unspecified");
+ strcpy(mtime_buf, "Unspecified");
+ strcpy(ctime_buf, "Unspecified");
+ if (attr->ia_valid & ATTR_ATIME)
+ {
+ ctime_r(&attr->ia_atime.tv_sec, atime_buf);
+ }
+ if (attr->ia_valid & ATTR_MTIME)
+ {
+ ctime_r(&attr->ia_mtime.tv_sec, mtime_buf);
+ }
+ if (attr->ia_valid & ATTR_CTIME)
+ {
+ ctime_r(&attr->ia_ctime.tv_sec, ctime_buf);
+ }
+ /* Removed for Bug 132374. jlt
+ DbgPrint("Novfs_i_setattr: %s\n" \
+ " ia_valid: 0x%x\n" \
+ " ia_mode: 0%o\n" \
+ " ia_uid: %d\n" \
+ " ia_gid: %d\n" \
+ " ia_size: %lld\n" \
+ " ia_atime: %s\n" \
+ " ia_mtime: %s\n" \
+ " ia_ctime: %s\n" \
+ " ia_attr_flags: 0x%x\n",
+ path,
+ attr->ia_valid,
+ attr->ia_mode,
+ attr->ia_uid,
+ attr->ia_gid,
+ attr->ia_size,
+ atime_buf,
+ mtime_buf,
+ ctime_buf,
+ attr->ia_attr_flags);
+ */
+
+ if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) )
+ {
+ ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
+
+ if (ia_valid & ATTR_ATIME)
+ inode->i_atime = attr->ia_atime;
+ if (ia_valid & ATTR_MTIME)
+ inode->i_mtime = attr->ia_mtime;
+ if (ia_valid & ATTR_CTIME)
+ inode->i_ctime = attr->ia_ctime;
+ if (ia_valid & ATTR_MODE) {
+ inode->i_mode = attr->ia_mode & (S_IFMT | S_IRWXU);
+ }
+ }
+ }
+ }
+ Novfs_Free(buf);
+ }
+
+ return(retVal);
+}
+
+/*++======================================================================*/
+int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode = 0;
+ char atime_buf[32];
+ char mtime_buf[32];
+ char ctime_buf[32];
+ struct inode *inode = dentry->d_inode;
+
+ ENTRY_INFO info;
+ char *path, *buf;
+ session_t session;
+ PINODE_DATA id;
+
+ if ( !IS_ROOT(dentry) &&
+ !IS_ROOT(dentry->d_parent) )
+ {
+ session = 0;
+ id = dentry->d_inode->u.generic_ip;
+
+ if (id && (id->Flags & UPDATE_INODE) )
+ {
+ session = Scope_Get_SessionId( id->Scope );
+
+ if (0 == session)
+ {
+ id->Scope = Scope_Get_ScopefromPath( dentry );
+ session = Scope_Get_SessionId(id->Scope);
+ }
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ retCode = Novfs_Get_File_Info(path, &info, session );
+ if ( !retCode )
+ {
+ update_inode(inode, &info);
+ id->Flags &= ~UPDATE_INODE;
+ }
+ }
+ Novfs_Free(buf);
+ }
+ }
+ }
+
+ kstat->ino = inode->i_ino;
+ kstat->dev = inode->i_sb->s_dev;
+ kstat->mode = inode->i_mode;
+ kstat->nlink = inode->i_nlink;
+ kstat->uid = inode->i_uid;
+ kstat->gid = inode->i_gid;
+ kstat->rdev = inode->i_rdev;
+ kstat->size = i_size_read(inode);
+ kstat->atime = inode->i_atime;
+ kstat->mtime = inode->i_mtime;
+ kstat->ctime = inode->i_ctime;
+ kstat->blksize = inode->i_blksize;
+ kstat->blocks = inode->i_blocks;
+ if (inode->i_bytes)
+ {
+ kstat->blocks++;
+ }
+ ctime_r(&kstat->atime.tv_sec, atime_buf);
+ ctime_r(&kstat->mtime.tv_sec, mtime_buf);
+ ctime_r(&kstat->ctime.tv_sec, ctime_buf);
+
+
+ DbgPrint("Novfs_i_getattr: 0x%x <%.*s>\n" \
+ " ino: %d\n" \
+ " dev: 0x%x\n" \
+ " mode: 0%o\n" \
+ " nlink: 0x%x\n" \
+ " uid: 0x%x\n" \
+ " gid: 0x%x\n" \
+ " rdev: 0x%x\n" \
+ " size: 0x%llx\n" \
+ " atime: %s\n" \
+ " mtime: %s\n" \
+ " ctime: %s\n" \
+ " blksize: 0x%x\n" \
+ " blocks: 0x%x\n",
+ retCode, dentry->d_name.len, dentry->d_name.name,
+ kstat->ino,
+ kstat->dev,
+ kstat->mode,
+ kstat->nlink,
+ kstat->uid,
+ kstat->gid,
+ kstat->rdev,
+ kstat->size,
+ atime_buf,
+ mtime_buf,
+ ctime_buf,
+ kstat->blksize,
+ kstat->blocks);
+ return( retCode );
+}
+
+
+/*++======================================================================*/
+int Novfs_i_revalidate(struct dentry *dentry)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+
+ DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, dentry->d_name.name);
+
+ return(0);
+}
+
+/*++======================================================================*/
+void Novfs_read_inode(struct inode *inode)
+/*
+ * Arguments:
+ *
+ * Returns: nothing
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment: Superblock operation
+ *
+ *=======================================================================-*/
+{
+ DbgPrint( "Novfs_read_inode: 0x%x %d\n", inode, inode->i_ino);
+}
+
+/*++======================================================================*/
+void Novfs_write_inode(struct inode *inode)
+/*
+ * Arguments:
+ *
+ * Returns: nothing
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment: Superblock operation
+ *
+ *=======================================================================-*/
+{
+ DbgPrint( "Novfs_write_inode: Inode=0x%x Ino=%d\n", inode, inode->i_ino);
+}
+
+/*++======================================================================*/
+int Novfs_notify_change(struct dentry *dentry, struct iattr *attr)
+/*
+ * Arguments:
+ *
+ * Returns: error code
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment: Superblock operation
+ *
+ *=======================================================================-*/
+{
+ struct inode *inode = dentry->d_inode;
+
+ DbgPrint( "Novfs_notify_change: Dentry=0x%x Name=%.*s Inode=0x%x Ino=%d ia_valid=0x%x\n",
+ dentry, dentry->d_name.len, dentry->d_name.name,inode, inode->i_ino, attr->ia_valid);
+ return(0);
+}
+
+/*++======================================================================*/
+void Novfs_clear_inode(struct inode *inode)
+/*
+ * Arguments: sb - pointer to the super_block
+ * buf - pointer to the statfs buffer
+ *
+ * Returns: 0
+ *
+ * Abstract: Called when statfs(2) system called.
+ *
+ * Notes:
+ *
+ * Environment: Superblock operation
+ *
+ *========================================================================*/
+{
+ InodeCount--;
+
+ if ( inode->u.generic_ip )
+ {
+ PINODE_DATA id=inode->u.generic_ip;
+
+ DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name);
+
+ Novfs_free_inode_cache(inode);
+
+ down( &InodeList_lock );
+ list_del( &id->IList );
+ up( &InodeList_lock );
+
+
+ Novfs_Free(inode->u.generic_ip);
+ inode->u.generic_ip = NULL;
+
+ remove_inode_hash( inode );
+
+ }
+ else
+ {
+ DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d\n", inode, inode->i_ino);
+ }
+}
+
+/*++======================================================================*/
+int
+NO_TRACE
+Novfs_show_options( struct seq_file *s, struct vfsmount *m )
+/*
+ * Arguments:
+ *
+ * Returns: 0
+ *
+ * Abstract: Called when /proc/mounts is read
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *buf, *path, *tmp;
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = d_path(m->mnt_root, m, buf, PATH_LENGTH_BUFFER);
+ if (path)
+ {
+ if ( !Novfs_CurrentMount || (Novfs_CurrentMount && strcmp(Novfs_CurrentMount, path)))
+ {
+ DbgPrint("Novfs_show_options: %.*s %.*s %s\n", m->mnt_root->d_name.len, m->mnt_root->d_name.name,
+ m->mnt_mountpoint->d_name.len, m->mnt_mountpoint->d_name.name, path);
+ tmp = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - (int)(path-buf), GFP_KERNEL);
+ if (tmp)
+ {
+ strcpy(tmp, path);
+ path = Novfs_CurrentMount;
+ Novfs_CurrentMount = tmp;
+ Daemon_SetMountPoint( Novfs_CurrentMount );
+
+ if (path)
+ {
+ Novfs_Free(path);
+ }
+ }
+ }
+ }
+ Novfs_Free( buf );
+ }
+ return(0);
+}
+
+/*++======================================================================*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+int Novfs_statfs(struct dentry *de, struct kstatfs *buf)
+#else
+int Novfs_statfs(struct super_block *sb, struct kstatfs *buf)
+#endif
+/*
+ * Arguments: sb - pointer to the super_block
+ * buf - pointer to the statfs buffer
+ *
+ * Returns: 0
+ *
+ * Abstract: Called when statfs(2) system called.
+ *
+ * Notes:
+ *
+ * Environment: Superblock operation
+ *
+ *========================================================================*/
+{
+ uint64_t td, fd, te, fe;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+ struct super_block *sb = de->d_sb;
+#endif
+
+ UNUSED_VARIABLE(sb);
+
+ DbgPrint("Novfs_statfs:\n");
+
+ td = fd = te = fe = 0;
+
+ Scope_Get_UserSpace( &td, &fd, &te, &fe );
+
+ DbgPrint("td=%llu\n", td);
+ DbgPrint("fd=%llu\n", fd);
+ DbgPrint("te=%llu\n", te);
+ DbgPrint("fe=%llu\n", fd);
+
+ buf->f_type = sb->s_magic;
+ buf->f_bsize = sb->s_blocksize;
+ buf->f_namelen = NW_MAX_PATH_LENGTH;
+ buf->f_blocks = (sector_t)(td + (uint64_t)(sb->s_blocksize-1)) >> (uint64_t)sb->s_blocksize_bits;
+ buf->f_bfree = (sector_t)fd >> (uint64_t)sb->s_blocksize_bits;
+ buf->f_bavail = (sector_t)buf->f_bfree;
+ buf->f_files = (sector_t)te;
+ buf->f_ffree = (sector_t)fe;
+ buf->f_frsize = sb->s_blocksize;
+ if (te > 0xffffffff)
+ buf->f_files = 0xffffffff;
+
+ if (fe > 0xffffffff)
+ buf->f_ffree = 0xffffffff;
+
+
+ DbgPrint("f_type: 0x%x\n", buf->f_type);
+ DbgPrint("f_bsize: %u\n", buf->f_bsize);
+ DbgPrint("f_namelen: %d\n", buf->f_namelen);
+ DbgPrint("f_blocks: %llu\n", buf->f_blocks);
+ DbgPrint("f_bfree: %llu\n", buf->f_bfree);
+ DbgPrint("f_bavail: %llu\n", buf->f_bavail);
+ DbgPrint("f_files: %llu\n", buf->f_files);
+ DbgPrint("f_ffree: %llu\n", buf->f_ffree);
+ DbgPrint("f_frsize: %u\n", buf->f_frsize);
+
+ return 0;
+}
+
+/*++======================================================================*/
+struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t Uid, ino_t ino, struct qstr *name)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *=======================================================================-*/
+{
+ struct inode * inode = new_inode(sb);
+
+ if (inode)
+ {
+ InodeCount++;
+ inode->i_mode = mode;
+ inode->i_uid = Uid;
+ inode->i_gid = 0;
+ inode->i_blksize = sb->s_blocksize;
+ inode->i_blkbits = sb->s_blocksize_bits;
+ inode->i_blocks = 0;
+ inode->i_rdev = 0;
+ inode->i_ino = (ino) ? ino: (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+ inode->i_mapping->a_ops = &Novfs_aops;
+ inode->i_atime.tv_sec = 0;
+ inode->i_atime.tv_nsec = 0;
+ inode->i_mtime = inode->i_ctime = inode->i_atime;
+
+ DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len);
+
+ if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL)))
+ {
+ PINODE_DATA id;
+ id = inode->u.generic_ip;
+
+ DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id);
+
+ id->Scope = NULL;
+ id->Flags = 0;
+ id->Inode = inode;
+ INIT_LIST_HEAD( &id->DirCache );
+ init_MUTEX( &id->DirCacheLock );
+
+ id->FileHandle = 0;
+ id->CacheFlag = 0;
+
+ down( &InodeList_lock );
+
+ list_add_tail(&id->IList, &InodeList);
+ up( &InodeList_lock );
+
+ id->Name[0] = '\0';
+
+ memcpy(id->Name, name->name, name->len);
+ id->Name[name->len] = '\0';
+
+ DbgPrint("Novfs_get_inode: name %s\n", id->Name);
+ }
+
+ insert_inode_hash(inode);
+
+ switch (mode & S_IFMT) {
+
+ case S_IFREG:
+ inode->i_op = &Novfs_file_inode_operations;
+ inode->i_fop = &Novfs_file_operations;
+ break;
+
+ case S_IFDIR:
+ inode->i_op = &Novfs_inode_operations;
+ inode->i_fop = &Novfs_dir_operations;
+ inode->i_blksize = 0;
+ inode->i_blkbits = 0;
+ break;
+
+ default:
+ init_special_inode(inode, mode, dev);
+ break;
+ }
+
+ DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size);
+ DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode);
+ DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize);
+ DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits);
+ DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks);
+ DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes);
+ }
+
+ DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino);
+ return (inode);
+}
+
+/*++======================================================================*/
+int Novfs_fill_super (struct super_block *SB, void *Data, int Silent)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct inode * inode;
+ struct dentry *server, *tree;
+ struct qstr name;
+/* PINODE_DATA id;
+*/
+ ENTRY_INFO info;
+
+ UNUSED_VARIABLE(Data);
+ UNUSED_VARIABLE(Silent);
+
+ SB->s_blocksize = PAGE_CACHE_SIZE;
+ SB->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL; /* Max file size */
+ SB->s_op = &Novfs_ops;
+ SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL);
+ SB->s_magic = NOVFS_MAGIC;
+
+
+ name.len = 1;
+ name.name = "/";
+
+ inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
+ if (!inode)
+ {
+ return( -ENOMEM );
+ }
+
+ Novfs_root = d_alloc_root(inode);
+
+ if (!Novfs_root)
+ {
+ iput(inode);
+ return( -ENOMEM );
+ }
+ Novfs_root->d_time = jiffies+(File_update_timeout*HZ);
+
+ inode->i_atime =
+ inode->i_ctime =
+ inode->i_mtime = CURRENT_TIME;
+
+
+ SB->s_root = Novfs_root;
+
+ DbgPrint( "Novfs_fill_super: root 0x%x\n", Novfs_root);
+
+ if (Novfs_root)
+ {
+ Novfs_root->d_op = &Novfs_dentry_operations;
+
+ name.name = SERVER_DIRECTORY_NAME;
+ name.len = strlen(SERVER_DIRECTORY_NAME);
+ name.hash = Novfs_internal_hash( &name );
+
+ inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
+ if (inode)
+ {
+ info.mode = inode->i_mode;
+ info.namelength = 0;
+ inode->i_size = info.size = 0;
+ inode->i_uid = info.uid = 0;
+ inode->i_gid = info.gid = 0;
+ inode->i_atime = info.atime =
+ inode->i_ctime = info.ctime =
+ inode->i_mtime = info.mtime = CURRENT_TIME;
+
+ server = d_alloc(Novfs_root, &name);
+ if (server)
+ {
+ server->d_op = &Novfs_dentry_operations;
+ server->d_time = 0xffffffff;
+ d_add(server, inode);
+ DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", SERVER_DIRECTORY_NAME, server);
+ Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
+ }
+ }
+
+ name.name = TREE_DIRECTORY_NAME;
+ name.len = strlen(TREE_DIRECTORY_NAME);
+ name.hash = Novfs_internal_hash( &name );
+
+ inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
+ if (inode)
+ {
+ info.mode = inode->i_mode;
+ info.namelength = 0;
+ inode->i_size = info.size = 0;
+ inode->i_uid = info.uid = 0;
+ inode->i_gid = info.gid = 0;
+ inode->i_atime = info.atime =
+ inode->i_ctime = info.ctime =
+ inode->i_mtime = info.mtime = CURRENT_TIME;
+ tree = d_alloc(Novfs_root, &name);
+ if (tree)
+ {
+ tree->d_op = &Novfs_dentry_operations;
+ tree->d_time = 0xffffffff;
+
+ d_add(tree, inode);
+ DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", TREE_DIRECTORY_NAME, tree);
+ Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
+ }
+ }
+ }
+
+ return( 0 );
+}
+
+/*++======================================================================*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+int Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data, struct vfsmount *Mnt)
+#else
+struct super_block * Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data)
+#endif
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+ int sb;
+#else
+ struct super_block *sb;
+#endif
+
+ UNUSED_VARIABLE(Dev_name);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+ sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super, Mnt);
+#else
+ sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super);
+#endif
+
+ DbgPrint( "Novfs_get_sb: sb=0x%x Fstype=0x%x Dev_name=%s\n", sb, Fstype, Dev_name);
+
+ return (sb );
+}
+
+/*++======================================================================*/
+void Novfs_kill_sb(struct super_block *SB)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ kill_litter_super(SB);
+}
+
+/*++======================================================================*/
+ssize_t Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ssize_t retval=0;
+
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(buf);
+ UNUSED_VARIABLE(nbytes);
+ UNUSED_VARIABLE(ppos);
+
+ DbgPrint( "Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked());
+
+ return retval;
+}
+
+/*++======================================================================*/
+ssize_t Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ssize_t retval=0;
+
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(buf);
+ UNUSED_VARIABLE(nbytes);
+ UNUSED_VARIABLE(ppos);
+
+ DbgPrint( "Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked());
+ if (buf && nbytes)
+ {
+ }
+
+ return(retval);
+}
+
+/*++======================================================================*/
+int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retval=0;
+
+ UNUSED_VARIABLE(inode);
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(cmd);
+ UNUSED_VARIABLE(arg);
+
+ DbgPrint( "Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked());
+
+ return(retval);
+}
+
+/*++======================================================================*/
+int __init init_novfs (void)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode;
+
+
+ retCode = Init_Procfs_Interface();
+
+ init_profile();
+
+ if ( !retCode )
+ {
+ DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, NOVFS_VERSION_STRING);
+ Init_Daemon_Queue();
+ Scope_Init();
+ retCode = register_filesystem(&Novfs_fs_type);
+ if ( retCode )
+ {
+ Uninit_Procfs_Interface();
+ Uninit_Daemon_Queue();
+ Scope_Uninit();
+ }
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+void __exit exit_novfs(void)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ printk( KERN_INFO "exit_novfs\n");
+
+ Scope_Uninit();
+ printk( KERN_INFO "exit_novfs after Scope_Uninit\n");
+
+ Uninit_Daemon_Queue();
+ printk( KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n");
+
+ uninit_profile();
+ printk( KERN_INFO "exit_novfs after uninit_profile\n");
+
+ Uninit_Procfs_Interface();
+ printk( KERN_INFO "exit_novfs Uninit_Procfs_Interface\n");
+
+ unregister_filesystem(&Novfs_fs_type);
+ printk( KERN_INFO "exit_novfs: Exit\n");
+
+ if (Novfs_CurrentMount)
+ {
+ Novfs_Free(Novfs_CurrentMount);
+ Novfs_CurrentMount = NULL;
+ }
+}
+
+/*++======================================================================*/
+int Novfs_lock_inode_cache( struct inode *i )
+/*
+ *
+ * Arguments: struct inode *i - pointer to directory inode
+ *
+ * Returns: 0 - locked
+ * -1 - not locked
+ *
+ * Abstract: Locks the inode cache.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ int retVal = 0;
+
+ DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i);
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ down( &id->DirCacheLock );
+ retVal = 1;
+ }
+ DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal);
+ return( retVal );
+}
+
+/*++======================================================================*/
+void Novfs_unlock_inode_cache( struct inode *i )
+/*
+ * Arguments: struct inode *i - pointer to directory inode
+ *
+ * Returns: nothing
+ *
+ * Abstract: Unlocks inode cache.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ up( &id->DirCacheLock );
+ }
+}
+
+/*++======================================================================*/
+int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info)
+/*
+ * Arguments: struct inode *i - pointer to directory inode
+ *
+ * Returns: 0 - item found
+ * -1 - done
+ *
+ * Abstract: Unlocks inode cache.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *l=NULL;
+ int retVal = -1;
+
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ if ( (NULL == iteration) || (NULL == *iteration) )
+ {
+ l = id->DirCache.next;
+ }
+ else
+ {
+ l = *iteration;
+ }
+
+ if (l == &id->DirCache)
+ {
+ l = NULL;
+ }
+ else
+ {
+ dc = list_entry(l, DIR_CACHE, list);
+
+ *ino = dc->ino;
+ info->type = 0;
+ info->mode = dc->mode;
+ info->size = dc->size;
+ info->atime = dc->atime;
+ info->mtime = dc->mtime;
+ info->ctime = dc->ctime;
+ info->namelength = dc->nameLen;
+ memcpy(info->name, dc->name, dc->nameLen);
+ info->name[dc->nameLen] = '\0';
+ retVal = 0;
+
+ l = l->next;
+ }
+ }
+ *iteration = l;
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ int retVal = -1;
+ char *n="<NULL>";
+ int nl=6;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ if (name && name->len)
+ {
+ n = (char *)name->name;
+ nl = name->len;
+ }
+ DbgPrint("Novfs_get_entry:\n" \
+ " inode: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n",
+ i, nl, n, *ino);
+
+ dc = Novfs_lookup_inode_cache(i, name, *ino);
+ if (dc)
+ {
+ dc->flags |= ENTRY_VALID;
+ retVal = 0;
+ *ino = dc->ino;
+ info->type = 0;
+ info->mode = dc->mode;
+ info->size = dc->size;
+ info->atime = dc->atime;
+ info->mtime = dc->mtime;
+ info->ctime = dc->ctime;
+ info->namelength = dc->nameLen;
+ memcpy(info->name, dc->name, dc->nameLen);
+ info->name[dc->nameLen] = '\0';
+ retVal = 0;
+ }
+ }
+ DbgPrint("Novfs_get_entry: return %d\n", retVal);
+ return( retVal );
+}
+
+int Novfs_get_entry_by_pos( struct inode *i, loff_t pos, ino_t* ino, PENTRY_INFO info)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retVal = -1;
+ loff_t count = 0;
+ loff_t i_pos = pos - 2;
+ struct list_head *inter = NULL;
+ while( !Novfs_enumerate_inode_cache(i, &inter, ino, info))
+ {
+ DbgPrint("Novfs_dir_readdir : Novfs_get_entry_by_pos : info->name = %s\n", info->name);
+ if(count == i_pos)
+ {
+ retVal = 0;
+ break;
+ }
+ else
+ count++;
+ }
+
+ return retVal;
+}
+
+/*++======================================================================*/
+int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ int retVal = -1;
+ char *n="<NULL>";
+ int nl=6;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ if (name && name->len)
+ {
+ n = (char *)name->name;
+ nl = name->len;
+ }
+ DbgPrint("Novfs_get_entry:\n" \
+ " inode: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n",
+ i, nl, n, *ino);
+
+ dc = Novfs_lookup_inode_cache(i, name, *ino);
+ if (dc)
+ {
+ retVal = 0;
+ *ino = dc->ino;
+ info->type = 0;
+ info->mode = dc->mode;
+ info->size = dc->size;
+ info->atime = dc->atime;
+ info->mtime = dc->mtime;
+ info->ctime = dc->ctime;
+ info->namelength = dc->nameLen;
+ memcpy(info->name, dc->name, dc->nameLen);
+ info->name[dc->nameLen] = '\0';
+ if (EntryTime)
+ {
+ *EntryTime = dc->jiffies;
+ }
+ retVal = 0;
+ }
+ }
+ DbgPrint("Novfs_get_entry: return %d\n", retVal);
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: This routine will return the first entry on the list
+ * and then remove it.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *l=NULL;
+ int retVal = -1;
+
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ l = id->DirCache.next;
+
+ if (l != &id->DirCache)
+ {
+ dc = list_entry(l, DIR_CACHE, list);
+
+ *ino = dc->ino;
+ info->type = 0;
+ info->mode = dc->mode;
+ info->size = dc->size;
+ info->atime = dc->atime;
+ info->mtime = dc->mtime;
+ info->ctime = dc->ctime;
+ info->namelength = dc->nameLen;
+ memcpy(info->name, dc->name, dc->nameLen);
+ info->name[dc->nameLen] = '\0';
+ retVal = 0;
+
+ list_del( &dc->list );
+ Novfs_Free( dc );
+ DCCount--;
+
+ }
+ }
+ return( retVal );
+}
+
+/*++======================================================================*/
+void Novfs_invalidate_inode_cache( struct inode *i )
+/*
+ * Arguments: struct inode *i - pointer to directory inode
+ *
+ * Returns: nothing
+ *
+ * Abstract: Marks all entries in the directory cache as invalid.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *l;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ list_for_each(l, &id->DirCache)
+ {
+ dc = list_entry(l, DIR_CACHE, list);
+ dc->flags &= ~ENTRY_VALID;
+ }
+ }
+}
+
+/*++======================================================================*/
+PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino )
+/*
+ * Arguments: struct inode *i - pointer to directory inode
+ * struct qstr *name - pointer to name
+ * ino_t - inode number
+ *
+ * Returns: DIR_CACHE entry if match
+ * NULL - if there is no match.
+ *
+ * Abstract: Checks a inode directory to see if there are any enties
+ * matching name or ino. If name is specified then ino is
+ * not used. ino is use if name is not specified.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc, retVal=NULL;
+ struct list_head *l;
+ char *n="<NULL>";
+ int nl=6;
+ int hash=0;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ if (name && name->name)
+ {
+ nl = name->len;
+ n = (char *)name->name;
+ hash = name->hash;
+ }
+ DbgPrint("Novfs_lookup_inode_cache:\n" \
+ " inode: 0x%p\n" \
+ " name: %.*s\n" \
+ " hash: 0x%x\n" \
+ " len: %d\n" \
+ " ino: %d\n",
+ i, nl, n, hash, nl, ino);
+
+ list_for_each(l, &id->DirCache)
+ {
+ dc = list_entry(l, DIR_CACHE, list);
+ if (name)
+ {
+
+/* DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \
+ " ino: %d\n" \
+ " hash: 0x%x\n" \
+ " len: %d\n" \
+ " name: %.*s\n",
+ dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name);
+*/
+ if ( (name->hash == dc->hash) &&
+ (name->len == dc->nameLen) &&
+ (0 == memcmp(name->name, dc->name, name->len)) )
+ {
+ retVal = dc;
+ break;
+ }
+ }
+ else
+ {
+ if (ino == dc->ino)
+ {
+ retVal = dc;
+ break;
+ }
+ }
+ }
+ }
+
+ DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal);
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino )
+/*
+ * Arguments: struct inode *i - pointer to directory inode
+ * struct qstr *name - pointer to name
+ * ino_t - inode number
+ *
+ * Returns: 0 if found
+ * !0 if not found
+ *
+ * Abstract: Checks a inode directory to see if there are any enties
+ * matching name or ino. If entry is found the valid bit
+ * is set.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ int retVal = -1;
+ char *n="<NULL>";
+ int nl=6;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ if (name && name->len)
+ {
+ n = (char *)name->name;
+ nl = name->len;
+ }
+ DbgPrint("Novfs_update_entry:\n" \
+ " inode: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n",
+ i, nl, n, ino);
+
+ dc = Novfs_lookup_inode_cache( i, name, ino );
+ if (dc)
+ {
+ dc->flags |= ENTRY_VALID;
+ retVal = 0;
+ }
+ }
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Novfs_add_inode_entry(
+ struct inode *i,
+ struct qstr *name,
+ ino_t ino,
+ PENTRY_INFO info)
+/*
+ * Arguments:
+ *
+ * Returns: -ENOMEM - alloc error.
+ * 0 - success.
+ *
+ * Abstract: Added entry to directory cache.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE new;
+ int retVal = -ENOMEM;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL);
+ if (new)
+ {
+ DCCount++;
+ DbgPrint("Novfs_add_inode_entry:\n" \
+ " inode: 0x%p\n" \
+ " id: 0x%p\n" \
+ " DC: 0x%p\n" \
+ " new: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n" \
+ " size: %lld\n" \
+ " mode: 0x%x\n",
+ i, id, &id->DirCache, new, name->len, name->name, ino, info->size, info->mode);
+
+ retVal = 0;
+ new->flags = ENTRY_VALID;
+ new->jiffies = get_jiffies_64();
+ new->size = info->size;
+ new->mode = info->mode;
+ new->atime = info->atime;
+ new->mtime = info->mtime;
+ new->ctime = info->ctime;
+ new->ino = ino;
+ new->hash = name->hash;
+ new->nameLen = name->len;
+ memcpy(new->name, name->name, name->len);
+ new->name[new->nameLen] = '\0';
+ list_add(&new->list, &id->DirCache);
+
+/* list_for_each(l, &id->DirCache)
+ {
+ dc = list_entry(l, DIR_CACHE, list);
+ if ( dc->hash > new->hash )
+ {
+ break;
+ }
+ }
+
+ DbgPrint("Novfs_add_inode_entry: adding 0x%p to 0x%p\n", new, l);
+ list_add(&new->list, l);
+*/
+ }
+ }
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ int retVal = -1;
+ char *n="<NULL>";
+ int nl=6;
+ char atime_buf[32];
+ char mtime_buf[32];
+ char ctime_buf[32];
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+
+ if (name && name->len)
+ {
+ n = (char *)name->name;
+ nl = name->len;
+ }
+ ctime_r(&info->atime.tv_sec, atime_buf);
+ ctime_r(&info->mtime.tv_sec, mtime_buf);
+ ctime_r(&info->ctime.tv_sec, ctime_buf);
+ DbgPrint("Novfs_update_entry:\n" \
+ " inode: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n" \
+ " size: %lld\n" \
+ " atime: %s\n" \
+ " mtime: %s\n" \
+ " ctime: %s\n",
+ i, nl, n, ino, info->size, atime_buf, mtime_buf, ctime_buf);
+
+
+ dc = Novfs_lookup_inode_cache(i, name, ino);
+ if (dc)
+ {
+ retVal = 0;
+ dc->flags = ENTRY_VALID;
+ dc->jiffies = get_jiffies_64();
+ dc->size = info->size;
+ dc->mode = info->mode;
+ dc->atime = info->atime;
+ dc->mtime = info->mtime;
+ dc->ctime = info->ctime;
+
+ ctime_r(&dc->atime.tv_sec, atime_buf);
+ ctime_r(&dc->mtime.tv_sec, mtime_buf);
+ ctime_r(&dc->ctime.tv_sec, ctime_buf);
+ DbgPrint("Novfs_update_entry entry: 0x%x\n" \
+ " flags: 0x%x\n" \
+ " jiffies: %lld\n" \
+ " ino: %d\n" \
+ " size: %lld\n" \
+ " mode: 0%o\n" \
+ " atime: %s\n" \
+ " mtime: %s %d\n" \
+ " ctime: %s\n" \
+ " hash: 0x%x\n" \
+ " nameLen: %d\n" \
+ " name: %s\n",
+ dc, dc->flags, dc->jiffies, dc->ino, dc->size, dc->mode,
+ atime_buf, mtime_buf, dc->mtime.tv_nsec, ctime_buf, dc->hash, dc->nameLen, dc->name);
+ }
+ }
+ DbgPrint("Novfs_update_entry: return %d\n", retVal);
+ return( retVal );
+}
+
+/*++======================================================================*/
+void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino)
+/*
+ * Arguments:
+ *
+ * Returns: nothing
+ *
+ * Abstract: Removes entry from directory cache. You can specify a name
+ * or an inode number.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ char *n="<NULL>";
+ int nl=6;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ dc = Novfs_lookup_inode_cache( i, name, ino );
+ if (dc)
+ {
+ if (name && name->name)
+ {
+ nl = name->len;
+ n = (char *)name->name;
+ }
+ DbgPrint("Novfs_remove_inode_entry:\n" \
+ " inode: 0x%p\n" \
+ " id: 0x%p\n" \
+ " DC: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n" \
+ " entry: 0x%p\n" \
+ " name: %.*s\n"\
+ " ino: %d\n" \
+ " next: 0x%p\n" \
+ " prev: 0x%p\n",
+ i, id, &id->DirCache, nl, n, ino, dc, dc->nameLen, dc->name, dc->ino, dc->list.next, dc->list.prev);
+ list_del( &dc->list );
+ Novfs_Free( dc );
+ DCCount--;
+
+ }
+ }
+}
+
+/*++======================================================================*/
+void Novfs_free_invalid_entries( struct inode *i )
+/*
+ * Arguments: struct inode *i - pointer to directory inode.
+ *
+ * Returns: nothing
+ *
+ * Abstract: Frees all invalid entries in the directory cache.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *l;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ list_for_each( l, &id->DirCache )
+ {
+ dc = list_entry( l, DIR_CACHE, list );
+ if ( 0 == (dc->flags & ENTRY_VALID) )
+ {
+ DbgPrint("Novfs_free_invalid_entries:\n" \
+ " inode: 0x%p\n" \
+ " id: 0x%p\n" \
+ " entry: 0x%p\n" \
+ " name: %.*s\n" \
+ " ino: %d\n",
+ i, id, dc, dc->nameLen, dc->name, dc->ino);
+ l = l->prev;
+ list_del( &dc->list );
+ Novfs_Free( dc );
+ DCCount--;
+ }
+ }
+ }
+}
+
+/*++======================================================================*/
+void Novfs_free_inode_cache( struct inode *i )
+/*
+ * Arguments: struct inode *i - pointer to directory inode.
+ *
+ * Returns: nothing
+ *
+ * Abstract: Frees all entries in the inode cache.
+ *
+ * Notes: DirCacheLock should be held before calling this routine.
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *l;
+
+ if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+ {
+ list_for_each( l, &id->DirCache )
+ {
+ dc = list_entry( l, DIR_CACHE, list );
+ l = l->prev;
+ list_del( &dc->list );
+ Novfs_Free( dc );
+ DCCount--;
+ }
+ }
+}
+
+/*++======================================================================*/
+int
+NO_TRACE
+Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+#ifdef CONFIG_KDB
+ struct inode *inode=NULL;
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *l;
+ char atime_buf[32];
+ char mtime_buf[32];
+ char ctime_buf[32];
+
+ if (Novfs_root)
+ {
+ inode = Novfs_root->d_inode;
+ }
+
+ if (argc > 0)
+ {
+ inode = (void *)simple_strtoul(argv[1], NULL, 0);
+ }
+
+ kdb_printf("Inode: 0x%p\n", inode);
+ if (inode)
+ {
+ id = inode->u.generic_ip;
+ kdb_printf("INODE_DATA: 0x%p\n", id);
+
+ if ( id && id->DirCache.next )
+ {
+ list_for_each(l, &id->DirCache)
+ {
+ dc = list_entry(l, DIR_CACHE, list);
+ ctime_r(&dc->atime.tv_sec, atime_buf);
+ ctime_r(&dc->mtime.tv_sec, mtime_buf);
+ ctime_r(&dc->ctime.tv_sec, ctime_buf);
+
+ DbgPrint("Cache Entry: 0x%p\n" \
+ " flags: 0x%x\n" \
+ " jiffies: %llu\n" \
+ " ino: %u\n" \
+ " size: %llu\n" \
+ " mode: 0%o\n" \
+ " atime: %s\n" \
+ " mtime: %s\n" \
+ " ctime: %s\n" \
+ " hash: 0x%x\n" \
+ " len: %d\n" \
+ " name: %s\n",
+ dc, dc->flags, dc->jiffies,
+ dc->ino, dc->size, dc->mode,
+ atime_buf, mtime_buf, ctime_buf,
+ dc->hash, dc->nameLen, dc->name);
+ }
+ }
+ }
+#endif
+ return(0);
+}
+
+/*++======================================================================*/
+void
+NO_TRACE
+Novfs_dump_inode( void *pf )
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ struct inode *inode;
+ void (*pfunc)(char *Fmt, ...) = pf;
+ PINODE_DATA id;
+ PDIR_CACHE dc;
+ struct list_head *il, *l;
+ char atime_buf[32];
+ char mtime_buf[32];
+ char ctime_buf[32];
+ unsigned long icnt=0, dccnt=0;
+
+ down( &InodeList_lock );
+ list_for_each(il, &InodeList)
+ {
+ id = list_entry(il, INODE_DATA, IList);
+ inode = id->Inode;
+ if (inode)
+ {
+ icnt++;
+
+ pfunc("Inode=0x%x I_ino=%d\n", inode, inode->i_ino);
+
+ pfunc(" atime=%s\n", ctime_r(&inode->i_atime.tv_sec, atime_buf));
+ pfunc(" ctime=%s\n", ctime_r(&inode->i_mtime.tv_sec, atime_buf));
+ pfunc(" mtime=%s\n", ctime_r(&inode->i_ctime.tv_sec, atime_buf));
+ pfunc(" size=%lld\n", inode->i_size);
+ pfunc(" mode=0%o\n", inode->i_mode);
+ }
+
+ pfunc(" INODE_DATA: 0x%p Name=%s Scope=0x%p\n", id, id->Name, id->Scope);
+
+ if (id->DirCache.next )
+ {
+ list_for_each(l, &id->DirCache)
+ {
+ dccnt++;
+ dc = list_entry(l, DIR_CACHE, list);
+ ctime_r(&dc->atime.tv_sec, atime_buf);
+ ctime_r(&dc->mtime.tv_sec, mtime_buf);
+ ctime_r(&dc->ctime.tv_sec, ctime_buf);
+
+ pfunc(" Cache Entry: 0x%p\n" \
+ " flags: 0x%x\n" \
+ " jiffies: %llu\n" \
+ " ino: %u\n" \
+ " size: %llu\n" \
+ " mode: 0%o\n" \
+ " atime: %s\n" \
+ " mtime: %s\n" \
+ " ctime: %s\n" \
+ " hash: 0x%x\n" \
+ " len: %d\n" \
+ " name: %s\n",
+ dc, dc->flags, dc->jiffies,
+ dc->ino, dc->size, dc->mode,
+ atime_buf, mtime_buf, ctime_buf,
+ dc->hash, dc->nameLen, dc->name);
+ }
+ }
+ }
+ up( &InodeList_lock );
+
+ pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, dccnt );
+
+}
+
+module_init(init_novfs)
+module_exit(exit_novfs)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Novell Inc.");
+MODULE_DESCRIPTION("Novell NetWare Client for Linux");
+MODULE_VERSION( NOVFS_VERSION_STRING );
diff -uNr src.old/src/m src/src/m
--- src.old/src/m 1970-01-01 01:00:00.000000000 +0100
+++ src/src/m 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+VERSION=`uname -r`
+
+make -C /usr/src/linux SUBDIRS=$PWD modules
+
+if [ -e novfs.ko ]
+then
+ mkdir -p -m 755 /lib/modules/$VERSION/kernel/fs/novfs
+ echo "copying novfs.ko to /lib/modules/$VERSION/kernel/fs/novfs"
+ cp novfs.ko /lib/modules/$VERSION/kernel/fs/novfs
+fi
diff -uNr src.old/src/mk_novfs src/src/mk_novfs
--- src.old/src/mk_novfs 1970-01-01 01:00:00.000000000 +0100
+++ src/src/mk_novfs 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,114 @@
+#!/bin/sh
+
+RVAL=1
+TO_BUILD=1
+
+BUILD_TYPE=modules
+
+if [ $1 ]
+then
+ if [ "$1" = "force" ]
+ then
+ FORCE=1
+ else
+ BUILD_TYPE=$1
+ FORCE=0
+ fi
+else
+ FORCE=0
+fi
+
+platform=`uname -i`
+
+if [ -d /usr/src/linux-obj/$platform ]
+then
+ for i in $(ls /usr/src/linux-obj/$platform)
+ do
+ TO_BUILD=1
+ VERSION=`cat /usr/src/linux-obj/$platform/$i/include/linux/version.h |grep UTS_RELEASE |awk '{printf("%s\n", substr($3, 2,length($3)-2))}'`
+ NOVFS_PATH=/lib/modules/$VERSION/kernel/fs/novfs
+
+ if [ -e /lib/modules/$VERSION/extra/novfs.ko ]
+ then
+ NOVFS_PATH=/lib/modules/$VERSION/extra
+
+ else
+ if [ -e /lib/modules/$VERSION/updates/novfs.ko ]
+ then
+ NOVFS_PATH=/lib/modules/$VERSION/updates
+
+ fi
+ fi
+
+ if [ -d /lib/modules/$VERSION ]
+ then
+
+ if [ -e $NOVFS_PATH/novfs.ko ]
+ then
+ CUR_NOVFS_VERSION=`od --strings=8 $NOVFS_PATH/novfs.ko |grep version= |awk '{split($2,a,"="); if("version"==a[1]) printf("%s", a[2])}'`
+ CUR_NOVFS_VFS_MAJOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[1])}'`
+ CUR_NOVFS_VFS_MINOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[2])}'`
+ CUR_NOVFS_VFS_SUB=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[3])}'`
+ CUR_NOVFS_VFS_RELEASE=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"-"); printf("%d", a[2])}'`
+
+ NOVFS_VFS_MAJOR=`cat Makefile |grep 'NOVFS_VFS_MAJOR =' |awk '{printf("%d", $3)}'`
+ NOVFS_VFS_MINOR=`cat Makefile |grep 'NOVFS_VFS_MINOR =' |awk '{printf("%d", $3)}'`
+ NOVFS_VFS_SUB=`cat Makefile |grep 'NOVFS_VFS_SUB =' |awk '{printf("%d", $3)}'`
+ NOVFS_VFS_RELEASE=`cat Makefile |grep 'NOVFS_VFS_RELEASE =' |awk '{printf("%d", $3)}'`
+ NOVFS_VFS_VERSION="$NOVFS_VFS_MAJOR.$NOVFS_VFS_MINOR.$NOVFS_VFS_SUB-$NOVFS_VFS_RELEASE"
+
+ TO_BUILD=0
+
+ if [ $NOVFS_VFS_MAJOR -gt $CUR_NOVFS_VFS_MAJOR ]
+ then
+ TO_BUILD=1
+ else
+ if [ $NOVFS_VFS_MAJOR -eq $CUR_NOVFS_VFS_MAJOR ]
+ then
+ if [ $NOVFS_VFS_MINOR -gt $CUR_NOVFS_VFS_MINOR ]
+ then
+ TO_BUILD=1
+ else
+ if [ $NOVFS_VFS_MINOR -eq $CUR_NOVFS_VFS_MINOR ]
+ then
+ if [ $NOVFS_VFS_SUB -gt $CUR_NOVFS_VFS_SUB ]
+ then
+ TO_BUILD=1
+ else
+ if [ $NOVFS_VFS_SUB -eq $CUR_NOVFS_VFS_SUB ]
+ then
+ if [ $NOVFS_VFS_RELEASE -gt $CUR_NOVFS_VFS_RELEASE ]
+ then
+ TO_BUILD=1
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+
+ if [ $FORCE -eq 1 ]
+ then
+ TO_BUILD=1;
+ fi
+
+ if [ $TO_BUILD -eq 1 ]
+ then
+ echo Building novfs.ko for $VERSION
+ make -C /usr/src/linux-obj/$platform/$i SUBDIRS=$PWD $BUILD_TYPE
+ RVAL=$?
+ if [ -e novfs.ko ]
+ then
+ mkdir -p -m 755 $NOVFS_PATH
+ echo "copying novfs.ko to $NOVFS_PATH"
+ cp novfs.ko $NOVFS_PATH
+ RVAL=$?
+ fi
+ fi
+ fi
+ done
+fi
+exit $RVAL
+
diff -uNr src.old/src/nwcapi.c src/src/nwcapi.c
--- src.old/src/nwcapi.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/nwcapi.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,2410 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: nwcapi.c
+ * Version: v1.00
+ * Author: James Turner/Richard Williams
+ *
+ * Abstract: This module contains functions used to interface to
+ * the library interface of the daemon.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+
+/*===[ Include files specific to this module ]============================*/
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+
+#include "nwcapi.h"
+#include "nwerror.h"
+#include "commands.h"
+
+#include "vfs.h"
+
+/*===[ External data ]====================================================*/
+
+/*===[ External prototypes ]==============================================*/
+
+extern int DbgPrint( char *Fmt, ... );
+extern void mydump(int size, void *dumpptr);
+
+extern session_t Scope_Get_SessionId( void *Scope );
+extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
+
+extern int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
+
+void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
+void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
+
+/*===[ Manifest constants ]===============================================*/
+
+/*===[ Type definitions ]=================================================*/
+
+/*===[ Function prototypes ]==============================================*/
+
+/*===[ Global variables ]=================================================*/
+
+/*===[ Code ]=============================================================*/
+
+/*++======================================================================*/
+
+/*++======================================================================*/
+int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCOpenConnByName openConn, connReply;
+NwcOpenConnByName ocbn;
+u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
+char *data;
+
+ cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn));
+ datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME;
+
+ cmd->dataLen = datalen;
+ openConn = (PNwdCOpenConnByName)cmd->data;
+
+ openConn->nameLen = strlen_user(ocbn.pName->pString);
+ openConn->serviceLen = strlen_user(ocbn.pServiceType);
+ openConn->uConnFlags = ocbn.uConnFlags;
+ openConn->ConnHandle = ocbn.ConnHandle;
+ data = (char *)openConn;
+ data += sizeof(*openConn);
+ openConn->oName = sizeof(*openConn);
+
+ openConn->oServiceType = openConn->oName + openConn->nameLen;
+ cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen);
+ data += openConn->nameLen;
+ cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ /*
+ * we got reply data from the daemon
+ */
+ connReply = (PNwdCOpenConnByName)reply->data;
+ retCode = reply->Reply.ErrorCode;
+ if (!retCode)
+ {
+ /*
+ * we got valid data.
+ */
+ connReply = (PNwdCOpenConnByName)reply->data;
+ ocbn.RetConnHandle = connReply->newConnHandle;
+ *Handle = connReply->newConnHandle;
+ cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn));
+ DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle);
+ }
+ Novfs_Free(reply);
+ }
+
+ Novfs_Free(cmd);
+ }
+
+ return((int)retCode);
+
+}
+
+/*++======================================================================*/
+int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCOpenConnByAddr openConn, connReply;
+NwcOpenConnByAddr ocba;
+NwcTranAddr tranAddr;
+u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
+char addr[MAX_ADDRESS_LENGTH];
+
+ cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba));
+ datalen = sizeof(*openConn);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_OPEN_CONN_BY_ADDRESS;
+ cmd->dataLen = datalen;
+ openConn = (PNwdCOpenConnByAddr)cmd->data;
+
+ cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr));
+
+ DbgPrint("NwOpenConnByAddr: tranAddr\n");
+ mydump(sizeof(tranAddr), &tranAddr);
+
+ openConn->TranAddr.uTransportType = tranAddr.uTransportType;
+ openConn->TranAddr.uAddressLength = tranAddr.uAddressLength;
+ memset(addr, 0xcc, sizeof(addr)-1);
+
+ cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength);
+
+ DbgPrint("NwOpenConnByAddr: addr\n");
+ mydump(sizeof(addr), addr);
+
+ openConn->TranAddr.oAddress = *(u_long *)(&addr[2]);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ /*
+ * we got reply data from the daemon
+ */
+ connReply = (PNwdCOpenConnByAddr)reply->data;
+ retCode = reply->Reply.ErrorCode;
+ if (!retCode)
+ {
+ /*
+ * we got valid data.
+ */
+ connReply = (PNwdCOpenConnByAddr)reply->data;
+ ocba.ConnHandle = connReply->ConnHandle;
+ *Handle = connReply->ConnHandle;
+ cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba));
+ DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle);
+ }
+ Novfs_Free(reply);
+ }
+
+ Novfs_Free(cmd);
+ }
+
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCOpenConnByRef openConn;
+NwcOpenConnByReference ocbr;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+
+ cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr));
+ datalen = sizeof(*openConn);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_OPEN_CONN_BY_REFERENCE;
+ cmd->dataLen = datalen;
+ openConn = (PNwdCOpenConnByRef)cmd->data;
+
+ memcpy(openConn, &ocbr, sizeof(ocbr));
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ /*
+ * we got reply data from the daemon
+ */
+ openConn = (PNwdCOpenConnByRef)reply->data;
+ retCode = reply->Reply.ErrorCode;
+ if (!retCode)
+ {
+ /*
+ * we got valid data.
+ */
+ ocbr.ConnHandle = openConn->ConnHandle;
+ *Handle = openConn->ConnHandle;
+
+ cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr));
+ DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle);
+ }
+ Novfs_Free(reply);
+ }
+
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwRawSend(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+NwcRequest xRequest;
+PNwcFrag frag, cFrag, reqFrag;
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+u_long x, totalLen;
+PNwdCNCPReq ncpData;
+PNwdCNCPRep ncpReply;
+u_char *reqData;
+unsigned long actualReplyLength=0;
+
+ DbgPrint("[XPLAT] Process Raw NCP Send\n");
+ cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
+
+ /*
+ * Figure out the length of the request
+ */
+ frag = Novfs_Malloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL);
+
+ DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
+
+ if (!frag)
+ return(retCode);
+
+ cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag));
+ totalLen = 0;
+
+ cFrag = frag;
+ for (x = 0; x < xRequest.uNumReplyFrags; x ++)
+ {
+ DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength);
+ totalLen += cFrag->uLength;
+ cFrag++;
+ }
+
+
+ DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen);
+ datalen = 0;
+ reqFrag = Novfs_Malloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL);
+ if (!reqFrag)
+ {
+ Novfs_Free(frag);
+ return(retCode);
+ }
+
+ cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag));
+ cFrag = reqFrag;
+ for (x = 0; x < xRequest.uNumRequestFrags; x ++)
+ {
+ datalen += cFrag->uLength;
+ cFrag++;
+ }
+
+ /*
+ * Allocate the cmd Request
+ */
+ cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData);
+ DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags);
+ DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen);
+
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_RAW_NCP_REQUEST;
+
+ /*
+ * build the NCP Request
+ */
+ cmd->dataLen = cmdlen - sizeof(*cmd);
+ ncpData = (PNwdCNCPReq)cmd->data;
+ ncpData->replyLen = totalLen;
+ ncpData->requestLen = datalen;
+ ncpData->ConnHandle = xRequest.ConnHandle;
+ ncpData->function = xRequest.uFunction;
+
+
+ reqData = ncpData->data;
+ cFrag = reqFrag;
+
+ for (x = 0; x < xRequest.uNumRequestFrags; x ++)
+ {
+ cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength);
+ reqData += cFrag->uLength;
+ cFrag++;
+ }
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ DbgPrint("RawNCP - reply = %x\n", reply);
+ DbgPrint("RawNCP - retCode = %x\n", retCode);
+
+ if (reply)
+ {
+ /*
+ * we got reply data from the daemon
+ */
+ ncpReply = (PNwdCNCPRep)reply->data;
+ retCode = reply->Reply.ErrorCode;
+
+ DbgPrint("RawNCP - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
+
+ /*
+ * We need to copy the reply frags to the packet.
+ */
+ reqData = ncpReply->data;
+ cFrag = frag;
+
+ totalLen = ncpReply->replyLen;
+ for (x = 0; x < xRequest.uNumReplyFrags; x ++)
+ {
+
+ DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, cFrag->uLength);
+
+ datalen = min(cFrag->uLength, totalLen);
+
+ cpylen = copy_to_user(cFrag->pData, reqData, datalen);
+ totalLen -= datalen;
+ reqData += datalen;
+ actualReplyLength += datalen;
+
+ cFrag++;
+ }
+
+ Novfs_Free(reply);
+ }
+ else
+ {
+ retCode = -EIO;
+ }
+
+ Novfs_Free(cmd);
+ }
+ xRequest.uActualReplyLength = actualReplyLength;
+ cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
+
+ Novfs_Free(reqFrag);
+ Novfs_Free(frag);
+
+ return(retCode);
+}
+
+/*++======================================================================*/
+int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcCloseConn cc;
+PNwdCCloseConn nwdClose;
+u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
+
+ datalen = sizeof(*nwdClose);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_CLOSE_CONN;
+
+ nwdClose = (PNwdCCloseConn)cmd->data;
+ cmd->dataLen = sizeof(*nwdClose);
+ nwdClose->ConnHandle = cc.ConnHandle;
+ *Handle = cc.ConnHandle;
+
+ /*
+ * send the request
+ */
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcCloseConn cc;
+PNwdCCloseConn nwdClose;
+u_long retCode = 0, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
+
+ datalen = sizeof(*nwdClose);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SYS_CLOSE_CONN;
+
+ nwdClose = (PNwdCCloseConn)cmd->data;
+ cmd->dataLen = sizeof(*nwdClose);
+ nwdClose->ConnHandle = cc.ConnHandle;
+ *Handle = cc.ConnHandle;
+
+ /*
+ * send the request
+ */
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwLoginIdentity(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+NwcLoginIdentity lgn, *plgn;
+int retCode = -ENOMEM;
+NclString server;
+NclString username;
+NclString password;
+u_long cpylen;
+NwcString nwcStr;
+
+ cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn));
+
+ DbgPrint("NwLoginIdentity:\n");
+ mydump(sizeof(lgn), &lgn);
+
+
+
+ cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr));
+ DbgPrint("NwLoginIdentity: DomainName\n");
+ mydump(sizeof(nwcStr), &nwcStr);
+
+ if ( (server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
+ {
+ server.type = nwcStr.DataType;
+ server.len = nwcStr.DataLen;
+ if ( !copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len) )
+ {
+ DbgPrint("NwLoginIdentity: Server\n");
+ mydump(server.len, server.buffer);
+
+ cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
+ DbgPrint("NwLoginIdentity: ObjectName\n");
+ mydump(sizeof(nwcStr), &nwcStr);
+
+ if ( (username.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
+ {
+ username.type = nwcStr.DataType;
+ username.len = nwcStr.DataLen;
+ if ( !copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len) )
+ {
+ DbgPrint("NwLoginIdentity: User\n");
+ mydump(username.len, username.buffer);
+
+ cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr));
+ DbgPrint("NwLoginIdentity: Password\n");
+ mydump(sizeof(nwcStr), &nwcStr);
+
+ if ( (password.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
+ {
+ password.type = nwcStr.DataType;
+ password.len = nwcStr.DataLen;
+ if ( !copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len) )
+ {
+ retCode = do_login(&server, &username, &password, (u_long *)&lgn.AuthenticationId, Session);
+ if (retCode)
+ {
+ lgn.AuthenticationId = 0;
+ }
+
+ plgn = (NwcLoginIdentity *)pdata->reqData;
+ cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId));
+
+ }
+ memset(password.buffer, 0, password.len);
+ Novfs_Free(password.buffer);
+ }
+ }
+ memset(username.buffer, 0, username.len);
+ Novfs_Free(username.buffer);
+ }
+ }
+ Novfs_Free(server.buffer);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int NwAuthConnWithId(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+NwcAuthenticateWithId pauth;
+PNwdCAuthenticateWithId pDauth;
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ datalen = sizeof(*pDauth);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID;
+
+
+ cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth));
+
+ pDauth = (PNwdCAuthenticateWithId)cmd->data;
+ cmd->dataLen = datalen;
+ pDauth->AuthenticationId = pauth.AuthenticationId;
+ pDauth->ConnHandle = pauth.ConnHandle;
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int NwLicenseConn(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcLicenseConn lisc;
+PNwdCLicenseConn pDLisc;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ datalen = sizeof(*pDLisc);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_LICENSE_CONN;
+
+
+ cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc));
+
+ pDLisc = (PNwdCLicenseConn)cmd->data;
+ cmd->dataLen = datalen;
+ pDLisc->ConnHandle = lisc.ConnHandle;
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+}
+
+
+/*++======================================================================*/
+int NwLogoutIdentity(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcLogoutIdentity logout;
+PNwdCLogoutIdentity pDLogout;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ datalen = sizeof(*pDLogout);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_LOGOUT_IDENTITY;
+
+ cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout));
+
+ pDLogout = (PNwdCLogoutIdentity)cmd->data;
+ cmd->dataLen = datalen;
+ pDLogout->AuthenticationId = logout.AuthenticationId;
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+int NwUnlicenseConn(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCUnlicenseConn pUconn;
+NwcUnlicenseConn ulc;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+
+ cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc));
+ datalen = sizeof(*pUconn);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_UNLICENSE_CONN;
+ cmd->dataLen = datalen;
+ pUconn = (PNwdCUnlicenseConn)cmd->data;
+
+ pUconn->ConnHandle = ulc.ConnHandle;
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ /*
+ * we got reply data from the daemon
+ */
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+
+/*++======================================================================*/
+int NwUnAuthenticate(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcUnauthenticate auth;
+PNwdCUnauthenticate pDAuth;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ datalen = sizeof(*pDAuth);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN;
+
+ cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth));
+
+ pDAuth = (PNwdCUnauthenticate)cmd->data;
+ cmd->dataLen = datalen;
+ pDAuth->AuthenticationId = auth.AuthenticationId;
+ pDAuth->ConnHandle = auth.ConnHandle;
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+
+/*++======================================================================*/
+int NwGetConnInfo(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcGetConnInfo connInfo;
+PNwdCGetConnInfo pDConnInfo;
+u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
+
+ cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo));
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_GET_CONN_INFO;
+
+ pDConnInfo = (PNwdCGetConnInfo)cmd->data;
+
+ pDConnInfo->ConnHandle = connInfo.ConnHandle;
+ pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
+ pDConnInfo->uInfoLength = connInfo.uInfoLength;
+ cmd->dataLen = sizeof(*pDConnInfo);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ GetConnData(&connInfo, cmd, reply);
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(retCode);
+
+}
+
+
+/*++======================================================================*/
+int NwSetConnInfo(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcSetConnInfo connInfo;
+PNwdCSetConnInfo pDConnInfo;
+u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
+
+ cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo));
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SET_CONN_INFO;
+
+ pDConnInfo = (PNwdCSetConnInfo)cmd->data;
+
+ pDConnInfo->ConnHandle = connInfo.ConnHandle;
+ pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
+ pDConnInfo->uInfoLength = connInfo.uInfoLength;
+ cmd->dataLen = sizeof(*pDConnInfo);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwGetIdentityInfo(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcGetIdentityInfo qidInfo, *gId;
+PNwdCGetIdentityInfo idInfo;
+NwcString xferStr;
+char *str;
+u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
+
+ cmdlen = sizeof(*cmd) + sizeof(*idInfo);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo));
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_GET_IDENTITY_INFO;
+
+ idInfo = (PNwdCGetIdentityInfo)cmd->data;
+
+ idInfo->AuthenticationId = qidInfo.AuthenticationId;
+ cmd->dataLen = sizeof(*idInfo);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+
+ if (!reply->Reply.ErrorCode)
+ {
+ /*
+ * Save the return info to the user structure.
+ */
+ gId = pdata->reqData;
+ idInfo = (PNwdCGetIdentityInfo)reply->data;
+ cpylen = copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId));
+ cpylen = copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType));
+ cpylen = copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags));
+ cpylen = copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType));
+ cpylen = copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType));
+
+ cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(NwcString));
+ str = (char *)((char *)reply->data + idInfo->pDomainNameOffset);
+ cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen);
+ xferStr.DataType = NWC_STRING_TYPE_ASCII;
+ xferStr.DataLen = idInfo->domainLen;
+ cpylen = copy_to_user(gId->pDomainName, &xferStr, sizeof(NwcString));
+
+
+ cpylen = copy_from_user(&xferStr, gId->pObjectName, sizeof(NwcString));
+ str = (char *)((char *)reply->data + idInfo->pObjectNameOffset);
+ cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen);
+ xferStr.DataLen = idInfo->objectLen - 1;
+ xferStr.DataType = NWC_STRING_TYPE_ASCII;
+ cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(NwcString));
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(retCode);
+}
+
+/*++======================================================================*/
+int NwScanConnInfo(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcScanConnInfo connInfo, *rInfo;
+PNwdCScanConnInfo pDConnInfo;
+u_long retCode = -ENOMEM, cmdlen, replylen, cpylen;
+u_char *localData;
+
+ cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo));
+
+ cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SCAN_CONN_INFO;
+
+ pDConnInfo = (PNwdCScanConnInfo)cmd->data;
+
+ DbgPrint("NwScanConnInfo: Input Data\n");
+ DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex);
+ DbgPrint("connInfo.uConnectionReference = 0x%X\n", connInfo.uConnectionReference);
+ DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", connInfo.uScanInfoLevel);
+ DbgPrint("connInfo.uScanInfoLen = 0x%X\n", connInfo.uScanInfoLen);
+ DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", connInfo.uReturnInfoLength);
+ DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", connInfo.uReturnInfoLevel);
+ DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags);
+
+
+ pDConnInfo->uScanIndex = connInfo.uScanIndex;
+ pDConnInfo->uConnectionReference = connInfo.uConnectionReference;
+ pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel;
+ pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen;
+ pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength;
+ pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel;
+ pDConnInfo->uScanFlags = connInfo.uScanFlags;
+
+ if (pDConnInfo->uScanInfoLen)
+ {
+ localData = (u_char *)pDConnInfo;
+ pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo);
+ localData += pDConnInfo->uScanConnInfoOffset;
+ cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen);
+ }
+ else
+ {
+ pDConnInfo->uScanConnInfoOffset = 0;
+ }
+
+
+ cmd->dataLen = sizeof(*pDConnInfo);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ DbgPrint("NwScanConnInfo: Reply recieved\n");
+ DbgPrint(" NextIndex = %x\n", connInfo.uScanIndex);
+ DbgPrint(" ErrorCode = %x\n", reply->Reply.ErrorCode);
+ DbgPrint(" data = %x\n", reply->data);
+
+ pDConnInfo = (PNwdCScanConnInfo)reply->data;
+ retCode = (u_long)reply->Reply.ErrorCode;
+ if (!retCode)
+ {
+ GetUserData(&connInfo, cmd, reply);
+ rInfo = (NwcScanConnInfo *)pdata->repData;
+ cpylen = copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex));
+ cpylen = copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference));
+ }
+ else
+ {
+ u_long x;
+
+ x = 0;
+ rInfo = (NwcScanConnInfo *)pdata->reqData;
+ cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference));
+ }
+
+ Novfs_Free(reply);
+ }
+ else
+ {
+ retCode = -EIO;
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(retCode);
+}
+
+/*++======================================================================*/
+void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
+/*
+ * Abstract: Copies the user data out of the scan conn info call.
+ *
+ *========================================================================*/
+
+{
+u_long uLevel;
+PNwdCScanConnInfo pDConnInfo;
+
+u_char *srcData = NULL;
+u_long dataLen = 0, cpylen;
+
+
+ pDConnInfo = (PNwdCScanConnInfo)reply->data;
+ uLevel = pDConnInfo->uReturnInfoLevel;
+ DbgPrint("[GetUserData] uLevel = %d, reply = 0x%X, reply->data = 0x%X\n", uLevel, reply, reply->data);
+
+ switch(uLevel)
+ {
+ case NWC_CONN_INFO_RETURN_ALL:
+ case NWC_CONN_INFO_TRAN_ADDR:
+ case NWC_CONN_INFO_NDS_STATE:
+ case NWC_CONN_INFO_MAX_PACKET_SIZE:
+ case NWC_CONN_INFO_LICENSE_STATE:
+ case NWC_CONN_INFO_PUBLIC_STATE:
+ case NWC_CONN_INFO_SERVICE_TYPE:
+ case NWC_CONN_INFO_DISTANCE:
+ case NWC_CONN_INFO_SERVER_VERSION:
+ case NWC_CONN_INFO_AUTH_ID:
+ case NWC_CONN_INFO_SUSPENDED:
+ case NWC_CONN_INFO_WORKGROUP_ID:
+ case NWC_CONN_INFO_SECURITY_STATE:
+ case NWC_CONN_INFO_CONN_NUMBER:
+ case NWC_CONN_INFO_USER_ID:
+ case NWC_CONN_INFO_BCAST_STATE:
+ case NWC_CONN_INFO_CONN_REF:
+ case NWC_CONN_INFO_AUTH_STATE:
+ case NWC_CONN_INFO_TREE_NAME:
+ case NWC_CONN_INFO_SERVER_NAME:
+ case NWC_CONN_INFO_VERSION:
+ srcData = (u_char *)pDConnInfo;
+ srcData += pDConnInfo->uReturnConnInfoOffset;
+ dataLen = pDConnInfo->uReturnInfoLength;
+ break;
+
+ case NWC_CONN_INFO_RETURN_NONE:
+ case NWC_CONN_INFO_TREE_NAME_UNICODE:
+ case NWC_CONN_INFO_SERVER_NAME_UNICODE:
+ case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
+ case NWC_CONN_INFO_ALTERNATE_ADDR:
+ case NWC_CONN_INFO_SERVER_GUID:
+ default:
+ break;
+ }
+
+ if (srcData && dataLen)
+ {
+ DbgPrint("Copy Data in GetUserData 0x%X -> 0x%X :: 0x%X\n",
+ srcData, connInfo->pReturnConnInfo, dataLen);
+ cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
+ }
+
+ return;
+}
+
+/*++======================================================================*/
+void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
+/*
+ * Abstract: Copies the user data out of the scan conn info call.
+ *
+ *========================================================================*/
+
+{
+u_long uLevel;
+PNwdCGetConnInfo pDConnInfo;
+
+u_char *srcData = NULL;
+u_long dataLen = 0, cpylen;
+
+
+ pDConnInfo = (PNwdCGetConnInfo)cmd->data;
+ uLevel = pDConnInfo->uInfoLevel;
+
+ switch(uLevel)
+ {
+ case NWC_CONN_INFO_RETURN_ALL:
+ srcData = (u_char *)reply->data;
+ dataLen = reply->dataLen;
+ break;
+
+ case NWC_CONN_INFO_RETURN_NONE:
+ dataLen = 0;
+ break;
+
+ case NWC_CONN_INFO_TRAN_ADDR:
+ {
+ u_char *dstData = connInfo->pConnInfo;
+ NwcTranAddr tranAddr;
+
+ srcData = (u_char *)reply->data;
+
+ cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr));
+ tranAddr.uTransportType = ((PNwdTranAddr)srcData)->uTransportType;
+ tranAddr.uAddressLength = ((PNwdTranAddr)srcData)->uAddressLength;
+ cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
+ cpylen = copy_to_user(tranAddr.puAddress, ((PNwdTranAddr)srcData)->Buffer, ((PNwdTranAddr)srcData)->uAddressLength);
+ dataLen=0;
+ break;
+ }
+ case NWC_CONN_INFO_NDS_STATE:
+ case NWC_CONN_INFO_MAX_PACKET_SIZE:
+ case NWC_CONN_INFO_LICENSE_STATE:
+ case NWC_CONN_INFO_PUBLIC_STATE:
+ case NWC_CONN_INFO_SERVICE_TYPE:
+ case NWC_CONN_INFO_DISTANCE:
+ case NWC_CONN_INFO_SERVER_VERSION:
+ case NWC_CONN_INFO_AUTH_ID:
+ case NWC_CONN_INFO_SUSPENDED:
+ case NWC_CONN_INFO_WORKGROUP_ID:
+ case NWC_CONN_INFO_SECURITY_STATE:
+ case NWC_CONN_INFO_CONN_NUMBER:
+ case NWC_CONN_INFO_USER_ID:
+ case NWC_CONN_INFO_BCAST_STATE:
+ case NWC_CONN_INFO_CONN_REF:
+ case NWC_CONN_INFO_AUTH_STATE:
+ case NWC_CONN_INFO_VERSION:
+ case NWC_CONN_INFO_SERVER_NAME:
+ case NWC_CONN_INFO_TREE_NAME:
+ srcData = (u_char *)reply->data;
+ dataLen = reply->dataLen;
+ break;
+
+ case NWC_CONN_INFO_TREE_NAME_UNICODE:
+ case NWC_CONN_INFO_SERVER_NAME_UNICODE:
+ break;
+
+ case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
+ break;
+
+ case NWC_CONN_INFO_ALTERNATE_ADDR:
+ break;
+
+ case NWC_CONN_INFO_SERVER_GUID:
+ break;
+
+ default:
+ break;
+ }
+
+ if (srcData && dataLen)
+ {
+ cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength);
+ }
+
+ return;
+}
+
+/*++======================================================================*/
+int NwGetDaemonVersion(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCGetRequesterVersion pDVersion;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ datalen = sizeof(*pDVersion);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_GET_REQUESTER_VERSION;
+ cmdlen = sizeof(*cmd);
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ pDVersion = (PNwdCGetRequesterVersion)reply->data;
+ cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion));
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+
+/*++======================================================================*/
+int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCGetPreferredDsTree pDGetTree;
+NwcGetPreferredDsTree xplatCall, *p;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+u_char *dPtr;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetPreferredDsTree));
+ datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength;
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE;
+ cmdlen = sizeof(*cmd);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ if (!retCode)
+ {
+ pDGetTree = (PNwdCGetPreferredDsTree)reply->data;
+ dPtr = reply->data + pDGetTree->DsTreeNameOffset;
+ p = (NwcGetPreferredDsTree *)pdata->reqData;
+
+ DbgPrint("NwcGetPreferredDSTree: Reply recieved\n");
+ DbgPrint(" TreeLen = %x\n", pDGetTree->uTreeLength);
+ DbgPrint(" TreeName = %s\n", dPtr);
+
+ cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4);
+ cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength);
+ }
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+PNwdCSetPreferredDsTree pDSetTree;
+NwcSetPreferredDsTree xplatCall;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+u_char *dPtr;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPreferredDsTree));
+ datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength;
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE;
+
+ pDSetTree = (PNwdCSetPreferredDsTree)cmd->data;
+ pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree);
+ pDSetTree->uTreeLength = xplatCall.uTreeLength;
+
+ dPtr = cmd->data + sizeof(*pDSetTree);
+ cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength);
+
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+
+/*++======================================================================*/
+int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcSetDefaultNameContext xplatCall;
+PNwdCSetDefaultNameContext pDSet;
+u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+u_char *dPtr;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetDefaultNameContext));
+ datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength;
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT;
+ cmd->dataLen = sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + xplatCall.uNameLength;
+
+ pDSet = (PNwdCSetDefaultNameContext)cmd->data;
+ dPtr = cmd->data;
+
+ pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext);
+ pDSet->uTreeLength = xplatCall.uTreeLength;
+ pDSet->NameContextOffset = pDSet->TreeOffset+xplatCall.uTreeLength;
+ pDSet->uNameLength = xplatCall.uNameLength;
+
+ cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
+ cpylen = copy_from_user(dPtr+pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength);
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcGetDefaultNameContext xplatCall;
+PNwdCGetDefaultNameContext pGet;
+char *dPtr;
+int retCode = -ENOMEM;
+u_long cmdlen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetDefaultNameContext));
+ cmdlen = sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT;
+ cmd->dataLen = sizeof(NwdCGetDefaultNameContext)+xplatCall.uTreeLength;
+
+ pGet = (PNwdCGetDefaultNameContext)cmd->data;
+ dPtr = cmd->data;
+
+ pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext);
+ pGet->uTreeLength = xplatCall.uTreeLength;
+
+ cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
+ dPtr[pGet->TreeOffset+pGet->uTreeLength] = 0;
+
+ retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ retCode = reply->Reply.ErrorCode;
+ if (!retCode)
+ {
+ pGet = (PNwdCGetDefaultNameContext)reply->data;
+
+ DbgPrint("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", retCode, pGet->uNameLength, xplatCall.uNameLength);
+ if (xplatCall.uNameLength < pGet->uNameLength)
+ {
+ pGet->uNameLength = xplatCall.uNameLength;
+ retCode = NWE_BUFFER_OVERFLOW;
+ }
+ dPtr = (char *)pGet + pGet->NameContextOffset;
+ cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength);
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(retCode);
+
+}
+
+/*++======================================================================*/
+int NwQueryFeature(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ NwcQueryFeature xpCall;
+ int status = SUCCESS;
+ u_long cpylen;
+
+ cpylen = copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature));
+ switch (xpCall.Feature)
+ {
+ case NWC_FEAT_NDS:
+ case NWC_FEAT_NDS_MTREE:
+ case NWC_FEAT_PRN_CAPTURE:
+ case NWC_FEAT_NDS_RESOLVE:
+
+ status = NWE_REQUESTER_FAILURE;
+
+ }
+ return( status );
+}
+
+/*++======================================================================*/
+int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcGetTreeMonitoredConnRef xplatCall, *p;
+PNwdCGetTreeMonitoredConnRef pDConnRef;
+char *dPtr;
+u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetTreeMonitoredConnRef));
+ datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen;
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF;
+
+ pDConnRef = (PNwdCGetTreeMonitoredConnRef)cmd->data;
+ pDConnRef->TreeName.boffset = sizeof(*pDConnRef);
+ pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen;
+ pDConnRef->TreeName.type = xplatCall.pTreeName->DataType;
+
+ dPtr = cmd->data + sizeof(*pDConnRef);
+ cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len);
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ pDConnRef = (PNwdCGetTreeMonitoredConnRef)reply->data;
+ dPtr = reply->data + pDConnRef->TreeName.boffset;
+ p = (NwcGetTreeMonitoredConnRef *)pdata->reqData;
+ cpylen = copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4);
+
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+
+ }
+
+ return(status);
+}
+
+/*++======================================================================*/
+int NwcEnumIdentities(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcEnumerateIdentities xplatCall, *eId;
+PNwdCEnumerateIdentities pEnum;
+NwcString xferStr;
+char *str;
+u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcEnumerateIdentities));
+ datalen = sizeof(*pEnum);
+ cmdlen = datalen + sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES;
+
+ DbgPrint("NwcEnumIdentities: Send Request\n");
+ DbgPrint(" iterator = %x\n", xplatCall.Iterator);
+ DbgPrint(" cmdlen = %d\n", cmdlen);
+
+ pEnum = (PNwdCEnumerateIdentities)cmd->data;
+ pEnum->Iterator = xplatCall.Iterator;
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+
+ eId = pdata->repData;
+ pEnum = (PNwdCEnumerateIdentities)reply->data;
+ cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator));
+ DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", pEnum->AuthenticationId);
+ cpylen = copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId));
+ cpylen = copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType));
+ cpylen = copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags));
+ cpylen = copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType));
+ cpylen = copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType));
+
+ if (!status)
+ {
+ cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(NwcString));
+ str = (char *)((char *)reply->data + pEnum->domainNameOffset);
+ DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", str);
+ cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen);
+ xferStr.DataType = NWC_STRING_TYPE_ASCII;
+ xferStr.DataLen = pEnum->domainNameLen - 1;
+ cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(NwcString));
+
+
+ cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(NwcString));
+ str = (char *)((char *)reply->data + pEnum->objectNameOffset);
+ DbgPrint("[XPLAT NWCAPI] Found User %s\n", str);
+ cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen);
+ xferStr.DataType = NWC_STRING_TYPE_ASCII;
+ xferStr.DataLen = pEnum->objectNameLen - 1;
+ cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(NwcString));
+ }
+
+ Novfs_Free(reply);
+
+ }
+ Novfs_Free(cmd);
+
+ }
+ return(status);
+}
+
+/*++======================================================================*/
+int NwcChangeAuthKey(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Change the password on the server
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcChangeKey xplatCall;
+PNwdCChangeKey pNewKey;
+NwcString xferStr;
+char *str;
+u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey));
+
+ datalen = sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
+ + xplatCall.pNewPassword->DataLen + xplatCall.pVerifyPassword->DataLen;
+
+ cmdlen = sizeof(*cmd) + datalen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ pNewKey = (PNwdCChangeKey)cmd->data;
+ cmd->dataLen = datalen;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_CHANGE_KEY;
+
+ pNewKey->NameType = xplatCall.NameType;
+ pNewKey->ObjectType = xplatCall.ObjectType;
+ pNewKey->AuthType = xplatCall.AuthType;
+ str = (char *)pNewKey;
+
+ /*
+ * Get the tree name
+ */
+ str += sizeof(*pNewKey);
+ cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
+ pNewKey->domainNameOffset = sizeof(*pNewKey);
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->domainNameLen = xferStr.DataLen;
+
+ /*
+ * Get the User Name
+ */
+ str += pNewKey->domainNameLen;
+ cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
+ pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->objectNameLen = xferStr.DataLen;
+
+ /*
+ * Get the New Password
+ */
+ str += pNewKey->objectNameLen;
+ cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(NwcString));
+ pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->newPasswordLen = xferStr.DataLen;
+
+ /*
+ * Get the Verify Password
+ */
+ str += pNewKey->newPasswordLen;
+ cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
+ pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen;
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->verifyPasswordLen = xferStr.DataLen;
+
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ memset(cmd, 0, cmdlen);
+
+ Novfs_Free(cmd);
+ }
+
+ return(status);
+}
+
+/*++======================================================================*/
+int NwcSetPrimaryConn(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Set the primary connection Id
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcSetPrimaryConnection xplatCall;
+PNwdCSetPrimaryConnection pConn;
+u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPrimaryConnection));
+
+ datalen = sizeof(NwdCSetPrimaryConnection);
+ cmdlen = sizeof(*cmd) + datalen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ pConn = (PNwdCSetPrimaryConnection)cmd->data;
+ cmd->dataLen = datalen;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SET_PRIMARY_CONN;
+ pConn->ConnHandle = xplatCall.ConnHandle;
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+
+ Novfs_Free(cmd);
+ }
+
+ return(status);
+}
+
+/*++======================================================================*/
+int NwcGetPrimaryConn(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Get the Primary connection
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+XPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long status = -ENOMEM, cmdlen, replylen, cpylen;
+
+
+ cmdlen = (u_long)(&((PXPLAT_CALL_REQUEST)0)->data);
+
+ cmd.dataLen = 0;
+ cmd.Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd.Command.SequenceNumber = 0;
+ cmd.Command.SessionId = Session;
+ cmd.NwcCommand = NWC_GET_PRIMARY_CONN;
+
+ status = Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ if (!status)
+ {
+ cpylen = copy_to_user(pdata->repData, reply->data, sizeof(u_long));
+ }
+
+ Novfs_Free(reply);
+ }
+
+ return(status);
+}
+
+
+/*++======================================================================*/
+int NwcSetMapDrive(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Get the Primary connection
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long status = 0, datalen, cmdlen, replylen, cpylen;
+NwcMapDriveEx symInfo;
+
+ DbgPrint("Call to NwcSetMapDrive\n");
+ cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+ cmdlen = sizeof(*cmd);
+ datalen = sizeof(symInfo) + symInfo.dirPathOffsetLength + symInfo.linkOffsetLength;
+
+ DbgPrint(" cmdlen = %d\n", cmdlen);
+ DbgPrint(" dataLen = %d\n", datalen);
+ DbgPrint(" symInfo.dirPathOffsetLength = %d\n", symInfo.dirPathOffsetLength);
+ DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength);
+ DbgPrint(" pdata->datalen = %d\n", pdata->reqLen);
+
+ mydump(sizeof(symInfo), &symInfo);
+
+ cmdlen += datalen;
+
+
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->dataLen = datalen;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_MAP_DRIVE;
+
+ cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(status);
+
+}
+
+/*++======================================================================*/
+int NwcUnMapDrive(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Get the Primary connection
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long status = 0, datalen, cmdlen, replylen, cpylen;
+NwcUnmapDriveEx symInfo;
+
+ DbgPrint("Call to NwcUnMapDrive\n");
+
+ cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+ cmdlen = sizeof(*cmd);
+ datalen = sizeof(symInfo) + symInfo.linkLen;
+
+ cmdlen += datalen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->dataLen = datalen;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_UNMAP_DRIVE;
+
+ cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+
+ return(status);
+}
+
+
+/*++======================================================================*/
+int NwcEnumerateDrives(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Get the Primary connection
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long status = 0, cmdlen, replylen, cpylen;
+u_long offset;
+char *cp;
+
+ DbgPrint("Call to NwcEnumerateDrives\n");
+
+ cmdlen = sizeof(*cmd);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+ cmd->dataLen = 0;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_ENUMERATE_DRIVES;
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ DbgPrint("Status Code = 0x%X\n", status);
+ if (!status)
+ {
+ offset = sizeof(u_long);
+ cp = reply->data;
+ replylen = ((PNwcGetMappedDrives)pdata->repData)->MapBuffLen;
+ cpylen = copy_to_user(pdata->repData, cp, offset);
+ cp += offset;
+ cpylen = copy_to_user(((PNwcGetMappedDrives)pdata->repData)->MapBuffer, cp, min(replylen - offset, reply->dataLen - offset));
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+
+ return(status);
+}
+
+
+/*++======================================================================*/
+int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Get the Primary connection
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+u_long status = 0x8866, cmdlen, replylen, cpylen;
+NwcGetBroadcastNotification msg;
+PNwdCGetBroadcastNotification dmsg;
+
+ cmdlen = sizeof(*cmd) + sizeof(*dmsg);
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+ if (cmd)
+ {
+
+ cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg));
+ cmd->dataLen = sizeof(*dmsg);
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+
+ cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE;
+ dmsg = (PNwdCGetBroadcastNotification)cmd->data;
+ dmsg->uConnReference = msg.uConnReference;
+
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ DbgPrint("Status Code = 0x%X\n", status);
+ if (!status)
+ {
+ /* we have a message so copy it to the user buffer */
+ cpylen = copy_to_user(pdata->repData, reply->data, min(pdata->repLen, reply->dataLen));
+ }
+ else
+ {
+ msg.messageLen = 0;
+ msg.message[0] = 0;
+ cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg));
+ }
+
+ Novfs_Free(reply);
+ }
+ Novfs_Free(cmd);
+ }
+ return(status);
+
+}
+
+
+int NwdSetKeyValue(PXPLAT pdata, session_t Session)
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcSetKey xplatCall;
+PNwdCSetKey pNewKey;
+NwcString cstrObjectName, cstrPassword;
+char *str;
+u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey));
+ cpylen = copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(NwcString));
+ cpylen = copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(NwcString));
+
+ datalen = sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen;
+
+ cmdlen = sizeof(*cmd) + datalen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ pNewKey = (PNwdCSetKey)cmd->data;
+ cmd->dataLen = datalen;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_SET_KEY;
+
+ pNewKey->ObjectType = xplatCall.ObjectType;
+ pNewKey->AuthenticationId = xplatCall.AuthenticationId;
+ pNewKey->ConnHandle = xplatCall.ConnHandle;
+ str = (char *)pNewKey;
+
+ /*
+ * Get the User Name
+ */
+ str += sizeof(NwdCSetKey);
+ cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen);
+
+ str +=
+ pNewKey->objectNameLen = cstrObjectName.DataLen;
+ pNewKey->objectNameOffset = sizeof(NwdCSetKey);
+
+ /*
+ * Get the Verify Password
+ */
+ cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen);
+
+ pNewKey->newPasswordLen = cstrPassword.DataLen;
+ pNewKey->newPasswordOffset = pNewKey->objectNameOffset+pNewKey->objectNameLen;
+
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ memset(cmd, 0, cmdlen);
+ Novfs_Free(cmd);
+ }
+
+ return(status);
+}
+
+/*++======================================================================*/
+int NwdVerifyKeyValue(PXPLAT pdata, session_t Session)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract: Change the password on the server
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+PXPLAT_CALL_REQUEST cmd;
+PXPLAT_CALL_REPLY reply;
+NwcVerifyKey xplatCall;
+PNwdCVerifyKey pNewKey;
+NwcString xferStr;
+char *str;
+u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey));
+
+ datalen = sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
+ + xplatCall.pVerifyPassword->DataLen;
+
+ cmdlen = sizeof(*cmd) + datalen;
+ cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+
+ if (cmd)
+ {
+ pNewKey = (PNwdCVerifyKey)cmd->data;
+ cmd->dataLen = datalen;
+ cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+ cmd->Command.SequenceNumber = 0;
+ cmd->Command.SessionId = Session;
+ cmd->NwcCommand = NWC_VERIFY_KEY;
+
+ pNewKey->NameType = xplatCall.NameType;
+ pNewKey->ObjectType = xplatCall.ObjectType;
+ pNewKey->AuthType = xplatCall.AuthType;
+ str = (char *)pNewKey;
+
+ /*
+ * Get the tree name
+ */
+ str += sizeof(*pNewKey);
+ cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
+ pNewKey->domainNameOffset = sizeof(*pNewKey);
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->domainNameLen = xferStr.DataLen;
+
+ /*
+ * Get the User Name
+ */
+ str += pNewKey->domainNameLen;
+ cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
+ pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->objectNameLen = xferStr.DataLen;
+
+ /*
+ * Get the Verify Password
+ */
+ str += pNewKey->objectNameLen;
+ cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
+ pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
+ cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+ pNewKey->verifyPasswordLen = xferStr.DataLen;
+
+ status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+ if (reply)
+ {
+ status = reply->Reply.ErrorCode;
+ Novfs_Free(reply);
+ }
+ memset(cmd, 0, cmdlen);
+ Novfs_Free(cmd);
+ }
+
+ return(status);
+}
diff -uNr src.old/src/proc.c src/src/proc.c
--- src.old/src/proc.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/proc.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,339 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: proc.c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module contains functions that create the
+ * interface to the proc filesystem.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+
+/*===[ Include files specific to this module ]============================*/
+#include "vfs.h"
+
+/*===[ External data ]====================================================*/
+extern char *Novfs_CurrentMount;
+
+/*===[ External prototypes ]==============================================*/
+extern int DbgPrint( char *Fmt, ... );
+
+extern ssize_t
+Daemon_Receive_Reply(struct file *file, const char *buf, size_t nbytes, loff_t *ppos);
+
+extern ssize_t
+Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
+
+extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+
+extern int Daemon_Library_close(struct inode *inode, struct file *file);
+extern int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+extern int Daemon_Library_open(struct inode *inode, struct file *file);
+extern ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
+extern ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
+extern loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
+
+extern int Daemon_Open_Control(struct inode *Inode, struct file *File);
+extern int Daemon_Close_Control(struct inode *Inode, struct file *File);
+
+extern int Daemon_getversion( char *Buf, int Length );
+
+/*===[ Manifest constants ]===============================================*/
+
+/*===[ Type definitions ]=================================================*/
+
+/*===[ Function prototypes ]==============================================*/
+ssize_t
+Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+
+ssize_t
+Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+
+int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+
+int Init_Procfs_Interface( void );
+void Uninit_Procfs_Interface( void );
+
+/*===[ Global variables ]=================================================*/
+struct proc_dir_entry *Novfs_Procfs_dir, *Novfs_Control, *Novfs_Library, *Novfs_Version;
+static struct file_operations Daemon_proc_fops;
+static struct file_operations Library_proc_fops;
+
+/*===[ Code ]=============================================================*/
+
+/*++======================================================================*/
+int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *buf, tbuf[48];
+ int len=0, i;
+
+ if ( !off )
+ {
+ buf = page+off;
+ *start = buf;
+ len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING);
+ i = Daemon_getversion(tbuf, sizeof(tbuf));
+ if ((i > 0) && i < (count-len))
+ {
+ len += sprintf(buf+len, "Novfsd Version=%s\n", tbuf);
+ }
+
+ if (Novfs_CurrentMount)
+ {
+ i = strlen(Novfs_CurrentMount);
+ if ((i > 0) && i < (count-len))
+ {
+ len += sprintf(buf+len, "Novfs mount=%s\n", Novfs_CurrentMount);
+ }
+ }
+ DbgPrint("Novfs_Get_Version:\n%s\n", buf);
+ }
+ *eof = 1;
+ return(len);
+}
+
+/*++======================================================================*/
+ssize_t
+Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ssize_t retval=0;
+
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(buf);
+ UNUSED_VARIABLE(nbytes);
+ UNUSED_VARIABLE(ppos);
+
+ DbgPrint( "Novfs_User_proc_read: kernel_locked 0x%x\n", kernel_locked());
+
+ return retval;
+}
+/*++======================================================================*/
+ssize_t
+Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ ssize_t retval=0;
+
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(ppos);
+
+ DbgPrint( "Novfs_User_proc_write: kernel_locked 0x%x\n", kernel_locked());
+ if (buf && nbytes)
+ {
+ }
+
+ return(retval);
+}
+
+/*++======================================================================*/
+int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retval=-ENOSYS;
+
+ UNUSED_VARIABLE(inode);
+ UNUSED_VARIABLE(file);
+ UNUSED_VARIABLE(cmd);
+ UNUSED_VARIABLE(arg);
+
+ DbgPrint( "Novfs_User_proc_ioctl: kernel_locked 0x%x\n", kernel_locked());
+
+ return(retval);
+}
+
+/*++======================================================================*/
+int Init_Procfs_Interface( void )
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ int retCode=0;
+
+ Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL);
+ if ( Novfs_Procfs_dir )
+ {
+ Novfs_Procfs_dir->owner = THIS_MODULE;
+
+ Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir);
+
+ if ( Novfs_Control )
+ {
+ Novfs_Control->owner = THIS_MODULE;
+ Novfs_Control->size = 0;
+ memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, sizeof(struct file_operations));
+
+ /*
+ * Setup our functions
+ */
+ Daemon_proc_fops.owner = THIS_MODULE;
+ Daemon_proc_fops.open = Daemon_Open_Control;
+ Daemon_proc_fops.release = Daemon_Close_Control;
+ Daemon_proc_fops.read = Daemon_Send_Command;
+ Daemon_proc_fops.write = Daemon_Receive_Reply;
+ Daemon_proc_fops.ioctl = Daemon_ioctl;
+
+ Novfs_Control->proc_fops = &Daemon_proc_fops;
+ }
+ else
+ {
+ remove_proc_entry(MODULE_NAME, NULL);
+ return(-ENOENT);
+ }
+
+ Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir);
+ if ( Novfs_Library )
+ {
+ Novfs_Library->owner = THIS_MODULE;
+ Novfs_Library->size = 0;
+
+ /*
+ * Setup our file functions
+ */
+ memcpy(&Library_proc_fops, Novfs_Library->proc_fops, sizeof(struct file_operations));
+ Library_proc_fops.owner = THIS_MODULE;
+ Library_proc_fops.open = Daemon_Library_open;
+ Library_proc_fops.release = Daemon_Library_close;
+ Library_proc_fops.read = Daemon_Library_read;
+ Library_proc_fops.write = Daemon_Library_write;
+ Library_proc_fops.llseek = Daemon_Library_llseek;
+ Library_proc_fops.ioctl = Daemon_Library_ioctl;
+ Novfs_Library->proc_fops = &Library_proc_fops;
+ }
+ else
+ {
+ remove_proc_entry("Control", Novfs_Procfs_dir);
+ remove_proc_entry(MODULE_NAME, NULL);
+ return(-ENOENT);
+ }
+
+ Novfs_Version = create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, Novfs_Get_Version, NULL);
+ if ( Novfs_Version )
+ {
+ Novfs_Version->owner = THIS_MODULE;
+ Novfs_Version->size = 0;
+ }
+ else
+ {
+ remove_proc_entry("Library", Novfs_Procfs_dir);
+ remove_proc_entry("Control", Novfs_Procfs_dir);
+ remove_proc_entry(MODULE_NAME, NULL);
+ retCode = -ENOENT;
+ }
+ }
+ else
+ {
+ retCode = -ENOENT;
+ }
+ return(retCode);
+}
+
+/*++======================================================================*/
+void Uninit_Procfs_Interface( void )
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+
+ DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n");
+ remove_proc_entry("Version", Novfs_Procfs_dir);
+
+ DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n");
+ remove_proc_entry("Control", Novfs_Procfs_dir);
+
+ DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n");
+ remove_proc_entry("Library", Novfs_Procfs_dir);
+
+ DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+ remove_proc_entry(MODULE_NAME, NULL);
+
+ DbgPrint("Uninit_Procfs_Interface done\n");
+}
diff -uNr src.old/src/profile.c src/src/profile.c
--- src.old/src/profile.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/profile.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,1199 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: profile.c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module contains a debugging code for
+ * the novfs VFS.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/time.h>
+
+#include <linux/profile.h>
+#include <linux/notifier.h>
+
+/*===[ Include files specific to this module ]============================*/
+#include "vfs.h"
+
+/*===[ External data ]====================================================*/
+extern struct dentry *Novfs_root;
+extern struct proc_dir_entry *Novfs_Procfs_dir;
+extern unsigned long File_update_timeout;
+extern int PageCache;
+
+/*===[ External prototypes ]==============================================*/
+extern void Scope_Dump_Tasklist( void );
+extern void Scope_Dump_Scopetable( void );
+extern void Daemon_Dumpque( void );
+extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
+extern int Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+extern void Novfs_dump_inode( void *pf );
+extern int Daemon_SendDebugCmd ( char *Command );
+
+
+/*===[ Manifest constants ]===============================================*/
+#define DBGBUFFERSIZE (1024*1024*32)
+
+/*===[ Type definitions ]=================================================*/
+typedef void daemon_command_t;
+
+typedef struct _SYMBOL_TABLE {
+ void *address;
+ char *name;
+} SYMBOL_TABLE, *PSYMBOL_TABLE;
+
+struct local_rtc_time {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+
+/*===[ Function prototypes ]==============================================*/
+int profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) __attribute__((__no_instrument_function__));
+int init_profile( void );
+
+char *ctime_r(time_t *clock, char *buf);
+int LocalPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
+int DbgPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
+
+void __cyg_profile_func_enter (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)) ;
+void __cyg_profile_func_exit (void *this_fn, void *call_site) __attribute__((__no_instrument_function__));
+void doline(unsigned char *b, unsigned char *p, unsigned char *l) __attribute__((__no_instrument_function__));
+void mydump(int size, void *dumpptr) __attribute__((__no_instrument_function__));
+void GregorianDay(struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
+void to_tm(int tim, struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
+char *ctime_r(time_t *clock, char *buf) __attribute__((__no_instrument_function__));
+int profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+
+void *Novfs_Malloc( size_t size, int flags ) __attribute__((__no_instrument_function__));
+void Novfs_Free( const void *p ) __attribute__((__no_instrument_function__));
+
+int profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs) __attribute__((__no_instrument_function__));
+void profile_dump_memorylist( void *pf );
+
+static ssize_t User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
+static ssize_t User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
+static int proc_read_DbgBuffer(char *page, char **start,
+ off_t off, int count,
+ int *eof, void *data) __attribute__((__no_instrument_function__));
+
+void profile_dump_dt(struct dentry *parent, void *pf );
+ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off);
+ssize_t profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off);
+ssize_t profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off);
+uint64_t get_nanosecond_time( void );
+
+/*===[ Global variables ]=================================================*/
+char *DbgPrintBuffer=NULL;
+char DbgPrintOn=0;
+char DbgSyslogOn=0;
+unsigned long DbgPrintBufferOffset=0;
+unsigned long DbgPrintBufferReadOffset=0;
+unsigned long DbgPrintBufferSize = DBGBUFFERSIZE;
+
+int Indent = 0;
+char IndentString[] = " ";
+
+static struct file_operations Dbg_proc_file_operations;
+static struct file_operations dentry_proc_file_ops;
+static struct file_operations inode_proc_file_ops;
+static struct file_operations memory_proc_file_ops;
+
+static struct proc_dir_entry *dbg_dir=NULL, *dbg_file=NULL;
+static struct proc_dir_entry *dentry_file=NULL;
+static struct proc_dir_entry *inode_file=NULL;
+static struct proc_dir_entry *memory_file=NULL;
+
+static struct notifier_block taskexit_nb;
+
+
+DECLARE_MUTEX(LocalPrint_lock);
+spinlock_t Syslog_lock = SPIN_LOCK_UNLOCKED;
+
+#include "profile_funcs.h"
+
+
+/*===[ Code ]=============================================================*/
+int
+profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data)
+{
+ struct task_struct *task = (struct task_struct *)data;
+
+ DbgPrint("profile_task_exit_callback: task 0x%p %u exiting %s\n", task, task->pid, task->comm);
+ return(0);
+}
+
+int init_profile( void )
+{
+ int retCode = 0;
+
+ if (Novfs_Procfs_dir)
+ {
+ dbg_dir = Novfs_Procfs_dir;
+ }
+ else
+ {
+ dbg_dir = proc_mkdir(MODULE_NAME, NULL);
+ }
+
+ if( dbg_dir )
+ {
+ dbg_dir->owner = THIS_MODULE;
+ dbg_file = create_proc_read_entry("Debug",
+ 0600,
+ dbg_dir,
+ proc_read_DbgBuffer,
+ NULL);
+ if ( dbg_file )
+ {
+ dbg_file->owner = THIS_MODULE;
+ dbg_file->size = DBGBUFFERSIZE;
+ memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, sizeof(struct file_operations));
+ Dbg_proc_file_operations.read = User_proc_read_DbgBuffer;
+ Dbg_proc_file_operations.write = User_proc_write_DbgBuffer;
+ dbg_file->proc_fops = &Dbg_proc_file_operations;
+ }
+ else
+ {
+ remove_proc_entry(MODULE_NAME, NULL);
+ vfree( DbgPrintBuffer );
+ DbgPrintBuffer = NULL;
+ }
+ }
+
+ if ( DbgPrintBuffer )
+ {
+ if( dbg_dir )
+ {
+ inode_file = create_proc_entry("inode",
+ 0600,
+ dbg_dir);
+ if ( inode_file )
+ {
+ inode_file->owner = THIS_MODULE;
+ inode_file->size = 0;
+ memcpy(&inode_proc_file_ops, inode_file->proc_fops, sizeof(struct file_operations));
+ inode_proc_file_ops.owner = THIS_MODULE;
+ inode_proc_file_ops.read = profile_inode_read;
+ inode_file->proc_fops = &inode_proc_file_ops;
+ }
+
+ dentry_file = create_proc_entry("dentry",
+ 0600,
+ dbg_dir);
+ if ( dentry_file )
+ {
+ dentry_file->owner = THIS_MODULE;
+ dentry_file->size = 0;
+ memcpy(&dentry_proc_file_ops, dentry_file->proc_fops, sizeof(struct file_operations));
+ dentry_proc_file_ops.owner = THIS_MODULE;
+ dentry_proc_file_ops.read = profile_dentry_read;
+ dentry_file->proc_fops = &dentry_proc_file_ops;
+ }
+
+ memory_file = create_proc_entry("memory",
+ 0600,
+ dbg_dir);
+ if ( memory_file )
+ {
+ memory_file->owner = THIS_MODULE;
+ memory_file->size = 0;
+ memcpy(&memory_proc_file_ops, memory_file->proc_fops, sizeof(struct file_operations));
+ memory_proc_file_ops.owner = THIS_MODULE;
+ memory_proc_file_ops.read = profile_memory_read;
+ memory_file->proc_fops = &memory_proc_file_ops;
+ }
+
+ }
+ else
+ {
+ vfree( DbgPrintBuffer );
+ DbgPrintBuffer = NULL;
+ }
+ }
+ return( retCode );
+}
+
+
+void uninit_profile( void )
+{
+ if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
+ if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
+ if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
+ if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
+
+ if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))
+ {
+ DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+ remove_proc_entry( MODULE_NAME, NULL );
+ }
+}
+
+
+static
+ssize_t
+User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos)
+{
+ ssize_t retval=nbytes;
+ u_char *lbuf, *p;
+ int i;
+ u_long cpylen;
+
+
+ UNUSED_VARIABLE( *ppos );
+
+ lbuf = Novfs_Malloc(nbytes+1, GFP_KERNEL);
+ if (lbuf)
+ {
+ cpylen = copy_from_user(lbuf, buf, nbytes);
+
+ lbuf[nbytes] = 0;
+ DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf);
+
+ for (i=0; lbuf[i] && lbuf[i] != '\n'; i++) ;
+
+ if ( '\n' == lbuf[i] )
+ {
+ lbuf[i] = '\0';
+ }
+
+ if ( !strcmp("on", lbuf))
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ DbgPrintOn = 1;
+ }
+ else if ( !strcmp("off", lbuf))
+ {
+ DbgPrintOn = 0;
+ }
+ else if ( !strcmp("reset", lbuf))
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ }
+ else if ( NULL != (p = strchr(lbuf, ' ')))
+ {
+ *p++ = '\0';
+ if ( !strcmp("syslog", lbuf))
+ {
+
+ if (!strcmp("on", p))
+ {
+ DbgSyslogOn = 1;
+ }
+ else if (!strcmp("off", p))
+ {
+ DbgSyslogOn = 0;
+ }
+ }
+ else if ( !strcmp("novfsd", lbuf))
+ {
+ Daemon_SendDebugCmd( p );
+ }
+ else if ( !strcmp("file_update_timeout", lbuf))
+ {
+ File_update_timeout = simple_strtoul(p, NULL, 0);
+ }
+ else if ( !strcmp("cache", lbuf))
+ {
+ if (!strcmp("on", p))
+ {
+ PageCache = 1;
+ }
+ else if (!strcmp("off", p))
+ {
+ PageCache = 0;
+ }
+ }
+ }
+ Novfs_Free(lbuf);
+ }
+
+ return (retval);
+}
+
+static
+ssize_t
+User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+
+{
+ ssize_t retval=0;
+ size_t count;
+
+ UNUSED_VARIABLE( *ppos );
+
+ if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset))
+ {
+
+ if (count > nbytes)
+ {
+ count = nbytes;
+ }
+
+ count -= copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], count);
+
+ if (count == 0)
+ {
+ if (retval == 0)
+ retval = -EFAULT;
+ }
+ else
+ {
+ DbgPrintBufferReadOffset += count;
+ if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ }
+ retval = count;
+ }
+ }
+
+ return retval;
+}
+
+static
+int
+proc_read_DbgBuffer(char *page, char **start,
+ off_t off, int count,
+ int *eof, void *data)
+{
+ int len;
+ static char bufd[512];
+
+ UNUSED_VARIABLE(start);
+ UNUSED_VARIABLE(eof);
+ UNUSED_VARIABLE(data);
+
+ sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n",
+ off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset);
+ printk(bufd);
+
+ len = DbgPrintBufferOffset - DbgPrintBufferReadOffset;
+
+ if ((int)(DbgPrintBufferOffset-DbgPrintBufferReadOffset) > count)
+ {
+ len = count;
+ }
+
+ if (len)
+ {
+ memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len);
+ DbgPrintBufferReadOffset += len;
+ }
+
+
+ if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ }
+
+ sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: return %d\n", len);
+ printk(bufd);
+
+ return len;
+}
+
+#define DBG_BUFFER_SIZE (2*1024)
+
+int
+LocalPrint( char *Fmt, ... )
+{
+ int len=0;
+ va_list args;
+
+ if (DbgPrintBuffer)
+ {
+ va_start(args, Fmt);
+ len += vsnprintf(DbgPrintBuffer+DbgPrintBufferOffset, DbgPrintBufferSize-DbgPrintBufferOffset, Fmt, args);
+ DbgPrintBufferOffset += len;
+ }
+
+ return(len);
+}
+
+
+int
+DbgPrint( char *Fmt, ... )
+{
+ char *buf;
+ int len=0;
+ unsigned long offset;
+ va_list args;
+
+ if ( (DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn )
+ {
+ buf = kmalloc( DBG_BUFFER_SIZE, GFP_KERNEL );
+
+ if (buf)
+ {
+ va_start(args, Fmt);
+ len = sprintf(buf, "[%d] ", current->pid);
+
+ len += vsnprintf(buf+len, DBG_BUFFER_SIZE-len, Fmt, args);
+ if ( -1 == len )
+ {
+ len = DBG_BUFFER_SIZE-1;
+ buf[len] = '\0';
+ }
+ /*
+ len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts);
+ len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args);
+ */
+
+ if (len)
+ {
+ if (DbgSyslogOn)
+ {
+ printk("<6>%s", buf);
+ }
+
+ if ( DbgPrintBuffer && DbgPrintOn )
+ {
+ if ((DbgPrintBufferOffset+len) > DbgPrintBufferSize)
+ {
+ offset = DbgPrintBufferOffset;
+ DbgPrintBufferOffset = 0;
+ memset(&DbgPrintBuffer[offset], 0, DbgPrintBufferSize-offset);
+ }
+
+ mb();
+
+ if ((DbgPrintBufferOffset+len) < DbgPrintBufferSize)
+ {
+ DbgPrintBufferOffset += len;
+ offset = DbgPrintBufferOffset-len;
+ memcpy(&DbgPrintBuffer[offset], buf, len+1);
+ }
+ }
+ }
+ kfree(buf);
+ }
+ }
+
+ return(len);
+}
+
+void
+__cyg_profile_func_enter (void *this_fn, void *call_site)
+{
+ PSYMBOL_TABLE sym;
+ uint64_t t64;
+
+
+ if ((void *)init_novfs == this_fn)
+ {
+ DbgPrintBuffer = vmalloc(DBGBUFFERSIZE);
+ taskexit_nb.notifier_call = profile_task_exit_callback;
+
+#ifdef CONFIG_KDB
+ kdb_register("novfs_tl", profile_dump_tasklist, "", "Dumps task list", 0);
+ kdb_register("novfs_st", profile_dump_scopetable, "", "Dumps the novfs scope table", 0);
+ kdb_register("novfs_dque", profile_dump_daemonque, "", "Dumps the novfs daemon que", 0);
+ kdb_register("novfs_db", profile_dump_DbgBuffer, "[-r] [-e size] [-i]", "Dumps the novfs DbgBuffer", 0);
+ kdb_register("novfs_den", profile_dump_DentryTree, "[dentry]", "Dumps a Dentry tree", 0);
+ kdb_register("novfs_ic", Novfs_dump_inode_cache, "[inode]", "Dumps a Inode Cache", 0);
+ kdb_register("novfs_inode", profile_dump_inode, "", "Dump allocated Inodes", 0);
+ kdb_register("novfs_mem", profile_dump_memorylist_dbg, "", "Dumps allocated memory", 0);
+#endif
+ }
+ else if (exit_novfs == this_fn)
+ {
+ /*
+ if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
+ if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
+ if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
+ if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
+
+ if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))
+ {
+ printk( KERN_INFO "Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+ remove_proc_entry( MODULE_NAME, NULL );
+ }
+ */
+ }
+
+ sym = SymbolTable;
+ while (sym->address)
+ {
+ if (this_fn == sym->address )
+ {
+ t64 = get_nanosecond_time();
+ DbgPrint("[%llu]%sS %s (0x%p 0x%p)\n", t64, &IndentString[sizeof(IndentString)-Indent-1], sym->name, this_fn, call_site);
+
+ Indent++;
+ if (Indent > (int)(sizeof(IndentString)-1))
+ Indent--;
+
+ break;
+ }
+ sym++;
+ }
+}
+
+void
+__cyg_profile_func_exit (void *this_fn, void *call_site)
+{
+ PSYMBOL_TABLE sym;
+ uint64_t t64;
+
+ if (exit_novfs == this_fn)
+ {
+ if (DbgPrintBuffer) vfree( DbgPrintBuffer );
+ DbgPrintBuffer = NULL;
+
+#ifdef CONFIG_KDB
+ kdb_unregister("novfs_tl");
+ kdb_unregister("novfs_st");
+ kdb_unregister("novfs_dque");
+ kdb_unregister("novfs_db");
+ kdb_unregister("novfs_den");
+ kdb_unregister("novfs_ic");
+ kdb_unregister("novfs_inode");
+ kdb_unregister("novfs_mem");
+#endif
+ return;
+ }
+
+ sym = SymbolTable;
+ while (sym->address)
+ {
+ if (this_fn == sym->address )
+ {
+ Indent--;
+ if (Indent < 0)
+ Indent = 0;
+
+ t64 = get_nanosecond_time();
+ DbgPrint("[%llu]%sR %s (0x%p)\n", t64, &IndentString[sizeof(IndentString)-Indent-1], sym->name, call_site);
+ break;
+ }
+ sym++;
+ }
+}
+
+void
+doline(unsigned char *b, unsigned char *e, unsigned char *l)
+{
+ *b++ = ' ';
+ while (l < e) {
+ if ((*l < ' ') || (*l > '~'))
+ {
+ *b++ = '.';
+ *b = '\0';
+ }
+ else
+ {
+ b += sprintf(b, "%c", *l);
+ }
+ l++;
+ }
+}
+
+void
+mydump(int size, void *dumpptr)
+{
+ unsigned char *ptr = (unsigned char *)dumpptr;
+ unsigned char *line=0, buf[80], *bptr=buf;
+ int i;
+
+ if ( DbgPrintBuffer )
+ {
+ if (size)
+ {
+ for (i=0; i < size; i++)
+ {
+ if (0 == (i % 16))
+ {
+ if (line)
+ {
+ doline(bptr, ptr, line);
+ DbgPrint("%s\n", buf);
+ bptr = buf;
+ }
+ bptr += sprintf(bptr, "0x%p: ", ptr);
+ line = ptr;
+ }
+ bptr += sprintf(bptr, "%02x ", *ptr++);
+ }
+ doline(bptr, ptr, line);
+ DbgPrint("%s\n", buf);
+ }
+ }
+}
+
+#define FEBRUARY 2
+#define STARTOFTIME 1970
+#define SECDAY 86400L
+#define SECYR (SECDAY * 365)
+#define leapyear(year) ((year) % 4 == 0)
+#define days_in_year(a) (leapyear(a) ? 366 : 365)
+#define days_in_month(a) (month_days[(a) - 1])
+
+static int month_days[12] = {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+ */
+void
+GregorianDay(struct local_rtc_time * tm)
+{
+ int leapsToDate;
+ int lastYear;
+ int day;
+ int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+ lastYear=tm->tm_year-1;
+
+ /*
+ * Number of leap corrections to apply up to end of last year
+ */
+ leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+
+ /*
+ * This year is a leap year if it is divisible by 4 except when it is
+ * divisible by 100 unless it is divisible by 400
+ *
+ * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+ */
+ if((tm->tm_year%4==0) &&
+ ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+ (tm->tm_mon>2))
+ {
+ /*
+ * We are past Feb. 29 in a leap year
+ */
+ day=1;
+ }
+ else
+ {
+ day=0;
+ }
+
+ day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
+ tm->tm_mday;
+
+ tm->tm_wday=day%7;
+}
+
+void
+to_tm(int tim, struct local_rtc_time * tm)
+{
+ register int i;
+ register long hms, day;
+
+ day = tim / SECDAY;
+ hms = tim % SECDAY;
+
+ /* Hours, minutes, seconds are easy */
+ tm->tm_hour = hms / 3600;
+ tm->tm_min = (hms % 3600) / 60;
+ tm->tm_sec = (hms % 3600) % 60;
+
+ /* Number of years in days */
+ for (i = STARTOFTIME; day >= days_in_year(i); i++)
+ day -= days_in_year(i);
+ tm->tm_year = i;
+
+ /* Number of months in days left */
+ if (leapyear(tm->tm_year))
+ days_in_month(FEBRUARY) = 29;
+ for (i = 1; day >= days_in_month(i); i++)
+ day -= days_in_month(i);
+ days_in_month(FEBRUARY) = 28;
+ tm->tm_mon = i;
+
+ /* Days are what is left over (+1) from all that. */
+ tm->tm_mday = day + 1;
+
+ /*
+ * Determine the day of week
+ */
+ GregorianDay(tm);
+}
+
+char *
+ctime_r(time_t *clock, char *buf)
+{
+ struct local_rtc_time tm;
+ static char *DAYOFWEEK[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+ static char *MONTHOFYEAR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ to_tm(*clock, &tm);
+
+ sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], MONTHOFYEAR[tm.tm_mon-1], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year);
+ return(buf);
+}
+
+
+#ifdef CONFIG_KDB
+
+int
+NO_TRACE
+profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ Scope_Dump_Tasklist();
+ return( 0 );
+}
+
+int
+NO_TRACE
+profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ Scope_Dump_Scopetable();
+ return( 0 );
+}
+
+int
+NO_TRACE
+profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ Daemon_Dumpque();
+ return( 0 );
+}
+
+int
+NO_TRACE
+profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long offset = DbgPrintBufferReadOffset;
+ if (argc > 0)
+ {
+ if (!strcmp("-r", argv[1]))
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ }
+ else if (!strcmp("-e", argv[1]) && (argc > 1))
+ {
+ offset = simple_strtoul(argv[2], NULL, 0);
+ if (offset && offset < DbgPrintBufferOffset)
+ {
+ offset = DbgPrintBufferOffset - offset;
+ }
+ else
+ {
+ offset = DbgPrintBufferOffset;
+ }
+ }
+ else if (!strcmp("-i", argv[1]))
+ {
+ kdb_printf("DbgPrintBuffer =0x%p\n", DbgPrintBuffer);
+ kdb_printf("DbgPrintBufferOffset =0x%lx\n", DbgPrintBufferOffset);
+ kdb_printf("DbgPrintBufferSize =0x%lx\n", DbgPrintBufferSize);
+ offset = DbgPrintBufferOffset;
+
+ }
+ }
+ while (DbgPrintBufferOffset > offset)
+ {
+ kdb_printf("%c", DbgPrintBuffer[offset++]);
+ }
+ return( 0 );
+}
+
+int
+NO_TRACE
+profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct dentry *parent=Novfs_root;
+
+ if (argc > 0)
+ {
+ parent = (void *)simple_strtoul(argv[1], NULL, 0);
+ }
+
+ if (parent)
+ {
+ profile_dump_dt(parent, kdb_printf );
+ }
+
+ return(0);
+}
+
+
+int
+NO_TRACE
+profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ Novfs_dump_inode( kdb_printf );
+ return( 0 );
+}
+
+#endif /* CONFIG_KDB */
+
+typedef struct memory_header
+{
+ struct list_head list;
+ void *caller;
+ size_t size;
+} MEMORY_LIST, *PMEMORY_LIST;
+
+spinlock_t Malloc_Lock = SPIN_LOCK_UNLOCKED;
+LIST_HEAD( Memory_List );
+
+void *Novfs_Malloc( size_t size, int flags )
+{
+ void *p=NULL;
+ PMEMORY_LIST mh;
+
+ mh = kmalloc(size + sizeof(MEMORY_LIST), flags);
+ if (mh)
+ {
+ mh->caller = __builtin_return_address(0);
+ mh->size = size;
+ spin_lock(&Malloc_Lock);
+ list_add(&mh->list, &Memory_List);
+ spin_unlock(&Malloc_Lock);
+ p = (char *)mh+sizeof(MEMORY_LIST);
+ /*DbgPrint("Novfs_Malloc: 0x%p 0x%p %d\n", p, mh->caller, size);
+ */
+ }
+ return(p);
+}
+
+void Novfs_Free( const void *p )
+{
+ PMEMORY_LIST mh;
+
+ if (p)
+ {
+ /*DbgPrint("Novfs_Free: 0x%p 0x%p\n", p, __builtin_return_address(0));
+ */
+ mh = (PMEMORY_LIST)((char *)p-sizeof(MEMORY_LIST));
+
+ spin_lock(&Malloc_Lock);
+ list_del(&mh->list);
+ spin_unlock(&Malloc_Lock);
+ kfree(mh);
+ }
+}
+
+
+int
+NO_TRACE
+profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+#ifdef CONFIG_KDB
+ profile_dump_memorylist(kdb_printf);
+#endif /* CONFIG_KDB */
+
+ return( 0 );
+}
+
+void
+NO_TRACE
+profile_dump_memorylist( void *pf )
+{
+ void (*pfunc)(char *Fmt, ...) = pf;
+
+ PMEMORY_LIST mh;
+ struct list_head *l;
+
+ size_t total=0;
+ int count=0;
+
+ spin_lock( &Malloc_Lock );
+
+ list_for_each( l, &Memory_List )
+ {
+ mh = list_entry(l, MEMORY_LIST, list);
+ pfunc("0x%p 0x%p 0x%p %d\n", mh, (char *)mh+sizeof(MEMORY_LIST), mh->caller, mh->size);
+ count++;
+ total += mh->size;
+ }
+ spin_unlock( &Malloc_Lock );
+
+ pfunc("Blocks=%d Total=%d\n", count, total);
+}
+
+void
+NO_TRACE
+profile_dump_dt(struct dentry *parent, void *pf )
+{
+ void (*pfunc)(char *Fmt, ...) = pf;
+ struct l {
+ struct l *next;
+ struct dentry *dentry;
+ } *l, *n, *start;
+ struct list_head *p;
+ struct dentry *d;
+ char *buf, *path, *sd;
+ char inode_number[16];
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+
+ if( NULL == buf )
+ {
+ return;
+ }
+
+ if (parent)
+ {
+ pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, parent->d_name.name);
+ if (parent->d_subdirs.next == &parent->d_subdirs)
+ {
+ pfunc("No children...\n");
+ }
+ else
+ {
+ start = Novfs_Malloc(sizeof(*start), GFP_KERNEL);
+ if (start)
+ {
+ start->next = NULL;
+ start->dentry = parent;
+ l = start;
+ while(l)
+ {
+ p = l->dentry->d_subdirs.next;
+ while(p != &l->dentry->d_subdirs)
+ {
+ d = list_entry(p, struct dentry, D_CHILD);
+ p = p->next;
+
+ if (d->d_subdirs.next != &d->d_subdirs)
+ {
+ n = Novfs_Malloc(sizeof(*n), GFP_KERNEL);
+ if (n)
+ {
+ n->next = l->next;
+ l->next = n;
+ n->dentry = d;
+ }
+ }
+ else
+ {
+ path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
+ if (path)
+ {
+ pfunc("1-0x%p %s\n" \
+ " d_name: %.*s\n" \
+ " d_parent: 0x%p\n" \
+ " d_count: %d\n" \
+ " d_flags: 0x%x\n" \
+ " d_subdirs: 0x%p\n" \
+ " d_inode: 0x%p\n",
+ d, path, d->d_name.len, d->d_name.name, d->d_parent,
+ atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, d->d_inode);
+ }
+ }
+ }
+ l = l->next;
+ }
+ l = start;
+ while(l)
+ {
+ d=l->dentry;
+ path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
+ if (path)
+ {
+ sd = " (None)";
+ if (&d->d_subdirs != d->d_subdirs.next)
+ {
+ sd = "";
+ }
+ inode_number[0] = '\0';
+ if (d->d_inode)
+ {
+ sprintf(inode_number, " (%lu)", d->d_inode->i_ino);
+ }
+ pfunc("0x%p %s\n" \
+ " d_parent: 0x%p\n" \
+ " d_count: %d\n" \
+ " d_flags: 0x%x\n" \
+ " d_subdirs: 0x%p%s\n" \
+ " d_inode: 0x%p%s\n",
+ d, path, d->d_parent,
+ atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, sd, d->d_inode, inode_number);
+ }
+
+ n = l;
+ l = l->next;
+ Novfs_Free(n);
+ }
+ }
+ }
+ }
+
+ Novfs_Free(buf);
+
+}
+
+/*int profile_inode_open(struct inode *inode, struct file *file)
+{
+
+}
+
+int profile_inode_close(struct inode *inode, struct file *file)
+{
+}
+*/
+ssize_t profile_common_read( char *buf, size_t len, loff_t *off )
+{
+ ssize_t retval=0;
+ size_t count;
+ unsigned long offset = *off;
+
+ if (0 != (count = DbgPrintBufferOffset - offset))
+ {
+ if (count > len)
+ {
+ count = len;
+ }
+
+ count -= copy_to_user(buf, &DbgPrintBuffer[offset], count);
+
+ if (count == 0)
+ {
+ retval = -EFAULT;
+ }
+ else
+ {
+ *off += (loff_t)count;
+ retval = count;
+ }
+ }
+ return retval;
+
+}
+
+//ssize_t NO_TRACE profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
+ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
+{
+ ssize_t retval=0;
+ unsigned long offset = *off;
+ static char save_DbgPrintOn;
+
+ if (offset == 0)
+ {
+ down(&LocalPrint_lock);
+ save_DbgPrintOn = DbgPrintOn;
+ DbgPrintOn = 0;
+
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ Novfs_dump_inode( LocalPrint );
+ }
+
+ retval = profile_common_read(buf, len, off);
+
+ if ( 0 == retval)
+ {
+ DbgPrintOn = save_DbgPrintOn;
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+
+ up(&LocalPrint_lock);
+ }
+
+ return retval;
+
+}
+
+ssize_t NO_TRACE profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off)
+{
+ ssize_t retval=0;
+ unsigned long offset = *off;
+ static char save_DbgPrintOn;
+
+ if (offset == 0)
+ {
+ down(&LocalPrint_lock);
+ save_DbgPrintOn = DbgPrintOn;
+ DbgPrintOn = 0;
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ profile_dump_dt(Novfs_root, LocalPrint);
+ }
+
+ retval = profile_common_read(buf, len, off);
+
+ if ( 0 == retval)
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ DbgPrintOn = save_DbgPrintOn;
+
+ up(&LocalPrint_lock);
+ }
+
+ return retval;
+
+}
+
+ssize_t NO_TRACE profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off)
+{
+ ssize_t retval=0;
+ unsigned long offset = *off;
+ static char save_DbgPrintOn;
+
+ if (offset == 0)
+ {
+ down(&LocalPrint_lock);
+ save_DbgPrintOn = DbgPrintOn;
+ DbgPrintOn = 0;
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ profile_dump_memorylist( LocalPrint );
+ }
+
+ retval = profile_common_read(buf, len, off);
+
+ if ( 0 == retval)
+ {
+ DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+ DbgPrintOn = save_DbgPrintOn;
+
+ up(&LocalPrint_lock);
+ }
+
+ return retval;
+
+}
+
+uint64_t get_nanosecond_time()
+{
+ struct timespec ts;
+ uint64_t retVal;
+
+ ts = current_kernel_time();
+
+ retVal = (uint64_t)NSEC_PER_SEC;
+ retVal *= (uint64_t)ts.tv_sec;
+ retVal += (uint64_t)ts.tv_nsec;
+
+ return( retVal );
+}
diff -uNr src.old/src/profile_funcs.h src/src/profile_funcs.h
--- src.old/src/profile_funcs.h 1970-01-01 01:00:00.000000000 +0100
+++ src/src/profile_funcs.h 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,415 @@
+extern void Daemon_Added_Resource( void );
+extern void Daemon_Close_Control( void );
+extern void Daemon_CreateSessionId( void );
+extern void Daemon_DestroySessionId( void );
+extern void Daemon_Dumpque( void );
+extern void Daemon_Get_UserSpace( void );
+extern void Daemon_Library_close( void );
+extern void Daemon_Library_ioctl( void );
+extern void Daemon_Library_open( void );
+extern void Daemon_Library_read( void );
+extern void Daemon_Library_write( void );
+extern void Daemon_Login( void );
+extern void Daemon_Logout( void );
+extern void Daemon_Open_Control( void );
+extern void Daemon_Poll( void );
+extern void Daemon_Receive_Reply( void );
+extern void Daemon_Remove_Resource( void );
+extern void Daemon_Send_Command( void );
+extern void Daemon_SetMountPoint( void );
+extern void Daemon_getpwuid( void );
+extern void Daemon_getversion( void );
+extern void Daemon_ioctl( void );
+extern void GetConnData( void );
+extern void GetUserData( void );
+extern void Init_Daemon_Queue( void );
+extern void Init_Procfs_Interface( void );
+extern void Novfs_Add_to_Root( void );
+extern void Novfs_Add_to_Root2( void );
+extern void Novfs_Close_File( void );
+extern void Novfs_Close_Stream( void );
+extern void Novfs_Control_ioctl( void );
+extern void Novfs_Control_read( void );
+extern void Novfs_Control_write( void );
+extern void Novfs_Create( void );
+extern void Novfs_Delete( void );
+extern void Novfs_Find_Name_In_List( void );
+extern void Novfs_Get_Connected_Server_List( void );
+extern void Novfs_Get_Directory_List( void );
+extern void Novfs_Get_Directory_ListEx( void );
+extern void Novfs_Get_File_Info( void );
+extern void Novfs_Get_File_Info2( void );
+extern void Novfs_Get_Server_Volume_List( void );
+extern void Novfs_Get_Version( void );
+extern void Novfs_Open_File( void );
+extern void Novfs_Read_File( void );
+extern void Novfs_Read_Stream( void );
+extern void Novfs_Remove_from_Root( void );
+extern void Novfs_Rename_File( void );
+extern void Novfs_Set_Attr( void );
+extern void Novfs_Truncate_File( void );
+extern void Novfs_User_proc_ioctl( void );
+extern void Novfs_User_proc_read( void );
+extern void Novfs_User_proc_write( void );
+extern void Novfs_Verify_Server_Name( void );
+extern void Novfs_Verify_Volume_Name( void );
+extern void Novfs_Write_File( void );
+extern void Novfs_Write_Stream( void );
+extern void Novfs_a_readpage( void );
+extern void Novfs_add_inode_entry( void );
+extern void Novfs_clear_inode( void );
+extern void Novfs_d_add( void );
+extern void Novfs_d_compare( void );
+extern void Novfs_d_delete( void );
+extern void Novfs_d_hash( void );
+extern void Novfs_d_iput( void );
+extern void Novfs_d_lookup( void );
+extern void Novfs_d_release( void );
+extern void Novfs_d_revalidate( void );
+extern void Novfs_d_strcmp( void );
+extern void Novfs_dget_path( void );
+extern void Novfs_dir_fsync( void );
+extern void Novfs_dir_lseek( void );
+extern void Novfs_dir_open( void );
+extern void Novfs_dir_read( void );
+extern void Novfs_dir_readdir( void );
+extern void Novfs_dir_release( void );
+extern void Novfs_enumerate_inode_cache( void );
+extern void Novfs_f_flush( void );
+extern void Novfs_f_fsync( void );
+extern void Novfs_f_ioctl( void );
+extern void Novfs_f_llseek( void );
+extern void Novfs_f_lock( void );
+extern void Novfs_f_mmap( void );
+extern void Novfs_f_open( void );
+extern void Novfs_f_read( void );
+extern void Novfs_f_readdir( void );
+extern void Novfs_f_release( void );
+extern void Novfs_f_write( void );
+extern void Novfs_fill_super( void );
+extern void Novfs_free_inode_cache( void );
+extern void Novfs_free_invalid_entries( void );
+extern void Novfs_get_alltrees( void );
+extern void Novfs_get_entry( void );
+extern void Novfs_get_entry_time( void );
+extern void Novfs_get_inode( void );
+extern void Novfs_get_remove_entry( void );
+extern void Novfs_get_sb( void );
+extern void Novfs_i_create( void );
+extern void Novfs_i_getattr( void );
+extern void Novfs_i_lookup( void );
+extern void Novfs_i_mkdir( void );
+extern void Novfs_i_mknod( void );
+extern void Novfs_i_permission( void );
+extern void Novfs_i_rename( void );
+extern void Novfs_i_revalidate( void );
+extern void Novfs_i_rmdir( void );
+extern void Novfs_i_setattr( void );
+extern void Novfs_i_unlink( void );
+extern void Novfs_internal_hash( void );
+extern void Novfs_invalidate_inode_cache( void );
+extern void Novfs_kill_sb( void );
+extern void Novfs_lock_inode_cache( void );
+extern void Novfs_lookup_inode_cache( void );
+extern void Novfs_lookup_validate( void );
+extern void Novfs_notify_change( void );
+extern void Novfs_read_inode( void );
+extern void Novfs_remove_inode_entry( void );
+extern void Novfs_show_options( void );
+extern void Novfs_statfs( void );
+extern void Novfs_tree_read( void );
+extern void Novfs_unlock_inode_cache( void );
+extern void Novfs_update_entry( void );
+extern void Novfs_verify_file( void );
+extern void Novfs_write_inode( void );
+extern void NwAuthConnWithId( void );
+extern void NwConnClose( void );
+extern void NwGetConnInfo( void );
+extern void NwGetDaemonVersion( void );
+extern void NwGetIdentityInfo( void );
+extern void NwLicenseConn( void );
+extern void NwLoginIdentity( void );
+extern void NwLogoutIdentity( void );
+extern void NwOpenConnByAddr( void );
+extern void NwOpenConnByName( void );
+extern void NwOpenConnByRef( void );
+extern void NwQueryFeature( void );
+extern void NwRawSend( void );
+extern void NwScanConnInfo( void );
+extern void NwSetConnInfo( void );
+extern void NwSysConnClose( void );
+extern void NwUnAuthenticate( void );
+extern void NwUnlicenseConn( void );
+extern void NwcChangeAuthKey( void );
+extern void NwcEnumIdentities( void );
+extern void NwcEnumerateDrives( void );
+extern void NwcGetBroadcastMessage( void );
+extern void NwcGetDefaultNameCtx( void );
+extern void NwcGetPreferredDSTree( void );
+extern void NwcGetPrimaryConn( void );
+extern void NwcGetTreeMonitoredConn( void );
+extern void NwcSetDefaultNameCtx( void );
+extern void NwcSetMapDrive( void );
+extern void NwcSetPreferredDSTree( void );
+extern void NwcSetPrimaryConn( void );
+extern void NwcUnMapDrive( void );
+extern void NwdConvertLocalHandle( void );
+extern void NwdConvertNetwareHandle( void );
+extern void NwdGetMountPath( void );
+extern void NwdSetKeyValue( void );
+extern void NwdSetMapDrive( void );
+extern void NwdUnMapDrive( void );
+extern void NwdVerifyKeyValue( void );
+extern void Queue_Daemon_Command( void );
+extern void Queue_get( void );
+extern void Queue_put( void );
+extern void RemoveDriveMaps( void );
+extern void Scope_Cleanup( void );
+extern void Scope_Cleanup_Thread( void );
+extern void Scope_Dump_Scopetable( void );
+extern void Scope_Dump_Tasklist( void );
+extern void Scope_Find_Scope( void );
+extern void Scope_Get_Hash( void );
+extern void Scope_Get_ScopeUsers( void );
+extern void Scope_Get_ScopefromName( void );
+extern void Scope_Get_ScopefromPath( void );
+extern void Scope_Get_SessionId( void );
+extern void Scope_Get_Uid( void );
+extern void Scope_Get_UserName( void );
+extern void Scope_Get_UserSpace( void );
+extern void Scope_Init( void );
+extern void Scope_Lookup( void );
+extern void Scope_Search4Scope( void );
+extern void Scope_Set_UserSpace( void );
+extern void Scope_Timer_Function( void );
+extern void Scope_Uninit( void );
+extern void Scope_Validate_Scope( void );
+extern void Uninit_Daemon_Queue( void );
+extern void Uninit_Procfs_Interface( void );
+extern void add_to_list( void );
+extern void begin_directory_enumerate( void );
+extern void directory_enumerate( void );
+extern void directory_enumerate_ex( void );
+extern void do_login( void );
+extern void do_logout( void );
+extern void end_directory_enumerate( void );
+extern void exit_novfs( void );
+extern void find_queue( void );
+extern void get_next_queue( void );
+extern void init_novfs( void );
+extern void local_unlink( void );
+extern void process_list( void );
+extern void update_inode( void );
+extern void verify_dentry( void );
+
+SYMBOL_TABLE SymbolTable[] = {
+ {Scope_Get_UserSpace, "Scope_Get_UserSpace"},
+ {NwLoginIdentity, "NwLoginIdentity"},
+ {Novfs_d_revalidate, "Novfs_d_revalidate"},
+ {Daemon_SetMountPoint, "Daemon_SetMountPoint"},
+ {Scope_Get_Hash, "Scope_Get_Hash"},
+ {Queue_get, "Queue_get"},
+ {Queue_Daemon_Command, "Queue_Daemon_Command"},
+ {Novfs_dir_fsync, "Novfs_dir_fsync"},
+ {Novfs_Read_File, "Novfs_Read_File"},
+ {Daemon_Library_close, "Daemon_Library_close"},
+ {NwRawSend, "NwRawSend"},
+ {Novfs_get_inode, "Novfs_get_inode"},
+ {Novfs_Remove_from_Root, "Novfs_Remove_from_Root"},
+ {Novfs_Find_Name_In_List, "Novfs_Find_Name_In_List"},
+ {Scope_Get_SessionId, "Scope_Get_SessionId"},
+ {NwOpenConnByAddr, "NwOpenConnByAddr"},
+ {Novfs_read_inode, "Novfs_read_inode"},
+ {Novfs_Truncate_File, "Novfs_Truncate_File"},
+ {Daemon_Login, "Daemon_Login"},
+ {Scope_Get_ScopefromPath, "Scope_Get_ScopefromPath"},
+ {NwcGetTreeMonitoredConn, "NwcGetTreeMonitoredConn"},
+ {Novfs_write_inode, "Novfs_write_inode"},
+ {Scope_Lookup, "Scope_Lookup"},
+ {NwQueryFeature, "NwQueryFeature"},
+ {Novfs_get_entry_time, "Novfs_get_entry_time"},
+ {Novfs_Control_write, "Novfs_Control_write"},
+ {Scope_Get_Uid, "Scope_Get_Uid"},
+ {NwSysConnClose, "NwSysConnClose"},
+ {NwConnClose, "NwConnClose"},
+ {Novfs_get_entry, "Novfs_get_entry"},
+ {Novfs_Rename_File, "Novfs_Rename_File"},
+ {NwdConvertLocalHandle, "NwdConvertLocalHandle"},
+ {Novfs_dir_lseek, "Novfs_dir_lseek"},
+ {Scope_Get_ScopefromName, "Scope_Get_ScopefromName"},
+ {NwcGetPrimaryConn, "NwcGetPrimaryConn"},
+ {Novfs_d_strcmp, "Novfs_d_strcmp"},
+ {Daemon_Library_ioctl, "Daemon_Library_ioctl"},
+ {end_directory_enumerate, "end_directory_enumerate"},
+ {directory_enumerate, "directory_enumerate"},
+ {begin_directory_enumerate, "begin_directory_enumerate"},
+ {NwdGetMountPath, "NwdGetMountPath"},
+ {NwAuthConnWithId, "NwAuthConnWithId"},
+ {Novfs_Set_Attr, "Novfs_Set_Attr"},
+ {Daemon_getversion, "Daemon_getversion"},
+ {Scope_Dump_Scopetable, "Scope_Dump_Scopetable"},
+ {NwcSetMapDrive, "NwcSetMapDrive"},
+ {Novfs_lookup_inode_cache, "Novfs_lookup_inode_cache"},
+ {Novfs_i_mkdir, "Novfs_i_mkdir"},
+ {Novfs_free_invalid_entries, "Novfs_free_invalid_entries"},
+ {Novfs_dump_inode_cache, "Novfs_dump_inode_cache"},
+ {Novfs_Write_Stream, "Novfs_Write_Stream"},
+ {Novfs_Verify_Server_Name, "Novfs_Verify_Server_Name"},
+ {GetConnData, "GetConnData"},
+ {Uninit_Procfs_Interface, "Uninit_Procfs_Interface"},
+ {Scope_Validate_Scope, "Scope_Validate_Scope"},
+ {Scope_Timer_Function, "Scope_Timer_Function"},
+ {Novfs_i_setattr, "Novfs_i_setattr"},
+ {Novfs_i_mknod, "Novfs_i_mknod"},
+ {Novfs_Verify_Volume_Name, "Novfs_Verify_Volume_Name"},
+ {Novfs_Close_Stream, "Novfs_Close_Stream"},
+ {Novfs_Add_to_Root, "Novfs_Add_to_Root"},
+ {Init_Procfs_Interface, "Init_Procfs_Interface"},
+ {Novfs_dump_inode, "Novfs_dump_inode"},
+ {Novfs_Get_Directory_List, "Novfs_Get_Directory_List"},
+ {Novfs_Get_Connected_Server_List, "Novfs_Get_Connected_Server_List"},
+ {Daemon_Logout, "Daemon_Logout"},
+ {do_logout, "do_logout"},
+ {Scope_Search4Scope, "Scope_Search4Scope"},
+ {NwdUnMapDrive, "NwdUnMapDrive"},
+ {Novfs_Control_read, "Novfs_Control_read"},
+ {Scope_Cleanup_Thread, "Scope_Cleanup_Thread"},
+ {Novfs_invalidate_inode_cache, "Novfs_invalidate_inode_cache"},
+ {Novfs_f_flush, "Novfs_f_flush"},
+ {Novfs_enumerate_inode_cache, "Novfs_enumerate_inode_cache"},
+ {Novfs_d_compare, "Novfs_d_compare"},
+ {Daemon_Library_write, "Daemon_Library_write"},
+ {GetUserData, "GetUserData"},
+ {Daemon_Remove_Resource, "Daemon_Remove_Resource"},
+ {Scope_Set_UserSpace, "Scope_Set_UserSpace"},
+ {Novfs_get_alltrees, "Novfs_get_alltrees"},
+ {Daemon_Get_UserSpace, "Daemon_Get_UserSpace"},
+ {Uninit_Daemon_Queue, "Uninit_Daemon_Queue"},
+ {NwcChangeAuthKey, "NwcChangeAuthKey"},
+ {NwLicenseConn, "NwLicenseConn"},
+ {Init_Daemon_Queue, "Init_Daemon_Queue"},
+ {Novfs_tree_read, "Novfs_tree_read"},
+ {Novfs_f_llseek, "Novfs_f_llseek"},
+ {find_queue, "find_queue"},
+ {Scope_Find_Scope, "Scope_Find_Scope"},
+ {Novfs_lookup_validate, "Novfs_lookup_validate"},
+ {Novfs_d_hash, "Novfs_d_hash"},
+ {Novfs_a_readpage, "Novfs_a_readpage"},
+ {Novfs_Create, "Novfs_Create"},
+ {Novfs_Close_File, "Novfs_Close_File"},
+ {Daemon_getpwuid, "Daemon_getpwuid"},
+ {Daemon_CreateSessionId, "Daemon_CreateSessionId"},
+ {Scope_dget_path, "Scope_dget_path"},
+ {NwcSetDefaultNameCtx, "NwcSetDefaultNameCtx"},
+ {NwcGetDefaultNameCtx, "NwcGetDefaultNameCtx"},
+ {NwUnAuthenticate, "NwUnAuthenticate"},
+ {Novfs_i_getattr, "Novfs_i_getattr"},
+ {Novfs_get_remove_entry, "Novfs_get_remove_entry"},
+ {Novfs_f_ioctl, "Novfs_f_ioctl"},
+ {Scope_Get_ScopeUsers, "Scope_Get_ScopeUsers"},
+ {Scope_Dump_Tasklist, "Scope_Dump_Tasklist"},
+ {NwOpenConnByRef, "NwOpenConnByRef"},
+ {Novfs_unlock_inode_cache, "Novfs_unlock_inode_cache"},
+ {Novfs_lock_inode_cache, "Novfs_lock_inode_cache"},
+ {Daemon_DestroySessionId, "Daemon_DestroySessionId"},
+ {do_login, "do_login"},
+ {Novfs_free_inode_cache, "Novfs_free_inode_cache"},
+ {Novfs_Read_Stream, "Novfs_Read_Stream"},
+ {Daemon_Library_read, "Daemon_Library_read"},
+ {NwdSetMapDrive, "NwdSetMapDrive"},
+ {Novfs_internal_hash, "Novfs_internal_hash"},
+ {Daemon_Receive_Reply, "Daemon_Receive_Reply"},
+ {Daemon_Library_open, "Daemon_Library_open"},
+ {get_next_queue, "get_next_queue"},
+ {exit_novfs, "exit_novfs"},
+ {NwcGetBroadcastMessage, "NwcGetBroadcastMessage"},
+ {Novfs_d_lookup, "Novfs_d_lookup"},
+ {Novfs_clear_inode, "Novfs_clear_inode"},
+ {Daemon_Open_Control, "Daemon_Open_Control"},
+ {NwdConvertNetwareHandle, "NwdConvertNetwareHandle"},
+ {NwcUnMapDrive, "NwcUnMapDrive"},
+ {Novfs_notify_change, "Novfs_notify_change"},
+ {Novfs_dir_release, "Novfs_dir_release"},
+ {directory_enumerate_ex, "directory_enumerate_ex"},
+ {RemoveDriveMaps, "RemoveDriveMaps"},
+ {NwOpenConnByName, "NwOpenConnByName"},
+ {Novfs_verify_file, "Novfs_verify_file"},
+ {Novfs_statfs, "Novfs_statfs"},
+ {Novfs_f_write, "Novfs_f_write"},
+ {Novfs_Get_File_Info, "Novfs_Get_File_Info"},
+ {Novfs_Delete, "Novfs_Delete"},
+ {update_inode, "update_inode"},
+ {NwcSetPreferredDSTree, "NwcSetPreferredDSTree"},
+ {NwcGetPreferredDSTree, "NwcGetPreferredDSTree"},
+ {Novfs_update_entry, "Novfs_update_entry"},
+ {Novfs_kill_sb, "Novfs_kill_sb"},
+ {Daemon_ioctl, "Daemon_ioctl"},
+ {Scope_Get_UserName, "Scope_Get_UserName"},
+ {NwcEnumerateDrives, "NwcEnumerateDrives"},
+ {Novfs_i_revalidate, "Novfs_i_revalidate"},
+ {Novfs_f_release, "Novfs_f_release"},
+ {Novfs_f_read, "Novfs_f_read"},
+ {Novfs_d_delete, "Novfs_d_delete"},
+ {Novfs_Write_File, "Novfs_Write_File"},
+ {Novfs_User_proc_ioctl, "Novfs_User_proc_ioctl"},
+ {Novfs_Get_File_Info2, "Novfs_Get_File_Info2"},
+ {NwdSetKeyValue, "NwdSetKeyValue"},
+ {Novfs_remove_inode_entry, "Novfs_remove_inode_entry"},
+ {Novfs_i_rename, "Novfs_i_rename"},
+ {Novfs_f_open, "Novfs_f_open"},
+ {Novfs_d_iput, "Novfs_d_iput"},
+ {Novfs_Get_Directory_ListEx, "Novfs_Get_Directory_ListEx"},
+ {Daemon_Close_Control, "Daemon_Close_Control"},
+ {verify_dentry, "verify_dentry"},
+ {process_list, "process_list"},
+ {local_unlink, "local_unlink"},
+ {init_novfs, "init_novfs"},
+ {NwUnlicenseConn, "NwUnlicenseConn"},
+ {NwGetConnInfo, "NwGetConnInfo"},
+ {Novfs_i_permission, "Novfs_i_permission"},
+ {Novfs_dir_read, "Novfs_dir_read"},
+ {NwcSetPrimaryConn, "NwcSetPrimaryConn"},
+ {Novfs_f_lock, "Novfs_f_lock"},
+ {Novfs_dir_readdir, "Novfs_dir_readdir"},
+ {Novfs_dir_open, "Novfs_dir_open"},
+ {Queue_put, "Queue_put"},
+ {NwLogoutIdentity, "NwLogoutIdentity"},
+ {NwGetIdentityInfo, "NwGetIdentityInfo"},
+ {Novfs_i_rmdir, "Novfs_i_rmdir"},
+ {Novfs_i_create, "Novfs_i_create"},
+ {Novfs_f_mmap, "Novfs_f_mmap"},
+ {Novfs_User_proc_read, "Novfs_User_proc_read"},
+ {Novfs_show_options, "Novfs_show_options"},
+ {Novfs_add_inode_entry, "Novfs_add_inode_entry"},
+ {Novfs_Open_File, "Novfs_Open_File"},
+ {Novfs_Get_Version, "Novfs_Get_Version"},
+ {Daemon_Poll, "Daemon_Poll"},
+ {add_to_list, "add_to_list"},
+ {Scope_Init, "Scope_Init"},
+ {Scope_Cleanup, "Scope_Cleanup"},
+ {NwSetConnInfo, "NwSetConnInfo"},
+ {Novfs_i_unlink, "Novfs_i_unlink"},
+ {Novfs_get_sb, "Novfs_get_sb"},
+ {Novfs_f_readdir, "Novfs_f_readdir"},
+ {Novfs_f_fsync, "Novfs_f_fsync"},
+ {Novfs_d_release, "Novfs_d_release"},
+ {Novfs_User_proc_write, "Novfs_User_proc_write"},
+ {Daemon_Send_Command, "Daemon_Send_Command"},
+ {Daemon_Dumpque, "Daemon_Dumpque"},
+ {NwcEnumIdentities, "NwcEnumIdentities"},
+ {NwGetDaemonVersion, "NwGetDaemonVersion"},
+ {Novfs_i_lookup, "Novfs_i_lookup"},
+ {Novfs_fill_super, "Novfs_fill_super"},
+ {Novfs_Get_Server_Volume_List, "Novfs_Get_Server_Volume_List"},
+ {Novfs_Add_to_Root2, "Novfs_Add_to_Root2"},
+ {Daemon_SendDebugCmd, "Daemon_SendDebugCmd"},
+ {Daemon_Added_Resource, "Daemon_Added_Resource"},
+ {Scope_Uninit, "Scope_Uninit"},
+ {NwdVerifyKeyValue, "NwdVerifyKeyValue"},
+ {NwScanConnInfo, "NwScanConnInfo"},
+ {Novfs_dget_path, "Novfs_dget_path"},
+ {Novfs_d_add, "Novfs_d_add"},
+ {Novfs_Control_ioctl, "Novfs_Control_ioctl"},
+ // Terminate the table
+ {NULL, NULL}
+};
diff -uNr src.old/src/scope.c src/src/scope.c
--- src.old/src/scope.c 1970-01-01 01:00:00.000000000 +0100
+++ src/src/scope.c 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,1214 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: scope.c
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: This module contains functions used to scope
+ * users.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+
+/*===[ Include files specific to Linux ]==================================*/
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/sched.h>
+#include <linux/personality.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/synclink.h>
+#include <linux/smp_lock.h>
+#include <asm/semaphore.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+
+/*===[ Include files specific to this module ]============================*/
+#include "vfs.h"
+#define LEADER signal->leader
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+ typedef struct task_struct task_t;
+#endif
+
+/*===[ External data ]====================================================*/
+
+/*===[ External prototypes ]==============================================*/
+extern int DbgPrint( char *Fmt, ... );
+extern int Daemon_CreateSessionId( uint64_t *SessionId );
+extern int Daemon_DestroySessionId( uint64_t SessionId );
+extern int Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
+extern int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
+
+extern int Novfs_Remove_from_Root(char *);
+extern int Novfs_Add_to_Root(char *);
+
+/*===[ Manifest constants ]===============================================*/
+#define CLEANUP_INTERVAL 10
+#define MAX_USERNAME_LENGTH 32
+
+/*===[ Type definitions ]=================================================*/
+typedef struct _SCOPE_LIST_
+{
+ struct list_head ScopeList;
+ scope_t ScopeId;
+ session_t SessionId;
+ pid_t ScopePid;
+ task_t *ScopeTask;
+ unsigned long ScopeHash;
+ uid_t ScopeUid;
+ uint64_t ScopeUSize;
+ uint64_t ScopeUFree;
+ uint64_t ScopeUTEnties;
+ uint64_t ScopeUAEnties;
+ int ScopeUserNameLength;
+ unsigned char ScopeUserName[MAX_USERNAME_LENGTH];
+} SCOPE_LIST, *PSCOPE_LIST;
+
+/*===[ Function prototypes ]==============================================*/
+void Scope_Init( void );
+void Scope_Uninit( void );
+
+PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked );
+PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create );
+unsigned long Scope_Get_Hash( PSCOPE_LIST Scope );
+uid_t Scope_Get_Uid( PSCOPE_LIST Scope );
+int Scope_Validate_Scope( PSCOPE_LIST Scope );
+char *Scope_Get_UserName( PSCOPE_LIST Scope );
+session_t Scope_Get_SessionId( PSCOPE_LIST Scope );
+PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name );
+int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+
+char *Scope_Get_ScopeUsers( void );
+void *Scope_Lookup( void );
+
+void Scope_Timer_Function(unsigned long Context);
+int Scope_Cleanup_Thread(void *Args);
+void Scope_Cleanup( void );
+char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
+void Scope_Dump_Tasklist( void );
+void Scope_Dump_Scopetable( void );
+
+/*===[ Global variables ]=================================================*/
+struct list_head Scope_List;
+struct semaphore Scope_Lock;
+struct semaphore Scope_Thread_Delay;
+int Scope_Thread_Terminate=0;
+struct semaphore Scope_Delay_Event;
+struct timer_list Scope_Timer;
+unsigned long Scope_Hash_Val=1;
+
+/*===[ Code ]=============================================================*/
+
+/*++======================================================================*/
+void Scope_Init( void )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ INIT_LIST_HEAD( &Scope_List );
+ init_MUTEX( &Scope_Lock );
+ init_MUTEX_LOCKED( &Scope_Thread_Delay );
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
+ kernel_thread( Scope_Cleanup_Thread, NULL, 0 );
+#else
+ kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST");
+#endif
+}
+
+/*++======================================================================*/
+void Scope_Uninit( void )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ Scope_Thread_Terminate = 1;
+
+ up(&Scope_Thread_Delay);
+
+ mb();
+ while( Scope_Thread_Terminate )
+ {
+ yield();
+ }
+ printk( KERN_INFO "Scope_Uninit: Exit\n");
+
+}
+
+/*++======================================================================*/
+PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope, rscope=NULL;
+ struct list_head *sl;
+ int offset;
+
+ DbgPrint("Scope_Search4Scope: 0x%llx 0x%x 0x%x\n", Id, Session, Locked);
+
+ if ( Session )
+ {
+ offset = (int)(&((PSCOPE_LIST)0)->SessionId);
+ }
+ else
+ {
+ offset = (int)(&((PSCOPE_LIST)0)->ScopeId);
+ }
+
+ if ( !Locked )
+ {
+ down( &Scope_Lock );
+ }
+
+ sl = Scope_List.next;
+ DbgPrint("Scope_Search4Scope: 0x%x\n", sl);
+ while (sl != &Scope_List)
+ {
+ scope = list_entry(sl, SCOPE_LIST, ScopeList);
+
+ if ( Id == *(session_t *)((char *)scope+offset) )
+ {
+ rscope = scope;
+ break;
+ }
+
+ sl = sl->next;
+ }
+
+ if ( !Locked )
+ {
+ up( &Scope_Lock );
+ }
+
+ DbgPrint("Scope_Search4Scope: return 0x%x\n", rscope);
+ return( rscope );
+}
+
+/*++======================================================================*/
+PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope=NULL, pscope=NULL;
+ task_t *task;
+ scope_t scopeId;
+ int addscope=0;
+
+ task = current;
+
+ DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
+
+ scopeId = task->euid;
+
+ scope = Scope_Search4Scope( scopeId, FALSE, FALSE );
+
+ if ( !scope && Create )
+ {
+ scope = Novfs_Malloc( sizeof(*pscope), GFP_KERNEL );
+ if ( scope )
+ {
+ scope->ScopeId = scopeId;
+ scope->SessionId = 0;
+ scope->ScopePid = task->pid;
+ scope->ScopeTask = task;
+ scope->ScopeHash = 0;
+ scope->ScopeUid = task->euid;
+ scope->ScopeUserName[0] = '\0';
+
+ if ( !Daemon_CreateSessionId( &scope->SessionId ) )
+ {
+ DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
+ memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName));
+ scope->ScopeUserNameLength = 0;
+ Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), scope->ScopeUserName);
+ scope->ScopeUserNameLength = strlen(scope->ScopeUserName);
+ addscope = 1;
+ }
+
+ scope->ScopeHash = Scope_Hash_Val++;
+ DbgPrint("Scope_Find_Scope: Adding 0x%x\n" \
+ " ScopeId: 0x%llx\n" \
+ " SessionId: 0x%llx\n" \
+ " ScopePid: %d\n" \
+ " ScopeTask: 0x%x\n" \
+ " ScopeHash: %d\n" \
+ " ScopeUid: %d\n" \
+ " ScopeUserNameLength: %d\n" \
+ " ScopeUserName: %s\n",
+ scope,
+ scope->ScopeId,
+ scope->SessionId,
+ scope->ScopePid,
+ scope->ScopeTask,
+ scope->ScopeHash,
+ scope->ScopeUid,
+ scope->ScopeUserNameLength,
+ scope->ScopeUserName);
+
+ if ( scope->SessionId )
+ {
+ down( &Scope_Lock );
+ list_add(&scope->ScopeList, &Scope_List);
+ up( &Scope_Lock );
+ }
+ else
+ {
+ Novfs_Free(scope);
+ scope = NULL;
+ }
+ }
+
+ if (addscope)
+ {
+ Novfs_Add_to_Root( scope->ScopeUserName );
+ }
+ }
+
+ return(scope);
+}
+
+/*++======================================================================*/
+unsigned long Scope_Get_Hash( PSCOPE_LIST Scope )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ unsigned long hash=0;
+
+ if ( NULL == Scope)
+ {
+ Scope = Scope_Find_Scope( TRUE );
+ }
+
+ if ( Scope && Scope_Validate_Scope( Scope ))
+ {
+ hash = Scope->ScopeHash;
+ }
+ return( hash );
+}
+
+/*++======================================================================*/
+uid_t Scope_Get_Uid( PSCOPE_LIST Scope )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ uid_t uid=0;
+
+ if ( NULL == Scope)
+ {
+ Scope = Scope_Find_Scope( TRUE );
+ }
+
+ if ( Scope && Scope_Validate_Scope( Scope ))
+ {
+ uid = Scope->ScopeUid;
+ }
+ return( uid );
+}
+
+/*++======================================================================*/
+int Scope_Validate_Scope( PSCOPE_LIST Scope )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST s;
+ struct list_head *sl;
+ int retVal = 0;
+
+ DbgPrint("Scope_Validate_Scope: 0x%x\n", Scope);
+
+ down( &Scope_Lock );
+
+ sl = Scope_List.next;
+ while (sl != &Scope_List)
+ {
+ s = list_entry(sl, SCOPE_LIST, ScopeList);
+
+ if ( s == Scope )
+ {
+ retVal = 1;
+ break;
+ }
+
+ sl = sl->next;
+ }
+
+ up( &Scope_Lock );
+
+ return( retVal );
+}
+
+/*++======================================================================*/
+char *Scope_Get_UserName( PSCOPE_LIST Scope )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *name=NULL;
+
+ if ( !Scope )
+ {
+ Scope = Scope_Find_Scope( TRUE );
+ }
+
+ if ( Scope && Scope_Validate_Scope( Scope ))
+ {
+ name = Scope->ScopeUserName;
+ }
+ return( name );
+}
+
+/*++======================================================================*/
+session_t Scope_Get_SessionId( PSCOPE_LIST Scope )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ session_t sessionId=0;
+
+ DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope);
+ if ( !Scope )
+ {
+ Scope = Scope_Find_Scope( TRUE );
+ }
+
+ if ( Scope && Scope_Validate_Scope( Scope ))
+ {
+ sessionId = Scope->SessionId;
+ }
+ DbgPrint("Scope_Get_SessionId: return 0x%llx\n", sessionId);
+ return( sessionId );
+}
+
+/*++======================================================================*/
+PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope, rscope=NULL;
+ struct list_head *sl;
+
+ DbgPrint("Scope_Get_ScopefromName: %.*s\n", Name->len, Name->name);
+
+ down( &Scope_Lock );
+
+ sl = Scope_List.next;
+ while (sl != &Scope_List)
+ {
+ scope = list_entry(sl, SCOPE_LIST, ScopeList);
+
+ if ( (Name->len == scope->ScopeUserNameLength) &&
+ (0 == strncmp(scope->ScopeUserName, Name->name, Name->len)) )
+ {
+ rscope = scope;
+ break;
+ }
+
+ sl = sl->next;
+ }
+
+ up( &Scope_Lock );
+
+ return( rscope );
+}
+
+/*++======================================================================*/
+int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope;
+ int retVal=0;
+
+ scope = Scope_Find_Scope( TRUE );
+
+ if ( scope )
+ {
+ if (TotalSize) scope->ScopeUSize = *TotalSize;
+ if (Free) scope->ScopeUFree = *Free;
+ if (TotalEnties) scope->ScopeUTEnties = *TotalEnties;
+ if (FreeEnties) scope->ScopeUAEnties = *FreeEnties;
+ }
+
+
+ return( retVal );
+}
+
+/*++======================================================================*/
+int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope;
+ int retVal=0;
+
+ uint64_t td, fd, te, fe;
+
+ scope = Scope_Find_Scope( TRUE );
+
+ td = fd = te = fe = 0;
+ if ( scope )
+ {
+
+ retVal = Daemon_Get_UserSpace(scope->SessionId, &td, &fd, &te, &fe);
+
+ scope->ScopeUSize = td;
+ scope->ScopeUFree = fd;
+ scope->ScopeUTEnties = te;
+ scope->ScopeUAEnties = fe;
+ }
+
+ if (TotalSize) *TotalSize = td;
+ if (Free) *Free = fd;
+ if (TotalEnties) *TotalEnties = te;
+ if (FreeEnties) *FreeEnties = fe;
+
+ return( retVal );
+}
+
+/*++======================================================================*/
+PSCOPE_LIST Scope_Get_ScopefromPath( struct dentry *Dentry )
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope=NULL;
+ char *buf, *path, *cp;
+ struct qstr name;
+
+ buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+ if (buf)
+ {
+ path = Scope_dget_path( Dentry, buf, PATH_LENGTH_BUFFER, 0 );
+ if (path)
+ {
+ DbgPrint("Scope_Get_ScopefromPath: %s\n", path );
+
+ if (*path == '/') path++;
+
+ cp = path;
+ if ( *cp )
+ {
+ while ( *cp && (*cp != '/') ) cp++;
+
+ *cp = '\0';
+ name.hash = 0;
+ name.len = (int)(cp-path);
+ name.name = path;
+ scope = Scope_Get_ScopefromName( &name );
+ }
+ }
+ Novfs_Free(buf);
+ }
+
+ return( scope );
+}
+
+/*++======================================================================*/
+char *add_to_list(char *Name, char *List, char *EndOfList)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ while (*Name && (List < EndOfList) )
+ {
+ *List++ = *Name++;
+ }
+
+ if (List < EndOfList)
+ {
+ *List++ = '\0';
+ }
+ return(List);
+}
+
+/*++======================================================================*/
+char *Scope_Get_ScopeUsers()
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope;
+ struct list_head *sl;
+ int asize=8*MAX_USERNAME_LENGTH;
+ char *list, *cp, *ep;
+
+ DbgPrint("Scope_Get_ScopeUsers\n");
+
+ do /* Copy list until done or out of memory */
+ {
+ list = Novfs_Malloc(asize, GFP_KERNEL);
+
+ DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list);
+ if (list)
+ {
+ cp = list;
+ ep = cp+asize;
+
+ /*
+ * Add the tree and server entries
+ */
+ cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep);
+ cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep);
+
+ down( &Scope_Lock );
+
+ sl = Scope_List.next;
+ while ( (sl != &Scope_List) && (cp < ep) )
+ {
+ scope = list_entry(sl, SCOPE_LIST, ScopeList);
+
+ DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", scope, scope->ScopeUserName);
+
+ cp = add_to_list(scope->ScopeUserName, cp, ep);
+
+ sl = sl->next;
+ }
+
+ up( &Scope_Lock );
+
+ if (cp < ep)
+ {
+ *cp++ = '\0';
+ asize = 0;
+ }
+ else /* Allocation was to small, up size */
+ {
+ asize *= 4;
+ Novfs_Free(list);
+ list=NULL;
+ }
+ }
+ else /* if allocation fails return an empty list */
+ {
+ break;
+ }
+ } while ( !list ); /* List was to small try again */
+
+ return( list );
+}
+
+/*++======================================================================*/
+void *Scope_Lookup()
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope;
+
+ scope = Scope_Find_Scope( TRUE );
+ return( scope );
+}
+
+/*++======================================================================*/
+void
+NO_TRACE
+Scope_Timer_Function(unsigned long Context)
+/*
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ up(&Scope_Thread_Delay);
+}
+
+/*++======================================================================*/
+int Scope_Cleanup_Thread(void *Args)
+/*
+ *
+ * Arguments:
+ *
+ * Returns:
+ *
+ * Abstract:
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope, rscope;
+ struct list_head *sl, cleanup;
+ task_t *task;
+
+ DbgPrint( "Scope_Cleanup_Thread: %d\n", current->pid);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
+ lock_kernel();
+ snprintf(current->comm, 16, "novfs_ST");
+ unlock_kernel();
+ sys_close(0);
+ sys_close(1);
+ sys_close(2);
+#endif
+
+ /*
+ * Setup and start que timer
+ */
+ init_timer( &Scope_Timer );
+
+ for ( ;; )
+ {
+ DbgPrint( "Scope_Cleanup_Thread: looping\n");
+ if ( Scope_Thread_Terminate )
+ {
+ break;
+ }
+
+ /*
+ * Check scope list for any terminated processes
+ */
+ down( &Scope_Lock );
+
+ sl = Scope_List.next;
+ INIT_LIST_HEAD( &cleanup );
+
+ while (sl != &Scope_List)
+ {
+ scope = list_entry(sl, SCOPE_LIST, ScopeList);
+ sl = sl->next;
+
+ rscope = NULL;
+ read_lock(&tasklist_lock);
+ for_each_process(task)
+ {
+ if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) )
+ {
+ rscope = scope;
+ break;
+ }
+ }
+ read_unlock(&tasklist_lock);
+ if ( !rscope )
+ {
+ list_move( &scope->ScopeList, &cleanup );
+ DbgPrint("Scope_Cleanup_Thread: Scope=0x%x\n", rscope);
+ }
+ }
+
+ up(&Scope_Lock);
+
+ sl = cleanup.next;
+ while ( sl != &cleanup )
+ {
+ scope = list_entry(sl, SCOPE_LIST, ScopeList);
+ sl = sl->next;
+
+ DbgPrint("Scope_Cleanup_Thread: Removing 0x%x\n" \
+ " ScopeId: 0x%llx\n" \
+ " SessionId: 0x%llx\n" \
+ " ScopePid: %d\n" \
+ " ScopeTask: 0x%x\n" \
+ " ScopeHash: %d\n" \
+ " ScopeUid: %d\n" \
+ " ScopeUserName: %s\n",
+ scope,
+ scope->ScopeId,
+ scope->SessionId,
+ scope->ScopePid,
+ scope->ScopeTask,
+ scope->ScopeHash,
+ scope->ScopeUid,
+ scope->ScopeUserName);
+ if ( !Scope_Search4Scope(scope->SessionId, TRUE, FALSE) )
+ {
+ Novfs_Remove_from_Root( scope->ScopeUserName );
+ Daemon_DestroySessionId( scope->SessionId );
+ }
+ Novfs_Free( scope );
+ }
+
+ Scope_Timer.expires = jiffies + HZ*CLEANUP_INTERVAL;
+ Scope_Timer.data = (unsigned long)0;
+ Scope_Timer.function = Scope_Timer_Function;
+ add_timer(&Scope_Timer);
+ DbgPrint( "Scope_Cleanup_Thread: sleeping\n");
+
+ if (down_interruptible( &Scope_Thread_Delay ))
+ {
+ break;
+ }
+ del_timer(&Scope_Timer);
+ }
+ Scope_Thread_Terminate = 0;
+
+ printk( KERN_INFO "Scope_Cleanup_Thread: Exit\n");
+ DbgPrint( "Scope_Cleanup_Thread: Exit\n");
+ return(0);
+}
+
+/*++======================================================================*/
+void Scope_Cleanup( void )
+/*
+ *
+ * Arguments: None
+ *
+ * Returns: Nothing
+ *
+ * Abstract: Removes all knows scopes.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ PSCOPE_LIST scope;
+ struct list_head *sl;
+
+ DbgPrint( "Scope_Cleanup:\n");
+
+ /*
+ * Check scope list for any terminated processes
+ */
+ down( &Scope_Lock );
+
+ sl = Scope_List.next;
+
+ while (sl != &Scope_List)
+ {
+ scope = list_entry( sl, SCOPE_LIST, ScopeList );
+ sl = sl->next;
+
+ list_del( &scope->ScopeList );
+
+ DbgPrint("Scope_Cleanup: Removing 0x%x\n" \
+ " ScopeId: 0x%llx\n" \
+ " SessionId: 0x%llx\n" \
+ " ScopePid: %d\n" \
+ " ScopeTask: 0x%x\n" \
+ " ScopeHash: %d\n" \
+ " ScopeUid: %d\n" \
+ " ScopeUserName: %s\n",
+ scope,
+ scope->ScopeId,
+ scope->SessionId,
+ scope->ScopePid,
+ scope->ScopeTask,
+ scope->ScopeHash,
+ scope->ScopeUid,
+ scope->ScopeUserName);
+ if ( !Scope_Search4Scope( scope->SessionId, TRUE, TRUE ) )
+ {
+ Novfs_Remove_from_Root( scope->ScopeUserName );
+ Daemon_DestroySessionId( scope->SessionId );
+ }
+ Novfs_Free( scope );
+ }
+
+ up(&Scope_Lock);
+
+}
+
+/*++======================================================================*/
+char *
+NO_TRACE
+Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags)
+/*
+ * Arguments: struct dentry *Dentry - starting entry
+ * char *Buf - pointer to memory buffer
+ * unsigned int Buflen - size of memory buffer
+ *
+ * Returns: pointer to path.
+ *
+ * Abstract: Walks the dentry chain building a path.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ char *retval=&Buf[Buflen];
+ struct dentry *p=Dentry;
+ int len;
+
+ *(--retval) = '\0';
+ Buflen--;
+
+/*
+ if (!IS_ROOT(p))
+ {
+ while (Buflen && !IS_ROOT(p))
+ {
+ if (Buflen > p->d_name.len)
+ {
+ retval -= p->d_name.len;
+ Buflen -= p->d_name.len;
+ memcpy(retval, p->d_name.name, p->d_name.len);
+ *(--retval) = '/';
+ Buflen--;
+ p = p->d_parent;
+ }
+ else
+ {
+ retval = NULL;
+ break;
+ }
+ }
+ }
+ if (Flags)
+ {
+ len = strlen(p->d_sb->s_type->name);
+ if (Buflen-len > 0)
+ {
+ retval -= len;
+ Buflen -= len;
+ memcpy(retval, p->d_sb->s_type->name, len);
+ *(--retval) = '/';
+ Buflen--;
+ }
+ }
+ else
+ {
+ *(--retval) = '/';
+ Buflen--;
+ }
+*/
+ do
+ {
+ if (Buflen > p->d_name.len)
+ {
+ retval -= p->d_name.len;
+ Buflen -= p->d_name.len;
+ memcpy(retval, p->d_name.name, p->d_name.len);
+ *(--retval) = '/';
+ Buflen--;
+ p = p->d_parent;
+ }
+ else
+ {
+ retval = NULL;
+ break;
+ }
+ } while (!IS_ROOT(p));
+
+ if (IS_ROOT(Dentry))
+ {
+ retval++;
+ }
+
+ if (Flags)
+ {
+ len = strlen(p->d_sb->s_type->name);
+ if (Buflen-len > 0)
+ {
+ retval -= len;
+ Buflen -= len;
+ memcpy(retval, p->d_sb->s_type->name, len);
+ *(--retval) = '/';
+ Buflen--;
+ }
+ }
+
+ return(retval);
+}
+
+void Scope_Dump_Tasklist( void )
+{
+#ifdef OLD_DEBUG_KERNEL
+ task_t *task;
+ struct files_struct *fs;
+ int i, open_files=0;
+ static char buf[1024];
+ char *path;
+
+
+ for_each_process(task)
+ {
+ kdb_printf("Task List:\n" \
+ " Task: 0x%p\n" \
+ " pid: %d\n" \
+ " tgid: %d\n" \
+ " uid: %d %d %d %d\n" \
+ " gid: %d\n" \
+ " parent: 0x%p\n" \
+ " comm: %s\n" \
+ " user: 0x%p\n" \
+ " real_parent: 0x%p\n" \
+ " parent_exec_id: 0x%x\n" \
+ " self_exec_id: 0x%x\n" \
+ " did_exec: 0x%x\n" \
+ " signal: 0x%p\n" \
+ " thread_info: 0x%p\n" \
+ " security: 0x%p\n",
+ task,
+ task->pid,
+ task->tgid,
+ task->uid,task->euid,task->suid,task->fsuid,
+ task->gid,
+ task->parent,
+ task->comm,
+ task->user,
+ task->real_parent,
+ task->parent_exec_id,
+ task->self_exec_id,
+ task->did_exec,
+ task->signal,
+ task->thread_info,
+ task->security);
+
+ fs = task->files;
+ kdb_printf(" File List: 0x%p\n", fs);
+ if (fs)
+ {
+ open_files = fs->max_fds;
+ kdb_printf(" Max fds: %d\n", open_files);
+ for (i = 0; i<open_files; i++)
+ {
+ struct file *f = fs->fd[i];
+ if (f && (f->f_dentry))
+ {
+ path = Scope_dget_path(f->f_dentry, buf, sizeof(buf), 1);
+ if ( !path )
+ {
+ path = buf;
+ memcpy(path, f->f_dentry->d_name.name, f->f_dentry->d_name.len);
+ path[f->f_dentry->d_name.len] = '\0';
+ }
+ kdb_printf(" file(%d): 0x%p\n" \
+ " f_dentry: 0x%p\n" \
+ " d_name: %s\n" \
+ " d_count: %d\n" \
+ " d_inode: 0x%p\n",
+ i, f, f->f_dentry, path,
+ atomic_read(&f->f_dentry->d_count),
+ f->f_dentry->d_inode);
+ }
+ }
+ }
+ }
+#endif
+}
+
+void Scope_Dump_Scopetable( void )
+{
+#ifdef CONFIG_KDB
+ PSCOPE_LIST scope;
+ struct list_head *sl;
+
+ sl = Scope_List.next;
+ while (sl != &Scope_List)
+ {
+ scope = list_entry(sl, SCOPE_LIST, ScopeList);
+ sl = sl->next;
+ kdb_printf("Scope List:\n" \
+ " Scope: 0x%p\n" \
+ " ScopeId: 0x%llx\n" \
+ " SessionId: 0x%llx\n" \
+ " ScopePid: %u\n" \
+ " ScopeTask: 0x%p\n" \
+ " ScopeHash: 0x%lx\n" \
+ " ScopeUid: %ld\n" \
+ " ScopeUserName: %s\n",
+ scope,
+ scope->ScopeId,
+ scope->SessionId,
+ scope->ScopePid,
+ scope->ScopeTask,
+ scope->ScopeHash,
+ (long)scope->ScopeUid,
+ scope->ScopeUserName);
+
+ }
+
+#endif
+}
diff -uNr src.old/src/vfs.h src/src/vfs.h
--- src.old/src/vfs.h 1970-01-01 01:00:00.000000000 +0100
+++ src/src/vfs.h 2006-10-16 15:08:22.000000000 +0200
@@ -0,0 +1,283 @@
+/*++========================================================================
+ * Program Name: Novell NCP Redirector for Linux
+ * File Name: vfs.h
+ * Version: v1.00
+ * Author: James Turner
+ *
+ * Abstract: Include module for novfs.
+ * Notes:
+ * Revision History:
+ *
+ *
+ * Copyright (C) 2005 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *======================================================================--*/
+#ifndef __STDC_VERSION__
+#define __STDC_VERSION__ 0L
+#endif
+
+/*===[ Include files specific to Linux ]==================================*/
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#endif /* CONFIG_KDB */
+
+#include <linux/version.h>
+#include <linux/namei.h>
+
+/*===[ Include files specific to this module ]============================*/
+
+/*===[ External data ]====================================================*/
+extern int Novfs_Version_Major;
+extern int Novfs_Version_Minor;
+extern int Novfs_Version_Sub;
+extern int Novfs_Version_Release;
+
+/*===[ External prototypes ]==============================================*/
+extern void *Novfs_Malloc( size_t, int );
+extern void Novfs_Free( const void * );
+
+
+/*===[ Manifest constants ]===============================================*/
+#define NOVFS_MAGIC 0x4e574653
+#define MODULE_NAME "novfs"
+
+#define UNUSED_VARIABLE(a) (a) = (a)
+
+#define TREE_DIRECTORY_NAME ".Trees"
+#define SERVER_DIRECTORY_NAME ".Servers"
+
+#define PATH_LENGTH_BUFFER PATH_MAX
+#define NW_MAX_PATH_LENGTH 255
+
+#define IOC_LOGIN 0x4a540000
+#define IOC_LOGOUT 0x4a540001
+#define IOC_XPLAT 0x4a540002
+#define IOC_SESSION 0x4a540003
+#define IOC_DEBUGPRINT 0x4a540004
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+#define D_CHILD d_u.d_child
+#define AS_TREE_LOCK(l) read_lock_irq(l)
+#define AS_TREE_UNLOCK(l) read_unlock_irq(l)
+#else
+#define D_CHILD d_child
+#define AS_TREE_LOCK(l) spin_lock_irq(l)
+#define AS_TREE_UNLOCK(l) spin_unlock_irq(l)
+#endif
+
+/*
+ * NetWare file attributes
+ */
+
+#define NW_ATTRIBUTE_NORMAL 0x00
+#define NW_ATTRIBUTE_READ_ONLY 0x01
+#define NW_ATTRIBUTE_HIDDEN 0x02
+#define NW_ATTRIBUTE_SYSTEM 0x04
+#define NW_ATTRIBUTE_EXECUTE_ONLY 0x08
+#define NW_ATTRIBUTE_DIRECTORY 0x10
+#define NW_ATTRIBUTE_ARCHIVE 0x20
+#define NW_ATTRIBUTE_EXECUTE 0x40
+#define NW_ATTRIBUTE_SHAREABLE 0x80
+
+/*
+ * Define READ/WRITE flag for DATA_LIST
+ */
+#define DLREAD 0
+#define DLWRITE 1
+
+/*
+ * Define list type
+ */
+#define USER_LIST 1
+#define SERVER_LIST 2
+#define VOLUME_LIST 3
+
+/*
+ * Define flags used in for inodes
+ */
+#define USER_INODE 1
+#define UPDATE_INODE 2
+
+/*
+ * Define flags for directory cache flags
+ */
+#define ENTRY_VALID 0x00000001
+
+#ifdef INTENT_MAGIC
+#define NDOPENFLAGS intent.it_flags
+#else
+#define NDOPENFLAGS intent.open.flags
+#endif
+
+/*
+ * daemon_command_t flags values
+ */
+#define INTERRUPTIBLE 1
+
+#define NO_TRACE __attribute__((__no_instrument_function__))
+
+#ifndef NOVFS_VFS_MAJOR
+#define NOVFS_VFS_MAJOR 0
+#endif
+
+#ifndef NOVFS_VFS_MINOR
+#define NOVFS_VFS_MINOR 0
+#endif
+
+#ifndef NOVFS_VFS_SUB
+#define NOVFS_VFS_SUB 0
+#endif
+
+#ifndef NOVFS_VFS_RELEASE
+#define NOVFS_VFS_RELEASE 0
+#endif
+
+#define VALUE_TO_STR( value ) #value
+#define DEFINE_TO_STR(value) VALUE_TO_STR(value)
+
+
+#define NOVFS_VERSION_STRING \
+ DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \
+ DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \
+ DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \
+ DEFINE_TO_STR(NOVFS_VFS_RELEASE) \
+ "\0"
+
+/*===[ Type definitions ]=================================================*/
+typedef struct _ENTRY_INFO
+{
+ int type;
+ umode_t mode;
+ uid_t uid;
+ gid_t gid;
+ loff_t size;
+ struct timespec atime;
+ struct timespec mtime;
+ struct timespec ctime;
+ int namelength;
+ unsigned char name[1];
+} ENTRY_INFO, *PENTRY_INFO;
+
+typedef struct _STRING_
+{
+ int Length;
+ unsigned char *Data;
+} STRING, *PSTRING;
+
+typedef struct _LOGIN_
+{
+ STRING Server;
+ STRING UserName;
+ STRING Password;
+} LOGIN, *PLOGIN;
+
+typedef struct _LOGOUT_
+{
+ STRING Server;
+} LOGOUT, *PLOGOUT;
+
+typedef uint64_t scope_t;
+typedef uint64_t session_t;
+
+typedef struct _DIR_CACHE_
+{
+ struct list_head list;
+ int flags;
+ u64 jiffies;
+ ino_t ino;
+ loff_t size;
+ umode_t mode;
+ struct timespec atime;
+ struct timespec mtime;
+ struct timespec ctime;
+ unsigned long hash;
+ int nameLen;
+ char name[1];
+} DIR_CACHE, *PDIR_CACHE;
+
+typedef struct _INODE_DATA_
+{
+ void *Scope;
+ unsigned long Flags;
+ struct list_head IList;
+ struct inode *Inode;
+ struct list_head DirCache;
+ struct semaphore DirCacheLock;
+ unsigned long FileHandle;
+ int CacheFlag;
+ char Name[1]; /* Needs to be last entry */
+} INODE_DATA, *PINODE_DATA;
+
+typedef struct _DATA_LIST_
+{
+ void *page;
+ void *offset;
+ int len;
+ int rwflag;
+} DATA_LIST, *PDATA_LIST;
+
+typedef struct _XPLAT_
+{
+ int xfunction;
+ unsigned long reqLen;
+ void *reqData;
+ unsigned long repLen;
+ void *repData;
+
+} XPLAT, *PXPLAT;
+
+
+/*===[ Function prototypes ]==============================================*/
+
+extern int DbgPrint( char *Fmt, ... );
+extern char *ctime_r(time_t *clock, char *buf);
+
+
+/*++======================================================================*/
+static inline unsigned long InterlockedIncrement( unsigned long *p )
+/*
+ *
+ * Arguments: unsigned long *p - pointer to value.
+ *
+ * Returns: unsigned long - value prior to increment.
+ *
+ * Abstract: The value of *p is incremented and the value of *p before
+ * it was incremented is returned. This is an atomic operation.
+ *
+ * Notes:
+ *
+ * Environment:
+ *
+ *========================================================================*/
+{
+ unsigned long x = 1;
+
+ mb();
+
+#if defined(__i386) || defined(__i386__)
+ __asm__ __volatile__(
+ " lock xadd %0,(%2)"
+ : "+r"(x), "=m"(p)
+ : "r"(p), "m"(p)
+ : "memory");
+
+#else
+ x = *p++;
+#endif
+ return( x );
+}