Xinu7/src/cmd/download/OLD/VERYOLD/getlsi.c
/* getlsi.c - procedure that automatically selects and LSI 11 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include "/usr/Xinu/include/getlsi.h"
#define MAXSTR 30
char *tmpnam = TMPNAME;
char tmpuser[MAXSTR];
char devname[MAXSTR];
char convert[MAXSTR];
char *loginid;
char *lsidevs[] = {
#include "/usr/Xinu/include/lsidevs.h"
"/dev/LSI"};
#define NDEVS sizeof(lsidevs)/sizeof(char *)
/************************************************************************/
/* */
/* getlsi -- get the LSI a user has already reserved, or one that is */
/* free */
/* */
/************************************************************************/
getlsi(usethis, lnum, lsifd, locknm)
int usethis; /* specific LSI, "my" LSI, or "any" LSI */
int *lnum; /* place to store # of lsi allocated */
int *lsifd; /* place to store lsi file descriptor */
char *locknm; /* place to store lock file name */
{
char *getlogin();
int fd;
char c;
if ( (loginid=getlogin()) == NULL)
loginid = (getpwuid(getuid()))->pw_name;
strcpy(tmpuser, tmpnam);
strcat(tmpuser, loginid);
*lnum = -1;
*locknm = '\0';
/* either get specified LSI, the one this user has reserved, */
/* or any LSI, depending on 'usethis' */
if (usethis == MYLSI) {
oldlsi(lnum,locknm);
} else if (usethis == ANYLSI) {
if (oldlsi(lnum,locknm) < 0)
newlsi(usethis,lnum,locknm);
} else
newlsi(usethis,lnum,locknm);
/* if successful, *lnum contains (nonnegative) number of lsi */
/* that was allocated. Else it is -1 */
if (*lnum >= 0) {
if ( (*lsifd = open(lsidevs[*lnum],2)) < 0) {
fprintf(stderr,"Cannot open %s\n",lsidevs[*lnum]);
unlink(locknm);
unlink(tmpuser);
return(-1);
}
touch(locknm);
return(*lnum);
}
if (usethis >= 0)
fprintf(stderr, "LSI #%d unavailable.\n", usethis);
else if (usethis == MYLSI)
fprintf(stderr,"No LSI on reserve for you.\n");
else
fprintf(stderr, "No LSI 11 available.\n");
return(-1);
}
/*
* oldlsi -- return id of LSI already allocated to this user
*/
oldlsi(lnum, locknm)
int *lnum; /* place to store lsi number */
char *locknm; /* place to store lock file name */
{
int fd;
int lsinum;
int len;
*lnum = -1;
if ( (fd=open(tmpuser,2)) >= 0) { /* user has a lock file */
len = read(fd, &lsinum, sizeof(int));
close(fd);
if (len != sizeof(int) || lsinum<0 || lsinum>=NDEVS) {
unlink(tmpuser);
return(-1);
}
sprintf(convert, "%d", lsinum);
strcpy(locknm, tmpnam);
strcat(locknm, convert);
if (access(locknm,4|2) < 0)
return(-1);
*lnum = lsinum;
return(lsinum);
}
return(-1);
}
newlsi(usethis, lnum, locknm)
int usethis; /* force using this lsi */
int *lnum; /* place to store lsi number used */
char *locknm; /* place to store lock file name */
{
int i, fd;
if (usethis >= 0) {
if (trylsi(usethis, locknm) >= 0)
return( *lnum = usethis );
return( *lnum = -1);
}
for (i=0 ; i<NDEVS ; i++) {
if (trylsi(i, locknm) >= 0)
return( *lnum = i );
}
return( *lnum = -1 );
}
struct stat sbuf;
/*
* trylsi -- see if a given lsi is available
*/
trylsi(lsinum, locknm)
int lsinum;
char *locknm;
{
long time();
long now;
int fd;
if (access(lsidevs[lsinum], 0) < 0)
return(-1);
strcpy(locknm, tmpnam);
sprintf(convert, "%d", lsinum);
strcat(locknm, convert);
if ((fd=creat(locknm,0600)) < 0) {
stat(locknm, &sbuf);
now = time(0L);
if ( (int)(now-sbuf.st_mtime) > 600)
unlink(locknm);
else
return(-1);
if ((fd=creat(locknm,0600)) < 0) {
fprintf(stderr,"Can't create lock\n");
exit(-1);
}
}
close(fd);
strcpy(tmpuser, tmpnam);
strcat(tmpuser, loginid);
unlink(tmpuser);
if ( (fd=creat(tmpuser,0666)) < 0) {
perror("Can't create tmp userid file");
exit(1);
}
write(fd, &lsinum, sizeof(int));
close(fd);
return(lsinum);
}
touch(locknm)
char *locknm; /* name of file to touch */
{
close(creat(locknm, 0600));
}