/** => zzip_fopen * * This function receives an additional argument pointing to * a ZZIP_FILE* being already in use. If this extra argument is * null then this function is identical with calling => zzip_fopen * * Per default, the old file stream is closed and only the internal * structures associated with it are kept. These internal structures * may be reused for the return value, and this is a lot quicker when * the filename matches a zipped file that is incidently in the very * same zip arch as the old filename wrapped in the stream struct. * * That's simply because the zip arch's central directory does not * need to be read again. As an extension for this function, if the * mode-string contains a "q" then the old stream is not closed but * left untouched, instead it is only given as a hint that a new * file handle may share/copy the zip arch structures of the old file * handle if that is possible, i.e when they are in the same zip arch. * * This function returns a new zzip-handle (use => zzip_close to return * it). On error this function will return null setting => errno(3). */ ZZIP_FILE* zzip_freopen(zzip_char_t* filename, zzip_char_t* mode, ZZIP_FILE* stream) { int o_flags = 0; int o_modes = 0664; if (! mode) mode = "rb"; # ifndef O_BINARY # define O_BINARY 0 # endif # ifndef O_NOCTTY # define O_NOCTTY 0 # endif # ifndef O_SYNC # define O_SYNC 0 # endif # ifndef O_NONBLOCK # define O_NONBLOCK 0 # endif for(; *mode; mode++) { switch (*mode) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': continue; /* ignore if not attached to other info */ case 'r': o_flags |= mode[1] == '+' ? O_RDWR : O_RDONLY; break; case 'w': o_flags |= mode[1] == '+' ? O_RDWR : O_WRONLY; o_flags |= O_TRUNC; break; case 'b': o_flags |= O_BINARY; break; case 'f': o_flags |= O_NOCTTY; break; case 'i': o_modes |= ZZIP_CASELESS; break; case '*': o_modes |= ZZIP_NOPATHS; break; case 'x': o_flags |= O_EXCL; break; case 's': o_flags |= O_SYNC; break; case 'n': o_flags |= O_NONBLOCK; break; case 'o': o_modes &=~ 07; o_modes |= ((mode[1] - '0'))&07; continue; case 'g': o_modes &=~ 070; o_modes |= ((mode[1] - '0')<<3)&070; continue; case 'u': o_modes &=~ 0700; o_modes |= ((mode[1] - '0')<<6)&0700; continue; case 'q': o_modes |= ZZIP_FACTORY; break; case 'z': /* compression level */ continue; /* currently ignored, just for write mode */ } } { ZZIP_FILE* fp = zzip_open_shared_io (stream, filename, o_flags, o_modes, 0, 0); if ( (!(o_modes&ZZIP_FACTORY)) && stream ) { zzip_file_close (stream); } return fp; } }
/** => zzip_open * * This function uses explicit ext and io instead of the internal * defaults, setting them to zero is equivalent to => zzip_open * * note that the two flag types have been split into an o_flags * (for fcntl-like openflags) and o_modes where the latter shall * carry the zzip_flags and possibly accessmodes for unix filesystems. * Since this version of zziplib can not write zipfiles, it is not * yet used for anything else than zzip-specific modeflags. * * This function returns a new zzip-handle (use => zzip_close to return * it). On error this function will return null setting => errno(3). */ ZZIP_FILE* zzip_open_ext_io(zzip_char_t* filename, int o_flags, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io) { return zzip_open_shared_io (0, filename, o_flags, o_modes, ext, io); }