"Fossies" - the Fresh Open Source Software Archive

Member "radmind-1.15.3/radmind-/retr.c" (30 Nov 2020, 14299 Bytes) of package /linux/privat/radmind-1.15.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright (c) 2003 Regents of The University of Michigan.
    3  * All Rights Reserved.  See COPYRIGHT.
    4  */
    5 
    6 #include "config.h"
    7 
    8 #include <sys/types.h>
    9 #include <sys/stat.h>
   10 #include <sys/param.h>
   11 #include <sys/time.h>
   12 #ifdef __APPLE__
   13 #include <sys/attr.h>
   14 #include <sys/paths.h>
   15 #endif /* __APPLE__ */
   16 #include <errno.h>
   17 #include <fcntl.h>
   18 #include <stdlib.h>
   19 #include <stdio.h>
   20 #include <string.h>
   21 #include <unistd.h>
   22 
   23 #include <openssl/ssl.h>
   24 #include <openssl/err.h>
   25 
   26 #include <openssl/evp.h>
   27 
   28 #ifdef HAVE_ZLIB
   29 #include <zlib.h>
   30 #endif /* HAVE_ZLIB */
   31 
   32 #include <snet.h>
   33 
   34 #include "openssl_compat.h" // Compatibility shims for OpenSSL < 1.1.0
   35 #include "applefile.h"
   36 #include "connect.h"
   37 #include "cksum.h"
   38 #include "base64.h"
   39 #include "code.h"
   40 #include "largefile.h"
   41 #include "progress.h"
   42 #include "mkprefix.h"
   43 
   44 extern void            (*logger)( char * );
   45 extern struct timeval   timeout;
   46 extern int      linenum;
   47 extern int      verbose;
   48 extern int      showprogress;
   49 extern int      dodots;
   50 extern int      cksum;
   51 extern int      errno;
   52 extern int      create_prefix;
   53 extern SSL_CTX      *ctx;
   54 
   55 /*
   56  * Download requests path from sn and writes it to disk.  The path to
   57  * this new file is returned via temppath which must be 2 * MAXPATHLEN.
   58  * 
   59  * Return Value:
   60  *  -1 - error, do not call closesn
   61  *   0 - OKAY
   62  *   1 - error, call closesn
   63  */
   64 
   65     int 
   66 retr( SNET *sn, char *pathdesc, char *path, char *temppath, mode_t tempmode,
   67     off_t transize, char *trancksum )
   68 {
   69     struct timeval  tv;
   70     char        *line;
   71     int         fd;
   72     unsigned int    md_len;
   73     int         returnval = -1;
   74     off_t       size = 0;
   75     char        buf[ 8192 ]; 
   76     ssize_t     rr;
   77     extern EVP_MD   *md;
   78     EVP_MD_CTX      *mdctx = EVP_MD_CTX_new();
   79     unsigned char   md_value[ SZ_BASE64_D( SZ_BASE64_E( EVP_MAX_MD_SIZE ) ) ];
   80     char        cksum_b64[ SZ_BASE64_E( EVP_MAX_MD_SIZE ) ];
   81 
   82     if ( cksum ) {
   83     if ( strcmp( trancksum, "-" ) == 0 ) {
   84         fprintf( stderr, "line %d: No checksum\n", linenum);
   85         fprintf( stderr, "%s\n", pathdesc );
   86         return( 1 );
   87     }
   88     EVP_DigestInit( mdctx, md );
   89     }
   90 
   91     if ( verbose ) printf( ">>> RETR %s\n", pathdesc );
   92     if ( snet_writef( sn, "RETR %s\n", pathdesc ) < 0 ) {
   93     fprintf( stderr, "retrieve %s failed: 1-%s\n", pathdesc,
   94         strerror( errno ));
   95     return( -1 );
   96     }
   97 
   98     tv = timeout;
   99     if (( line = snet_getline_multi( sn, logger, &tv )) == NULL ) {
  100     fprintf( stderr, "retrieve %s failed: 2-%s\n", pathdesc,
  101         strerror( errno ));
  102     return( -1 );
  103     }
  104 
  105     if ( *line != '2' ) {
  106     fprintf( stderr, "%s\n", line );
  107     return( 1 );
  108     }
  109 
  110     /* Get file size from server */
  111     tv = timeout;
  112     if (( line = snet_getline( sn, &tv )) == NULL ) {
  113     fprintf( stderr, "retrieve %s failed: 3-%s\n", pathdesc,
  114         strerror( errno ));
  115     return( -1 );
  116     }
  117     size = strtoofft( line, NULL, 10 );
  118     if ( verbose ) printf( "<<< %" PRIofft "d\n", size );
  119     if ( transize >= 0 && size != transize ) {
  120     fprintf( stderr, "line %d: size in transcript does not match size "
  121         "from server\n", linenum );
  122     fprintf( stderr, "%s\n", pathdesc );
  123     return( -1 );
  124     }
  125 
  126     /*Create temp file name*/
  127     if ( snprintf( temppath, MAXPATHLEN, "%s.radmind.%i",
  128         path, getpid()) >= MAXPATHLEN ) {
  129     fprintf( stderr, "%s.radmind.%i: too long", path,
  130         (int)getpid());
  131     return( -1 );
  132     }
  133     /* Open file */
  134     if (( fd = open( temppath, O_WRONLY | O_CREAT, tempmode )) < 0 ) {
  135     if ( create_prefix && errno == ENOENT ) {
  136         errno = 0;
  137         if ( mkprefix( temppath ) != 0 ) {
  138         perror( temppath );
  139         return( -1 );
  140         }
  141         if (( fd = open( temppath, O_WRONLY | O_CREAT, tempmode )) < 0 ) {
  142         perror( temppath );
  143         return( -1 );
  144         }
  145     } else {
  146         perror( temppath );
  147         return( -1 );
  148     }
  149     }
  150 
  151     if ( verbose ) printf( "<<< " );
  152 
  153     /* Get file from server */
  154     while ( size > 0 ) {
  155     tv = timeout;
  156     if (( rr = snet_read( sn, buf, MIN( sizeof( buf ), size ),
  157         &tv )) <= 0 ) {
  158         fprintf( stderr, "retrieve %s failed: 4-%s\n", pathdesc,
  159         strerror( errno ));
  160         returnval = -1;
  161         goto error2;
  162     }
  163     if ( write( fd, buf, (size_t)rr ) != rr ) {
  164         perror( temppath );
  165         returnval = -1;
  166         goto error2;
  167     }
  168     if ( cksum ) {
  169         EVP_DigestUpdate( mdctx, buf, (unsigned int)rr );
  170     }
  171     if ( dodots ) { putc( '.', stdout ); fflush( stdout ); }
  172     size -= rr;
  173     if ( showprogress ) {
  174         progressupdate( rr, path );
  175     }
  176     }
  177     if ( close( fd ) != 0 ) {
  178     perror( path );
  179     returnval = -1;
  180     goto error1;
  181     }
  182     if ( verbose ) printf( "\n" );
  183 
  184     tv = timeout;
  185     if (( line = snet_getline( sn, &tv )) == NULL ) {
  186     fprintf( stderr, "retrieve %s failed: 5-%s\n", pathdesc,
  187         strerror( errno ));
  188     returnval = -1;
  189     goto error1;
  190     }
  191     if ( strcmp( line, "." ) != 0 ) {
  192     fprintf( stderr, "%s", line );
  193     fprintf( stderr, "%s\n", pathdesc );
  194     returnval = -1;
  195     goto error1;
  196     }
  197     if ( verbose ) printf( "<<< .\n" );
  198 
  199     /* cksum file */
  200     if ( cksum ) {
  201     EVP_DigestFinal( mdctx, md_value, &md_len );
  202     base64_e( md_value, md_len, cksum_b64 );
  203     EVP_MD_CTX_free(mdctx);
  204     if ( strcmp( trancksum, cksum_b64 ) != 0 ) {
  205         fprintf( stderr, "line %d: checksum in transcript does not match "
  206         "checksum from server\n", linenum );
  207         fprintf( stderr, "%s\n", pathdesc );
  208         returnval = 1;
  209         goto error1;
  210     }
  211     }
  212 
  213     return( 0 );
  214 
  215 error2:
  216     close( fd );
  217 error1:
  218     unlink( temppath );
  219     return( returnval );
  220 }
  221 
  222 #ifdef __APPLE__
  223 
  224 /*
  225  * Return Value:
  226  *  -1 - error, do not call closesn
  227  *   0 - OKAY
  228  *   1 - error, call closesn
  229  */
  230 
  231     int
  232 retr_applefile( SNET *sn, char *pathdesc, char *path, char *temppath,
  233     mode_t tempmode, off_t transize, char *trancksum )
  234 {
  235     int             dfd, rfd;
  236     unsigned int        md_len;
  237     int             returnval = -1;
  238     off_t           size;
  239     size_t          rsize;
  240     ssize_t         rc;
  241     char            finfo[ FINFOLEN ];
  242     char            buf[ 8192 ];
  243     char            rsrc_path[ MAXPATHLEN ];
  244     char            *line;
  245     struct as_header        ah;
  246     extern struct as_header as_header;
  247     extern struct attrlist  setalist;
  248     struct as_entry     ae_ents[ 3 ]; 
  249     struct timeval      tv;
  250     extern EVP_MD           *md;
  251     EVP_MD_CTX              *mdctx;
  252     unsigned char           md_value[ SZ_BASE64_D( SZ_BASE64_E( EVP_MAX_MD_SIZE ) ) ];
  253     char                cksum_b64[ SZ_BASE64_E( EVP_MAX_MD_SIZE ) ];
  254 
  255     if ( cksum ) {
  256         if ( strcmp( trancksum, "-" ) == 0 ) {
  257         fprintf( stderr, "line %d: No checksum\n", linenum);
  258         fprintf( stderr, "%s\n", pathdesc );
  259             return( 1 );
  260         }
  261         EVP_DigestInit( mdctx, md );
  262     }
  263 
  264     if ( verbose ) printf( ">>> RETR %s\n", pathdesc );
  265     if ( snet_writef( sn, "RETR %s\n", pathdesc ) < 0 ) {
  266     fprintf( stderr, "retrieve applefile %s failed: 1-%s\n", pathdesc,
  267         strerror( errno ));
  268     return( -1 );
  269     }
  270 
  271     tv = timeout;
  272     if (( line = snet_getline_multi( sn, logger, &tv )) == NULL ) {
  273     fprintf( stderr, "retrieve applefile %s failed: 2-%s\n", pathdesc,
  274         strerror( errno ));
  275     return( -1 );
  276     }
  277 
  278     if ( *line != '2' ) {
  279         fprintf( stderr, "%s\n", line );
  280         return( 1 );
  281     }
  282 
  283     /* Get file size from server */
  284     tv = timeout;
  285     if (( line = snet_getline( sn, &tv )) == NULL ) {
  286     fprintf( stderr, "retrieve applefile %s failed: 3-%s\n", pathdesc,
  287         strerror( errno ));
  288     return( -1 );
  289     }
  290     size = strtoofft( line, NULL, 10 );
  291     if ( verbose ) printf( "<<< %" PRIofft "d\n", size );
  292     if ( transize >= 0 && size != transize ) {
  293     fprintf( stderr, "line %d: size in transcript does not match size"
  294         "from server\n", linenum );
  295     fprintf( stderr, "%s\n", pathdesc );
  296     return( -1 );
  297     }  
  298     if ( size < ( AS_HEADERLEN + ( 3 * sizeof( struct as_entry )) +
  299         FINFOLEN )) {
  300     fprintf( stderr,
  301         "retrieve applefile %s failed: AppleSingle-encoded file too "
  302         "short\n", path );
  303     return( -1 );
  304     }
  305 
  306     /* read header to determine if file is encoded in applesingle */
  307     tv = timeout;
  308     if (( rc = snet_read( sn, ( char * )&ah, AS_HEADERLEN, &tv )) <= 0 ) {
  309     fprintf( stderr, "retrieve applefile %s failed: 4-%s\n", pathdesc,
  310         strerror( errno ));
  311     return( -1 );
  312     }
  313     if (( rc != AS_HEADERLEN ) ||
  314         ( memcmp( &as_header, &ah, AS_HEADERLEN ) != 0 )) {
  315     fprintf( stderr,
  316         "retrieve applefile %s failed: corrupt AppleSingle-encoded file\n",
  317         path );
  318     return( -1 );
  319     }
  320     if ( cksum ) {
  321     EVP_DigestUpdate( mdctx, (char *)&ah, (unsigned int)rc );
  322     }
  323 
  324     /* name temp file */
  325     if ( snprintf( temppath, MAXPATHLEN, "%s.radmind.%i", path,
  326         getpid()) >= MAXPATHLEN ) {
  327     fprintf( stderr, "%s.radmind.%i: too long", path, ( int )getpid());
  328     return( -1 );
  329     }
  330 
  331     /* data fork must exist to write to rsrc fork */        
  332     /* Open here so messages from mkprefix don't verbose dots */
  333     if (( dfd = open( temppath, O_CREAT | O_EXCL | O_WRONLY, tempmode )) < 0 ) {
  334     if ( create_prefix && errno == ENOENT ) {
  335         errno = 0;
  336         if ( mkprefix( temppath ) != 0 ) {
  337         perror( temppath );
  338         return( -1 );
  339         }
  340         if (( dfd = open( temppath, O_CREAT | O_EXCL | O_WRONLY,
  341             tempmode )) < 0 ) {
  342         perror( temppath );
  343         return( -1 );
  344         }
  345     } else {
  346         perror( temppath );
  347         return( -1 );
  348     }
  349     }
  350 
  351     if ( verbose ) printf( "<<< " );
  352     if ( dodots ) { putc( '.', stdout ); fflush( stdout ); }
  353     size -= rc;
  354     if ( showprogress ) {
  355     progressupdate( rc, path );
  356     }
  357 
  358     /* read header entries */
  359     tv = timeout;
  360     if (( rc = snet_read( sn, ( char * )&ae_ents,
  361         ( 3 * sizeof( struct as_entry )), &tv )) <= 0 ) {
  362     fprintf( stderr, "retrieve applefile %s failed: 5-%s\n", pathdesc,
  363         strerror( errno ));
  364     returnval = -1;
  365     goto error2;
  366     }
  367     if ( rc != ( 3 * sizeof( struct as_entry ))) {
  368     fprintf( stderr,
  369         "retrieve applefile %s failed: corrupt AppleSingle-encoded file\n",
  370         path );
  371     returnval = -1;
  372     goto error2;
  373     }
  374 
  375     /* Should we check for valid ae_ents here? YES! */
  376 
  377     if ( cksum ) {
  378     EVP_DigestUpdate( mdctx, (char *)&ae_ents, (unsigned int)rc );
  379     }
  380     if ( dodots ) { putc( '.', stdout ); fflush( stdout ); }
  381 
  382     size -= rc;
  383     if ( showprogress ) {
  384     progressupdate( rc, path );
  385     }
  386 
  387     /* read finder info */
  388     tv = timeout;
  389     if (( rc = snet_read( sn, finfo, FINFOLEN, &tv )) <= 0 ) {
  390     fprintf( stderr, "retrieve applefile %s failed: 6-%s\n", pathdesc,
  391         strerror( errno ));
  392     returnval = -1;
  393     goto error2;
  394     }
  395     if ( rc != FINFOLEN ) {
  396     fprintf( stderr,
  397         "retrieve applefile %s failed: corrupt AppleSingle-encoded file\n",
  398         path );
  399     returnval = -1;
  400     goto error2;
  401     }
  402     if ( cksum ) {
  403     EVP_DigestUpdate( mdctx, finfo, (unsigned int)rc );
  404     }
  405     if ( dodots ) { putc( '.', stdout ); fflush( stdout ); }
  406     size -= rc;
  407     if ( showprogress ) {
  408     progressupdate( rc, path );
  409     }
  410 
  411     /*
  412      * endian handling: swap bytes to architecture
  413      * native from AppleSingle big-endian.
  414      *
  415      * This doesn't affect the checksum, since we
  416      * already summed the header entries above.
  417      */
  418     as_entry_hostswap( &ae_ents[ AS_RFE ] );
  419 
  420     if ( ae_ents[ AS_RFE ].ae_length > 0 ) {
  421     /* make rsrc fork name */
  422     if ( snprintf( rsrc_path, MAXPATHLEN, "%s%s", temppath,
  423         _PATH_RSRCFORKSPEC ) >= MAXPATHLEN ) {
  424         fprintf( stderr, "%s%s: path too long\n", temppath,
  425         _PATH_RSRCFORKSPEC );
  426         returnval = -1;
  427         goto error2;
  428     }
  429 
  430     /* No need to mkprefix as dfd is already present */
  431     if (( rfd = open( rsrc_path, O_WRONLY, 0 )) < 0 ) {
  432         perror( rsrc_path );
  433         returnval = -1;
  434         goto error2;
  435     }
  436 
  437     for ( rsize = ae_ents[ AS_RFE ].ae_length;
  438                     rsize > 0; rsize -= rc ) {
  439         tv = timeout;
  440         if (( rc = snet_read( sn, buf, ( int )MIN( sizeof( buf ), rsize ),
  441             &tv )) <= 0 ) {
  442         fprintf( stderr, "retrieve applefile %s failed: 7-%s\n",
  443             pathdesc, strerror( errno ));
  444         returnval = -1;
  445         goto error3;
  446         }
  447         if (( write( rfd, buf, ( unsigned int )rc )) != rc ) {
  448         perror( rsrc_path );
  449         returnval = -1;
  450         goto error3;
  451         }
  452         if ( cksum ) {
  453         EVP_DigestUpdate( mdctx, buf, (unsigned int)rc );
  454         }
  455         if ( dodots ) { putc( '.', stdout ); fflush( stdout ); }
  456         if ( showprogress ) {
  457         progressupdate( rc, path );
  458         }
  459     }
  460 
  461     size -= ae_ents[ AS_RFE ].ae_length;
  462     
  463     if ( close( rfd ) < 0 ) {
  464         perror( rsrc_path );
  465         goto error2;
  466     }
  467     }
  468 
  469     /* write data fork to file */
  470     for ( rc = 0; size > 0; size -= rc ) {
  471         tv = timeout;
  472         if (( rc = snet_read( sn, buf, MIN( sizeof( buf ), size ),
  473         &tv )) <= 0 ) {
  474         fprintf( stderr, "retrieve applefile %s failed: 8-%s\n", pathdesc,
  475         strerror( errno ));
  476         returnval = -1;
  477         goto error2;
  478     }
  479 
  480     if ( write( dfd, buf, ( unsigned int )rc ) != rc ) {
  481         perror( temppath );
  482         returnval = -1;
  483         goto error2;
  484     }
  485 
  486     if ( cksum ) {
  487         EVP_DigestUpdate( mdctx, buf, (unsigned int)rc );
  488     }
  489     if ( dodots ) { putc( '.', stdout ); fflush( stdout); }
  490     if ( showprogress ) {
  491         progressupdate( rc, path );
  492     }
  493     }
  494 
  495     if ( close( dfd ) < 0 ) {
  496     perror( temppath );
  497     returnval = -1;
  498     goto error1;
  499     }
  500     if ( verbose ) printf( "\n" );
  501 
  502     /* set finder info for newly decoded applefile */
  503     if ( setattrlist( temppath, &setalist, finfo, FINFOLEN,
  504         FSOPT_NOFOLLOW ) != 0 ) {
  505     fprintf( stderr,
  506         "retrieve applefile %s failed: Could not set attributes\n",
  507         pathdesc );
  508     returnval = -1;
  509     goto error1;
  510     }
  511 
  512     tv = timeout;
  513     if (( line = snet_getline( sn, &tv )) == NULL ) {
  514     fprintf( stderr, "retrieve applefile %s failed: 9-%s\n", pathdesc,
  515         strerror( errno ));
  516     returnval = -1;
  517     goto error1;
  518     }
  519     if ( strcmp( line, "." ) != 0 ) {
  520         fprintf( stderr, "%s", line );
  521     fprintf( stderr, "%s\n", pathdesc );
  522     returnval = -1;
  523     goto error1;
  524     }
  525     if ( verbose ) printf( "<<< .\n" );
  526 
  527     if ( cksum ) {
  528     EVP_DigestFinal( mdctx, md_value, &md_len );
  529     base64_e(( char*)&md_value, md_len, cksum_b64 );
  530         EVP_MD_CTX_free(mdctx);
  531         if ( strcmp( trancksum, cksum_b64 ) != 0 ) {
  532         fprintf( stderr, "line %d: checksum in transcript does not match "
  533         "checksum from server\n", linenum );
  534     fprintf( stderr, "%s\n", pathdesc );
  535             returnval = 1;
  536         goto error1;
  537         }
  538     }
  539 
  540     return( 0 );
  541 
  542 error3:
  543     close( rfd );
  544 error2:
  545     close( dfd );
  546 error1:
  547     unlink( temppath );
  548     return( returnval );
  549 }
  550 
  551 #else /* !__APPLE__ */
  552 
  553     int
  554 retr_applefile( SNET *sn, char *pathdesc, char *path, char *temppath,
  555     mode_t tempmode, off_t transize, char *trancksum )
  556 {
  557     errno = EINVAL;
  558     return( -1 );
  559 }
  560 
  561 #endif /* __APPLE__ */