Commit 8bf26ec8 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.68

parent e4cb6d89
This diff is collapsed.
ncpfs is a filesystem which understands the NCP protocol, designed by the
Novell Corporation for their NetWare(tm) product. NCP is functionally
similar to the NFS used in the tcp/ip community.
To mount a Netware-Filesystem, you need a special mount program, which can
be found in ncpfs package. Homesite for ncpfs is linux01.gwdg.de/pub/ncpfs,
but sunsite and its many mirrors will have it as well.
Related products are linware and mars_nwe, which will give Linux partial
Netware Server functionality.
Linware's home site is: klokan.sh.cvut.cz/pub/linux/linware,
Mars_nwe can be found on linux01.gwdg.de/pub/ncpfs.
Maintainers And Source Submission Procedures
In order to keep things easy for the maintainers please try to
follow the guidelines given. Not all of these guidelines matter for every
trivial patch so apply some common sense.
1. Always _test_ your changes however small on at least 4 or 5 people,
preferably many more.
2. Try and release a few ALPHA test versions to the net. Announce them
onto the kernel channel and await results. This is especially important
for device drivers because often thats the only way you will find things
like the fact version 3 firmware needs a magic fix you didnt know about, or
some clown changed the chips on a board and not its name (Don't laugh look
at the SMC etherpower for that).
3. Make sure your changes compile correctly in multiple configurations.
4. When you are happy with a change make it generally available for
testing and await feedback.
5. Make a patch available to the relevant maintainer in the list. Use
'diff -u' to make the patch easy to merge. Be prepared to get your changes
sent back with seemingly silly requests about formatting and variable names.
These aren't as silly as they seem, one job the maintainers (and especially
Linus) do is to keep things looking the same. Sometimes this means that
the clever hack in your driver to get around a problem actual needs to
become a generalised kernel feature ready for next time.
PLEASE try and include any credit lines you want added with the
patch. It avoids people being missed off by mistake and makes it easier to
know who wants adding and who doesn't.
PLEASE Document known bugs. If it doesnt work for everything or
does something very odd once a month document it.
6. Make sure you have the right to send any changes you make. If you
do changes at work you may find your employer owns the patch not you.
7. Happy hacking
[This file is new: I've just put the existing network contacts in, other
people please add yourselves] -- AC
-----------------------------------
Maintainers List (try to look for most precise areas first)
P: Person
M: Mail patches to
L: Mailing list that is relevant to this area
S: Status
Supported: Someone is actually paid to look after this (wildly
improbable).
Maintained: Someone actually looks after it.
Odd Fixes: It has a maintainer but they don't have time to do
much other than throw the odd patch in. See below..
Orphan: No current maintainer [but maybe you could take the
role as you write your new driver].
Obsolete: Ex code. Something tagged obsolete generally means
its been replaced by a better system and you should
be using that.
3C501 NETWORK DRIVER
P: Alan Cox
M: net-patches@lxorguk.ukuu.org.uk
L: linux-net@vger.rutgers.edu
S: Maintained
APPLETALK NETWORK LAYER
P: Alan Cox & University Of Michigan
M: net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu
L: [Someone fill in the netatalk list here]
S: Maintained
AX.25 NETWORK LAYER
P: Jon Naylor
M: jsn@cs.nott.ac.uk
L: linux-hams@vger.rutges.edu
S: Maintained
IPX NETWORK LAYER
P: Alan Cox [for the moment]
M: net-patches@lxorguk.ukuu.org.uk
L: linux-ipx@vger.rutgers.edu [will change]
S: Maintained
NETROM NETWORK LAYER
P: Jon Naylor
M: jsn@cs.nott.ac.uk
L: linux-hams@vger.rutges.edu
S: Maintained
NETWORKING [GENERAL]:
P: Alan Cox
M: net-patches@lxorguk.ukuu.org.uk
L: linux-net@vger.rutgers.edu
S: Odd Fixes <-> Maintained subject to workloads
SMP:
P: Alan Cox
M: smp-patches@lxorguk.ukuu.org.uk
L: linux-smp@vger.rutgers.edu
S: Maintained
REST:
P: Linus Torvalds
S: Buried alive in email
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 67
SUBLEVEL = 68
ARCH = i386
......
......@@ -53,6 +53,10 @@ SWAP_DEV = 0
! ld86 requires an entry symbol. This may as well be the usual one.
.globl _main
_main:
nop
jmp over_magic
.byte 0xF0
over_magic:
#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
int 3
#endif
......
......@@ -30,7 +30,6 @@ CONFIG_M586=y
# Floppy, IDE, and other block devices
#
CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_IDE=y
#
......@@ -43,6 +42,8 @@ CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_RZ1000=y
# CONFIG_BLK_DEV_TRITON is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_XD is not set
#
......
......@@ -5,7 +5,6 @@ mainmenu_option next_comment
comment 'Floppy, IDE, and other block devices'
tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
bool 'Enhanced IDE/MFM/RLL disk/cdrom/tape support' CONFIG_BLK_DEV_IDE
comment 'Please see drivers/block/README.ide for help/info on IDE drives'
if [ "$CONFIG_BLK_DEV_IDE" = "n" ]; then
......@@ -29,6 +28,10 @@ else
bool ' ALI M1439/M1445 chipset support' CONFIG_BLK_DEV_ALI14XX
fi
fi
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
define_bool CONFIG_BLK_DEV_HD y
fi
......
......@@ -36,6 +36,14 @@ else
endif
endif
ifeq ($(CONFIG_BLK_DEV_LOOP),y)
L_OBJS += loop.o
else
ifeq ($(CONFIG_BLK_DEV_LOOP),m)
M_OBJS += loop.o
endif
endif
ifeq ($(CONFIG_BLK_DEV_HD),y)
L_OBJS += hd.o
endif
......
......@@ -608,6 +608,9 @@ int blk_dev_init(void)
#ifdef CONFIG_BLK_DEV_RAM
rd_init();
#endif
#ifdef CONFIG_BLK_DEV_LOOP
loop_init();
#endif
#ifdef CONFIG_BLK_DEV_IDE
ide_init(); /* this MUST preceed hd_init */
#endif
......
This diff is collapsed.
#ifndef _LINUX_LOOP_H
#define _LINUX_LOOP_H
/*
* include/linux/loop.h
*
* Written by Theodore Ts'o, 3/29/93.
*
* Copyright 1993 by Theodore Ts'o. Redistribution of this file is
* permitted under the GNU Public License.
*/
#define LO_NAME_SIZE 64
#define LO_KEY_SIZE 32
struct loop_device {
int lo_number;
struct inode *lo_inode;
int lo_refcnt;
kdev_t lo_device;
int lo_offset;
int lo_encrypt_type;
int lo_encrypt_key_size;
int lo_flags;
int (*transfer)(struct loop_device *, int cmd,
char *raw_buf, char *loop_buf, int size);
char lo_name[LO_NAME_SIZE];
char lo_encrypt_key[LO_KEY_SIZE];
#ifdef DES_AVAILABLE
des_key_schedule lo_des_key;
unsigned long lo_des_init[2];
#endif
};
typedef int (* transfer_proc_t)(struct loop_device *, int cmd,
char *raw_buf, char *loop_buf, int size);
/*
* Loop flags
*/
#define LO_FLAGS_DO_BMAP 0x00000001
struct loop_info {
int lo_number; /* ioctl r/o */
dev_t lo_device; /* ioctl r/o */
unsigned long lo_inode; /* ioctl r/o */
dev_t lo_rdevice; /* ioctl r/o */
int lo_offset;
int lo_encrypt_type;
int lo_encrypt_key_size; /* ioctl w/o */
int lo_flags; /* ioctl r/o */
char lo_name[LO_NAME_SIZE];
unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
unsigned long lo_init[2];
char reserved[4];
};
/*
* Loop encryption types --- LO_CRYPT_IDEA isn't supported yet
*/
#define LO_CRYPT_NONE 0
#define LO_CRYPT_XOR 1
#define LO_CRYPT_DES 2
#define LO_CRYPT_IDEA 5
#define MAX_LO_CRYPT 4
/*
* IOCTL commands --- we will commandeer 0x4C ('L')
*/
#define LOOP_SET_FD 0x4C00
#define LOOP_CLR_FD 0x4C01
#define LOOP_SET_STATUS 0x4C02
#define LOOP_GET_STATUS 0x4C03
#endif
......@@ -13,7 +13,7 @@ fi
tristate 'Parallel printer support' CONFIG_PRINTER
tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
if [ "$CONFIG_PSMOUSE" = "y" ]; then
if [ "$CONFIG_PSMOUSE" != "n" ]; then
bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
fi
tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
......@@ -39,6 +39,7 @@ if [ "$CONFIG_APM" = "y" ]; then
fi
bool 'Watchdog Timer Support' CONFIG_WATCHDOG
if [ "$CONFIG_WATCHDOG" != "n" ]; then
bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
tristate ' WDT Watchdog timer' CONFIG_WDT
if [ "$CONFIG_WDT" = "y" ]; then
bool ' WDT501 features' CONFIG_WDT_501
......
......@@ -18,12 +18,13 @@
* driver this won't always recover a failed machine.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/mouse.h>
#define WATCHDOG_MINOR 130
#define TIMER_MARGIN (60*HZ) /* Allow 1 minute */
......@@ -68,7 +69,9 @@ static void softdog_release(struct inode *inode, struct file *file)
/*
* Shut off the timer.
*/
#ifndef CONFIG_WATCHDOG_NOWAYOUT
del_timer(&watchdog_ticktock);
#endif
timer_alive=0;
}
......
......@@ -187,8 +187,10 @@ static void wdt_release(struct inode *inode, struct file *file)
{
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
#ifndef CONFIG_WATCHDOG_NOWAYOUT
inb_p(WDT_DC); /* Disable counters */
wdt_ctr_load(2,0); /* 0 length reset pulses now */
#endif
wdt_is_open=0;
}
MOD_DEC_USE_COUNT;
......
......@@ -36,10 +36,10 @@ L_OBJS += sk_g16.o
endif
ifeq ($(CONFIG_NET_IPIP),y)
L_OBJS += tunnel.o
L_OBJS += new_tunnel.o
else
ifeq ($(CONFIG_NET_IPIP),m)
M_OBJS += tunnel.o
M_OBJS += new_tunnel.o
endif
endif
......
This diff is collapsed.
......@@ -106,6 +106,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( OPTI, OPTI_82C558, "82C558"),
DEVICE( OPTI, OPTI_82C621, "82C621"),
DEVICE( OPTI, OPTI_82C822, "82C822"),
DEVICE( SGS, SGS_2000, "STG 2000X"),
DEVICE( SGS, SGS_1764, "STG 1764X"),
DEVICE( BUSLOGIC, BUSLOGIC_946C_2,"BT-946C"),
DEVICE( BUSLOGIC, BUSLOGIC_946C, "BT-946C"),
DEVICE( BUSLOGIC, BUSLOGIC_930, "BT-930"),
......@@ -151,6 +153,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( ASP, ASP_ABP940, "ABP940"),
DEVICE( IMS, IMS_8849, "8849"),
DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c"),
DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)"),
DEVICE( INTERG, INTERG_1680, "IGA-1680"),
DEVICE( REALTEK, REALTEK_8029, "8029"),
DEVICE( INIT, INIT_320P, "320 P"),
......@@ -171,6 +174,10 @@ struct pci_dev_info dev_info[] = {
DEVICE( ZEITNET, ZEITNET_1225, "1225"),
DEVICE( SPECIALIX, SPECIALIX_XIO, "XIO/SIO host"),
DEVICE( SPECIALIX, SPECIALIX_RIO, "RIO host"),
DEVICE( RP, RP8OCTA, "RocketPort 8 Oct"),
DEVICE( RP, RP8INTF, "RocketPort 8 Intf"),
DEVICE( RP, RP16INTF, "RocketPort 16 Intf"),
DEVICE( RP, RP32INTF, "RocketPort 32 Intf"),
DEVICE( CYCLADES, CYCLADES_Y, "Cyclome-Y"),
DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
......@@ -464,6 +471,7 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_MUTECH: return "Mutech";
case PCI_VENDOR_ID_ZEITNET: return "ZeitNet";
case PCI_VENDOR_ID_SPECIALIX: return "Specialix";
case PCI_VENDOR_ID_RP: return "Comtrol";
case PCI_VENDOR_ID_CYCLADES: return "Cyclades";
case PCI_VENDOR_ID_SYMPHONY: return "Symphony";
case PCI_VENDOR_ID_TEKRAM: return "Tekram";
......
......@@ -234,12 +234,14 @@ static struct dev_info device_list[] =
{"MAXTOR","MXT-1240S","I1.2", BLIST_NOLUN}, /* Locks up when LUN>0 polled */
{"MAXTOR","XT-4170S","B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */
{"MAXTOR","XT-8760S","B7B", BLIST_NOLUN}, /* guess what? */
{"MEDIAVIS","RENO CD-ROMX2A","2.03",BLIST_NOLUN},/*Responds to all lun */
{"NEC","CD-ROM DRIVE:841","1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
{"RODIME","RO3000S","2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
{"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
* for aha152x controller, which causes
* SCSI code to reset bus.*/
{"SEAGATE", "ST296","921", BLIST_NOLUN}, /* Responds to all lun */
{"SEAGATE","ST1581","6538",BLIST_NOLUN}, /* Responds to all lun */
{"SONY","CD-ROM CDU-541","4.3d", BLIST_NOLUN},
{"SONY","CD-ROM CDU-55S","1.0i", BLIST_NOLUN},
{"SONY","CD-ROM CDU-561","1.7x", BLIST_NOLUN},
......
......@@ -290,7 +290,7 @@ static int count(char ** argv)
unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem)
{
char *tmp, *pag = NULL;
char *tmp, *tmp1, *pag = NULL;
int len, offset = 0;
unsigned long old_fs, new_fs;
......@@ -303,14 +303,12 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
while (argc-- > 0) {
if (from_kmem == 1)
set_fs(new_fs);
if (!(tmp = get_user(argv+argc)))
if (!(tmp1 = tmp = get_user(argv+argc)))
panic("VFS: argc is wrong");
if (from_kmem == 1)
set_fs(old_fs);
len=0; /* remember zero-padding */
do {
len++;
} while (get_user(tmp++));
while (get_user(tmp++));
len = tmp - tmp1;
if (p < len) { /* this shouldn't happen - 128kB */
set_fs(old_fs);
return 0;
......@@ -329,7 +327,16 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
set_fs(new_fs);
}
*(pag + offset) = get_user(tmp);
if (len == 0 || offset == 0)
*(pag + offset) = get_user(tmp);
else {
int bytes_to_copy = (len > offset) ? offset : len;
tmp -= bytes_to_copy;
p -= bytes_to_copy;
offset -= bytes_to_copy;
len -= bytes_to_copy;
memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
}
}
}
if (from_kmem==2)
......
......@@ -68,13 +68,14 @@ void fat_put_super(struct super_block *sb)
static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
gid_t *gid,int *umask,int *debug,int *fat,int *quiet,
int *blksize, char *dotsOK, char *sys_immutable)
int *blksize, char *dotsOK, char *sys_immutable, char *showexec)
{
char *this_char,*value;
*check = 'n';
*conversion = 'b';
*dotsOK = 0;
*showexec = 0;
*uid = current->uid;
*gid = current->gid;
*umask = current->fs->umask;
......@@ -105,6 +106,9 @@ static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
else if (!strcmp(this_char,"nodots")) {
*dotsOK = 0;
}
else if (!strcmp(this_char,"showexec")) {
*showexec = 1;
}
else if (!strcmp(this_char,"dotsOK") && value) {
if (!strcmp(value,"yes")) *dotsOK = 1;
else if (!strcmp(value,"no")) *dotsOK = 0;
......@@ -173,7 +177,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
struct msdos_boot_sector *b;
int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
int debug,error,fat,quiet;
char check,conversion,dotsOK,sys_immutable;
char check,conversion,dotsOK,sys_immutable,showexec;
uid_t uid;
gid_t gid;
int umask;
......@@ -187,7 +191,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
}
}
if (!parse_options((char *) data,&check,&conversion,&uid,&gid,&umask,
&debug,&fat,&quiet,&blksize,&dotsOK,&sys_immutable)
&debug,&fat,&quiet,&blksize,&dotsOK,&sys_immutable,&showexec)
|| (blksize != 512 && blksize != 1024)) {
sb->s_dev = 0;
MOD_DEC_USE_COUNT;
......@@ -299,6 +303,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
MSDOS_SB(sb)->fs_umask = umask;
MSDOS_SB(sb)->quiet = quiet;
MSDOS_SB(sb)->dotsOK = dotsOK;
MSDOS_SB(sb)->showexec = showexec;
MSDOS_SB(sb)->sys_immutable = sys_immutable;
MSDOS_SB(sb)->vfat = 0; /* vfat_read_super sets this */
MSDOS_SB(sb)->umsdos = 0; /* umsdos_read_super will set this */
......@@ -433,7 +438,8 @@ void fat_read_inode(struct inode *inode, struct inode_operations *fs_dir_inode_o
}
} else { /* not a directory */
inode->i_mode = MSDOS_MKMODE(raw_entry->attr,
((IS_NOEXEC(inode) || !is_exec(raw_entry->ext))
((IS_NOEXEC(inode) || (MSDOS_SB(inode->i_sb)->showexec &&
!is_exec(raw_entry->ext)))
? S_IRUGO|S_IWUGO : S_IRWXUGO)
& ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFREG;
inode->i_op = (sb->s_blocksize == 1024)
......
......@@ -151,7 +151,7 @@ void clear_inode(struct inode * inode)
{
struct wait_queue * wait;
invalidate_inode_pages(inode, 0);
truncate_inode_pages(inode, 0);
wait_on_inode(inode);
if (IS_WRITABLE(inode)) {
if (inode->i_sb && inode->i_sb->dq_op)
......
......@@ -11,6 +11,10 @@ O_TARGET := ncpfs.o
O_OBJS := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o
M_OBJS := $(O_TARGET)
# If you want debugging output, please uncomment the following line
# EXTRA_CFLAGS += -DDEBUG_NCP=1
include $(TOPDIR)/Rules.make
ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
......
......@@ -96,7 +96,7 @@ static struct file_operations ncp_dir_operations = {
NULL, /* write - bad */
ncp_readdir, /* readdir */
NULL, /* select - default */
ncp_ioctl, /* ioctl - default */
ncp_ioctl, /* ioctl */
NULL, /* mmap */
NULL, /* no special open code */
NULL, /* no special release code */
......@@ -159,6 +159,11 @@ ncp_readdir(struct inode *inode, struct file *filp,
return -EBADF;
}
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if (c_entry == NULL)
{
i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
......@@ -640,6 +645,11 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
iput(dir);
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir)))
{
iput(dir);
return -EIO;
}
DDPRINTK("ncp_lookup: %s, len %d\n", __name, len);
......@@ -772,6 +782,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
iput(dir);
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir)))
{
iput(dir);
return -EIO;
}
strncpy(_name, name, len);
_name[len] = '\0';
......@@ -779,7 +794,8 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir), _name,
OC_MODE_CREATE|OC_MODE_OPEN,
OC_MODE_CREATE|OC_MODE_OPEN|
OC_MODE_REPLACE,
0, AR_READ|AR_WRITE,
&finfo) != 0)
{
......@@ -828,6 +844,11 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
iput(dir);
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir)))
{
iput(dir);
return -EIO;
}
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir), _name,
......@@ -858,8 +879,14 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
iput(dir);
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir)))
{
iput(dir);
return -EIO;
}
if (ncp_find_inode(dir, name) != NULL)
{
iput(dir);
error = -EBUSY;
}
else
......@@ -877,7 +904,7 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
}
else
{
error = -EINVAL;
error = -EACCES;
}
}
iput(dir);
......@@ -896,8 +923,14 @@ ncp_unlink(struct inode *dir, const char *name, int len)
iput(dir);
return -ENOENT;
}
if (!ncp_conn_valid(NCP_SERVER(dir)))
{
iput(dir);
return -EIO;
}
if (ncp_find_inode(dir, name) != NULL)
{
iput(dir);
error = -EBUSY;
}
else
......@@ -914,7 +947,7 @@ ncp_unlink(struct inode *dir, const char *name, int len)
}
else
{
error = -EINVAL;
error = -EACCES;
}
}
iput(dir);
......@@ -936,6 +969,12 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
goto finished;
}
if (!ncp_conn_valid(NCP_SERVER(old_dir)))
{
res = -EIO;
goto finished;
}
if (!new_dir || !S_ISDIR(new_dir->i_mode))
{
printk("ncp_rename: new inode is NULL or not a directory\n");
......
......@@ -93,6 +93,10 @@ ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
DPRINTK("ncp_file_read: inode = NULL\n");
return -EINVAL;
}
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if (!S_ISREG(inode->i_mode))
{
......@@ -172,6 +176,10 @@ ncp_file_write(struct inode *inode, struct file *file, const char *buf,
DPRINTK("ncp_file_write: inode = NULL\n");
return -EINVAL;
}
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if (!S_ISREG(inode->i_mode))
{
......
......@@ -6,6 +6,7 @@
*/
#include <linux/module.h>
#include <linux/config.h>
#include <asm/system.h>
#include <asm/segment.h>
......@@ -20,6 +21,9 @@
#include <linux/locks.h>
#include <linux/fcntl.h>
#include <linux/malloc.h>
#ifdef CONFIG_KERNELD
#include <linux/kerneld.h>
#endif
#include "ncplib_kernel.h"
extern int close_fp(struct file *filp);
......@@ -182,6 +186,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
struct ncp_server *server;
struct file *ncp_filp;
struct file *wdog_filp;
struct file *msg_filp;
kdev_t dev = sb->s_dev;
int error;
......@@ -197,6 +202,8 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
printk("ncp warning: mount version %s than kernel\n",
(data->version < NCP_MOUNT_VERSION) ?
"older" : "newer");
sb->s_dev = 0;
return NULL;
}
if ( (data->ncp_fd >= NR_OPEN)
......@@ -217,6 +224,15 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
return NULL;
}
if ( (data->message_fd >= NR_OPEN)
|| ((msg_filp = current->files->fd[data->message_fd]) == NULL)
|| (!S_ISSOCK(msg_filp->f_inode->i_mode)))
{
printk("ncp_read_super: invalid wdog socket\n");
sb->s_dev = 0;
return NULL;
}
/* We must malloc our own super-block info */
server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
GFP_KERNEL);
......@@ -229,6 +245,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
ncp_filp->f_count += 1;
wdog_filp->f_count += 1;
msg_filp->f_count += 1;
lock_super(sb);
......@@ -242,10 +259,12 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
server->ncp_filp = ncp_filp;
server->wdog_filp = wdog_filp;
server->msg_filp = msg_filp;
server->lock = 0;
server->wait = NULL;
server->packet = NULL;
server->buffer_size = 0;
server->conn_status = 0;
server->m = *data;
server->m.file_mode = (server->m.file_mode &
......@@ -253,6 +272,9 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
server->m.dir_mode = (server->m.dir_mode &
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
/* protect against invalid mount points */
server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0';
server->packet_size = NCP_PACKET_SIZE;
server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
......@@ -278,6 +300,15 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
goto fail;
}
if (ncp_catch_message(server) != 0)
{
printk("ncp_read_super: Could not catch messages\n");
ncp_dont_catch_watchdog(server);
error = -EINVAL;
unlock_super(sb);
goto fail;
}
ncp_lock_server(server);
error = ncp_connect(server);
ncp_unlock_server(server);
......@@ -324,6 +355,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
fail:
ncp_filp->f_count -= 1;
wdog_filp->f_count -= 1;
msg_filp->f_count -= 1;
ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
return NULL;
}
......@@ -343,6 +375,7 @@ ncp_put_super(struct super_block *sb)
ncp_dont_catch_watchdog(server);
close_fp(server->wdog_filp);
close_fp(server->msg_filp);
ncp_free_all_inodes(server);
......@@ -357,6 +390,32 @@ ncp_put_super(struct super_block *sb)
MOD_DEC_USE_COUNT;
}
/* This routine is called from an interrupt in ncp_msg_data_ready. So
* we have to be careful NOT to sleep here! */
void
ncp_trigger_message(struct ncp_server *server)
{
char command[ sizeof(server->m.mount_point)
+ sizeof(NCP_MSG_COMMAND) + 2];
if (server == NULL)
{
printk("ncp_trigger_message: invalid server!\n");
return;
}
DPRINTK("ncp_trigger_message: on %s\n",
server->m.mount_point);
#ifdef CONFIG_KERNELD
strcpy(command, NCP_MSG_COMMAND);
strcat(command, " ");
strcat(command, server->m.mount_point);
DPRINTK("ksystem: %s\n", command);
ksystem(command, KERNELD_NOWAIT);
#endif
}
static void
ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
{
......@@ -386,6 +445,11 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
int info_mask;
struct nw_modify_dos_info info;
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if ((result = inode_change_ok(inode, attr)) < 0)
return result;
......@@ -493,6 +557,7 @@ int init_ncp_fs(void)
}
#ifdef MODULE
int
init_module( void)
{
int status;
......
......@@ -133,6 +133,11 @@ ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
{
DPRINTK("ncp_mmap: called\n");
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
/* only PAGE_COW or read-only supported now */
if (vma->vm_flags & VM_SHARED)
return -EINVAL;
......
......@@ -411,12 +411,18 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
struct nw_file_info *target)
{
int result;
__u16 search_attribs = 0x0006;
if ((create_attributes & aDIR) != 0)
{
search_attribs |= 0x8000;
}
ncp_init_request(server);
ncp_add_byte(server, 1); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, open_create_mode);
ncp_add_word(server, 0x8006);
ncp_add_word(server, search_attribs);
ncp_add_dword(server, RIM_ALL);
ncp_add_dword(server, create_attributes);
/* The desired acc rights seem to be the inherited rights mask
......
......@@ -93,13 +93,8 @@ ncp_wdog_data_ready(struct sock *sk, int len)
/* How to check connection number here? */
)
{
/* Error, throw away the complete packet */
_recvfrom(sock, (void *)packet_buf, 2, 1, 0,
&sender, &addr_len);
printk("ncpfs: got strange packet on watchdog "
"socket\n");
}
else
{
......@@ -123,7 +118,6 @@ ncp_wdog_data_ready(struct sock *sk, int len)
}
}
int
ncp_catch_watchdog(struct ncp_server *server)
{
......@@ -146,7 +140,7 @@ ncp_catch_watchdog(struct ncp_server *server)
if (sock->type != SOCK_DGRAM)
{
printk("ncp_catch_watchdog: did not get SOCK_STREAM\n");
printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n");
server->data_ready = NULL;
return -EINVAL;
}
......@@ -160,7 +154,7 @@ ncp_catch_watchdog(struct ncp_server *server)
return -EINVAL;
}
DDPRINTK("ncp_catch_watchdog.: sk->d_r = %x, server->d_r = %x\n",
DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
(unsigned int)(sk->data_ready),
(unsigned int)(server->data_ready));
......@@ -198,11 +192,11 @@ ncp_dont_catch_watchdog(struct ncp_server *server)
if (sock->type != SOCK_DGRAM)
{
printk("ncp_dont_catch_watchdog: did not get SOCK_STREAM\n");
printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n");
return -EINVAL;
}
sk = (struct sock *)(sock->data);
sk = (struct sock *)(sock->data);
if (sk == NULL)
{
......@@ -234,8 +228,88 @@ ncp_dont_catch_watchdog(struct ncp_server *server)
return 0;
}
static void
ncp_msg_data_ready(struct sock *sk, int len)
{
struct socket *sock = sk->socket;
if (!sk->dead)
{
unsigned char packet_buf[2];
struct sockaddr_ipx sender;
int addr_len = sizeof(struct sockaddr_ipx);
int result;
unsigned short fs;
fs = get_fs();
set_fs(get_ds());
result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
&sender, &addr_len);
DPRINTK("ncpfs: got message of size %d from:\n", result);
DPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
" conn:%02X,type:%c\n",
htonl(sender.sipx_network),
sender.sipx_node[0], sender.sipx_node[1],
sender.sipx_node[2], sender.sipx_node[3],
sender.sipx_node[4], sender.sipx_node[5],
ntohs(sender.sipx_port),
packet_buf[0], packet_buf[1]);
ncp_trigger_message(sk->ipx_ncp_server);
set_fs(fs);
}
}
int
ncp_catch_message(struct ncp_server *server)
{
struct file *file;
struct inode *inode;
struct socket *sock;
struct sock *sk;
if ( (server == NULL)
|| ((file = server->msg_filp) == NULL)
|| ((inode = file->f_inode) == NULL)
|| (!S_ISSOCK(inode->i_mode)))
{
printk("ncp_catch_message: did not get valid server!\n");
return -EINVAL;
}
sock = &(inode->u.socket_i);
if (sock->type != SOCK_DGRAM)
{
printk("ncp_catch_message: did not get SOCK_DGRAM\n");
return -EINVAL;
}
sk = (struct sock *)(sock->data);
if (sk == NULL)
{
printk("ncp_catch_message: sk == NULL");
return -EINVAL;
}
DDPRINTK("ncp_catch_message: sk->d_r = %x\n",
(unsigned int)(sk->data_ready));
if (sk->data_ready == ncp_msg_data_ready)
{
printk("ncp_catch_message: already done\n");
return -EINVAL;
}
sk->data_ready = ncp_msg_data_ready;
sk->ipx_ncp_server = server;
return 0;
}
#define NCP_SLACK_SPACE 1024
#define _S(nr) (1<<((nr)-1))
......@@ -474,13 +548,30 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
static int
ncp_do_request(struct ncp_server *server, int size)
{
int result;
if (server->lock == 0)
{
printk("ncpfs: Server not locked!\n");
return -EIO;
}
return do_ncp_rpc_call(server, size);
if (!ncp_conn_valid(server))
{
return -EIO;
}
result = do_ncp_rpc_call(server, size);
DDPRINTK("do_ncp_rpc_call returned %d\n", result);
if (result < 0)
{
/* There was a problem with I/O, so the connections is
* no longer usable. */
ncp_invalidate_conn(server);
}
return result;
}
/* ncp_do_request assures that at least a complete reply header is
......
......@@ -81,7 +81,7 @@ static inline void revalidate_inode(struct nfs_server * server, struct inode * i
return;
NFS_OLDMTIME(inode) = fattr.mtime.seconds;
}
invalidate_inode_pages(inode, 0);
invalidate_inode_pages(inode);
}
......@@ -118,18 +118,15 @@ static inline void do_read_nfs(struct inode * inode, char * buf, unsigned long p
result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
pos, rsize, buf, &fattr);
if (result < 0)
goto partial;
break;
refresh = 1;
count -= rsize;
pos += rsize;
buf += rsize;
count -= result;
pos += result;
buf += result;
if (result < rsize)
goto partial;
break;
} while (count);
nfs_refresh_inode(inode, &fattr);
return;
partial:
memset(buf, 0, count);
if (refresh)
nfs_refresh_inode(inode, &fattr);
......
......@@ -272,14 +272,34 @@ static int get_uptime(char * buffer)
static int get_meminfo(char * buffer)
{
struct sysinfo i;
int len;
si_meminfo(&i);
si_swapinfo(&i);
return sprintf(buffer, " total: used: free: shared: buffers: cached:\n"
len = sprintf(buffer, " total: used: free: shared: buffers: cached:\n"
"Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n"
"Swap: %8lu %8lu %8lu\n",
i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram, page_cache_size*PAGE_SIZE,
i.totalswap, i.totalswap-i.freeswap, i.freeswap);
/*
* Tagged format, for easy grepping and expansion. The above will go away
* eventually, once the tools have been updated.
*/
return len + sprintf(buffer+len,
"MemTotal: %8lu kB\n"
"MemFree: %8lu kB\n"
"MemShared: %8lu kB\n"
"Buffers: %8lu kB\n"
"Cached: %8lu kB\n"
"SwapTotal: %8lu kB\n"
"SwapFree: %8lu kB\n",
i.totalram >> 10,
i.freeram >> 10,
i.sharedram >> 10,
i.bufferram >> 10,
page_cache_size << (PAGE_SHIFT - 10),
i.totalswap >> 10,
i.freeswap >> 10);
}
static int get_version(char * buffer)
......@@ -452,6 +472,164 @@ static unsigned long get_wchan(struct task_struct *p)
# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
#endif
/* Gcc optimizes away "strlen(x)" for constant x */
#define ADDBUF(buffer, string) \
do { memcpy(buffer, string, strlen(string)); \
buffer += strlen(string); } while (0)
static inline char * task_name(struct task_struct *p, char * buf)
{
int i;
char * name;
ADDBUF(buf, "Name:\t");
name = p->comm;
i = sizeof(p->comm);
do {
unsigned char c = *name;
name++;
i--;
*buf = c;
if (!c)
break;
if (c == '\\') {
buf[1] = c;
buf += 2;
continue;
}
if (c == '\n') {
buf[0] = '\\';
buf[1] = 'n';
buf += 2;
continue;
}
buf++;
} while (i);
*buf = '\n';
return buf+1;
}
static inline char * task_state(struct task_struct *p, char *buffer)
{
#define NR_STATES (sizeof(states)/sizeof(const char *))
unsigned int n = p->state;
static const char * states[] = {
"R (running)",
"S (sleeping)",
"D (disk sleep)",
"Z (zombie)",
"T (stopped)",
"W (paging)",
". Huh?"
};
if (n >= NR_STATES)
n = NR_STATES-1;
buffer += sprintf(buffer,
"State:\t%s\n"
"Pid:\t%d\n"
"PPid:\t%d\n"
"Uid:\t%d\t%d\t%d\t%d\n"
"Gid:\t%d\t%d\t%d\t%d\n",
states[n],
p->pid, p->p_pptr->pid,
p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid);
return buffer;
}
static inline char * task_mem(struct task_struct *p, char *buffer)
{
struct mm_struct * mm = p->mm;
if (mm && mm != &init_mm) {
struct vm_area_struct * vma = mm->mmap;
unsigned long data = 0, stack = 0;
unsigned long exec = 0, lib = 0;
for (vma = mm->mmap; vma; vma = vma->vm_next) {
unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
if (!vma->vm_inode) {
data += len;
if (vma->vm_flags & VM_GROWSDOWN)
stack += len;
continue;
}
if (vma->vm_flags & VM_WRITE)
continue;
if (vma->vm_flags & VM_EXEC) {
exec += len;
if (vma->vm_flags & VM_EXECUTABLE)
continue;
lib += len;
}
}
buffer += sprintf(buffer,
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
"VmRSS:\t%8lu kB\n"
"VmData:\t%8lu kB\n"
"VmStk:\t%8lu kB\n"
"VmExe:\t%8lu kB\n"
"VmLib:\t%8lu kB\n",
mm->total_vm << (PAGE_SHIFT-10),
mm->locked_vm << (PAGE_SHIFT-10),
mm->rss << (PAGE_SHIFT-10),
data - stack, stack,
exec - lib, lib);
}
return buffer;
}
static inline char * task_sig(struct task_struct *p, char *buffer)
{
buffer += sprintf(buffer,
"SigPnd:\t%08lx\n"
"SigBlk:\t%08lx\n",
p->signal, p->blocked);
if (p->sig) {
struct sigaction * action = p->sig->action;
unsigned long sig_ign = 0, sig_caught = 0;
unsigned long bit = 1;
int i;
for (i = 0; i < 32; i++) {
switch((unsigned long) action->sa_handler) {
case 0:
break;
case 1:
sig_ign |= bit;
break;
default:
sig_caught |= bit;
}
bit <<= 1;
action++;
}
buffer += sprintf(buffer,
"SigIgn:\t%08lx\n"
"SigCgt:\t%08lx\n",
sig_ign, sig_caught);
}
return buffer;
}
static int get_status(int pid, char * buffer)
{
char * orig = buffer;
struct task_struct ** p = get_task(pid), *tsk;
if (!p || (tsk = *p) == NULL)
return 0;
buffer = task_name(tsk, buffer);
buffer = task_state(tsk, buffer);
buffer = task_mem(tsk, buffer);
buffer = task_sig(tsk, buffer);
return buffer - orig;
}
static int get_stat(int pid, char * buffer)
{
struct task_struct ** p = get_task(pid), *tsk;
......@@ -857,6 +1035,8 @@ static int get_root_array(char * page, int type, char **start, off_t offset, int
static int get_process_array(char * page, int pid, int type)
{
switch (type) {
case PROC_PID_STATUS:
return get_status(pid, page);
case PROC_PID_ENVIRON:
return get_env(pid, page);
case PROC_PID_CMDLINE:
......
......@@ -82,6 +82,12 @@ struct proc_dir_entry proc_pid = {
void proc_base_init(void)
{
proc_register(&proc_pid, &(struct proc_dir_entry) {
PROC_PID_STATUS, 6, "status",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations,
NULL, proc_pid_fill_inode,
});
proc_register(&proc_pid, &(struct proc_dir_entry) {
PROC_PID_MEM, 3, "mem",
S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
......
......@@ -222,6 +222,7 @@ void proc_read_inode(struct inode * inode)
inode->i_op = &proc_array_inode_operations;
return;
case PROC_PID_CMDLINE:
case PROC_PID_STATUS:
case PROC_PID_STAT:
case PROC_PID_STATM:
inode->i_mode = S_IFREG | S_IRUGO;
......
......@@ -546,7 +546,7 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
extern int check_disk_change(kdev_t dev);
extern void invalidate_inodes(kdev_t dev);
extern void invalidate_inode_pages(struct inode *, unsigned long);
extern void invalidate_inode_pages(struct inode *);
extern void invalidate_buffers(kdev_t dev);
extern int floppy_is_wp(int minor);
extern void sync_inodes(kdev_t dev);
......
......@@ -2,7 +2,7 @@
#ifndef _LINUX_INTERRUPT_H
#define _LINUX_INTERRUPT_H
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <asm/bitops.h>
struct bh_struct {
......@@ -49,10 +49,12 @@ extern inline void enable_bh(int nr)
extern inline void start_bh_atomic(void)
{
intr_count++;
barrier();
}
extern inline void end_bh_atomic(void)
{
barrier();
intr_count--;
}
......
......@@ -10,6 +10,9 @@
#include <stdarg.h>
#include <linux/linkage.h>
/* Optimization barrier */
#define barrier() __asm__("": : :"memory")
#define INT_MAX ((int)(~0U>>1))
#define UINT_MAX (~0U)
#define LONG_MAX ((long)(~0UL>>1))
......
......@@ -223,6 +223,7 @@ extern unsigned long get_unmapped_area(unsigned long, unsigned long);
/* filemap.c */
extern unsigned long page_unuse(unsigned long);
extern int shrink_mmap(int, unsigned long);
extern void truncate_inode_pages(struct inode *, unsigned long);
#define GFP_BUFFER 0x00
#define GFP_ATOMIC 0x01
......
......@@ -23,6 +23,7 @@ struct msdos_sb_info {
int prev_free; /* previously returned free cluster number */
int free_clusters; /* -1 if undefined */
char dotsOK;
char showexec; /* 1 = only set x bit for com/exe/bat */
char sys_immutable; /* system files are immutable */
int vfat; /* 0=no vfat long filename support, 1=vfat support */
int umsdos; /* 1 if mounted by umsdos, 0 if not */
......
......@@ -54,6 +54,8 @@ struct ncp_fs_info {
#define NCP_MAXPATHLEN 255
#define NCP_MAXNAMELEN 14
#define NCP_MSG_COMMAND "/sbin/nwmsg"
#ifdef __KERNEL__
/* The readdir cache size controls how many directory entries are
......@@ -145,6 +147,7 @@ struct super_block *ncp_read_super(struct super_block *sb,
extern int init_ncp_fs(void);
void ncp_invalidate_connection(struct ncp_server *server);
int ncp_conn_is_valid(struct ncp_server *server);
void ncp_trigger_message(struct ncp_server *server);
/* linux/fs/ncpfs/sock.c */
int ncp_request(struct ncp_server *server, int function);
......@@ -152,6 +155,7 @@ int ncp_connect(struct ncp_server *server);
int ncp_disconnect(struct ncp_server *server);
int ncp_catch_watchdog(struct ncp_server *server);
int ncp_dont_catch_watchdog(struct ncp_server *server);
int ncp_catch_message(struct ncp_server *server);
void ncp_lock_server(struct ncp_server *server);
void ncp_unlock_server(struct ncp_server *server);
......
......@@ -22,8 +22,8 @@ struct ncp_server {
it completely. */
struct file *ncp_filp; /* File pointer to ncp socket */
struct file *wdog_filp; /* File pointer to wdog socket */
struct file *msg_filp; /* File pointer to message socket */
void *data_ready; /* The wdog socket gets a new
data_ready callback. We store the
old one for checking purposes and
......@@ -35,7 +35,8 @@ struct ncp_server {
u8 completion; /* Status message from server */
u8 conn_status; /* Bit 4 = 1 ==> Server going down, no
requests allowed anymore */
requests allowed anymore.
Bit 0 = 1 ==> Server is down. */
int buffer_size; /* Negotiated bufsize */
......@@ -56,6 +57,18 @@ struct ncp_server {
char root_path; /* '\0' */
};
static inline int
ncp_conn_valid(struct ncp_server *server)
{
return ((server->conn_status & 0x11) == 0);
}
static inline void
ncp_invalidate_conn(struct ncp_server *server)
{
server->conn_status |= 0x01;
}
#endif /* __KERNEL__ */
#endif
......@@ -13,7 +13,7 @@
#include <linux/ncp.h>
#include <linux/ncp_fs_i.h>
#define NCP_MOUNT_VERSION 1
#define NCP_MOUNT_VERSION 2
#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
#define NCP_PASSWORD_LEN 20
......@@ -30,10 +30,10 @@ struct ncp_mount_data {
uid_t mounted_uid; /* Who may umount() this filesystem? */
struct sockaddr_ipx serv_addr;
unsigned char server_name[49];
unsigned char server_name[NCP_BINDERY_NAME_LEN];
unsigned char username[NCP_USERNAME_LEN+1];
unsigned char password[NCP_PASSWORD_LEN+1];
unsigned char mount_point[PATH_MAX+1];
unsigned char mounted_vol[NCP_VOLNAME_LEN+1];
unsigned int time_out; /* How long should I wait after
sending a NCP request? */
......
......@@ -34,13 +34,17 @@
#define MAX_ADDR_LEN 7
#ifndef CONFIG_AX25
#ifndef CONFIG_TR
#ifndef CONFIG_NET_IPIP
#define MAX_HEADER 32 /* We really need about 18 worst case .. so 32 is aligned */
#else
#define MAX_HEADER 48 /* We need to allow for having tunnel headers */
#endif /* IPIP */
#else
#define MAX_HEADER 48 /* Token Ring header needs 40 bytes ... 48 is aligned */
#endif
#endif /* TR */
#else
#define MAX_HEADER 96 /* AX.25 + NetROM */
#endif
#endif /* AX25 */
#define IS_MYADDR 1 /* address is (one of) our own */
#define IS_LOOPBACK 2 /* address is for LOOPBACK */
......
......@@ -327,6 +327,8 @@
#define PCI_DEVICE_ID_OPTI_82C822 0xc822
#define PCI_VENDOR_ID_SGS 0x104a
#define PCI_DEVICE_ID_SGS_2000 0x0008
#define PCI_DEVICE_ID_SGS_1764 0x0009
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
#define PCI_DEVICE_ID_BUSLOGIC_946C_2 0x0140
......@@ -418,6 +420,7 @@
#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
#define PCI_VENDOR_ID_AMCC 0x10e8
#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
#define PCI_VENDOR_ID_INTERG 0x10ea
#define PCI_DEVICE_ID_INTERG_1680 0x1680
......@@ -465,6 +468,12 @@
#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
#define PCI_VENDOR_ID_RP 0x11fe
#define PCI_DEVICE_ID_RP8OCTA 0x0001
#define PCI_DEVICE_ID_RP8INTF 0x0002
#define PCI_DEVICE_ID_RP16INTF 0x0003
#define PCI_DEVICE_ID_RP32INTF 0x0004
#define PCI_VENDOR_ID_CYCLADES 0x120e
#define PCI_DEVICE_ID_CYCLADES_Y 0x0100
......
......@@ -46,6 +46,7 @@ enum root_directory_inos {
enum pid_directory_inos {
PROC_PID_INO = 2,
PROC_PID_STATUS,
PROC_PID_MEM,
PROC_PID_CWD,
PROC_PID_ROOT,
......
......@@ -185,7 +185,7 @@ struct scc_stat {
};
struct scc_modem{
struct scc_modem {
long speed; /* Line speed, bps */
char clocksrc; /* 0 = DPLL, 1 = external, 2 = divider */
char nrz; /* NRZ instead of NRZI */
......
......@@ -104,8 +104,6 @@ struct sched_param {
#ifdef __KERNEL__
#define barrier() __asm__("": : :"memory")
extern void sched_init(void);
extern void show_state(void);
extern void trap_init(void);
......
......@@ -203,6 +203,7 @@ extern int ax25_rt_get_info(char *, char **, off_t, int, int);
extern int ax25_cs_get_info(char *, char **, off_t, int, int);
extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern void ax25_rt_build_path(ax25_cb *, ax25_address *);
extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *);
extern void ax25_rt_device_down(struct device *);
extern int ax25_rt_ioctl(unsigned int, void *);
extern void ax25_ip_mode_set(ax25_address *, struct device *, char);
......
......@@ -197,6 +197,12 @@ struct sock
ipx_address ipx_dest_addr;
ipx_interface *ipx_intrfc;
unsigned short ipx_port;
/* To handle asynchronous messages from the NetWare server, we have to
* know the connection this socket belongs to. Sorry to blow up this
* structure even more. */
struct ncp_server *ipx_ncp_server;
#ifdef CONFIG_IPX_INTERN
unsigned char ipx_node[IPX_NODE_LEN];
#endif
......
......@@ -180,6 +180,7 @@ struct symbol_table symbol_table = {
X(check_disk_change),
X(invalidate_buffers),
X(invalidate_inodes),
X(invalidate_inode_pages),
X(fsync_dev),
X(permission),
X(inode_setattr),
......@@ -192,6 +193,7 @@ struct symbol_table symbol_table = {
X(__bforget),
X(ll_rw_block),
X(__wait_on_buffer),
X(__wait_on_page),
X(mark_buffer_uptodate),
X(unlock_buffer),
X(dcache_lookup),
......
......@@ -41,7 +41,40 @@ struct page * page_hash_table[PAGE_HASH_SIZE];
* Simple routines for both non-shared and shared mappings.
*/
void invalidate_inode_pages(struct inode * inode, unsigned long start)
/*
* Invalidate the pages of an inode, removing all pages that aren't
* locked down (those are sure to be up-to-date anyway, so we shouldn't
* invalidate them).
*/
void invalidate_inode_pages(struct inode * inode)
{
struct page ** p;
struct page * page;
p = &inode->i_pages;
while ((page = *p) != NULL) {
if (page->locked) {
p = &page->next;
continue;
}
inode->i_nrpages--;
if ((*p = page->next) != NULL)
(*p)->prev = page->prev;
page->dirty = 0;
page->next = NULL;
page->prev = NULL;
remove_page_from_hash_queue(page);
page->inode = NULL;
free_page(page_address(page));
continue;
}
}
/*
* Truncate the page cache at a set offset, removing the pages
* that are beyond that offset (and zeroing out partial pages).
*/
void truncate_inode_pages(struct inode * inode, unsigned long start)
{
struct page ** p;
struct page * page;
......@@ -261,14 +294,12 @@ void __wait_on_page(struct page *page)
* inode->i_op->readpage() function for the actual low-level
* stuff.
*/
#define READAHEAD_PAGES 3
#define MAX_IO_PAGES 4
#define MAX_READAHEAD (PAGE_SIZE*4)
int generic_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int read = 0, newpage = 0;
int read = 0;
unsigned long pos;
unsigned long page_cache = 0;
int pre_read = 0;
if (count <= 0)
return 0;
......@@ -277,8 +308,6 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
do {
struct page *page;
unsigned long offset, addr, nr;
int i;
off_t p;
if (pos >= inode->i_size)
break;
......@@ -326,48 +355,29 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
add_page_to_hash_queue(inode, page);
inode->i_op->readpage(inode, page);
/* We only set "newpage" when we encounter a
completely uncached page. This way, we do no
readahead if we are still just reading data out of
the cache (even if the cached page is not yet
uptodate --- it may be currently being read as a
result of previous readahead). -- sct */
newpage = 1;
found_page:
addr = page_address(page);
if (nr > count)
nr = count;
/* We have two readahead cases. First, do data
pre-read if the current read request is for more
than one page, so we can merge the adjacent
requests. */
if (newpage && nr < count) {
if (pre_read > 0)
pre_read -= PAGE_SIZE;
else {
pre_read = (MAX_IO_PAGES-1) * PAGE_SIZE;
if (pre_read > (count - nr))
pre_read = count - nr;
for (i=0, p=pos; i<pre_read; i+=PAGE_SIZE) {
p += PAGE_SIZE;
page_cache = try_to_read_ahead(inode, p, page_cache);
}
}
}
else
/* Second, do readahead at the end of the read, if we
are still waiting on the current IO to complete, if
readahead is flagged for the file, and if we have
finished with the current block. */
if (newpage && nr == count && filp->f_reada
&& !((pos + nr) & ~PAGE_MASK)) {
for (i=0, p=pos; i<READAHEAD_PAGES; i++) {
p += PAGE_SIZE;
page_cache = try_to_read_ahead(inode, p, page_cache);
/*
* We may want to do read-ahead.. Do this only
* if we're waiting for the current page to be
* filled in, and if
* - we're going to read more than this page
* - if "f_reada" is set
*/
if (page->locked) {
if (nr < count || filp->f_reada) {
unsigned long ahead = 0;
do {
ahead += PAGE_SIZE;
page_cache = try_to_read_ahead(inode, pos + ahead, page_cache);
} while (ahead < MAX_READAHEAD);
}
__wait_on_page(page);
}
wait_on_page(page);
if (nr > inode->i_size - pos)
nr = inode->i_size - pos;
memcpy_tofs(buf, (void *) (addr + offset), nr);
......
......@@ -48,6 +48,7 @@
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/pgtable.h>
#include <asm/string.h>
unsigned long high_memory = 0;
......@@ -177,13 +178,12 @@ void free_page_tables(struct task_struct * tsk)
int new_page_tables(struct task_struct * tsk)
{
pgd_t * page_dir, * new_pg;
int i;
if (!(new_pg = pgd_alloc()))
return -ENOMEM;
page_dir = pgd_offset(&init_mm, 0);
for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++)
new_pg[i] = page_dir[i];
memcpy(new_pg + USER_PTRS_PER_PGD, page_dir + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof (pgd_t));
invalidate_mm(tsk->mm);
SET_PAGE_DIR(tsk, new_pg);
tsk->mm->pgd = new_pg;
......@@ -801,7 +801,7 @@ void vmtruncate(struct inode * inode, unsigned long offset)
{
struct vm_area_struct * mpnt;
invalidate_inode_pages(inode, offset);
truncate_inode_pages(inode, offset);
if (!inode->i_mmap)
return;
mpnt = inode->i_mmap;
......
This diff is collapsed.
......@@ -27,7 +27,7 @@
* AX.25 030 Jonathan(G4KLX) Added AX.25 fragment reception.
* Upgraded state machine for SABME.
* Added arbitrary protocol id support.
* Joerg(DL1BKE) Added DAMA support
* AX.25 031 Joerg(DL1BKE) Added DAMA support
*/
#include <linux/config.h>
......@@ -268,14 +268,12 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
case DISC:
ax25_send_control(ax25, UA, pf, C_RESPONSE);
if (ax25->dama_slave)
{
if (ax25->dama_slave) {
ax25->state = AX25_STATE_0;
ax25->dama_slave = 0;
ax25_dama_off(ax25);
if (ax25->sk != NULL)
{
if (ax25->sk != NULL) {
ax25->sk->state = TCP_CLOSE;
ax25->sk->err = 0;
if (!ax25->sk->dead)
......@@ -321,12 +319,11 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
case REJ:
case RNR:
case RR:
if (pf)
{
if (pf) {
if (ax25->dama_slave)
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
else
ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
}
break;
......@@ -465,8 +462,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
ax25_check_iframes_acked(ax25, nr);
}
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf)
{
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
......@@ -477,8 +473,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
if (ns == ax25->vr) {
queued = ax25_rx_iframe(ax25, skb);
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf)
{
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
......@@ -492,7 +487,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
ax25_enquiry_response(ax25);
} else {
if (!(ax25->condition & ACK_PENDING_CONDITION)) {
ax25->t2timer = ax25->t2;
......@@ -501,8 +496,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
} else {
if (ax25->condition & REJECT_CONDITION) {
if (pf)
{
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
......@@ -513,7 +507,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
ax25_send_control(ax25, REJ, pf, C_RESPONSE);
ax25_send_control(ax25, REJ, pf, C_RESPONSE);
ax25->condition &= ~ACK_PENDING_CONDITION;
}
}
......@@ -716,8 +710,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
ax25_frames_acked(ax25, nr);
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf)
{ /* dl1bke 960114 */
if (pf) { /* dl1bke 960114 */
if (ax25->dama_slave)
ax25_enquiry_response(ax25);
else
......@@ -728,8 +721,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
if (ns == ax25->vr) {
queued = ax25_rx_iframe(ax25, skb);
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf)
{ /* dl1bke 960114 */
if (pf) { /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
......@@ -743,7 +735,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
ax25_enquiry_response(ax25);
} else {
if (!(ax25->condition & ACK_PENDING_CONDITION)) {
ax25->t2timer = ax25->t2;
......@@ -752,8 +744,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
} else {
if (ax25->condition & REJECT_CONDITION) {
if (pf)
{ /* dl1bke 960114 */
if (pf) { /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
......@@ -764,7 +755,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
if (ax25->dama_slave) /* dl1bke 960114 */
dama_enquiry_response(ax25);
else
ax25_send_control(ax25, REJ, pf, C_RESPONSE);
ax25_send_control(ax25, REJ, pf, C_RESPONSE);
ax25->condition &= ~ACK_PENDING_CONDITION;
}
}
......
......@@ -24,7 +24,7 @@
* Jonathan(G4KLX) Only poll when window is full.
* AX.25 030 Jonathan(G4KLX) Added fragmentation to ax25_output.
* Added support for extended AX.25.
* Joerg(DL1BKE) Added DAMA support
* AX.25 031 Joerg(DL1BKE) Added DAMA support
*/
#include <linux/config.h>
......@@ -109,8 +109,7 @@ void ax25_output(ax25_cb *ax25, struct sk_buff *skb)
skb_queue_tail(&ax25->write_queue, skb); /* Throw it on the queue */
}
if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4)
{
if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
if (!ax25->dama_slave) /* bke 960114: we aren't allowed to transmit */
ax25_kick(ax25); /* in DAMA mode unless we received a Poll */
}
......@@ -318,34 +317,34 @@ void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
}
}
/* dl1bke 960114: shouldn't ax25/dama_check_need_response reside as */
/* static inline void ...() in ax25.h, should it? ;-) */
/*
* dl1bke 960114: shouldn't ax25/dama_check_need_response reside as
* static inline void ...() in ax25.h, should it? ;-)
*/
void ax25_check_need_response(ax25_cb *ax25, int type, int pf)
{
if (!ax25->dama_slave && type == C_COMMAND && pf)
ax25_enquiry_response(ax25);
}
/* dl1bke 960114: transmit I frames on DAMA poll */
void dama_enquiry_response(ax25_cb * ax25)
/*
* dl1bke 960114: transmit I frames on DAMA poll
*/
void dama_enquiry_response(ax25_cb *ax25)
{
ax25_cb * ax25o = NULL;
ax25_cb *ax25o;
if (!(ax25->condition & PEER_RX_BUSY_CONDITION) )
{
if (!(ax25->condition & PEER_RX_BUSY_CONDITION)) {
ax25_requeue_frames(ax25);
ax25_kick(ax25);
}
if (ax25->state == AX25_STATE_1 ||
ax25->state == AX25_STATE_2 ||
skb_peek(&ax25->ack_queue) != NULL)
{
ax25_t1_timeout(ax25);
} else
if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 ||
skb_peek(&ax25->ack_queue) != NULL) {
ax25_t1_timeout(ax25);
} else {
ax25->n2count = 0;
}
ax25->t3timer = ax25->t3;
......@@ -367,31 +366,29 @@ void dama_enquiry_response(ax25_cb * ax25)
/* transmissions of the other channels as well... This version */
/* gives better performance on FLEXNET nodes. (Why, Gunter?) */
for (ax25o=ax25_list; ax25o; ax25o=ax25o->next)
{
for (ax25o = ax25_list; ax25o != NULL; ax25o = ax25o->next) {
if (ax25o->device != ax25->device)
continue;
if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2)
{
if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
ax25_t1_timeout(ax25o);
continue;
}
if ( !ax25o->dama_slave)
if (!ax25o->dama_slave)
continue;
if ( !(ax25o->condition & PEER_RX_BUSY_CONDITION) &&
(ax25o->state == AX25_STATE_3 ||
(ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0)) )
{
(ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0))) {
ax25_requeue_frames(ax25o);
ax25_kick(ax25o);
}
if (ax25o->state == AX25_STATE_1 ||
ax25o->state == AX25_STATE_2 ||
skb_peek(&ax25o->ack_queue) != NULL) ax25_t1_timeout(ax25o);
if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 ||
skb_peek(&ax25o->ack_queue) != NULL) {
ax25_t1_timeout(ax25o);
}
ax25o->t3timer = ax25o->t3;
}
......
......@@ -30,7 +30,7 @@
* AX.25 031 Jonathan(G4KLX) Added concept of default route.
* Joerg(DL1BKE) ax25_rt_build_path() find digipeater list and device by
* destination call. Needed for IP routing via digipeater
*
* Jonathan(G4KLX) Added routing for IP datagram packets.
*/
#include <linux/config.h>
......@@ -101,21 +101,14 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev, ax25_digi *digi)
}
if (count > AX25_ROUTE_MAX) {
oldest->callsign = *src;
oldest->dev = dev;
if (oldest->digipeat != NULL) {
if (oldest->digipeat != NULL)
kfree_s(oldest->digipeat, sizeof(ax25_digi));
oldest->digipeat = NULL;
}
oldest->stamp = xtime;
oldest->n = 1;
oldest->ip_mode = ' ';
return;
ax25_rt = oldest;
} else {
if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
return; /* No space */
}
if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
return; /* No space */
ax25_rt->callsign = *src;
ax25_rt->dev = dev;
ax25_rt->digipeat = NULL;
......@@ -128,16 +121,18 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev, ax25_digi *digi)
kfree_s(ax25_rt, sizeof(struct ax25_route));
return;
}
memcpy(ax25_rt->digipeat, digi, sizeof(ax25_digi));
*ax25_rt->digipeat = *digi;
}
save_flags(flags);
cli();
if (ax25_rt != oldest) {
save_flags(flags);
cli();
ax25_rt->next = ax25_route;
ax25_route = ax25_rt;
ax25_rt->next = ax25_route;
ax25_route = ax25_rt;
restore_flags(flags);
restore_flags(flags);
}
}
void ax25_rt_device_down(struct device *dev)
......@@ -402,12 +397,12 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
call = (ax25_address *)ax25->device->dev_addr;
}
memcpy(&ax25->source_addr, call, sizeof(ax25_address));
ax25->source_addr = *call;
if (ax25_rt->digipeat != NULL) {
if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
return -ENOMEM;
memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
*ax25->digipeat = *ax25_rt->digipeat;
}
if (ax25->sk != NULL)
......@@ -424,8 +419,7 @@ void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr)
struct ax25_route *ax25_rt;
for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
if ( ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->digipeat != NULL ) {
if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->digipeat != NULL) {
if (ax25_rt->dev == NULL)
continue;
......@@ -433,12 +427,48 @@ void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr)
return;
ax25->device = ax25_rt->dev;
memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
*ax25->digipeat = *ax25_rt->digipeat;
return;
}
}
ax25->digipeat = NULL;
}
void ax25_dg_build_path(struct sk_buff *skb, ax25_address *addr, struct device *dev)
{
struct ax25_route *ax25_rt;
ax25_address src, dest;
unsigned char *bp;
int len;
for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev == dev) {
if (ax25_rt->digipeat == NULL)
return;
len = ax25_rt->digipeat->ndigi * AX25_ADDR_LEN;
if (skb_headroom(skb) < len) {
printk("ax25_dg_build_path: not enough headroom for in skb\n");
return;
}
memcpy(&dest, skb->data + 1, AX25_ADDR_LEN);
memcpy(&src, skb->data + 8, AX25_ADDR_LEN);
bp = skb_push(skb, len);
*bp++ = 0x00; /* KISS Data */
build_ax25_addr(bp, &src, &dest, ax25_rt->digipeat, C_COMMAND, MODULUS);
return;
}
}
}
/*
* Register the mode of an incoming IP frame. It is assumed that an entry
* already exists in the routing table.
......@@ -563,7 +593,6 @@ int ax25_dev_ioctl(unsigned int cmd, void *arg)
struct device *dev;
struct ax25_dev *ax25_dev;
int err;
int count;
switch (cmd) {
case SIOCAX25SETPARMS:
......
......@@ -25,7 +25,7 @@
* Added fragmentation support.
* Darryl(G7LED) Added function ax25_requeue_frames() to split
* it up from ax25_frames_acked().
* Joerg(DL1BKE) DAMA needs KISS Fullduplex ON/OFF.
* AX.25 031 Joerg(DL1BKE) DAMA needs KISS Fullduplex ON/OFF.
* Thus we have ax25_kiss_cmd() now... ;-)
* Dave Brown(N2RJT)
* Killed a silly bug in the DAMA code.
......@@ -360,8 +360,7 @@ unsigned char *ax25_parse_addr(unsigned char *buf, int len, ax25_address *src, a
digi->lastrepeat = -1;
digi->ndigi = 0;
while (!(buf[-1] & LAPB_E))
{
while (!(buf[-1] & LAPB_E)) {
if (d >= AX25_MAX_DIGIS) return NULL; /* Max of 6 digis */
if (len < 7) return NULL; /* Short packet */
......@@ -473,7 +472,16 @@ void ax25_digi_invert(ax25_digi *in, ax25_digi *out)
out->lastrepeat = 0;
}
void ax25_kiss_cmd(ax25_cb * ax25, unsigned char cmd, unsigned char param)
/*
* :::FIXME:::
* This is ****NOT**** the right approach. Not all drivers do kiss. We
* need a driver level request to switch duplex mode, that does either
* SCC changing, PI config or KISS as required.
*
* Not to mention this request isnt currently reliable.
*/
void ax25_kiss_cmd(ax25_cb *ax25, unsigned char cmd, unsigned char param)
{
struct sk_buff *skb;
unsigned char *p;
......@@ -487,8 +495,7 @@ void ax25_kiss_cmd(ax25_cb * ax25, unsigned char cmd, unsigned char param)
skb->free = 1;
skb->arp = 1;
if (ax25->sk != NULL)
{
if (ax25->sk != NULL) {
skb->sk = ax25->sk;
ax25->sk->wmem_alloc += skb->truesize;
}
......@@ -507,10 +514,9 @@ void ax25_dama_on(ax25_cb *ax25)
{
int count = ax25_dev_is_dama_slave(ax25->device);
if (count == 0)
{
if (ax25->sk && ax25->sk->debug)
printk("DAMA on\n");
if (count == 0) {
if (ax25->sk != NULL && ax25->sk->debug)
printk("ax25_dama_on: DAMA on\n");
ax25_kiss_cmd(ax25, 5, 1);
}
}
......@@ -519,11 +525,9 @@ void ax25_dama_off(ax25_cb *ax25)
{
int count = ax25_dev_is_dama_slave(ax25->device);
if (count == 0)
{
if (ax25->sk && ax25->sk->debug)
printk("DAMA off\n");
if (count == 0) {
if (ax25->sk != NULL && ax25->sk->debug)
printk("ax25_dama_off: DAMA off\n");
ax25_kiss_cmd(ax25, 5, 0);
}
}
......
......@@ -17,6 +17,7 @@
* AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from the
* sock structure.
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
*/
#include <linux/config.h>
......@@ -112,7 +113,7 @@ static void ax25_timer(unsigned long param)
if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
ax25->condition &= ~OWN_RX_BUSY_CONDITION;
if (!ax25->dama_slave) /* dl1bke */
ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
ax25->condition &= ~ACK_PENDING_CONDITION;
break;
}
......@@ -133,19 +134,15 @@ static void ax25_timer(unsigned long param)
if (ax25->condition & ACK_PENDING_CONDITION) {
ax25->condition &= ~ACK_PENDING_CONDITION;
if (!ax25->dama_slave) /* dl1bke 960114 */
ax25_timeout_response(ax25);
ax25_timeout_response(ax25);
}
}
}
if (ax25->t3timer > 0 && --ax25->t3timer == 0)
{
if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
/* dl1bke 960114: T3 expires and we are in DAMA mode: */
/* send a DISC and abort the connection */
if (ax25->dama_slave)
{
if (ax25->dama_slave) {
#ifdef CONFIG_NETROM
nr_link_failed(&ax25->dest_addr, ax25->device);
#endif
......@@ -153,8 +150,7 @@ static void ax25_timer(unsigned long param)
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
ax25->state = AX25_STATE_0;
if (ax25->sk != NULL)
{
if (ax25->sk != NULL) {
if (ax25->sk->debug)
printk("T3 Timeout\n");
ax25->sk->state = TCP_CLOSE;
......@@ -179,14 +175,13 @@ static void ax25_timer(unsigned long param)
/* nevertheless we have to re-enqueue the timer struct... */
if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
ax25_reset_timer(ax25);
return;
}
if (!ax25_dev_is_dama_slave(ax25->device))
{
if (ax25->dama_slave) ax25->dama_slave = 0;
if (!ax25_dev_is_dama_slave(ax25->device)) {
if (ax25->dama_slave)
ax25->dama_slave = 0;
ax25_t1_timeout(ax25);
}
}
......@@ -200,8 +195,6 @@ static void ax25_timer(unsigned long param)
* Thus we'll have to do parts of our T1 handling in
* ax25_enquiry_response().
*/
void ax25_t1_timeout(ax25_cb * ax25)
{
switch (ax25->state) {
......@@ -255,14 +248,14 @@ void ax25_t1_timeout(ax25_cb * ax25)
} else {
ax25->n2count++;
if (!ax25_dev_is_dama_slave(ax25->device)) /* dl1bke */
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
}
break;
case AX25_STATE_3:
ax25->n2count = 1;
if (!ax25->dama_slave) /* dl1bke 960114 */
ax25_transmit_enquiry(ax25);
ax25_transmit_enquiry(ax25);
ax25->state = AX25_STATE_4;
break;
......@@ -286,7 +279,7 @@ void ax25_t1_timeout(ax25_cb * ax25)
} else {
ax25->n2count++;
if (!ax25->dama_slave) /* dl1bke 960114 */
ax25_transmit_enquiry(ax25);
ax25_transmit_enquiry(ax25);
}
break;
}
......
......@@ -43,6 +43,8 @@
* on a Sparc.
* Bjorn Ekwall : Added KERNELD hack.
* Alan Cox : Cleaned up the backlog initialise.
* Craig Metz : SIOCGIFCONF fix if space for under
* 1 device.
*
*/
......@@ -214,8 +216,15 @@ struct device *dev_get(const char *name)
extern __inline__ void dev_load(const char *name)
{
if(!dev_get(name))
request_module(name);
char *sptr;
if(!dev_get(name)) {
#ifdef CONFIG_NET_ALIAS
for (sptr=name ; *sptr ; sptr++) if(*sptr==':') break;
if (!(*sptr && *(sptr+1)))
#endif
request_module(name);
}
}
#endif
......@@ -788,11 +797,6 @@ static int dev_ifconf(char *arg)
{
if(!(dev->flags & IFF_UP)) /* Downed devices don't count */
continue;
memset(&ifr, 0, sizeof(struct ifreq));
strcpy(ifr.ifr_name, dev->name);
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
/*
* Have we run out of space here ?
*/
......@@ -800,6 +804,12 @@ static int dev_ifconf(char *arg)
if (len < sizeof(struct ifreq))
break;
memset(&ifr, 0, sizeof(struct ifreq));
strcpy(ifr.ifr_name, dev->name);
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
(*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
/*
* Write this block to the caller's space.
*/
......
......@@ -15,9 +15,12 @@
* - net_alias_type objs registration/unreg., module-ables.
* - /proc/net/aliases & /proc/net/alias_types entries
* Fixes:
* JJC : several net_alias_type func. renamed.
* JJC : net_alias_type object methods now pass *this.
* JJC : xxx_rcv device selection based on <src,dst> addrs
* JJC : several net_alias_type func. renamed.
* JJC : net_alias_type object methods now pass
* *this.
* JJC : xxx_rcv device selection based on <src,dst>
* addrs
* Andreas Schultz : Kerneld support.
*
* FIXME:
* - User calls sleep/wake_up locking.
......@@ -30,6 +33,7 @@
*
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
......@@ -47,6 +51,10 @@
#include <linux/net_alias.h>
#ifdef CONFIG_KERNELD
#include <linux/kerneld.h>
#endif
/*
* Only allow the following flags to pass from main device to aliases
*/
......@@ -346,13 +354,23 @@ net_alias_dev_create(struct device *main_dev, int slot, int *err, struct sockadd
*/
nat = nat_getbytype(family);
if (!nat)
{
printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
main_dev->name, slot, family);
/* *err = -EAFNOSUPPORT; */
*err = -EINVAL;
return NULL;
if (!nat) {
#ifdef CONFIG_KERNELD
char modname[20];
sprintf (modname,"netalias-%d", family);
request_module(modname);
nat = nat_getbytype(family);
if (!nat) {
#endif
printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
main_dev->name, slot, family);
/* *err = -EAFNOSUPPORT; */
*err = -EINVAL;
return NULL;
#ifdef CONFIG_KERNELD
}
#endif
}
/*
......
......@@ -558,17 +558,15 @@ void __release_sock(struct sock *sk)
*/
/* See if we have any packets built up. */
start_bh_atomic();
while ((skb = __skb_dequeue(&sk->back_log)) != NULL)
{
barrier();
sk->users = 1;
if (sk->prot->rcv)
sk->prot->rcv(skb, skb->dev, (struct options*)skb->proto_priv,
skb->saddr, skb->len, skb->daddr, 1,
/* Only used for/by raw sockets. */
(struct inet_protocol *)sk->pair);
sk->users = 0;
barrier();
}
end_bh_atomic();
#endif
}
......@@ -322,36 +322,24 @@ void destroy_sock(struct sock *sk)
kfree_skb(skb, FREE_WRITE);
}
/*
* In case it's sleeping somewhere.
*/
if (!sk->dead)
sk->write_space(sk);
/*
* Don't discard received data until the user side kills its
* half of the socket.
* Clean up the read buffer.
*/
if (sk->dead)
while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
{
while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
{
/*
* This will take care of closing sockets that were
* listening and didn't accept everything.
*/
if (skb->sk != NULL && skb->sk != sk)
{
IS_SKB(skb);
skb->sk->dead = 1;
skb->sk->prot->close(skb->sk, 0);
}
if (skb->sk != NULL && skb->sk != sk)
{
IS_SKB(skb);
kfree_skb(skb, FREE_READ);
skb->sk->prot->close(skb->sk, 0);
}
}
IS_SKB(skb);
kfree_skb(skb, FREE_READ);
}
/*
* Now we need to clean up the send head.
......@@ -396,7 +384,6 @@ void destroy_sock(struct sock *sk)
if (sk->pair)
{
sk->pair->dead = 1;
sk->pair->prot->close(sk->pair, 0);
sk->pair = NULL;
}
......@@ -407,7 +394,7 @@ void destroy_sock(struct sock *sk)
* everything is gone.
*/
if (sk->dead && sk->rmem_alloc == 0 && sk->wmem_alloc == 0)
if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0)
{
if(sk->opt)
kfree(sk->opt);
......@@ -423,6 +410,7 @@ void destroy_sock(struct sock *sk)
{
/* this should never happen. */
/* actually it can if an ack has just been sent. */
printk("Socket destroy delayed\n");
sk->destroy = 1;
sk->ack_backlog = 0;
release_sock(sk);
......@@ -1028,7 +1016,6 @@ static int inet_accept(struct socket *sock, struct socket *newsock, int flags)
{
struct sock *sk=(struct sock *)newsock->data;
newsock->data=NULL;
sk->dead = 1;
destroy_sock(sk);
}
......@@ -1078,7 +1065,6 @@ static int inet_accept(struct socket *sock, struct socket *newsock, int flags)
if (sk2->state != TCP_ESTABLISHED && sk2->err > 0)
{
err = sock_error(sk2);
sk2->dead=1;
destroy_sock(sk2);
newsock->data = NULL;
return err;
......
......@@ -53,6 +53,9 @@
* message (960131).
* Christian Daudt : removed del_timer from
* igmp_timer_expire function (960205).
* Christian Daudt : igmp_heard_report now only calls
* igmp_timer_expire if tm->running is
* true (960216).
*/
......@@ -288,7 +291,7 @@ static void igmp_heard_report(struct device *dev, unsigned long address)
if ((address & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP) {
/* Timers are only set for non-local groups */
for(im=dev->ip_mc_list;im!=NULL;im=im->next) {
if(im->multiaddr==address) {
if(im->multiaddr==address && im->tm_running) {
igmp_stop_timer(im);
}
}
......
......@@ -62,6 +62,7 @@
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/route.h>
......@@ -557,9 +558,10 @@ static __inline__ void fib_add_1(short flags, __u32 dst, __u32 mask,
{
/*
* Don't try to add a gateway we can't reach..
* Tunnel devices are exempt from this rule.
*/
if (dev != get_gw_dev(gw))
if ((dev != get_gw_dev(gw)) && dev->type!=ARPHRD_TUNNEL)
return;
flags |= RTF_GATEWAY;
......
......@@ -480,7 +480,6 @@ static void tcp_close_pending (struct sock *sk)
while ((skb = skb_dequeue(&sk->receive_queue)) != NULL)
{
skb->sk->dead=1;
tcp_close(skb->sk, 0);
kfree_skb(skb, FREE_READ);
}
......@@ -1728,7 +1727,7 @@ static int tcp_close_state(struct sock *sk, int dead)
/*
* Shutdown the sending side of a connection. Much like close except
* that we don't receive shut down or set sk->dead=1.
* that we don't receive shut down or set sk->dead.
*/
void tcp_shutdown(struct sock *sk, int how)
......@@ -1817,6 +1816,7 @@ static void tcp_close(struct sock *sk, unsigned long timeout)
tcp_set_state(sk, TCP_CLOSE);
tcp_close_pending(sk);
release_sock(sk);
sk->dead = 1;
return;
}
......@@ -1873,9 +1873,9 @@ static void tcp_close(struct sock *sk, unsigned long timeout)
* This will destroy it. The timers will take care of actually
* free'ing up the memory.
*/
sk->dead = 1;
tcp_cache_zap(); /* Kill the cache again. */
release_sock(sk);
sk->dead = 1;
}
......
......@@ -670,9 +670,7 @@ void tcp_send_synack(struct sock * newsk, struct sock * sk, struct sk_buff * skb
if (buff == NULL)
{
sk->err = ENOMEM;
newsk->dead = 1;
newsk->state = TCP_CLOSE;
/* And this will destroy it */
destroy_sock(newsk);
kfree_skb(skb, FREE_READ);
tcp_statistics.TcpAttemptFails++;
return;
......@@ -697,8 +695,7 @@ void tcp_send_synack(struct sock * newsk, struct sock * sk, struct sk_buff * skb
sk->err = tmp;
buff->free = 1;
kfree_skb(buff,FREE_WRITE);
newsk->dead = 1;
newsk->state = TCP_CLOSE;
destroy_sock(newsk);
skb->sk = sk;
kfree_skb(skb, FREE_READ);
tcp_statistics.TcpAttemptFails++;
......
......@@ -94,7 +94,7 @@ void net_timer (unsigned long data)
if (sk->users)
{
sk->timer.expires = jiffies+10;
sk->timer.expires = jiffies+HZ;
add_timer(&sk->timer);
sti();
return;
......@@ -134,15 +134,7 @@ void net_timer (unsigned long data)
* the socket to be freed.
*/
if(sk->wmem_alloc!=0 || sk->rmem_alloc!=0)
{
sk->wmem_alloc++; /* So it DOESN'T go away */
destroy_sock (sk);
sk->wmem_alloc--; /* Might now have hit 0 - fall through and do it again if so */
sk->users = 0; /* This will be ok, the destroy won't totally work */
}
if(sk->wmem_alloc==0 && sk->rmem_alloc==0)
destroy_sock(sk); /* Socket gone, DON'T update sk->users! */
destroy_sock(sk);
break;
case TIME_CLOSE:
......@@ -152,7 +144,7 @@ void net_timer (unsigned long data)
if (!sk->dead)
sk->state_change(sk);
sk->shutdown = SHUTDOWN_MASK;
reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME);
reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
break;
default:
......
......@@ -1614,6 +1614,7 @@ ipx_create(struct socket *sock, int protocol)
sk->socket=sock;
sk->type=sock->type;
sk->ipx_type=0; /* General user level IPX */
sk->ipx_ncp_server = NULL;
sk->debug=0;
sk->ipx_intrfc = NULL;
memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
......
This diff is collapsed.
......@@ -55,8 +55,7 @@ int nr_rx_ip(struct sk_buff *skb, struct device *dev)
{
struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
if (!dev->start)
{
if (!dev->start) {
stats->rx_errors++;
return 0;
}
......
......@@ -150,7 +150,7 @@ void nr_kick(struct sock *sk)
end = (sk->nr->va + sk->window) % NR_MODULUS;
if (!(sk->nr->condition & PEER_RX_BUSY_CONDITION) &&
start != end &&
start != end &&
skb_peek(&sk->write_queue) != NULL) {
sk->nr->vs = start;
......@@ -208,13 +208,13 @@ void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
*/
dptr = skb_push(skb, NR_NETWORK_LEN);
memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
memcpy(dptr, &sk->nr->source_addr, AX25_ADDR_LEN);
dptr[6] &= ~LAPB_C;
dptr[6] &= ~LAPB_E;
dptr[6] |= SSSID_SPARE;
dptr += AX25_ADDR_LEN;
memcpy(dptr, &sk->nr->dest_addr, sizeof(ax25_address));
memcpy(dptr, &sk->nr->dest_addr, AX25_ADDR_LEN);
dptr[6] &= ~LAPB_C;
dptr[6] |= LAPB_E;
dptr[6] |= SSSID_SPARE;
......
......@@ -88,21 +88,20 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
return -ENOMEM;
memcpy(&nr_neigh->callsign, ax25, sizeof(ax25_address));
nr_neigh->digipeat= NULL;
nr_neigh->dev = dev;
nr_neigh->quality = nr_default.quality;
nr_neigh->locked = 0;
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
nr_neigh->callsign = *ax25;
nr_neigh->digipeat = NULL;
nr_neigh->dev = dev;
nr_neigh->quality = nr_default.quality;
nr_neigh->locked = 0;
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
if (ax25_digi != NULL) {
if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
kfree_s(nr_neigh, sizeof(*nr_neigh));
return -ENOMEM;
}
memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi));
*nr_neigh->digipeat = *ax25_digi;
}
save_flags(flags);
......@@ -118,7 +117,7 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
if ((nr_node = (struct nr_node *)kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL)
return -ENOMEM;
memcpy(&nr_node->callsign, nr, sizeof(ax25_address));
nr_node->callsign = *nr;
memcpy(&nr_node->mnemonic, mnemonic, sizeof(nr_node->mnemonic));
nr_node->which = 0;
......@@ -355,14 +354,13 @@ static int nr_add_neigh(ax25_address *callsign, struct device *dev, unsigned int
if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
return -ENOMEM;
memcpy(&nr_neigh->callsign, callsign, sizeof(ax25_address));
nr_neigh->digipeat= NULL;
nr_neigh->dev = dev;
nr_neigh->quality = quality;
nr_neigh->locked = 1;
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
nr_neigh->callsign = *callsign;
nr_neigh->digipeat = NULL;
nr_neigh->dev = dev;
nr_neigh->quality = quality;
nr_neigh->locked = 1;
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
save_flags(flags);
cli();
......
......@@ -192,12 +192,12 @@ void nr_write_internal(struct sock *sk, int frametype)
*dptr++ = 0;
*dptr++ = frametype;
*dptr++ = sk->window;
memcpy(dptr, &sk->nr->user_addr, sizeof(ax25_address));
memcpy(dptr, &sk->nr->user_addr, AX25_ADDR_LEN);
dptr[6] &= ~LAPB_C;
dptr[6] &= ~LAPB_E;
dptr[6] |= SSSID_SPARE;
dptr += AX25_ADDR_LEN;
memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
memcpy(dptr, &sk->nr->source_addr, AX25_ADDR_LEN);
dptr[6] &= ~LAPB_C;
dptr[6] &= ~LAPB_E;
dptr[6] |= SSSID_SPARE;
......
......@@ -20,6 +20,7 @@
* Alan Cox : Limit size of allocated blocks.
* Alan Cox : Fixed the stupid socketpair bug.
* Alan Cox : BSD compatibility fine tuning.
* Alan Cox : Fixed a bug in connect when interrupted.
*
*
* Known differences from reference BSD that was tested:
......@@ -69,8 +70,9 @@ static unix_socket *unix_socket_list=NULL;
#define min(a,b) (((a)<(b))?(a):(b))
/*
* Make sure the unix name is null-terminated.
* Make sure the unix name is null-terminated.
*/
static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
{
if (len >= sizeof(*sunaddr))
......@@ -468,9 +470,13 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
sock->state=SS_UNCONNECTED;
return -ECONNREFUSED;
}
if(sock->state==SS_CONNECTING)
if(sock->state!=SS_CONNECTING)
return -EISCONN;
if(flags&O_NONBLOCK)
return -EALREADY;
return -EISCONN;
/*
* Drop through the connect up logic to the wait.
*/
}
if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
......@@ -478,15 +484,14 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
unix_mkname(sunaddr, addr_len);
if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
{
sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
sk->protinfo.af_unix.other=NULL;
sock->state=SS_UNCONNECTED;
}
if(sock->type==SOCK_DGRAM)
if(sk->type==SOCK_DGRAM)
{
if(sk->protinfo.af_unix.other)
{
sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
sk->protinfo.af_unix.other=NULL;
sock->state=SS_UNCONNECTED;
}
other=unix_find_other(sunaddr->sun_path, &err);
if(other==NULL)
return err;
......
......@@ -79,7 +79,8 @@ function help () {
#now pick out the right help text:
text=$(sed -n "/^$var[ ]*\$/,\${
/^$var[ ]*\$/b
/^#.*/b;/^[ ]*\$/q
/^#.*/b
/^[ ]*\$/q
p
}" Documentation/Configure.help)
if [ -z "$text" ]
......
......@@ -588,11 +588,12 @@ function activate_menu () {
default="${defaults%%*}" defaults="${defaults#*}"
;;
2)
echo >>dialog.out
read selection <dialog.out
default="${selection##* }"
case "$selection" in
*"-->"*) : ;;
*) eval help $selection ;;
*) eval help "$selection" ;;
esac
;;
255|1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment