~ubuntu-branches/debian/lenny/mtools/lenny

« back to all changes in this revision

Viewing changes to floppyd.c

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2006-07-08 12:36:15 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060708123615-0vrt17kv065uagfw
Replaced libx11-dev and libxau-dev by xlibs-static-dev and
libxt-dev as build-dependencies. Please refer to #347025.
Closes: #367558. Patch by Vincent Rivière <riviere@iut-rodez.fr>.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
#define DEBUG 0
17
17
 
18
 
#include "config.h"
 
18
#include "sysincludes.h"
19
19
 
20
20
#ifdef USE_FLOPPYD
21
21
 
96
96
#define BUFFERED_IO_SIZE         16348
97
97
 
98
98
 
99
 
void serve_client(int sock, char* device_name);
100
 
 
101
 
 
102
 
 
103
 
#define New(type) ((type*)(malloc(sizeof(type))))
 
99
void serve_client(int sock, char **device_name, int n_dev);
 
100
 
104
101
 
105
102
#ifdef USE_FLOPPYD_BUFFERED_IO
106
103
typedef struct io_buffer {
385
382
    return 0;
386
383
}
387
384
 
 
385
static char *dispName;
 
386
 
388
387
 
389
388
char do_auth(io_buffer sock, int *version) 
390
389
{
395
394
        char *ptr;
396
395
        int len;
397
396
 
 
397
        char authFile[41]="/tmp/floppyd.XXXXXX";
398
398
        char template[4096];
399
399
 
400
400
        Packet reply = newPacket();
441
441
                return 0;
442
442
        }
443
443
 
444
 
        /* CPhipps 2000/02/11 - Do the open and test in one call, to avoid
445
 
         * race condition. Open with safe permissions. */
446
 
        fd = open(XauFileName(), O_WRONLY | O_CREAT | O_EXCL, 0600);
447
 
        
448
 
        /* Locked! */
449
 
        if (fd == -1) {
 
444
        umask(077);
 
445
        fd = mkstemp(authFile);
 
446
        if(fd == -1) {
 
447
                /* Different error than file exists */
450
448
                put_dword(reply, 0, AUTH_DEVLOCKED);
451
449
                send_packet(reply, sock);
452
450
                close(fd);
454
452
                destroyPacket(mit_cookie);
455
453
                return 0;
456
454
        }
 
455
        setenv("XAUTHORITY", authFile, 1);
457
456
 
458
457
        ptr = template;
459
458
        ptr[4095] = 0;
489
488
 
490
489
        destroyPacket(mit_cookie);
491
490
 
492
 
        displ = XOpenDisplay(":0");
 
491
        displ = XOpenDisplay(dispName);
493
492
        if (!displ) {
494
493
                unlink(XauFileName());
495
494
                put_dword(reply, 0, AUTH_AUTHFAILED);
502
501
        put_dword(reply, 0, AUTH_SUCCESS);
503
502
        send_packet(reply, sock);
504
503
        destroyPacket(reply);
 
504
        unlink(XauFileName());
505
505
        return 1;
506
506
}
507
507
 
694
694
/*
695
695
 * This is the main loop when running as a server.
696
696
 */
697
 
static void server_main_loop(int sock, char* device_name)
 
697
static void server_main_loop(int sock, char **device_name, int n_dev)
698
698
{
699
699
        struct sockaddr_in      addr;
700
700
        unsigned int            len;
728
728
                                 * Start the proxy work in the new socket.
729
729
                                 */
730
730
#endif
731
 
                                serve_client(new_sock,device_name);
 
731
                                serve_client(new_sock,device_name, n_dev);
732
732
                                exit(0);
733
733
#if DEBUG == 0
734
734
                }
761
761
}
762
762
 
763
763
 
764
 
char *makeDisplayName(char *base, int port)
 
764
char *makeDisplayName(int dispNr)
765
765
{
766
 
        char *result;
767
 
        int displaynr = (port - FLOPPYD_DEFAULT_PORT) % 10;
768
 
        int len=strlen(base);
769
 
 
770
 
        result = malloc(len+5);
771
 
        strcpy(result, base);
772
 
        result[len++] = ':';
773
 
        result[len++] = '0' + displaynr;
774
 
        result[len++] = '.';
775
 
        result[len++] = '0';
776
 
        result[len]='\0';
777
 
        return result;
 
766
        char result[80];
 
767
        sprintf(result, ":%d.0", dispNr);
 
768
        return strdup(result);
778
769
}
779
770
 
780
771
int main (int argc, char** argv) 
783
774
        int                     arg;
784
775
        int                     run_as_server = 0;
785
776
        IPaddr_t                bind_ip = INADDR_ANY;
786
 
        short                   bind_port = FLOPPYD_DEFAULT_PORT;
 
777
        unsigned short          bind_port = 0;
787
778
        uid_t                   run_uid = 65535;
788
779
        gid_t                   run_gid = 65535;
789
780
        char*                   username = strdup("nobody");
790
781
        int                     sock;
791
782
        int                     port_is_supplied = 0;
792
 
        int                     no_local = 0;
793
783
 
794
784
        char *server_hostname=NULL;
795
 
        char* device_name = NULL; 
796
 
        char *authFile=0;
797
 
        char *p, *q;
798
 
        const char *authKey = "XAUTHORITY";
 
785
        char **device_name = NULL; 
 
786
        char *floppy0 = "/dev/fd0";
 
787
        int n_dev;
799
788
 
800
789
 
801
790
        /*
802
791
         * Parse the command line arguments.
803
792
         */
804
 
        while ((arg = getopt(argc, argv, "lds:r:b:")) != EOF)
 
793
        while ((arg = getopt(argc, argv, "ds:r:b:x:")) != EOF)
805
794
                {
806
795
                        switch (arg)
807
796
                                {
825
814
                                                bind_ip = getipaddress(optarg);
826
815
                                                server_hostname=optarg;
827
816
                                                break;
828
 
 
829
 
                                        case 'l':
830
 
                                                no_local = 1;
 
817
                                        case 'x':
 
818
                                                dispName = strdup(optarg);
831
819
                                                break;
832
820
 
833
821
                                        case '?':
837
825
                }
838
826
 
839
827
        if(optind < argc) {
840
 
                device_name = argv[optind++];
 
828
                device_name = argv + optind;
 
829
                n_dev = argc - optind;
 
830
        } else {
 
831
                device_name = &floppy0;
 
832
                n_dev = 1;
841
833
        }
842
834
 
843
 
        if(optind < argc) {
844
 
                fprintf(stderr, "Ignoring extra argument %s\n", argv[optind]);
 
835
        if(dispName == NULL)
 
836
                dispName = getenv("DISPLAY");
 
837
        if(dispName==NULL && bind_port != 0)
 
838
                dispName=makeDisplayName((unsigned short)(bind_port - 5703));
 
839
        if(dispName==NULL)              
 
840
                dispName=":0";
 
841
 
 
842
        if(bind_port == 0) {
 
843
                char *p = strchr(dispName,':');
 
844
                bind_port = FLOPPYD_DEFAULT_PORT;
 
845
                if(p != NULL)
 
846
                        bind_port += atoi(p+1);
845
847
        }
846
848
 
847
849
        if(!run_as_server) {
865
867
        if (run_as_server && (bind_ip == INADDR_NONE)) {
866
868
                usage(argv[0], "The server ipaddr is invalid.");
867
869
        }
868
 
        if (run_as_server && (bind_port == -1)) {
 
870
        if (run_as_server && (bind_port == 0))  {
869
871
                usage(argv[0], "No server port was specified (or it was invalid).");
870
872
        }
871
 
        
872
 
        if(!device_name) {
873
 
                device_name = "/dev/fd0";
874
 
        }
875
 
 
876
 
        if (!device_name || !*device_name) {
877
 
                usage(argv[0], "No device name specified.");
878
 
        }
879
 
 
880
 
        authFile = malloc(strlen(authKey) + 1+ strlen(device_name)*2+7);
881
 
        strcpy(authFile, authKey);
882
 
        strcat(authFile, "=/tmp/");
883
 
        for(p=device_name, q = strlen(authKey) + authFile+6; *p; p++) {
884
 
                switch(*p) {
885
 
                        case '/':
886
 
                                *q++ = '-';
887
 
                                *q++ = '+';
888
 
                                break;
889
 
                        case '-':
890
 
                                *q++ = '-';
891
 
                                *q++ = '-';
892
 
                                break;
893
 
                        default:
894
 
                                *q++ = *p;
895
 
                }
896
 
        }
897
 
        *q = *p;
898
 
        putenv(authFile);
 
873
 
899
874
 
900
875
        /*
901
876
         * See if we should run as a server.
902
877
         */
903
 
        if (run_as_server)
904
 
                {
905
 
                        /*
906
 
                         * Start by binding to the port, the child inherits this socket.
907
 
                         */
908
 
                        sock = bind_to_port(bind_ip, bind_port);
909
 
 
910
 
                        /*
911
 
                         * Start a server process. When DEBUG is defined, just run
912
 
                         * in the foreground.
913
 
                         */
 
878
        if (run_as_server) {
 
879
                /*
 
880
                 * Start by binding to the port, the child inherits this socket.
 
881
                 */
 
882
                sock = bind_to_port(bind_ip, bind_port);
 
883
                
 
884
                /*
 
885
                 * Start a server process. When DEBUG is defined, just run
 
886
                 * in the foreground.
 
887
                 */
914
888
#if DEBUG
915
 
                        switch (0)
 
889
                switch (0)
916
890
#else
917
 
                                switch (fork())
 
891
                        switch (fork())
918
892
#endif
919
 
                                        {
920
 
                                                case -1:
921
 
                                                        perror("fork()");
922
 
                                                        exit(1);
923
 
 
924
 
                                                case 0:
925
 
                                                        /*
926
 
                                                         * Ignore some signals.
927
 
                                                         */
928
 
                                                        signal(SIGHUP, SIG_IGN);
 
893
                                {
 
894
                                case -1:
 
895
                                        perror("fork()");
 
896
                                        exit(1);
 
897
                                        
 
898
                                case 0:
 
899
                                        /*
 
900
                                         * Ignore some signals.
 
901
                                         */
 
902
                                        signal(SIGHUP, SIG_IGN);
929
903
#if DEBUG
930
 
                                                        signal(SIGINT, SIG_IGN);
 
904
                                        signal(SIGINT, SIG_IGN);
931
905
#endif
932
 
                                                        signal(SIGQUIT, SIG_IGN);
933
 
                                                        signal(SIGTSTP, SIG_IGN);
934
 
                                                        signal(SIGCONT, SIG_IGN);
935
 
                                                        signal(SIGPIPE, alarm_signal);
936
 
                                                        /*signal(SIGALRM, alarm_signal);*/
937
 
 
938
 
                                                        /*
939
 
                                                         * Drop back to an untrusted user.
940
 
                                                         */
941
 
                                                        setgid(run_gid);
942
 
                                                        initgroups(username, -1);
943
 
                                                        setuid(run_uid);
944
 
 
945
 
                                                        /*
946
 
                                                         * Start a new session and group.
947
 
                                                         */
948
 
                                                        setsid();
 
906
                                        signal(SIGQUIT, SIG_IGN);
 
907
                                        signal(SIGTSTP, SIG_IGN);
 
908
                                        signal(SIGCONT, SIG_IGN);
 
909
                                        signal(SIGPIPE, alarm_signal);
 
910
                                        /*signal(SIGALRM, alarm_signal);*/
 
911
                                        
 
912
                                        /*
 
913
                                         * Drop back to an untrusted user.
 
914
                                         */
 
915
                                        setgid(run_gid);
 
916
                                        initgroups(username, -1);
 
917
                                        setuid(run_uid);
 
918
                                        
 
919
                                        /*
 
920
                                         * Start a new session and group.
 
921
                                         */
 
922
                                        setsid();
949
923
#ifdef SETPGRP_VOID
950
 
                                                        setpgrp();
 
924
                                        setpgrp();
951
925
#else
952
 
                                                        setpgrp(0,0);
 
926
                                        setpgrp(0,0);
953
927
#endif
954
928
#if DEBUG
955
 
                                                        close(2);
956
 
                                                        open("/dev/null", O_WRONLY);
 
929
                                        close(2);
 
930
                                        open("/dev/null", O_WRONLY);
957
931
#endif
958
 
                                                        /*
959
 
                                                         * Handle the server main loop.
960
 
                                                         */
961
 
                                                        server_main_loop(sock, device_name);
962
 
 
963
 
                                                        /*
964
 
                                                         * Should never exit.
965
 
                                                         */
966
 
                                                        exit(1);
967
 
                                        }
968
 
 
969
 
                        /*
970
 
                         * Parent exits at this stage.
971
 
                         */
972
 
                        exit(0);
973
 
                }
 
932
                                        /*
 
933
                                         * Handle the server main loop.
 
934
                                         */
 
935
                                        server_main_loop(sock, device_name, n_dev);
 
936
                                        
 
937
                                        /*
 
938
                                         * Should never exit.
 
939
                                         */
 
940
                                        exit(1);
 
941
                                }
 
942
                
 
943
                /*
 
944
                 * Parent exits at this stage.
 
945
                 */
 
946
                exit(0);
 
947
        }
974
948
 
975
949
        signal(SIGHUP, alarm_signal);
976
950
#if DEBUG == 0
989
963
#endif
990
964
        /* Starting from inetd */
991
965
 
992
 
        serve_client(sockfd, device_name);
 
966
        serve_client(sockfd, device_name, n_dev);
993
967
        return 0;
994
968
}
995
969
 
1012
986
        exit(-1);
1013
987
}
1014
988
 
1015
 
void serve_client(int sockhandle, char* device_name) {
 
989
#include "lockdev.h"
 
990
 
 
991
void serve_client(int sockhandle, char **device_name, int n_dev) {
1016
992
        Packet opcode;
1017
993
        Packet parm;
1018
994
 
1066
1042
        if(version == FLOPPYD_PROTOCOL_VERSION_OLD) {
1067
1043
                                /* old protocol */
1068
1044
                readOnly = 0;
1069
 
                devFd = open(device_name, O_RDWR);
 
1045
                devFd = open(device_name[0], O_RDWR);
1070
1046
                
1071
1047
                if (devFd < 0) {
1072
1048
                        readOnly = 1;
1073
 
                        devFd = open(device_name, 
 
1049
                        devFd = open(device_name[0], 
1074
1050
                                     O_RDONLY);
1075
1051
                }
1076
1052
                if(devFd < 0) {
1077
1053
                        send_reply(0, sock, devFd);
1078
1054
                        stopLoop = 1;
1079
1055
                }
 
1056
                lock_dev(devFd, !readOnly, NULL);
1080
1057
        }
1081
1058
 
1082
1059
 
1083
1060
        while(!stopLoop) {
 
1061
                int dev_nr = 0;
1084
1062
                int rval = 0;
1085
1063
                /*
1086
1064
                 * Allow 60 seconds for any activity.
1088
1066
                /*alarm(60);*/
1089
1067
 
1090
1068
                if (!recv_packet(opcode, sock, 1)) {
1091
 
                    fprintf(stderr, "No Recv packet\n");
1092
1069
                        break;
1093
1070
                }
1094
1071
/*              if(opcode->data[0] != OP_CLOSE)*/
1095
1072
                    recv_packet(parm, sock, MAX_DATA_REQUEST);
1096
1073
 
 
1074
 
1097
1075
                switch(opcode->data[0]) {
1098
1076
                        case OP_OPRO:
1099
 
                                devFd = open(device_name, O_RDONLY);
 
1077
                                if(get_length(parm) >= 4)
 
1078
                                        dev_nr = get_dword(parm,0);
 
1079
                                else
 
1080
                                        dev_nr = 0;
 
1081
                                if(dev_nr >= n_dev) {
 
1082
                                        send_reply(0, sock, -1);
 
1083
                                        break;
 
1084
                                }
 
1085
 
 
1086
                                devFd = open(device_name[dev_nr], O_RDONLY);
1100
1087
#if DEBUG
1101
1088
                                fprintf(stderr, "Device opened\n");
1102
1089
#endif
 
1090
                                if(devFd >= 0 && lock_dev(devFd, 0, NULL)) {
 
1091
                                        send_reply(0, sock, -1);
 
1092
                                        break;
 
1093
                                }
1103
1094
                                send_reply(0, sock, devFd);
1104
1095
                                readOnly = 1;
1105
1096
                                break;
1106
1097
                        case OP_OPRW:
1107
 
                                devFd = open(device_name, O_RDWR);
 
1098
                                if(get_length(parm) >= 4)
 
1099
                                        dev_nr = get_dword(parm,0);
 
1100
                                else
 
1101
                                        dev_nr = 0;
 
1102
                                if(dev_nr >= n_dev) {
 
1103
                                        send_reply(0, sock, -1);
 
1104
                                        break;
 
1105
                                }
 
1106
                                devFd = open(device_name[dev_nr], O_RDWR);
 
1107
                                if(devFd >= 0 && lock_dev(devFd, 1, NULL)) {
 
1108
                                        send_reply(0, sock, -1);
 
1109
                                        break;
 
1110
                                }
1108
1111
                                send_reply(0, sock, devFd);
1109
1112
                                readOnly = 0;
1110
1113
                                break;
1114
1117
#endif
1115
1118
                                read_packet(parm, devFd, get_dword(parm, 0));
1116
1119
                                send_reply(devFd, sock, get_length(parm));
1117
 
                                send_packet(parm, sock);
1118
 
                                
 
1120
                                if(get_length(parm) >= 0)
 
1121
                                        send_packet(parm, sock);
1119
1122
                                break;
1120
1123
                        case OP_WRITE:
1121
1124
#if DEBUG