4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/types.h>
38 #include <auth_attr.h>
39 #include <auth_list.h>
42 #include "transport.h"
46 #include "misc_scsi.h"
52 int priv_change_needed
= 0;
55 my_zalloc(size_t size
)
62 /* Lets wait a sec. and try again */
63 if (errno
== EAGAIN
) {
69 (void) err_msg("%s\n", gettext(strerror(errno
)));
70 (void) err_msg(gettext(
71 "Memory allocation failure, Exiting...\n"));
75 (void) memset(ret
, 0, size
);
80 * Prints a string after going back pos number of steps.
81 * Mainly used to show %age complete.
84 str_print(char *str
, int pos
)
86 if ((pos
> 0) && (pos
< 80)) {
87 (void) memset(strbuf
, 8, pos
);
89 (void) printf(strbuf
);
90 (void) memset(strbuf
, ' ', pos
);
92 (void) printf(strbuf
);
93 (void) memset(strbuf
, 8, pos
);
95 (void) printf(strbuf
);
98 (void) printf("%s", str
);
99 (void) fflush(stdout
);
100 return (strlen(str
));
104 * dump the trackio_error struct.
107 print_trackio_error(struct trackio_error
*te
)
111 msg
= gettext("System could not supply data at the required rate.\n");
112 msg1
= gettext("Try using a lower speed for write\n");
114 switch (te
->err_type
) {
115 case TRACKIO_ERR_SYSTEM
:
116 err_msg(gettext("System error: %s\n"), strerror(te
->te_errno
));
118 case TRACKIO_ERR_TRANSPORT
:
119 err_msg(gettext("Transport mechanism error:\n"));
120 if (te
->status
== 2) {
121 if ((te
->key
== 3) && (te
->asc
== 0x0c) &&
128 err_msg(gettext("Bad media.\n"));
132 err_msg("Sense key %x, asc/asq %x/%x\n",
133 te
->key
, te
->asc
, te
->ascq
);
135 err_msg(gettext("I/O error\n"));
139 if (te
->te_errno
!= 0)
140 err_msg("%s\n", strerror(te
->te_errno
));
142 case TRACKIO_ERR_USER_ABORT
:
143 err_msg(gettext("User abort.\n"));
146 err_msg(gettext("Unknown error type.\n"));
148 err_msg("Trackio err type %d\n", te
->err_type
);
157 return (str_errno_to_string(str_errno
));
158 return (strerror(errno
));
162 get_audio_type(char *ext
)
164 if ((strcasecmp(ext
, "au") == 0) ||
165 (strcasecmp(ext
, "sun") == 0))
166 return (AUDIO_TYPE_SUN
);
167 if ((strcasecmp(ext
, "wav") == 0) ||
168 (strcasecmp(ext
, "riff") == 0))
169 return (AUDIO_TYPE_WAV
);
170 if (strcasecmp(ext
, "cda") == 0)
171 return (AUDIO_TYPE_CDA
);
172 if (strcasecmp(ext
, "aur") == 0)
173 return (AUDIO_TYPE_AUR
);
179 * common routines for showing progress.
183 static uint64_t last_total
;
195 progress(int64_t arg
, int64_t completed
)
198 uint64_t total
= (uint64_t)arg
;
200 if (completed
== -1) {
201 /* Got ^C. Add 2 to progress pos to compensate for ^ and C */
202 progress_pos
= str_print("(flushing ...)", progress_pos
+2);
206 if (tm
!= time(NULL
)) {
208 (void) snprintf(s
, BUFSIZE
,
209 gettext("%d bytes written"), completed
);
211 progress_pos
= str_print(s
, progress_pos
);
214 total
= (((uint64_t)completed
) * 100)/total
;
215 if (total
== last_total
)
219 /* There is clearly a miscalculation somewhere */
221 (void) printf("\nWrote more than 100 %% !!\n");
225 /* l10n_NOTE : 'done' as in "Writing track 1...done" */
226 (void) snprintf(s
, BUFSIZE
, gettext("done.\n"));
228 (void) snprintf(s
, BUFSIZE
, "%d %%", (uint_t
)total
);
230 progress_pos
= str_print(s
, progress_pos
);
238 if (priv_change_needed
&& (cur_uid
!= 0)) {
247 if (priv_change_needed
&& (cur_uid
== 0)) {
248 if (seteuid(ruid
) == 0)
254 check_auth(uid_t uid
)
262 /* fail if we cannot get password entry */
267 * check in the RBAC authority files to see if
268 * the user has permission to use CDRW
270 if (chkauthattr(CDRW_AUTH
, pw
->pw_name
) != 1) {
271 /* user is not in database, return failure */
279 * This will busy delay in ms milliseconds. Needed for cases
280 * where 1 sec wait is too long. This is needed for some newer
281 * drives which can empty the drive cache very quickly.
290 req
= start
+ ((hrtime_t
)ms
* 1000000);
292 while (gethrtime() < req
)