stable/branches/experimental/net-fs/novell-novfs/files/novell-novfs-1.2.0_to_2.0.0.patch

32749 lines
913 KiB
Diff
Raw Normal View History

2007-07-09 12:53:37 +02:00
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 );
+}