10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52523Szk194757 * Common Development and Distribution License (the "License").
62523Szk194757 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*4274Szk194757 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate #include <fcntl.h>
290Sstevel@tonic-gate #include <string.h>
300Sstevel@tonic-gate #include <errno.h>
310Sstevel@tonic-gate #include <sys/types.h>
320Sstevel@tonic-gate #include <unistd.h>
330Sstevel@tonic-gate #include <sys/stat.h>
340Sstevel@tonic-gate #include <sys/statvfs.h>
350Sstevel@tonic-gate #include <stdio.h>
360Sstevel@tonic-gate #include <stdlib.h>
370Sstevel@tonic-gate #include <libintl.h>
380Sstevel@tonic-gate #include <limits.h>
390Sstevel@tonic-gate #include <audio/au.h>
400Sstevel@tonic-gate
410Sstevel@tonic-gate #include "bstream.h"
420Sstevel@tonic-gate #include "util.h"
430Sstevel@tonic-gate #include "audio.h"
440Sstevel@tonic-gate #include "byteorder.h"
450Sstevel@tonic-gate #include "main.h"
460Sstevel@tonic-gate
470Sstevel@tonic-gate int str_errno;
480Sstevel@tonic-gate
490Sstevel@tonic-gate char *
str_errno_to_string(int serrno)500Sstevel@tonic-gate str_errno_to_string(int serrno)
510Sstevel@tonic-gate {
520Sstevel@tonic-gate switch (serrno) {
530Sstevel@tonic-gate case STR_ERR_NO_ERR:
540Sstevel@tonic-gate return (gettext("No error"));
550Sstevel@tonic-gate case STR_ERR_NO_REG_FILE:
560Sstevel@tonic-gate return (gettext("Not a regular file"));
570Sstevel@tonic-gate case STR_ERR_NO_READ_STDIN:
580Sstevel@tonic-gate return (gettext("Stdin not open for reading"));
590Sstevel@tonic-gate case STR_ERR_AU_READ_ERR:
600Sstevel@tonic-gate return (gettext("Unable to read au header"));
610Sstevel@tonic-gate case STR_ERR_AU_UNSUPPORTED_FORMAT:
620Sstevel@tonic-gate return (gettext("Unsupported au format"));
630Sstevel@tonic-gate case STR_ERR_AU_BAD_HEADER:
640Sstevel@tonic-gate return (gettext("Bad au header"));
650Sstevel@tonic-gate case STR_ERR_WAV_READ_ERR:
660Sstevel@tonic-gate return (gettext("Unable to read wav header"));
670Sstevel@tonic-gate case STR_ERR_WAV_UNSUPPORTED_FORMAT:
680Sstevel@tonic-gate return (gettext("Unsupported wav format"));
690Sstevel@tonic-gate case STR_ERR_WAV_BAD_HEADER:
700Sstevel@tonic-gate return (gettext("Bad wav header"));
71*4274Szk194757 case STR_ERR_ISO_READ_ERR:
72*4274Szk194757 return (gettext("Unable to read ISO header"));
73*4274Szk194757 case STR_ERR_ISO_BAD_HEADER:
74*4274Szk194757 return (gettext("Invalid ISO header or not an ISO"));
750Sstevel@tonic-gate default:
760Sstevel@tonic-gate return (gettext("unknown error"));
770Sstevel@tonic-gate }
780Sstevel@tonic-gate }
790Sstevel@tonic-gate
800Sstevel@tonic-gate static int
file_stream_size(bstreamhandle h,off_t * size)810Sstevel@tonic-gate file_stream_size(bstreamhandle h, off_t *size)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate struct stat st;
840Sstevel@tonic-gate
850Sstevel@tonic-gate str_errno = 0;
860Sstevel@tonic-gate
870Sstevel@tonic-gate if (fstat(h->bstr_fd, &st) < 0)
880Sstevel@tonic-gate return (0);
890Sstevel@tonic-gate if ((st.st_mode & S_IFMT) != S_IFREG) {
900Sstevel@tonic-gate str_errno = STR_ERR_NO_REG_FILE;
910Sstevel@tonic-gate return (0);
920Sstevel@tonic-gate }
930Sstevel@tonic-gate *size = st.st_size;
940Sstevel@tonic-gate return (1);
950Sstevel@tonic-gate }
960Sstevel@tonic-gate
970Sstevel@tonic-gate static int
audio_stream_size(bstreamhandle h,off_t * size)980Sstevel@tonic-gate audio_stream_size(bstreamhandle h, off_t *size)
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate str_errno = 0;
1010Sstevel@tonic-gate *size = (off_t)(uintptr_t)(h->bstr_private);
1020Sstevel@tonic-gate return (1);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate static int
file_stream_read(bstreamhandle h,uchar_t * buf,off_t size)1060Sstevel@tonic-gate file_stream_read(bstreamhandle h, uchar_t *buf, off_t size)
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate str_errno = 0;
1090Sstevel@tonic-gate return (read(h->bstr_fd, buf, size));
1100Sstevel@tonic-gate }
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate static int
file_stream_write(bstreamhandle h,uchar_t * buf,off_t size)1130Sstevel@tonic-gate file_stream_write(bstreamhandle h, uchar_t *buf, off_t size)
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate str_errno = 0;
1160Sstevel@tonic-gate return (write(h->bstr_fd, buf, size));
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate /*
1200Sstevel@tonic-gate * with reverse byteorder
1210Sstevel@tonic-gate */
1220Sstevel@tonic-gate static int
file_stream_read_wrbo(bstreamhandle h,uchar_t * buf,off_t size)1230Sstevel@tonic-gate file_stream_read_wrbo(bstreamhandle h, uchar_t *buf, off_t size)
1240Sstevel@tonic-gate {
1250Sstevel@tonic-gate int cnt;
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate str_errno = 0;
1280Sstevel@tonic-gate cnt = read(h->bstr_fd, buf, size);
1290Sstevel@tonic-gate if (cnt > 0) {
1300Sstevel@tonic-gate int i;
1310Sstevel@tonic-gate uchar_t ch;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate for (i = 0; i < cnt; i += 2) {
1340Sstevel@tonic-gate ch = buf[i];
1350Sstevel@tonic-gate buf[i] = buf[i+1];
1360Sstevel@tonic-gate buf[i+1] = ch;
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate return (cnt);
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate /*
1430Sstevel@tonic-gate * This will change the byteorder in the buffer but that is fine with us.
1440Sstevel@tonic-gate */
1450Sstevel@tonic-gate static int
file_stream_write_wrbo(bstreamhandle h,uchar_t * buf,off_t size)1460Sstevel@tonic-gate file_stream_write_wrbo(bstreamhandle h, uchar_t *buf, off_t size)
1470Sstevel@tonic-gate {
1480Sstevel@tonic-gate int i;
1490Sstevel@tonic-gate uchar_t ch;
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate str_errno = 0;
1520Sstevel@tonic-gate if (size > 0) {
1530Sstevel@tonic-gate for (i = 0; i < size; i += 2) {
1540Sstevel@tonic-gate ch = buf[i];
1550Sstevel@tonic-gate buf[i] = buf[i+1];
1560Sstevel@tonic-gate buf[i+1] = ch;
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate return (write(h->bstr_fd, buf, size));
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate static int
file_stream_close(bstreamhandle h)1630Sstevel@tonic-gate file_stream_close(bstreamhandle h)
1640Sstevel@tonic-gate {
1650Sstevel@tonic-gate int fd;
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate str_errno = 0;
1680Sstevel@tonic-gate fd = h->bstr_fd;
1690Sstevel@tonic-gate free(h);
1700Sstevel@tonic-gate return (close(fd));
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate static int
stdin_stream_close(bstreamhandle h)1740Sstevel@tonic-gate stdin_stream_close(bstreamhandle h)
1750Sstevel@tonic-gate {
1760Sstevel@tonic-gate str_errno = 0;
1770Sstevel@tonic-gate free(h);
1780Sstevel@tonic-gate return (0);
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate static int
wav_write_stream_close(bstreamhandle h)1820Sstevel@tonic-gate wav_write_stream_close(bstreamhandle h)
1830Sstevel@tonic-gate {
1840Sstevel@tonic-gate uint32_t sz;
1850Sstevel@tonic-gate Wave_filehdr wav;
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate str_errno = 0;
1880Sstevel@tonic-gate (void) memset(&wav, 0, sizeof (wav));
1890Sstevel@tonic-gate sz = lseek(h->bstr_fd, 0L, SEEK_END);
1900Sstevel@tonic-gate (void) lseek(h->bstr_fd, 0L, SEEK_SET);
1910Sstevel@tonic-gate if (read(h->bstr_fd, &wav, sizeof (wav)) != sizeof (wav)) {
1920Sstevel@tonic-gate return (1);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate wav.total_chunk_size = CPU_TO_LE32(sz - 8);
1950Sstevel@tonic-gate wav.data_size = CPU_TO_LE32(sz - 44);
1960Sstevel@tonic-gate (void) lseek(h->bstr_fd, 0L, SEEK_SET);
1970Sstevel@tonic-gate if (write(h->bstr_fd, &wav, sizeof (wav)) != sizeof (wav)) {
1980Sstevel@tonic-gate return (1);
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate (void) close(h->bstr_fd);
2010Sstevel@tonic-gate free(h);
2020Sstevel@tonic-gate return (0);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate static int
au_write_stream_close(bstreamhandle h)2060Sstevel@tonic-gate au_write_stream_close(bstreamhandle h)
2070Sstevel@tonic-gate {
2080Sstevel@tonic-gate uint32_t sz;
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate str_errno = 0;
2110Sstevel@tonic-gate sz = lseek(h->bstr_fd, 0L, SEEK_END);
2120Sstevel@tonic-gate sz -= PRE_DEF_AU_HDR_LEN;
2130Sstevel@tonic-gate sz = CPU_TO_BE32(sz);
2140Sstevel@tonic-gate if (lseek(h->bstr_fd, 8L, SEEK_SET) < 0)
2150Sstevel@tonic-gate return (1);
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate if (write(h->bstr_fd, &sz, 4) < 0)
2180Sstevel@tonic-gate return (1);
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate (void) close(h->bstr_fd);
2210Sstevel@tonic-gate free(h);
2220Sstevel@tonic-gate return (0);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate /* ARGSUSED */
2260Sstevel@tonic-gate static void
stdin_stream_rewind(bstreamhandle h)2270Sstevel@tonic-gate stdin_stream_rewind(bstreamhandle h)
2280Sstevel@tonic-gate {
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate static void
file_stream_rewind(bstreamhandle h)2320Sstevel@tonic-gate file_stream_rewind(bstreamhandle h)
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate (void) lseek(h->bstr_fd, 0L, SEEK_SET);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate static void
au_stream_rewind(bstreamhandle h)2380Sstevel@tonic-gate au_stream_rewind(bstreamhandle h)
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate au_filehdr_t au;
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate (void) lseek(h->bstr_fd, 0L, SEEK_SET);
2430Sstevel@tonic-gate if (read(h->bstr_fd, &au, sizeof (au)) != sizeof (au)) {
2440Sstevel@tonic-gate return;
2450Sstevel@tonic-gate }
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate if (lseek(h->bstr_fd, (long)(BE32_TO_CPU(au.au_offset)),
2480Sstevel@tonic-gate SEEK_SET) < 0) {
2490Sstevel@tonic-gate return;
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate }
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate static void
wav_stream_rewind(bstreamhandle h)2540Sstevel@tonic-gate wav_stream_rewind(bstreamhandle h)
2550Sstevel@tonic-gate {
2560Sstevel@tonic-gate (void) lseek(h->bstr_fd, (long)(sizeof (Wave_filehdr)), SEEK_SET);
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate bstreamhandle
open_file_read_stream(char * file)2600Sstevel@tonic-gate open_file_read_stream(char *file)
2610Sstevel@tonic-gate {
2620Sstevel@tonic-gate bstreamhandle h;
2630Sstevel@tonic-gate int fd;
2640Sstevel@tonic-gate struct stat st;
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate str_errno = 0;
2670Sstevel@tonic-gate if (stat(file, &st) < 0)
2680Sstevel@tonic-gate return (NULL);
2690Sstevel@tonic-gate if ((st.st_mode & S_IFMT) == S_IFDIR) {
2700Sstevel@tonic-gate str_errno = STR_ERR_NO_REG_FILE;
2710Sstevel@tonic-gate return (NULL);
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate fd = open(file, O_RDONLY);
2740Sstevel@tonic-gate if (fd < 0)
2750Sstevel@tonic-gate return (NULL);
2760Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
2770Sstevel@tonic-gate h->bstr_fd = fd;
2780Sstevel@tonic-gate h->bstr_read = file_stream_read;
2790Sstevel@tonic-gate h->bstr_close = file_stream_close;
2800Sstevel@tonic-gate h->bstr_size = file_stream_size;
2810Sstevel@tonic-gate h->bstr_rewind = file_stream_rewind;
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate return (h);
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate bstreamhandle
open_iso_read_stream(char * fname)287*4274Szk194757 open_iso_read_stream(char *fname)
288*4274Szk194757 {
289*4274Szk194757 bstreamhandle h;
290*4274Szk194757 off_t iso_size = 0;
291*4274Szk194757 char iso_desc[ISO9660_PRIMARY_DESC_SIZE];
292*4274Szk194757
293*4274Szk194757 h = open_file_read_stream(fname);
294*4274Szk194757
295*4274Szk194757 /* If we don't have a valid handle immediately return NULL */
296*4274Szk194757 if (h == NULL)
297*4274Szk194757 return (NULL);
298*4274Szk194757
299*4274Szk194757 if (debug)
300*4274Szk194757 (void) printf("Checking the ISO 9660 file header\n");
301*4274Szk194757
302*4274Szk194757 /* Check to see if we have a valid sized ISO image */
303*4274Szk194757 h->bstr_size(h, &iso_size);
304*4274Szk194757 if (iso_size < ISO9660_HEADER_SIZE) {
305*4274Szk194757 if (debug)
306*4274Szk194757 (void) printf("ISO 9660 header size not sane.\n");
307*4274Szk194757 h->bstr_close(h);
308*4274Szk194757 str_errno = STR_ERR_ISO_BAD_HEADER;
309*4274Szk194757 return (NULL);
310*4274Szk194757 }
311*4274Szk194757
312*4274Szk194757 if (debug)
313*4274Szk194757 (void) printf("ISO 9660 header size is sane.\n");
314*4274Szk194757
315*4274Szk194757 /* Skip over the boot block sector of the ISO. */
316*4274Szk194757 (void) lseek(h->bstr_fd, ISO9660_BOOT_BLOCK_SIZE, SEEK_SET);
317*4274Szk194757
318*4274Szk194757 /*
319*4274Szk194757 * Try to read in the ISO Descriptor and validate this
320*4274Szk194757 * is in fact an ISO 9660 image.
321*4274Szk194757 */
322*4274Szk194757 if (read(h->bstr_fd, iso_desc, ISO9660_PRIMARY_DESC_SIZE) ==
323*4274Szk194757 ISO9660_PRIMARY_DESC_SIZE) {
324*4274Szk194757 /*
325*4274Szk194757 * Bytes one through five of a valid ISO 9660 cd image
326*4274Szk194757 * should contain the string CD001. High Sierra format,
327*4274Szk194757 * the ISO 9660 predecessor, fills this field with the
328*4274Szk194757 * string CDROM. If neither is the case then we should
329*4274Szk194757 * close the stream, set str_errno, and return NULL.
330*4274Szk194757 */
331*4274Szk194757 if (strncmp(iso_desc + ISO9660_STD_IDENT_OFFSET, "CD001",
332*4274Szk194757 5) != 0 && strncmp(iso_desc + ISO9660_STD_IDENT_OFFSET,
333*4274Szk194757 "CDROM", 5) != 0) {
334*4274Szk194757 if (debug)
335*4274Szk194757 (void) printf("Invalid ISO 9660 identifier.\n");
336*4274Szk194757 h->bstr_close(h);
337*4274Szk194757 str_errno = STR_ERR_ISO_BAD_HEADER;
338*4274Szk194757 return (NULL);
339*4274Szk194757 }
340*4274Szk194757 } else {
341*4274Szk194757 h->bstr_close(h);
342*4274Szk194757 str_errno = STR_ERR_ISO_READ_ERR;
343*4274Szk194757 return (NULL);
344*4274Szk194757 }
345*4274Szk194757
346*4274Szk194757 /*
347*4274Szk194757 * Our ISO image is valid rewind the stream
348*4274Szk194757 * and return the handle.
349*4274Szk194757 */
350*4274Szk194757 if (debug)
351*4274Szk194757 (void) printf("ISO 9660 header is sane.\n");
352*4274Szk194757 h->bstr_rewind(h);
353*4274Szk194757 return (h);
354*4274Szk194757 }
355*4274Szk194757
356*4274Szk194757 bstreamhandle
open_stdin_read_stream(void)3570Sstevel@tonic-gate open_stdin_read_stream(void)
3580Sstevel@tonic-gate {
3590Sstevel@tonic-gate bstreamhandle h;
3600Sstevel@tonic-gate int mode;
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate str_errno = 0;
3630Sstevel@tonic-gate if ((mode = fcntl(0, F_GETFD, NULL)) < 0) {
3640Sstevel@tonic-gate str_errno = STR_ERR_NO_READ_STDIN;
3650Sstevel@tonic-gate return (NULL);
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate mode &= 3;
3680Sstevel@tonic-gate if ((mode != O_RDONLY) && (mode != O_RDWR)) {
3690Sstevel@tonic-gate str_errno = STR_ERR_NO_READ_STDIN;
3700Sstevel@tonic-gate return (NULL);
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
3730Sstevel@tonic-gate h->bstr_fd = 0;
3740Sstevel@tonic-gate h->bstr_read = file_stream_read;
3750Sstevel@tonic-gate h->bstr_close = stdin_stream_close;
3760Sstevel@tonic-gate h->bstr_size = file_stream_size;
3770Sstevel@tonic-gate h->bstr_rewind = stdin_stream_rewind;
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate return (h);
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate bstreamhandle
open_au_read_stream(char * fname)3830Sstevel@tonic-gate open_au_read_stream(char *fname)
3840Sstevel@tonic-gate {
3850Sstevel@tonic-gate bstreamhandle h;
3860Sstevel@tonic-gate int fd, sav;
3870Sstevel@tonic-gate au_filehdr_t *au;
3880Sstevel@tonic-gate struct stat st;
3890Sstevel@tonic-gate uint32_t data_size;
3900Sstevel@tonic-gate
3910Sstevel@tonic-gate au = NULL;
3920Sstevel@tonic-gate str_errno = 0;
3930Sstevel@tonic-gate fd = open(fname, O_RDONLY);
3940Sstevel@tonic-gate if (fd < 0)
3950Sstevel@tonic-gate return (NULL);
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate if (fstat(fd, &st) < 0) {
3980Sstevel@tonic-gate goto au_open_failed;
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate if ((st.st_mode & S_IFMT) != S_IFREG) {
4010Sstevel@tonic-gate str_errno = STR_ERR_NO_REG_FILE;
4020Sstevel@tonic-gate goto au_open_failed;
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate au = (au_filehdr_t *)my_zalloc(sizeof (*au));
4050Sstevel@tonic-gate if (read(fd, au, sizeof (*au)) != sizeof (*au)) {
4060Sstevel@tonic-gate str_errno = STR_ERR_AU_READ_ERR;
4070Sstevel@tonic-gate goto au_open_failed;
4080Sstevel@tonic-gate }
4090Sstevel@tonic-gate au->au_magic = BE32_TO_CPU(au->au_magic);
4100Sstevel@tonic-gate au->au_offset = BE32_TO_CPU(au->au_offset);
4110Sstevel@tonic-gate au->au_data_size = BE32_TO_CPU(au->au_data_size);
4120Sstevel@tonic-gate au->au_encoding = BE32_TO_CPU(au->au_encoding);
4130Sstevel@tonic-gate au->au_sample_rate = BE32_TO_CPU(au->au_sample_rate);
4140Sstevel@tonic-gate au->au_channels = BE32_TO_CPU(au->au_channels);
4150Sstevel@tonic-gate
4160Sstevel@tonic-gate if (au->au_magic != AUDIO_AU_FILE_MAGIC) {
4170Sstevel@tonic-gate str_errno = STR_ERR_AU_BAD_HEADER;
4180Sstevel@tonic-gate goto au_open_failed;
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate if ((au->au_encoding != AUDIO_AU_ENCODING_LINEAR_16) ||
4210Sstevel@tonic-gate (au->au_sample_rate != 44100) || (au->au_channels != 2)) {
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate str_errno = STR_ERR_AU_UNSUPPORTED_FORMAT;
4240Sstevel@tonic-gate goto au_open_failed;
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate if (au->au_data_size != AUDIO_AU_UNKNOWN_SIZE) {
4270Sstevel@tonic-gate if ((au->au_offset + au->au_data_size) != st.st_size) {
4280Sstevel@tonic-gate str_errno = STR_ERR_AU_BAD_HEADER;
4290Sstevel@tonic-gate goto au_open_failed;
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate data_size = au->au_data_size;
4320Sstevel@tonic-gate } else {
4330Sstevel@tonic-gate data_size = st.st_size - au->au_offset;
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate if (data_size == 0) {
4360Sstevel@tonic-gate str_errno = STR_ERR_AU_UNSUPPORTED_FORMAT;
4370Sstevel@tonic-gate goto au_open_failed;
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate if (lseek(fd, au->au_offset, SEEK_SET) < 0) {
4400Sstevel@tonic-gate goto au_open_failed;
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate free(au);
4440Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
4450Sstevel@tonic-gate h->bstr_fd = fd;
4460Sstevel@tonic-gate h->bstr_read = file_stream_read_wrbo;
4470Sstevel@tonic-gate h->bstr_close = file_stream_close;
4480Sstevel@tonic-gate h->bstr_size = audio_stream_size;
4490Sstevel@tonic-gate h->bstr_rewind = au_stream_rewind;
4500Sstevel@tonic-gate h->bstr_private = (void *)data_size;
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate return (h);
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate au_open_failed:
4550Sstevel@tonic-gate sav = errno;
4560Sstevel@tonic-gate (void) close(fd);
4570Sstevel@tonic-gate if (au != NULL)
4580Sstevel@tonic-gate free(au);
4590Sstevel@tonic-gate errno = sav;
4600Sstevel@tonic-gate return (NULL);
4610Sstevel@tonic-gate }
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate bstreamhandle
open_wav_read_stream(char * fname)4640Sstevel@tonic-gate open_wav_read_stream(char *fname)
4650Sstevel@tonic-gate {
4660Sstevel@tonic-gate bstreamhandle h;
4670Sstevel@tonic-gate int fd, sav;
4680Sstevel@tonic-gate Wave_filehdr *wav;
4690Sstevel@tonic-gate struct stat st;
4700Sstevel@tonic-gate uint32_t data_size;
4710Sstevel@tonic-gate
4720Sstevel@tonic-gate wav = NULL;
4730Sstevel@tonic-gate str_errno = 0;
4740Sstevel@tonic-gate fd = open(fname, O_RDONLY);
4750Sstevel@tonic-gate if (fd < 0)
4760Sstevel@tonic-gate return (NULL);
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate if (fstat(fd, &st) < 0) {
4790Sstevel@tonic-gate goto wav_open_failed;
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate if ((st.st_mode & S_IFMT) != S_IFREG) {
4820Sstevel@tonic-gate str_errno = STR_ERR_NO_REG_FILE;
4830Sstevel@tonic-gate goto wav_open_failed;
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate wav = (Wave_filehdr *)my_zalloc(sizeof (*wav));
4860Sstevel@tonic-gate if (read(fd, wav, sizeof (*wav)) != sizeof (*wav)) {
4870Sstevel@tonic-gate str_errno = STR_ERR_WAV_READ_ERR;
4880Sstevel@tonic-gate goto wav_open_failed;
4890Sstevel@tonic-gate }
4900Sstevel@tonic-gate if ((strncmp(wav->riff, "RIFF", 4) != 0) ||
4910Sstevel@tonic-gate (strncmp(wav->wave, "WAVE", 4) != 0)) {
4920Sstevel@tonic-gate str_errno = STR_ERR_WAV_BAD_HEADER;
4930Sstevel@tonic-gate goto wav_open_failed;
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate if (((CPU_TO_LE32(wav->total_chunk_size) + 8) != st.st_size) ||
4960Sstevel@tonic-gate (strncmp(wav->fmt, "fmt ", 4) != 0) ||
4970Sstevel@tonic-gate (CPU_TO_LE16(wav->fmt_tag) != 1) ||
4980Sstevel@tonic-gate (CPU_TO_LE16(wav->n_channels) != 2) ||
4990Sstevel@tonic-gate (CPU_TO_LE32(wav->sample_rate) != 44100) ||
5000Sstevel@tonic-gate (CPU_TO_LE16(wav->bits_per_sample) != 16) ||
5010Sstevel@tonic-gate (strncmp(wav->data, "data", 4) != 0) ||
5020Sstevel@tonic-gate ((CPU_TO_LE32(wav->data_size) + 44) != st.st_size)) {
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate str_errno = STR_ERR_WAV_UNSUPPORTED_FORMAT;
5050Sstevel@tonic-gate goto wav_open_failed;
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate data_size = CPU_TO_LE32(wav->data_size);
5080Sstevel@tonic-gate if (lseek(fd, sizeof (*wav), SEEK_SET) < 0) {
5090Sstevel@tonic-gate goto wav_open_failed;
5100Sstevel@tonic-gate }
5110Sstevel@tonic-gate
5120Sstevel@tonic-gate free(wav);
5130Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
5140Sstevel@tonic-gate h->bstr_fd = fd;
5150Sstevel@tonic-gate h->bstr_read = file_stream_read;
5160Sstevel@tonic-gate h->bstr_close = file_stream_close;
5170Sstevel@tonic-gate h->bstr_size = audio_stream_size;
5180Sstevel@tonic-gate h->bstr_rewind = wav_stream_rewind;
5190Sstevel@tonic-gate h->bstr_private = (void *)data_size;
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate return (h);
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate wav_open_failed:
5240Sstevel@tonic-gate sav = errno;
5250Sstevel@tonic-gate (void) close(fd);
5260Sstevel@tonic-gate if (wav != NULL)
5270Sstevel@tonic-gate free(wav);
5280Sstevel@tonic-gate errno = sav;
5290Sstevel@tonic-gate return (NULL);
5300Sstevel@tonic-gate }
5310Sstevel@tonic-gate
5320Sstevel@tonic-gate bstreamhandle
open_aur_read_stream(char * fname)5330Sstevel@tonic-gate open_aur_read_stream(char *fname)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate bstreamhandle h;
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate h = open_file_read_stream(fname);
5380Sstevel@tonic-gate if (h != NULL) {
5390Sstevel@tonic-gate h->bstr_read = file_stream_read_wrbo;
5400Sstevel@tonic-gate }
5410Sstevel@tonic-gate return (h);
5420Sstevel@tonic-gate }
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate bstreamhandle
open_au_write_stream(char * fname)5450Sstevel@tonic-gate open_au_write_stream(char *fname)
5460Sstevel@tonic-gate {
5470Sstevel@tonic-gate bstreamhandle h;
5480Sstevel@tonic-gate int esav, fd;
5490Sstevel@tonic-gate uchar_t head[] = PRE_DEF_AU_HDR;
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate str_errno = 0;
5520Sstevel@tonic-gate fd = -1;
5530Sstevel@tonic-gate /* O_RDWR because we need to read while closing */
5540Sstevel@tonic-gate fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
5550Sstevel@tonic-gate if (fd < 0)
5560Sstevel@tonic-gate goto open_au_write_stream_failed;
5570Sstevel@tonic-gate if (write(fd, head, PRE_DEF_AU_HDR_LEN) != PRE_DEF_AU_HDR_LEN) {
5580Sstevel@tonic-gate goto open_au_write_stream_failed;
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
5610Sstevel@tonic-gate h->bstr_fd = fd;
5620Sstevel@tonic-gate h->bstr_write = file_stream_write_wrbo;
5630Sstevel@tonic-gate h->bstr_close = au_write_stream_close;
5640Sstevel@tonic-gate return (h);
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate open_au_write_stream_failed:
5670Sstevel@tonic-gate esav = errno;
5680Sstevel@tonic-gate if (fd != -1)
5690Sstevel@tonic-gate (void) close(fd);
5700Sstevel@tonic-gate errno = esav;
5710Sstevel@tonic-gate return (NULL);
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate bstreamhandle
open_wav_write_stream(char * fname)5750Sstevel@tonic-gate open_wav_write_stream(char *fname)
5760Sstevel@tonic-gate {
5770Sstevel@tonic-gate bstreamhandle h;
5780Sstevel@tonic-gate int esav, fd;
5790Sstevel@tonic-gate uchar_t head[] = PRE_DEF_WAV_HDR;
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate str_errno = 0;
5820Sstevel@tonic-gate fd = -1;
5830Sstevel@tonic-gate fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
5840Sstevel@tonic-gate if (fd < 0)
5850Sstevel@tonic-gate goto open_wav_write_stream_failed;
5860Sstevel@tonic-gate if (write(fd, head, PRE_DEF_WAV_HDR_LEN) != PRE_DEF_WAV_HDR_LEN) {
5870Sstevel@tonic-gate goto open_wav_write_stream_failed;
5880Sstevel@tonic-gate }
5890Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
5900Sstevel@tonic-gate h->bstr_fd = fd;
5910Sstevel@tonic-gate h->bstr_write = file_stream_write;
5920Sstevel@tonic-gate h->bstr_close = wav_write_stream_close;
5930Sstevel@tonic-gate return (h);
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate open_wav_write_stream_failed:
5960Sstevel@tonic-gate esav = errno;
5970Sstevel@tonic-gate if (fd != -1)
5980Sstevel@tonic-gate (void) close(fd);
5990Sstevel@tonic-gate errno = esav;
6000Sstevel@tonic-gate return (NULL);
6010Sstevel@tonic-gate }
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate bstreamhandle
open_aur_write_stream(char * fname)6040Sstevel@tonic-gate open_aur_write_stream(char *fname)
6050Sstevel@tonic-gate {
6060Sstevel@tonic-gate bstreamhandle h;
6070Sstevel@tonic-gate int fd;
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate str_errno = 0;
6100Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
6110Sstevel@tonic-gate if (fd < 0)
6120Sstevel@tonic-gate return (NULL);
6130Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
6140Sstevel@tonic-gate h->bstr_fd = fd;
6150Sstevel@tonic-gate h->bstr_write = file_stream_write_wrbo;
6160Sstevel@tonic-gate h->bstr_close = file_stream_close;
6170Sstevel@tonic-gate return (h);
6180Sstevel@tonic-gate }
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate bstreamhandle
open_file_write_stream(char * fname)6210Sstevel@tonic-gate open_file_write_stream(char *fname)
6220Sstevel@tonic-gate {
6230Sstevel@tonic-gate bstreamhandle h;
6240Sstevel@tonic-gate int fd;
6250Sstevel@tonic-gate
6260Sstevel@tonic-gate str_errno = 0;
6270Sstevel@tonic-gate fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
6280Sstevel@tonic-gate if (fd < 0)
6290Sstevel@tonic-gate return (NULL);
6300Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
6310Sstevel@tonic-gate h->bstr_fd = fd;
6320Sstevel@tonic-gate h->bstr_write = file_stream_write;
6330Sstevel@tonic-gate h->bstr_close = file_stream_close;
6340Sstevel@tonic-gate return (h);
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate
6370Sstevel@tonic-gate bstreamhandle
open_temp_file_stream(void)6380Sstevel@tonic-gate open_temp_file_stream(void)
6390Sstevel@tonic-gate {
6400Sstevel@tonic-gate bstreamhandle h;
6410Sstevel@tonic-gate char *t;
6420Sstevel@tonic-gate int fd;
6430Sstevel@tonic-gate
6440Sstevel@tonic-gate str_errno = 0;
6450Sstevel@tonic-gate
6460Sstevel@tonic-gate t = (char *)get_tmp_name();
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate if (strlcat(t, "/cdXXXXXX", PATH_MAX) >= PATH_MAX)
6490Sstevel@tonic-gate return (NULL);
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate fd = mkstemp(t);
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate if (debug)
6540Sstevel@tonic-gate (void) printf("temp is: %s length: %d\n", t, strlen(t));
6550Sstevel@tonic-gate
6560Sstevel@tonic-gate if (fd < 0)
6570Sstevel@tonic-gate return (NULL);
6580Sstevel@tonic-gate (void) unlink(t);
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate h = (bstreamhandle)my_zalloc(sizeof (*h));
6610Sstevel@tonic-gate h->bstr_fd = fd;
6620Sstevel@tonic-gate h->bstr_read = file_stream_read;
6630Sstevel@tonic-gate h->bstr_write = file_stream_write;
6640Sstevel@tonic-gate h->bstr_close = file_stream_close;
6650Sstevel@tonic-gate h->bstr_size = file_stream_size;
6660Sstevel@tonic-gate h->bstr_rewind = file_stream_rewind;
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate return (h);
6690Sstevel@tonic-gate }
6700Sstevel@tonic-gate
671472Sec158148 /*
672472Sec158148 * check_avail_temp_space returns 0 if there is adequate space
673472Sec158148 * in the temporary directory, or a non-zero error code if
674472Sec158148 * something goes wrong
675472Sec158148 */
6760Sstevel@tonic-gate int
check_avail_temp_space(size_t req_size)677472Sec158148 check_avail_temp_space(size_t req_size)
6780Sstevel@tonic-gate {
6790Sstevel@tonic-gate struct statvfs buf;
6802523Szk194757 u_longlong_t free_size = 0;
6810Sstevel@tonic-gate
682472Sec158148 if (statvfs(get_tmp_name(), &buf) < 0) {
683472Sec158148 return (errno);
684472Sec158148 }
6850Sstevel@tonic-gate
686472Sec158148 free_size = buf.f_bfree * buf.f_frsize;
6870Sstevel@tonic-gate
688472Sec158148 if (free_size <= req_size)
689472Sec158148 return (ENOMEM);
690472Sec158148
691472Sec158148 return (0);
6920Sstevel@tonic-gate }
6930Sstevel@tonic-gate
6940Sstevel@tonic-gate
6950Sstevel@tonic-gate char *
get_tmp_name(void)6960Sstevel@tonic-gate get_tmp_name(void)
6970Sstevel@tonic-gate {
6980Sstevel@tonic-gate char *t;
6990Sstevel@tonic-gate char *envptr;
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate t = (char *)my_zalloc(PATH_MAX);
7020Sstevel@tonic-gate
7030Sstevel@tonic-gate /*
7040Sstevel@tonic-gate * generate temp directory path based on this order:
7050Sstevel@tonic-gate * user specified (-m option), temp env variable,
7060Sstevel@tonic-gate * and finally /tmp if nothing is found.
7070Sstevel@tonic-gate */
7080Sstevel@tonic-gate
7090Sstevel@tonic-gate if (alt_tmp_dir) {
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate /* copy and leave room for temp filename */
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate (void) strlcpy(t, alt_tmp_dir, PATH_MAX - 10);
7140Sstevel@tonic-gate } else {
7150Sstevel@tonic-gate envptr = getenv("TMPDIR");
7160Sstevel@tonic-gate if (envptr != NULL) {
7170Sstevel@tonic-gate (void) strlcpy(t, envptr, PATH_MAX - 10);
7180Sstevel@tonic-gate } else {
7190Sstevel@tonic-gate (void) strlcpy(t, "/tmp", 5);
7200Sstevel@tonic-gate }
7210Sstevel@tonic-gate }
7220Sstevel@tonic-gate
7230Sstevel@tonic-gate /*
7240Sstevel@tonic-gate * no need to check if path is valid. statvfs will catch
7250Sstevel@tonic-gate * it later and fail with a proper error message.
7260Sstevel@tonic-gate */
7270Sstevel@tonic-gate
7280Sstevel@tonic-gate return (t);
7290Sstevel@tonic-gate }
730