Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
134b5d6ebf |
BIN
.downloads/ncpfs-2.0.6.tgz
Normal file
BIN
.downloads/ncpfs-2.0.6.tgz
Normal file
Binary file not shown.
14
BUGS
14
BUGS
@@ -5,6 +5,20 @@ But there are really problems that might be fixed in the future.
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
You might experience lockups of ncpfs volumes. It happens especially
|
||||||
|
under high network traffic, not necessarily only IPX traffic. I am not
|
||||||
|
able to reproduce this problem on my machine, so I'm sorry I can not
|
||||||
|
do anything about that. When such a lockup happens, you have to shut
|
||||||
|
down the complete ipx subsystem by deleting all ipx interfaces,
|
||||||
|
unmounting all ncpfs volumes (in this order!) and restarting all
|
||||||
|
again.
|
||||||
|
|
||||||
|
For the kernel hackers who want to look at the problem: The routine
|
||||||
|
ipx_sendmsg in net/ipx/af_ipx.c sometimes locks forever if called with
|
||||||
|
nonblock=0. I DO NOT KNOW WHY!!! HELP ME, PLEASE!
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
'df' returns 0: Free disk space is distributed among the volumes in
|
'df' returns 0: Free disk space is distributed among the volumes in
|
||||||
NetWare. df is only able to report one number per mounted
|
NetWare. df is only able to report one number per mounted
|
||||||
filesystem. As connections are quite expensive for NetWare (with
|
filesystem. As connections are quite expensive for NetWare (with
|
||||||
|
|||||||
10
Changes
10
Changes
@@ -1,6 +1,16 @@
|
|||||||
I only began this file with ncpfs-0.12. If you're interested in older
|
I only began this file with ncpfs-0.12. If you're interested in older
|
||||||
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
|
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
|
||||||
|
|
||||||
|
ncpfs-2.0.5 -> ncpfs-2.0.6
|
||||||
|
- Added a short description of a problem that I need help with to the
|
||||||
|
file BUGS. If you know a bit of the linux networking code, please
|
||||||
|
take a look at it. Thanks a lot.
|
||||||
|
- Added canonic output format to nwpbvalues and the command nwbpset. I
|
||||||
|
would like to invite you to help building capable bindery management
|
||||||
|
utilities. For little examples, look at the manual page of nwbpset.
|
||||||
|
- Added some values to ipxparse. Those interested in NDS should take a
|
||||||
|
look at it. It's really not much, but maybe it's a beginning.
|
||||||
|
|
||||||
ncpfs-2.0.4 -> ncpfs-2.0.5
|
ncpfs-2.0.4 -> ncpfs-2.0.5
|
||||||
- Removed another bug in nwbpvalues.
|
- Removed another bug in nwbpvalues.
|
||||||
- Cleaned up man/Makefile
|
- Cleaned up man/Makefile
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
|||||||
# Makefile for the linux ncp-filesystem routines.
|
# Makefile for the linux ncp-filesystem routines.
|
||||||
#
|
#
|
||||||
|
|
||||||
VERSION = 2.0.5
|
VERSION = 2.0.6
|
||||||
|
|
||||||
# If you are using kerneld to autoload ncp support,
|
# If you are using kerneld to autoload ncp support,
|
||||||
# uncomment this (kerneld is in linux since about 1.3.57):
|
# uncomment this (kerneld is in linux since about 1.3.57):
|
||||||
|
|||||||
@@ -329,9 +329,10 @@ int handle_burst(struct sockaddr_ipx *source,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_ncp (struct sockaddr_ipx *source,
|
void
|
||||||
struct sockaddr_ipx *target,
|
handle_ncp(struct sockaddr_ipx *source,
|
||||||
unsigned char *buf, int length, int no)
|
struct sockaddr_ipx *target,
|
||||||
|
unsigned char *buf, int length, int no)
|
||||||
{
|
{
|
||||||
struct ncp_request_header *rq = (struct ncp_request_header *)buf;
|
struct ncp_request_header *rq = (struct ncp_request_header *)buf;
|
||||||
struct ncp_reply_header *rs = (struct ncp_reply_header *)buf;
|
struct ncp_reply_header *rs = (struct ncp_reply_header *)buf;
|
||||||
@@ -339,6 +340,10 @@ void handle_ncp (struct sockaddr_ipx *source,
|
|||||||
int data_length = 0;
|
int data_length = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
static struct sockaddr_ipx request_source;
|
||||||
|
static struct ncp_request_header request_header;
|
||||||
|
static char request_data[5];
|
||||||
|
|
||||||
if (ntohs(rq->type) == NCP_REQUEST)
|
if (ntohs(rq->type) == NCP_REQUEST)
|
||||||
{
|
{
|
||||||
/* Request */
|
/* Request */
|
||||||
@@ -346,6 +351,10 @@ void handle_ncp (struct sockaddr_ipx *source,
|
|||||||
rq->conn_low + 256 * rq->conn_high,
|
rq->conn_low + 256 * rq->conn_high,
|
||||||
rq->sequence, rq->task);
|
rq->sequence, rq->task);
|
||||||
|
|
||||||
|
memcpy(&request_source, source, sizeof(request_source));
|
||||||
|
memcpy(&request_header, rq, sizeof(request_header));
|
||||||
|
memcpy(request_data, rq+1, sizeof(request_data));
|
||||||
|
|
||||||
data = buf + sizeof(struct ncp_request_header);
|
data = buf + sizeof(struct ncp_request_header);
|
||||||
data_length = length - sizeof(struct ncp_request_header);
|
data_length = length - sizeof(struct ncp_request_header);
|
||||||
|
|
||||||
@@ -583,13 +592,343 @@ void handle_ncp (struct sockaddr_ipx *source,
|
|||||||
data_length -= 1;
|
data_length -= 1;
|
||||||
break;
|
break;
|
||||||
case 97:
|
case 97:
|
||||||
|
{
|
||||||
|
struct INPUT
|
||||||
|
{
|
||||||
|
__u16 proposed_max_size;
|
||||||
|
__u8 security_flag;
|
||||||
|
} *i = (struct INPUT *)data;
|
||||||
|
|
||||||
printf("fn: %-3d\n", rq->function);
|
printf("fn: %-3d\n", rq->function);
|
||||||
printf("Get Big Packet NCP Max Packet Size\n");
|
printf("Get Big Packet NCP Max Packet Size\n");
|
||||||
|
printf("proposed_max_size: %x\n",
|
||||||
|
ntohs(i->proposed_max_size));
|
||||||
|
printf("security_flag: %x\n",
|
||||||
|
i->security_flag);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 101:
|
case 101:
|
||||||
|
{
|
||||||
|
struct INPUT
|
||||||
|
{
|
||||||
|
__u32 local_conn_id;
|
||||||
|
__u32 local_max_packet_size;
|
||||||
|
__u16 local_target_socket;
|
||||||
|
__u32 local_max_send_size;
|
||||||
|
__u32 local_max_recv_size;
|
||||||
|
} *i = (struct INPUT *)data;
|
||||||
|
|
||||||
printf("fn: %-3d\n", rq->function);
|
printf("fn: %-3d\n", rq->function);
|
||||||
printf("Packet Burst Connection Request\n");
|
printf("Packet Burst Connection Request\n");
|
||||||
|
printf("local_conn_id: %lx\n",
|
||||||
|
ntohl(i->local_conn_id));
|
||||||
|
printf("local_max_packet_size: %lx\n",
|
||||||
|
ntohl(i->local_max_packet_size));
|
||||||
|
printf("local_target_socket: %lx\n",
|
||||||
|
ntohl(i->local_target_socket));
|
||||||
|
printf("local_max_send_size: %lx\n",
|
||||||
|
ntohl(i->local_max_send_size));
|
||||||
|
printf("local_max_recv_size: %lx\n",
|
||||||
|
ntohl(i->local_max_recv_size));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
case 104:
|
||||||
|
{
|
||||||
|
printf("fn: %-3d, subfn: %-3d, NDS call\n",
|
||||||
|
rq->function, data[0]);
|
||||||
|
|
||||||
|
/* I took this information from the (german!!)
|
||||||
|
book 'Einf"uhrung in die NetWare LAN
|
||||||
|
Analyse', Laura A. Chappell, Dan E. Hakes,
|
||||||
|
Novell Press, Markt & Technik, ISBN
|
||||||
|
3-8272-5084-6, and from the book mentioned
|
||||||
|
in the ncpfs README. I'm not sure it is
|
||||||
|
correct, because I do not have NW 4.x. If
|
||||||
|
you have the time, could you watch a NW4
|
||||||
|
workstation, and tell me whether anything
|
||||||
|
of this makes sense at all. */
|
||||||
|
|
||||||
|
switch(data[0])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
printf("Ping for NDS\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
struct INPUT
|
||||||
|
{
|
||||||
|
__u8 subfunction_code;
|
||||||
|
__u32 fragger_handle;
|
||||||
|
__u32 max_fragment_size;
|
||||||
|
__u32 message_size;
|
||||||
|
__u32 fragment_flag;
|
||||||
|
__u32 verb;
|
||||||
|
} *i = (struct INPUT *)data;
|
||||||
|
printf("Send NDS Fragment Request/Reply\n");
|
||||||
|
printf("fragger_handle: %lx\n",
|
||||||
|
(unsigned long)i->fragger_handle);
|
||||||
|
printf("max_fragment_size: %lx\n",
|
||||||
|
(unsigned long)i->max_fragment_size);
|
||||||
|
printf("message_size: %lx\n",
|
||||||
|
(unsigned long)i->message_size);
|
||||||
|
printf("fragment_flag: %lx\n",
|
||||||
|
(unsigned long)i->fragment_flag);
|
||||||
|
printf("verb: %d\n", i->verb);
|
||||||
|
|
||||||
|
switch (i->verb)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
printf("Resolve Name\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("Read Entry Information\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("Read\n");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
printf("Compare\n");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
printf("List\n");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
printf("Search Entries\n");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
printf("Add Entry\n");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
printf("Remove Entry\n");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
printf("Modify Entry\n");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
printf("Modify RDN\n");
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
printf("Create Attribute\n");
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
printf("Read Attribute Definition\n");
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
printf("Remove Attribute Definition\n");
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
printf("Define Class\n");
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
printf("Read Class Definition\n");
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
printf("Modify Class Definition\n");
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
printf("Remove Class Definition\n");
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
printf("List Containable Classes\n");
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
printf("Get Effective Rights\n");
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
printf("Add Partition\n");
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
printf("Remove Partition\n");
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
printf("List Partitions\n");
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
printf("Split Partition\n");
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
printf("Join Partitions\n");
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
printf("Add Replica\n");
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
printf("Remove Replica\n");
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
printf("Open Stream\n");
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
printf("Search Filter\n");
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
printf("Create Subordinate Reference\n");
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
printf("Link Replica\n");
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
printf("Change Replica Type\n");
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
printf("Start Update Schema\n");
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
printf("End Update Schema\n");
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
printf("Update Schema\n");
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
printf("Start Update Replica\n");
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
printf("End Update Replica\n");
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
printf("Update Replica\n");
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
printf("Synchronize Partition\n");
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
printf("Synchronize Schema\n");
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
printf("Read Syntaxes\n");
|
||||||
|
break;
|
||||||
|
case 41:
|
||||||
|
printf("Get Replica Root ID\n");
|
||||||
|
break;
|
||||||
|
case 42:
|
||||||
|
printf("Begin Move Entry\n");
|
||||||
|
break;
|
||||||
|
case 43:
|
||||||
|
printf("Finish Move Entry\n");
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
printf("Release Moved Entry\n");
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
printf("Backup Entry\n");
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
printf("Restore Entry\n");
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
printf("Save DIB\n");
|
||||||
|
break;
|
||||||
|
case 48:
|
||||||
|
case 49:
|
||||||
|
printf("Unused\n");
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
printf("Close Iteration\n");
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
printf("Unused\n");
|
||||||
|
break;
|
||||||
|
case 52:
|
||||||
|
printf("Audit Skulking\n");
|
||||||
|
break;
|
||||||
|
case 53:
|
||||||
|
printf("Get Server Address\n");
|
||||||
|
break;
|
||||||
|
case 54:
|
||||||
|
printf("Set Keys\n");
|
||||||
|
break;
|
||||||
|
case 55:
|
||||||
|
printf("Change Password\n");
|
||||||
|
break;
|
||||||
|
case 56:
|
||||||
|
printf("Verify Password\n");
|
||||||
|
break;
|
||||||
|
case 57:
|
||||||
|
printf("Begin Login\n");
|
||||||
|
break;
|
||||||
|
case 58:
|
||||||
|
printf("Finish Login\n");
|
||||||
|
break;
|
||||||
|
case 59:
|
||||||
|
printf("Begin Authentication\n");
|
||||||
|
break;
|
||||||
|
case 60:
|
||||||
|
printf("Finish Authentication\n");
|
||||||
|
break;
|
||||||
|
case 61:
|
||||||
|
printf("Logout\n");
|
||||||
|
break;
|
||||||
|
case 62:
|
||||||
|
printf("Repair Ring\n");
|
||||||
|
break;
|
||||||
|
case 63:
|
||||||
|
printf("Repair Timestamps\n");
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
printf("Create Back Link\n");
|
||||||
|
break;
|
||||||
|
case 65:
|
||||||
|
printf("Delete External Reference\n");
|
||||||
|
break;
|
||||||
|
case 66:
|
||||||
|
printf("Rename External Reference\n");
|
||||||
|
break;
|
||||||
|
case 67:
|
||||||
|
printf("Create Directory Entry\n");
|
||||||
|
break;
|
||||||
|
case 68:
|
||||||
|
printf("Remove Directory Entry\n");
|
||||||
|
break;
|
||||||
|
case 69:
|
||||||
|
printf("Designate New Master\n");
|
||||||
|
break;
|
||||||
|
case 70:
|
||||||
|
printf("Change Tree Name\n");
|
||||||
|
break;
|
||||||
|
case 71:
|
||||||
|
printf("Partition Entry Count\n");
|
||||||
|
break;
|
||||||
|
case 72:
|
||||||
|
printf("Check Login Restrictions\n");
|
||||||
|
break;
|
||||||
|
case 73:
|
||||||
|
printf("Start Join\n");
|
||||||
|
break;
|
||||||
|
case 74:
|
||||||
|
printf("Low Level Split\n");
|
||||||
|
break;
|
||||||
|
case 75:
|
||||||
|
printf("Low Level Join\n");
|
||||||
|
break;
|
||||||
|
case 76:
|
||||||
|
printf("Abort Low Level Join\n");
|
||||||
|
break;
|
||||||
|
case 77:
|
||||||
|
printf("Get All Servers\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown Verb: %d\n",
|
||||||
|
data[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
printf("Close NDS Fragment\n");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
printf("Return Bindery Context\n");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
printf("Monitor NDS connection\n");
|
||||||
|
break;
|
||||||
|
case 200:
|
||||||
|
printf("NDS Auditing\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
printf("fn: %-3d\n", rq->function);
|
printf("fn: %-3d\n", rq->function);
|
||||||
}
|
}
|
||||||
@@ -605,6 +944,70 @@ void handle_ncp (struct sockaddr_ipx *source,
|
|||||||
|
|
||||||
data = buf + sizeof(struct ncp_reply_header);
|
data = buf + sizeof(struct ncp_reply_header);
|
||||||
data_length = length - sizeof(struct ncp_reply_header);
|
data_length = length - sizeof(struct ncp_reply_header);
|
||||||
|
|
||||||
|
if ( (memcmp(&request_source, target,
|
||||||
|
sizeof(request_source)) == 0)
|
||||||
|
&& (request_header.sequence == rs->sequence))
|
||||||
|
{
|
||||||
|
switch (request_header.function)
|
||||||
|
{
|
||||||
|
case 22:
|
||||||
|
switch (request_data[2])
|
||||||
|
{
|
||||||
|
case 18:
|
||||||
|
{
|
||||||
|
struct XDATA
|
||||||
|
{
|
||||||
|
__u8 new_directory_handle;
|
||||||
|
__u8 access_rights_mask;
|
||||||
|
} *x = (struct XDATA *)data;
|
||||||
|
printf("new_directory_handle: %x\n",
|
||||||
|
x->new_directory_handle);
|
||||||
|
printf("access_rights_mask: %x\n",
|
||||||
|
x->access_rights_mask);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 72:
|
||||||
|
printf("Read data\n");
|
||||||
|
data_length = 0;
|
||||||
|
break;
|
||||||
|
case 97:
|
||||||
|
{
|
||||||
|
struct XDATA
|
||||||
|
{
|
||||||
|
__u16 accepted_max_size;
|
||||||
|
__u16 echo_socket;
|
||||||
|
__u8 security_flag;
|
||||||
|
} *x = (struct XDATA *)data;
|
||||||
|
printf("accepted_max_size: %x\n",
|
||||||
|
ntohs(x->accepted_max_size));
|
||||||
|
printf("echo_socket: %x\n",
|
||||||
|
ntohs(x->echo_socket));
|
||||||
|
printf("security_flag: %x\n",
|
||||||
|
(x->security_flag));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 101:
|
||||||
|
{
|
||||||
|
struct XDATA
|
||||||
|
{
|
||||||
|
__u8 completion_code;
|
||||||
|
__u32 remote_target_id;
|
||||||
|
__u32 remote_max_packet_size;
|
||||||
|
} *x = (struct XDATA *)data;
|
||||||
|
printf("completion_code: %x\n",
|
||||||
|
x->completion_code);
|
||||||
|
printf("remote_target_id: %lx\n",
|
||||||
|
ntohl(x->remote_target_id));
|
||||||
|
printf("remote_max_packet_size: %lx\n",
|
||||||
|
ntohl(x->remote_max_packet_size));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ nwbols \- List NetWare Bindery Objects
|
|||||||
.B -t
|
.B -t
|
||||||
.I type
|
.I type
|
||||||
] [
|
] [
|
||||||
.B -v
|
.B -o
|
||||||
|
.I pattern
|
||||||
] [
|
] [
|
||||||
.B pattern
|
.B -v
|
||||||
]
|
]
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -95,7 +96,8 @@ objects to be listed.
|
|||||||
must be given as a decimal number.
|
must be given as a decimal number.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.B pattern
|
.B -o
|
||||||
|
.I pattern
|
||||||
.RS 3
|
.RS 3
|
||||||
Specifying a pattern is another way to restrict the objects
|
Specifying a pattern is another way to restrict the objects
|
||||||
listed. Please note that this pattern is evaluated by the NetWare
|
listed. Please note that this pattern is evaluated by the NetWare
|
||||||
|
|||||||
107
man/nwbpset.1
Normal file
107
man/nwbpset.1
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
.TH NWBPSET 1 8/7/1996 nwbpset nwbpset
|
||||||
|
.SH NAME
|
||||||
|
nwbpset \- Create a bindery property or set its value
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B nwbpset
|
||||||
|
[
|
||||||
|
.B -h
|
||||||
|
] [
|
||||||
|
.B -S
|
||||||
|
.I server
|
||||||
|
] [
|
||||||
|
.B -U
|
||||||
|
.I user name
|
||||||
|
] [
|
||||||
|
.B -P
|
||||||
|
.I password
|
||||||
|
|
|
||||||
|
.B -n
|
||||||
|
] [
|
||||||
|
.B -C
|
||||||
|
]
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B nwbpset
|
||||||
|
Reads a property specification from the standard input and creates and
|
||||||
|
sets the corresponding property. The format is determined by the
|
||||||
|
output of 'nwbpvalues -c'. nwbpset will hopefully become an important
|
||||||
|
part of the bindery management suite of ncpfs, together with
|
||||||
|
'nwbpvalues -c'. See util/nwbpsecurity for an example.
|
||||||
|
|
||||||
|
As another example, look at the following command line:
|
||||||
|
|
||||||
|
nwbpvalues -t 1 -o supervisor -p user_defaults -c |\\
|
||||||
|
sed '2s/.*/ME/'|\\
|
||||||
|
sed '3s/.*/LOGIN_CONTROL/'|\\
|
||||||
|
nwbpset
|
||||||
|
|
||||||
|
With this command, the property user_defaults of the user object
|
||||||
|
\'supervisor\' is copied into the property login_control of the user
|
||||||
|
object \'me\'.
|
||||||
|
|
||||||
|
nwbpvalues -t 1 -o me -p login_control -c |\\
|
||||||
|
sed '9s/.*/ff/'|\\
|
||||||
|
nwbpset
|
||||||
|
|
||||||
|
This command disables the user object me.
|
||||||
|
|
||||||
|
Feel free to contribute other examples!
|
||||||
|
|
||||||
|
.B nwbpset
|
||||||
|
looks up the file
|
||||||
|
.I $HOME/.nwclient
|
||||||
|
to find a file server, a user name and possibly a password. See
|
||||||
|
nwclient(5) for more information. Please note that the access
|
||||||
|
permissions of $HOME/.nwclient MUST be 600 for security reasons.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
|
||||||
|
.B -h
|
||||||
|
.RS 3
|
||||||
|
.B -h
|
||||||
|
is used to print out a short help text.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.B -S
|
||||||
|
.I server
|
||||||
|
.RS 3
|
||||||
|
.B server
|
||||||
|
is the name of the server you want to use.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.B -U
|
||||||
|
.I user
|
||||||
|
.RS 3
|
||||||
|
.B user
|
||||||
|
is the user name to use for login.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.B -P
|
||||||
|
.I password
|
||||||
|
.RS 3
|
||||||
|
.B password
|
||||||
|
is the password to use for login. If neither
|
||||||
|
.B -n
|
||||||
|
nor
|
||||||
|
.B -P
|
||||||
|
are given, and the user has no open connection to the server, nwbpset
|
||||||
|
prompts for a password.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.B -n
|
||||||
|
.RS 3
|
||||||
|
.B -n
|
||||||
|
should be given if no password is required for the login.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.B -C
|
||||||
|
.RS 3
|
||||||
|
By default, passwords are converted to uppercase before they are sent
|
||||||
|
to the server, because most servers require this. You can turn off
|
||||||
|
this conversion by
|
||||||
|
.B -C.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.SH AUTHORS
|
||||||
|
nwbpset was written by Volker Lendecke. See the Changes file of ncpfs
|
||||||
|
for other contributors.
|
||||||
@@ -29,6 +29,8 @@ nwbpvalues \- Print a NetWare Bindery Propery's contents
|
|||||||
.I property
|
.I property
|
||||||
] [
|
] [
|
||||||
.B -v
|
.B -v
|
||||||
|
] [
|
||||||
|
.B -c
|
||||||
]
|
]
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -122,6 +124,11 @@ the object flags, its security byte and the properties flag is also
|
|||||||
listed.
|
listed.
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.B -c
|
||||||
|
.RS 3
|
||||||
|
Use canonical output, to be used with nwbpset.
|
||||||
|
.RE
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
nwbpvalues was written by Volker Lendecke with the corresponding
|
nwbpvalues was written by Volker Lendecke with the corresponding
|
||||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Begin3
|
Begin3
|
||||||
Title: ncpfs
|
Title: ncpfs
|
||||||
Version: 2.0.5
|
Version: 2.0.6
|
||||||
Entered-date: 01. August 1996
|
Entered-date: 08. August 1996
|
||||||
Description: With ncpfs you can mount volumes of your netware
|
Description: With ncpfs you can mount volumes of your netware
|
||||||
server under Linux. You can also print to netware
|
server under Linux. You can also print to netware
|
||||||
print queues and spool netware print queues to the
|
print queues and spool netware print queues to the
|
||||||
@@ -13,7 +13,7 @@ Author: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
|
|||||||
Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
|
Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
|
||||||
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
|
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
|
||||||
Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs
|
Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs
|
||||||
~132k ncpfs-2.0.5.tgz
|
~136k ncpfs-2.0.6.tgz
|
||||||
~ 1k ncpfs-2.0.5.lsm
|
~ 1k ncpfs-2.0.6.lsm
|
||||||
Copying-policy: GPL
|
Copying-policy: GPL
|
||||||
End
|
End
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd
|
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd
|
||||||
USERUTILS += nwbols nwbocreate nwborm nwboprops
|
USERUTILS += nwbols nwbocreate nwborm nwboprops
|
||||||
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd
|
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd nwbpset
|
||||||
USERUTILS += nwgrant nwrevoke nwuserlist nwrights
|
USERUTILS += nwgrant nwrevoke nwuserlist nwrights
|
||||||
UIDUTILS = ncpmount ncpumount
|
UIDUTILS = ncpmount ncpumount
|
||||||
SBINUTILS = nwmsg
|
SBINUTILS = nwmsg
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ help(void)
|
|||||||
"-C Don't convert password to uppercase\n"
|
"-C Don't convert password to uppercase\n"
|
||||||
"\n"
|
"\n"
|
||||||
"-t type Object type to be listed (decimal)\n"
|
"-t type Object type to be listed (decimal)\n"
|
||||||
|
"-o object Object pattern\n"
|
||||||
"-v Verbose listing\n"
|
"-v Verbose listing\n"
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "h?vt:")) != EOF)
|
while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF)
|
||||||
{
|
{
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
@@ -73,6 +74,9 @@ main(int argc, char **argv)
|
|||||||
case 't':
|
case 't':
|
||||||
type = atoi(optarg);
|
type = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
pattern = optarg;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
break;
|
break;
|
||||||
@@ -82,17 +86,12 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind < argc-1)
|
if (optind < argc)
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind == argc-1)
|
|
||||||
{
|
|
||||||
pattern = argv[optind];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = pattern; *p != '\0'; p++)
|
for (p = pattern; *p != '\0'; p++)
|
||||||
{
|
{
|
||||||
*p = toupper(*p);
|
*p = toupper(*p);
|
||||||
|
|||||||
24
util/nwbpsecurity
Executable file
24
util/nwbpsecurity
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
SECURITY=`nwbpvalues $* -c | head -3 | tail -1`
|
||||||
|
WRITE=`echo $SECURITY | cut -b1`
|
||||||
|
READ=`echo $SECURITY | cut -b2`
|
||||||
|
|
||||||
|
function print_sec () {
|
||||||
|
case "$1" in
|
||||||
|
0 ) echo "Everyone"
|
||||||
|
;;
|
||||||
|
1 ) echo "Logged in"
|
||||||
|
;;
|
||||||
|
2 ) echo "Object"
|
||||||
|
;;
|
||||||
|
3 ) echo "Supervisor"
|
||||||
|
;;
|
||||||
|
* ) echo "Bindery"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
echo -n "Write security: "
|
||||||
|
print_sec $WRITE
|
||||||
|
echo -n "Read security : "
|
||||||
|
print_sec $READ
|
||||||
238
util/nwbpset.c
Normal file
238
util/nwbpset.c
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* nwbpset.c
|
||||||
|
*
|
||||||
|
* Create a property and set its values
|
||||||
|
*
|
||||||
|
* Copyright (C) 1996 by Volker Lendecke
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ncplib.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static char *progname;
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s [options]\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
help(void)
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
printf("usage: %s [options] [values]\n", progname);
|
||||||
|
printf("\n"
|
||||||
|
"-h Print this help text\n"
|
||||||
|
"-S server Server name to be used\n"
|
||||||
|
"-U username Username sent to server\n"
|
||||||
|
"-P password Use this password\n"
|
||||||
|
"-n Do not use any password\n"
|
||||||
|
"-C Don't convert password to uppercase\n"
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_line(char *buf, int len, FILE *stream)
|
||||||
|
{
|
||||||
|
char *result = fgets(buf, len, stream);
|
||||||
|
if (result != NULL)
|
||||||
|
{
|
||||||
|
buf[strlen(buf)-1] = '\0'; /* remove newline */
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct ncp_conn *conn;
|
||||||
|
char object_name[49];
|
||||||
|
int object_type = -1;
|
||||||
|
char property_name[17];
|
||||||
|
int property_flag, property_security;
|
||||||
|
struct ncp_property_info info;
|
||||||
|
long err;
|
||||||
|
int result = 1;
|
||||||
|
char buf[512];
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
|
||||||
|
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||||
|
{
|
||||||
|
com_err(argv[0], err, "when initializing");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "h?")) != EOF)
|
||||||
|
{
|
||||||
|
switch(opt) {
|
||||||
|
case 'h':
|
||||||
|
case '?':
|
||||||
|
help();
|
||||||
|
goto finished;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
if (get_line(buf, sizeof(buf), stdin) == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Illegal format on stdin\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
object_type = strtoul(buf, NULL, 16);
|
||||||
|
|
||||||
|
memset(object_name, 0, sizeof(object_name));
|
||||||
|
if (get_line(object_name, sizeof(object_name), stdin) == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Illegal format on stdin\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
memset(property_name, 0, sizeof(property_name));
|
||||||
|
if (get_line(property_name, sizeof(property_name), stdin) == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Illegal format on stdin\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
if (get_line(buf, sizeof(buf), stdin) == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Illegal format on stdin\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
property_flag = (atoi(buf) & 3);
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
if (get_line(buf, sizeof(buf), stdin) == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Illegal format on stdin\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
property_security = (strtoul(buf, NULL, 16) & 0xff);
|
||||||
|
|
||||||
|
if (ncp_scan_property(conn, object_type, object_name,
|
||||||
|
0xffffffff, property_name, &info) == 0)
|
||||||
|
{
|
||||||
|
/* Property already exists */
|
||||||
|
|
||||||
|
if ((property_flag & 2) != (info.property_flags & 2))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Tried to write %s property\n",
|
||||||
|
(property_flag & 2) != 0 ?
|
||||||
|
"SET over existing ITEM" :
|
||||||
|
"ITEM over existing SET");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.property_security != property_security)
|
||||||
|
{
|
||||||
|
if (ncp_change_property_security(conn, object_type,
|
||||||
|
object_name,
|
||||||
|
property_name,
|
||||||
|
property_security)!=0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not change "
|
||||||
|
"property security\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ncp_create_property(conn, object_type, object_name,
|
||||||
|
property_name, property_flag,
|
||||||
|
property_security) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not create property\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((property_flag & 2) == 0)
|
||||||
|
{
|
||||||
|
/* ITEM property */
|
||||||
|
int i;
|
||||||
|
int length;
|
||||||
|
int segno;
|
||||||
|
char property_value[255*128];
|
||||||
|
|
||||||
|
memset(property_value, 0, sizeof(property_value));
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(property_value); i++)
|
||||||
|
{
|
||||||
|
if (get_line(buf, sizeof(buf), stdin) == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
property_value[i] = strtoul(buf, NULL, 16);
|
||||||
|
}
|
||||||
|
length = i-1;
|
||||||
|
|
||||||
|
for (segno = 1; segno <= 255; segno++)
|
||||||
|
{
|
||||||
|
struct nw_property segment;
|
||||||
|
int offset = (segno-1)*128;
|
||||||
|
|
||||||
|
if ( offset > length )
|
||||||
|
{
|
||||||
|
/* everything written */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(segment.value, &(property_value[offset]), 128);
|
||||||
|
segment.more_flag = segno*128 < length;
|
||||||
|
if (ncp_write_property_value(conn, object_type,
|
||||||
|
object_name,
|
||||||
|
property_name,
|
||||||
|
segno, &segment) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not write property\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* SET property */
|
||||||
|
|
||||||
|
while (get_line(buf, sizeof(buf), stdin) != NULL)
|
||||||
|
{
|
||||||
|
int element_type = strtoul(buf, NULL, 16);
|
||||||
|
char element_name[49];
|
||||||
|
|
||||||
|
memset(element_name, 0, sizeof(element_name));
|
||||||
|
if (get_line(element_name, sizeof(element_name),
|
||||||
|
stdin) == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Illegal format on stdin\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ncp_add_object_to_set(conn, object_type,
|
||||||
|
object_name, property_name,
|
||||||
|
element_type,
|
||||||
|
element_name) != 0)
|
||||||
|
{
|
||||||
|
if (conn->completion != 0xE9) /* object already
|
||||||
|
in set */
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not add object "
|
||||||
|
"to set\n");
|
||||||
|
goto finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
finished:
|
||||||
|
ncp_close(conn);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ help(void)
|
|||||||
"-t type Object type (decimal value)\n"
|
"-t type Object type (decimal value)\n"
|
||||||
"-p property Name of property to be listed\n"
|
"-p property Name of property to be listed\n"
|
||||||
"-v Verbose object listing\n"
|
"-v Verbose object listing\n"
|
||||||
|
"-c Canonical output, for use with nwbpadd\n"
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ main(int argc, char *argv[])
|
|||||||
__u8 property_value[255*128];
|
__u8 property_value[255*128];
|
||||||
int segno;
|
int segno;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
int canonical = 0;
|
||||||
struct nw_property segment;
|
struct nw_property segment;
|
||||||
struct ncp_property_info info;
|
struct ncp_property_info info;
|
||||||
long err;
|
long err;
|
||||||
@@ -69,7 +71,7 @@ main(int argc, char *argv[])
|
|||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "h?o:t:p:v")) != EOF)
|
while ((opt = getopt(argc, argv, "h?o:t:p:vc")) != EOF)
|
||||||
{
|
{
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
case 'o':
|
case 'o':
|
||||||
@@ -92,6 +94,9 @@ main(int argc, char *argv[])
|
|||||||
case 'v':
|
case 'v':
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
canonical = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
help();
|
help();
|
||||||
@@ -142,10 +147,29 @@ main(int argc, char *argv[])
|
|||||||
segno += 1;
|
segno += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (canonical != 0)
|
||||||
|
{
|
||||||
|
printf("%-4.4x\n%s\n", object_type, object_name);
|
||||||
|
printf("%s\n%d\n%x\n",
|
||||||
|
info.property_name, info.property_flags, info.property_security);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if ((info.property_flags & 2) == 0)
|
if ((info.property_flags & 2) == 0)
|
||||||
{
|
{
|
||||||
print_property(property_name, property_value, segno);
|
/* ITEM property */
|
||||||
|
if (canonical != 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < segno*128; i++)
|
||||||
|
{
|
||||||
|
printf("%-2.2x\n", property_value[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_property(property_name, property_value, segno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -166,7 +190,13 @@ main(int argc, char *argv[])
|
|||||||
if (ncp_get_bindery_object_name(conn, ntohl(value[i]),
|
if (ncp_get_bindery_object_name(conn, ntohl(value[i]),
|
||||||
&o) == 0)
|
&o) == 0)
|
||||||
{
|
{
|
||||||
if (verbose != 0)
|
if (canonical != 0)
|
||||||
|
{
|
||||||
|
printf("%-4.4x\n%s\n",
|
||||||
|
(unsigned int) o.object_type,
|
||||||
|
o.object_name);
|
||||||
|
}
|
||||||
|
else if (verbose != 0)
|
||||||
{
|
{
|
||||||
printf("%s %08X %04X\n",
|
printf("%s %08X %04X\n",
|
||||||
o.object_name,
|
o.object_name,
|
||||||
|
|||||||
Reference in New Issue
Block a user