Files
ncpfs/ncpmount.c
ncpfs archive import 7591e85f7b Import ncpfs 0.1
2026-04-28 20:39:57 +02:00

333 lines
6.7 KiB
C

/*
* ncpmount.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
/* #include <sys/wait.h> */ /* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
#include <linux/ipx.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ipxutil.h"
static char *progname;
static char *mount_point;
static char *server_name;
struct sap_query {
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
};
struct sap_server_ident {
unsigned short server_type;
char server_name[48];
IPXNet server_network;
IPXNode server_node;
IPXPort server_port;
unsigned short intermediate_network;
} __attribute__ ((packed));
void
ipx_fprint_node(FILE* file,IPXNode node)
{
fprintf(file,"%02X%02X%02X%02X%02X%02X",
(unsigned char)node[0],
(unsigned char)node[1],
(unsigned char)node[2],
(unsigned char)node[3],
(unsigned char)node[4],
(unsigned char)node[5]
);
}
void
ipx_fprint_network(FILE* file,IPXNet net)
{
fprintf(file,"%08lX",ntohl(net));
}
void
ipx_fprint_port(FILE* file,IPXPort port)
{
fprintf(file,"%04X",ntohs(port));
}
void
ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx)
{
ipx_fprint_network(file,sipx->sipx_network);
fprintf(file,":");
ipx_fprint_node(file,sipx->sipx_node);
fprintf(file,":");
ipx_fprint_port(file,sipx->sipx_port);
}
void
ipx_print_node(IPXNode node)
{
ipx_fprint_node(stdout,node);
}
void
ipx_print_network(IPXNet net)
{
ipx_fprint_network(stdout,net);
}
void
ipx_print_port(IPXPort port)
{
ipx_fprint_port(stdout,port);
}
void
ipx_print_saddr(struct sockaddr_ipx* sipx)
{
ipx_fprint_saddr(stdout,sipx);
}
int
ipx_sap_find_server(char *name, int server_type, int timeout,
struct sockaddr_ipx *result)
{
struct sockaddr_ipx ipxs;
char data[1024];
int sock;
int opt;
int res = -1;
int name_len = strlen(name);
fd_set rd, wr, ex;
struct timeval tv;
if (name_len > 48) {
return -1;
}
sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
if (sock==-1) {
return -1;
}
opt=1;
/* Permit broadcast output */
if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST, &opt,sizeof(opt))==-1)
{
perror("setsockopt");
goto finished;
}
memset(&ipxs, 0, sizeof(ipxs));
ipxs.sipx_family=AF_IPX;
ipxs.sipx_network=htonl(0x0);
ipxs.sipx_port=htons(0x0);
ipxs.sipx_type=IPX_SAP_PTYPE;
if(bind(sock,(struct sockaddr*)&ipxs,sizeof(ipxs))==-1)
{
perror("bind");
goto finished;
}
*(unsigned short *)data = htons(0x0001);
*(unsigned short *)&(data[2]) = htons(server_type);
memset(&ipxs, 0, sizeof(ipxs));
ipxs.sipx_family=AF_IPX;
ipxs.sipx_network=htonl(0x0);
ipx_assign_node(ipxs.sipx_node, IPX_BROADCAST_NODE);
ipxs.sipx_port=htons(IPX_SAP_PORT);
ipxs.sipx_type=IPX_SAP_PTYPE;
if (sendto(sock, data, 4, 0,
(struct sockaddr *)&ipxs, sizeof(ipxs)) < 0) {
perror("sendto");
goto finished;
}
FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&ex);
FD_SET(sock, &rd);
tv.tv_sec = timeout;
tv.tv_usec = 0;
if (select(sock+1, &rd, &wr, &ex, &tv) == -1) {
perror("select");
goto finished;
}
if (FD_ISSET(sock, &rd)) {
int len = recv(sock, data, 1024, 0);
int i;
struct sap_server_ident *ident;
for (i = 2; i < len; i += 64) {
ident = (struct sap_server_ident *)(data+i);
if ( (strncmp(name,ident->server_name,name_len)==0)
&& (name_len < 48)
&& (ident->server_name[name_len] == '\0'))
{
result->sipx_family = AF_IPX;
result->sipx_network =
ident->server_network;
result->sipx_port = ident->server_port;
ipx_assign_node(result->sipx_node,
ident->server_node);
res = 0;
goto finished;
}
}
}
finished:
close(sock);
return res;
}
int ipx_sscanf_node(char *buf, unsigned char node[6])
{
int i;
int n[6];
if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x",
&(n[0]), &(n[1]), &(n[2]),
&(n[3]), &(n[4]), &(n[5]))) != 6) {
return i;
}
for (i=0; i<6; i++) {
node[i] = n[i];
}
return 6;
}
int
main(int argc, char **argv)
{
struct ncp_mount_data data;
struct stat st;
struct sockaddr_ipx addr;
int ncp_sock, wdog_sock;
int flags;
progname = argv[0];
if (geteuid() != 0) {
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
memset(&data, 0, sizeof(struct ncp_mount_data));
if (argc != 5) {
fprintf(stderr, "usage: %s server mount-point"
" user password\n", progname);
exit(1);
}
server_name = argv[1];
mount_point = argv[2];
if (stat(mount_point, &st) == -1) {
fprintf(stderr, "could not find mount point %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
ncp_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (ncp_sock == -1) {
fprintf(stderr, "could not open ncp socket: %s\n",
strerror(errno));
exit(1);
}
wdog_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (wdog_sock == -1) {
fprintf(stderr, "could not open wdog socket: %s\n",
strerror(errno));
exit(1);
}
addr.sipx_type = NCP_PTYPE;
if (bind(ncp_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
fprintf(stderr, "bind(ncp_sock, ): %s\n",
strerror(errno));
exit(1);
}
if (bind(wdog_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
fprintf(stderr, "bind(wdog_sock, ): %s\n",
strerror(errno));
exit(1);
}
if (ipx_sap_find_server(server_name, IPX_SAP_FILE_SERVER,
3, &addr) != 0) {
fprintf(stderr, "could not find server %s\n", server_name);
exit(1);
}
printf("server: ");
ipx_fprint_saddr(stdout, &addr);
printf("\n");
data.version = NCP_MOUNT_VERSION;
data.ncp_fd = ncp_sock;
data.wdog_fd = wdog_sock;
data.mounted_uid = getuid();
data.serv_addr = addr;
strcpy(data.server_name, server_name);
data.time_out = 20; /* 2 seconds */
data.retry_count = 2;
data.uid = 501; /* me */
data.gid = 100; /* users */
data.file_mode = data.dir_mode = S_IRWXU|S_IRWXG|S_IRWXO;
strcpy(data.username, argv[3]);
strcpy(data.password, argv[4]);
flags = MS_MGC_VAL;
if (mount(NULL, mount_point, "ncpfs", flags, (char *)&data) < 0) {
perror("mount error");
fprintf(stderr, "Maybe you should try your password in "
"upper case\n");
return -1;
}
close(ncp_sock);
close(wdog_sock);
return 0;
}