/[debburn]/cdrkit/trunk/scgskeleton/skel.c
ViewVC logotype

Contents of /cdrkit/trunk/scgskeleton/skel.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 369 - (hide annotations) (download)
Wed Oct 25 21:06:11 2006 UTC (6 years, 7 months ago) by blade
Original Path: nonameyet/branches/cleanup/scgskeleton/skel.c
File MIME type: text/plain
File size: 10966 byte(s)
Merge with trunk at revision 368
1 blade 219 /*
2     * This file has been modified for the cdrkit suite.
3     *
4     * The behaviour and appearence of the program code below can differ to a major
5     * extent from the version distributed by the original author(s).
6     *
7     * For details, see Changelog file distributed with the cdrkit package. If you
8     * received this file from another source then ask the distributing person for
9     * a log of modifications.
10     *
11     */
12    
13 blade 2 /* @(#)skel.c 1.6 06/02/05 Copyright 1987, 1995-2006 J. Schilling */
14     #ifndef lint
15     static char sccsid[] =
16     "@(#)skel.c 1.6 06/02/05 Copyright 1987, 1995-2006 J. Schilling";
17     #endif
18     /*
19     * Skeleton for the use of the scg genearal SCSI - driver
20     *
21     * Copyright (c) 1987, 1995-2006 J. Schilling
22     */
23     /*
24     * This program is free software; you can redistribute it and/or modify
25     * it under the terms of the GNU General Public License version 2
26     * as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License along with
34     * this program; see the file COPYING. If not, write to the Free Software
35     * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36     */
37    
38     #include <mconfig.h>
39     #include <stdio.h>
40     #include <standard.h>
41     #include <unixstd.h>
42     #include <stdxlib.h>
43     #include <strdefs.h>
44     #include <fctldefs.h>
45     #include <timedefs.h>
46     #include <signal.h>
47     #include <schily.h>
48     #ifdef HAVE_PRIV_H
49     #include <priv.h>
50     #endif
51    
52     #ifdef NEED_O_BINARY
53     #include <io.h> /* for setmode() prototype */
54     #endif
55    
56     #include <scg/scgcmd.h>
57     #include <scg/scsireg.h>
58     #include <scg/scsitransp.h>
59    
60     #include "scsi_scan.h"
61     #include "cdrecord.h"
62     #include "defaults.h"
63    
64     char skel_version[] = "1.1";
65    
66 kaner-guest 368 extern BOOL getlong(char *, long *, long, long);
67     extern BOOL getint(char *, int *, int, int);
68 blade 2
69     struct exargs {
70     SCSI *scgp;
71     int old_secsize;
72     int flags;
73     int exflags;
74     char oerr[3];
75     } exargs;
76    
77 kaner-guest 368 static void usage(int ret);
78     static void intr(int sig);
79     static void exscsi(int excode, void *arg);
80     static void excdr(int excode, void *arg);
81     static int prstats(void);
82     static int prstats_silent(void);
83     static void doit(SCSI *scgp);
84     static void dofile(SCSI *scgp, char *filename);
85 blade 2
86    
87     struct timeval starttime;
88     struct timeval stoptime;
89     int didintr;
90     int exsig;
91    
92     char *Sbuf;
93     long Sbufsize;
94    
95     int help;
96     int xdebug;
97     int lverbose;
98     int quiet;
99     BOOL is_suid;
100    
101 kaner-guest 368 static void
102     usage(int ret)
103 blade 2 int ret;
104     {
105 blade 369 fprintf(stderr, "Usage:\tscgskeleton [options]\n");
106     fprintf(stderr, "options:\n");
107     fprintf(stderr, "\t-version print version information and exit\n");
108     fprintf(stderr, "\tdev=target SCSI target to use\n");
109     fprintf(stderr, "\tf=filename Name of file to read/write\n");
110     fprintf(stderr, "\tts=# set maximum transfer size for a single SCSI command\n");
111     fprintf(stderr, "\ttimeout=# set the default SCSI command timeout to #.\n");
112     fprintf(stderr, "\tdebug=#,-d Set to # or increment misc debug level\n");
113     fprintf(stderr, "\tkdebug=#,kd=# do Kernel debugging\n");
114     fprintf(stderr, "\t-quiet,-q be more quiet in error retry mode\n");
115     fprintf(stderr, "\t-verbose,-v increment general verbose level by one\n");
116     fprintf(stderr, "\t-Verbose,-V increment SCSI command transport verbose level by one\n");
117     fprintf(stderr, "\t-silent,-s do not print status of failed SCSI commands\n");
118     fprintf(stderr, "\t-scanbus scan the SCSI bus and exit\n");
119 blade 2 exit(ret);
120     }
121    
122     char opts[] = "debug#,d+,kdebug#,kd#,timeout#,quiet,q,verbose+,v+,Verbose+,V+,x+,xd#,silent,s,help,h,version,scanbus,dev*,ts&,f*";
123    
124 kaner-guest 368 int
125     main(int argc, char *argv[])
126 blade 2 {
127     char *dev = NULL;
128     int fcount;
129     int cac;
130     char * const *cav;
131     int scsibus = -1;
132     int target = -1;
133     int lun = -1;
134     int silent = 0;
135     int verbose = 0;
136     int kdebug = 0;
137     int debug = 0;
138     int deftimeout = 40;
139     int pversion = 0;
140     int scanbus = 0;
141     SCSI *scgp;
142     char *filename = NULL;
143    
144 kaner-guest 368 save_args(argc, argv);
145 blade 2
146 kaner-guest 368 cac = --argc;
147     cav = ++argv;
148 blade 2
149     if (getallargs(&cac, &cav, opts,
150     &debug, &debug,
151     &kdebug, &kdebug,
152     &deftimeout,
153     &quiet, &quiet,
154     &lverbose, &lverbose,
155     &verbose, &verbose,
156     &xdebug, &xdebug,
157     &silent, &silent,
158     &help, &help, &pversion,
159     &scanbus,
160     &dev,
161     getnum, &Sbufsize,
162     &filename) < 0) {
163     errmsgno(EX_BAD, "Bad flag: %s.\n", cav[0]);
164     usage(EX_BAD);
165     }
166     if (help)
167     usage(0);
168     if (pversion) {
169 blade 217 printf("scgskeleton %s (%s) "
170     "Copyright (C) 1987, 1995-2006 Jörg Schilling\n",
171     skel_version, HOST_SYSTEM);
172 blade 2 exit(0);
173     }
174    
175     fcount = 0;
176 kaner-guest 368 cac = argc;
177     cav = argv;
178 blade 2
179     while (getfiles(&cac, &cav, opts) > 0) {
180     fcount++;
181     if (fcount == 1) {
182     if (*astoi(cav[0], &target) != '\0') {
183     errmsgno(EX_BAD,
184     "Target '%s' is not a Number.\n",
185     cav[0]);
186     usage(EX_BAD);
187     /* NOTREACHED */
188     }
189     }
190     if (fcount == 2) {
191     if (*astoi(cav[0], &lun) != '\0') {
192     errmsgno(EX_BAD,
193     "Lun is '%s' not a Number.\n",
194     cav[0]);
195     usage(EX_BAD);
196     /* NOTREACHED */
197     }
198     }
199     if (fcount == 3) {
200     if (*astoi(cav[0], &scsibus) != '\0') {
201     errmsgno(EX_BAD,
202     "Scsibus is '%s' not a Number.\n",
203     cav[0]);
204     usage(EX_BAD);
205     /* NOTREACHED */
206     }
207     }
208     cac--;
209     cav++;
210     }
211 blade 369 /*fprintf(stderr, "dev: '%s'\n", dev);*/
212 blade 2
213     cdr_defaults(&dev, NULL, NULL, NULL);
214     if (debug) {
215     printf("dev: '%s'\n", dev);
216     }
217     if (!scanbus && dev == NULL &&
218     scsibus == -1 && (target == -1 || lun == -1)) {
219     errmsgno(EX_BAD, "No SCSI device specified.\n");
220     usage(EX_BAD);
221     }
222     if (dev || scanbus) {
223     char errstr[80];
224    
225     /*
226     * Call scg_remote() to force loading the remote SCSI transport
227     * library code that is located in librscg instead of the dummy
228     * remote routines that are located inside libscg.
229     */
230     scg_remote();
231     if (dev != NULL &&
232     ((strncmp(dev, "HELP", 4) == 0) ||
233     (strncmp(dev, "help", 4) == 0))) {
234     scg_help(stderr);
235     exit(0);
236     }
237     if ((scgp = scg_open(dev, errstr, sizeof (errstr), debug, lverbose)) == (SCSI *)0) {
238     int err = geterrno();
239    
240     errmsgno(err, "%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":"");
241     errmsgno(EX_BAD, "For possible targets try 'scgskeleton -scanbus'. Make sure you are root.\n");
242     errmsgno(EX_BAD, "For possible transport specifiers try 'scgskeleton dev=help'.\n");
243     exit(err);
244     }
245     } else {
246     if (scsibus == -1 && target >= 0 && lun >= 0)
247     scsibus = 0;
248    
249     scgp = scg_smalloc();
250     scgp->debug = debug;
251     scgp->kdebug = kdebug;
252    
253     scg_settarget(scgp, scsibus, target, lun);
254     if (scg__open(scgp, NULL) <= 0)
255     comerr("Cannot open SCSI driver.\n");
256     }
257     scgp->silent = silent;
258     scgp->verbose = verbose;
259     scgp->debug = debug;
260     scgp->kdebug = kdebug;
261     scg_settimeout(scgp, deftimeout);
262    
263     if (Sbufsize == 0)
264     Sbufsize = 256*1024L;
265     Sbufsize = scg_bufsize(scgp, Sbufsize);
266     if ((Sbuf = scg_getbuf(scgp, Sbufsize)) == NULL)
267     comerr("Cannot get SCSI I/O buffer.\n");
268    
269     #ifdef HAVE_PRIV_SET
270     /*
271     * Give up privs we do not need anymore.
272     * We no longer need:
273     * file_dac_read,net_privaddr
274     * We still need:
275     * sys_devices
276     */
277     priv_set(PRIV_OFF, PRIV_EFFECTIVE,
278     PRIV_FILE_DAC_READ, PRIV_NET_PRIVADDR, NULL);
279     priv_set(PRIV_OFF, PRIV_PERMITTED,
280     PRIV_FILE_DAC_READ, PRIV_NET_PRIVADDR, NULL);
281     priv_set(PRIV_OFF, PRIV_INHERITABLE,
282     PRIV_FILE_DAC_READ, PRIV_NET_PRIVADDR, PRIV_SYS_DEVICES, NULL);
283     #endif
284     /*
285     * This is only for OS that do not support fine grained privs.
286     */
287     is_suid = geteuid() != getuid();
288     /*
289     * We don't need root privilleges anymore.
290     */
291     #ifdef HAVE_SETREUID
292     if (setreuid(-1, getuid()) < 0)
293     #else
294     #ifdef HAVE_SETEUID
295     if (seteuid(getuid()) < 0)
296     #else
297     if (setuid(getuid()) < 0)
298     #endif
299     #endif
300     comerr("Panic cannot set back effective uid.\n");
301    
302     /* code to use SCG */
303    
304     if (scanbus) {
305     select_target(scgp, stdout);
306     exit(0);
307     }
308     do_inquiry(scgp, FALSE);
309     allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
310    
311     exargs.scgp = scgp;
312     exargs.old_secsize = -1;
313     /* exargs.flags = flags;*/
314     exargs.oerr[2] = 0;
315    
316     /*
317     * Install exit handler before we change the drive status.
318     */
319     on_comerr(exscsi, &exargs);
320     signal(SIGINT, intr);
321     signal(SIGTERM, intr);
322    
323     if (filename)
324     dofile(scgp, filename);
325     else
326     doit(scgp);
327    
328     comexit(0);
329     return (0);
330     }
331    
332     /*
333     * XXX Leider kann man vim Signalhandler keine SCSI Kommandos verschicken
334     * XXX da meistens das letzte SCSI Kommando noch laeuft.
335     * XXX Eine Loesung waere ein Abort Callback in SCSI *.
336     */
337 kaner-guest 368 static void
338     intr(int sig)
339 blade 2 {
340     didintr++;
341     exsig = sig;
342     /* comexit(sig);*/
343     }
344    
345     /* ARGSUSED */
346 kaner-guest 368 static void
347     exscsi(int excode, void *arg)
348 blade 2 {
349     struct exargs *exp = (struct exargs *)arg;
350     int i;
351    
352     /*
353     * Try to restore the old sector size.
354     */
355     if (exp != NULL && exp->exflags == 0) {
356     for (i = 0; i < 10*100; i++) {
357     if (!exp->scgp->running)
358     break;
359     if (i == 10) {
360     errmsgno(EX_BAD,
361     "Waiting for current SCSI command to finish.\n");
362     }
363     usleep(100000);
364     }
365    
366     #ifdef ___NEEDED___
367     /*
368     * Try to set drive back to original state.
369     */
370     if (!exp->scgp->running) {
371     if (exp->oerr[2] != 0) {
372     domode(exp->scgp, exp->oerr[0], exp->oerr[1]);
373     }
374     if (exp->old_secsize > 0 && exp->old_secsize != 2048)
375     select_secsize(exp->scgp, exp->old_secsize);
376     }
377     #endif
378     exp->exflags++; /* Make sure that it only get called once */
379     }
380     }
381    
382 kaner-guest 368 static void
383     excdr(int excode, void *arg)
384 blade 2 {
385     exscsi(excode, arg);
386    
387     #ifdef needed
388     /* Do several other restores/statistics here (see cdrecord.c) */
389     #endif
390     }
391    
392     /*
393     * Return milliseconds since start time.
394     */
395 kaner-guest 368 static int
396 blade 2 prstats()
397     {
398     int sec;
399     int usec;
400     int tmsec;
401    
402     if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
403     comerr("Cannot get time\n");
404    
405     sec = stoptime.tv_sec - starttime.tv_sec;
406     usec = stoptime.tv_usec - starttime.tv_usec;
407     tmsec = sec*1000 + usec/1000;
408     #ifdef lint
409     tmsec = tmsec; /* Bisz spaeter */
410     #endif
411     if (usec < 0) {
412     sec--;
413     usec += 1000000;
414     }
415    
416 blade 369 fprintf(stderr, "Time total: %d.%03dsec\n", sec, usec/1000);
417 blade 2 return (1000*sec + (usec / 1000));
418     }
419    
420     /*
421     * Return milliseconds since start time, but be silent this time.
422     */
423 kaner-guest 368 static int
424 blade 2 prstats_silent()
425     {
426     int sec;
427     int usec;
428     int tmsec;
429    
430     if (gettimeofday(&stoptime, (struct timezone *)0) < 0)
431     comerr("Cannot get time\n");
432    
433     sec = stoptime.tv_sec - starttime.tv_sec;
434     usec = stoptime.tv_usec - starttime.tv_usec;
435     tmsec = sec*1000 + usec/1000;
436     #ifdef lint
437     tmsec = tmsec; /* Bisz spaeter */
438     #endif
439     if (usec < 0) {
440     sec--;
441     usec += 1000000;
442     }
443    
444     return (1000*sec + (usec / 1000));
445     }
446    
447 kaner-guest 368 static void
448     doit(SCSI *scgp)
449 blade 2 {
450     int i = 0;
451    
452     for (;;) {
453     if (!wait_unit_ready(scgp, 60))
454     comerrno(EX_BAD, "Device not ready.\n");
455    
456     printf("0:read\n");
457     /* printf("7:wne 8:floppy 9:verify 10:checkcmds 11:read disk 12:write disk\n");*/
458    
459     getint("Enter selection:", &i, 0, 20);
460     if (didintr)
461     return;
462    
463     switch (i) {
464    
465     /* case 1: read_disk(scgp, 0); break;*/
466    
467 blade 369 default: fprintf(stderr, "Unimplemented selection %d\n", i);
468 blade 2 }
469     }
470     }
471    
472 kaner-guest 368 static void
473     dofile(SCSI *scgp, char *filename)
474 blade 2 {
475     }
476    
477     /*
478     * Add your own code below....
479     */

  ViewVC Help
Powered by ViewVC 1.1.5