3124 Remove any existing references to utmp, use utmpx instead
[unleashed.git] / usr / src / cmd / bnu / grades.c
blob9a7fbee7316c1902dc71cdc06b8fac518d653f97
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 #include "uucp.h"
30 #include <grp.h>
32 #define G_EXT 0
33 #define G_INT 1
34 #define G_RES 2
35 #define G_ACT 3
36 #define G_IDF 4
37 #define G_MAX 512 /* max number of fields in the Grades file line */
38 #define SMBUF 128
40 #define TYPE 0
41 #define FILE1 1
42 #define FILE2 2
43 #define USER 3
44 #define OPTS 4
45 #define FILE3 5
47 extern int rdfulline(), jsize(), gdirf(), gnamef();
48 extern void wfcommit();
50 static void mailAdmin(); /* Send mail to administrator. */
53 * chkgrp - checks to see the group has permission
54 * to use a service grade queue.
56 * returns
58 * SUCCESS - if the group has permissions
59 * FAIL - if group does not
63 static int
64 chkgrp(carray,na)
65 char **carray;
66 int na;
68 struct group *grp;
69 int i;
70 gid_t gid;
72 gid = getgid();
73 grp = getgrgid(gid);
75 for (i = G_IDF; i < na; i++)
76 if (EQUALS(carray[i], grp->gr_name))
77 return(SUCCESS);
79 return(FAIL);
83 * chkusr - checks the permission fields of the Grades file
84 * to determine if the user can queue to a particular service grade.
86 * returns
88 * SUCCESS - if the user can queue to the service grade.
89 * FAIL - if the user can not queue to this service grade.
93 static int
94 chkusr(carray, na)
95 char **carray;
96 int na;
98 int i;
101 * start at the point where the users are supposed to be in the
102 * Grades file. Loop thru until the end of the user list is
103 * found or the user name is found. If the user name is found then
104 * return TRUE. If the end of the list is found, return FAIL.
107 DEBUG(9, "User (%s)\n", User);
109 /* check for any user and return if so */
111 if (EQUALS(carray[G_IDF], "Any"))
112 return(SUCCESS);
114 DEBUG(9, "Members of administrator defined service grade (%s)\n", carray[G_EXT]);
116 for (i = G_IDF; i < na; i++) {
117 DEBUG(9, "%s\n", carray[i]);
118 if (EQUALS(User, carray[i]))
119 return(SUCCESS);
122 return(FAIL);
126 * fgrade - finds the appropiate queue to queue a job into
128 * returns
129 * SUCCESS -> found a queue
130 * FAIL -> can't find a queue
134 fgrade(scfile)
135 struct cs_struct *scfile;
137 char fdgrade();
138 FILE *cfd;
139 char line[BUFSIZ];
140 char *carray[G_MAX];
141 long climit;
143 /* Check for the default service grade first */
145 if (strcmp(scfile->sgrade, "default") == 0) {
146 scfile->grade = fdgrade();
147 return(SUCCESS);
150 /* open grades file to begin a linear for the grade requested */
152 cfd = fopen(GRADES, "r");
154 /* loop until the file is empty or we find the grade we want */
156 while (rdfulline(cfd, line, BUFSIZ) != 0) {
157 (void) getargs(line, carray, G_MAX);
159 /* check to see if this is the grade we want */
161 if (!EQUALS(scfile->sgrade, carray[G_EXT]))
162 continue;
164 if (jsize(scfile, carray[G_RES], &climit) != FAIL) {
165 (void) fclose(cfd);
166 scfile->grade = *carray[G_INT];
167 return(SUCCESS);
171 (void) fclose(cfd);
173 (void) fprintf(stderr, gettext("Job size (%ld bytes)"
174 " exceeds maximum number of bytes (%ld bytes)"
175 " allowed into this service grade (%s).\n"
176 "Job queued to default grade.\n"),
177 scfile->jsize, climit, scfile->sgrade);
179 scfile->grade = fdgrade();
180 return(SUCCESS);
184 * fdgrade - finds the default queue for this system
186 * returns
187 * a one char name for the default queue
191 char
192 fdgrade()
194 FILE *cfd;
195 char line[BUFSIZ];
196 char *carray[G_MAX];
198 /* Check for the default grade first */
200 cfd = fopen(GRADES, "r");
202 /* loop until the end of the file is read */
204 for (; rdfulline(cfd, line, BUFSIZ) != 0;) {
206 /* parse the fields of this line */
208 (void) getargs(line, carray, G_MAX);
210 /* check to see if the administrator has defined
211 * a default grade for the machine.
214 if (strcmp(carray[G_EXT], "default") != 0)
215 continue;
217 /* default must be defined in the file
218 * close the file, get the queue name, and return.
221 (void) fclose(cfd);
222 return(*carray[G_INT]);
225 /* no default defined in this file. close file.
226 * get our default queue and return.
229 (void) fclose(cfd);
230 return(D_QUEUE);
234 * job_size - determines the size of a job
236 * returns
238 * SUCCESS - if the size of the job can be determined
239 * FAIL - otherwise
243 job_size(scfile)
244 struct cs_struct *scfile;
246 extern int Dfileused;
247 struct stat s;
248 FILE *fp;
249 char line[BUFSIZ];
250 char *carray[G_MAX];
251 int na;
252 int nodfile = FALSE;
253 int ret;
255 scfile->jsize = 0;
257 fp = fopen(scfile->file, "r");
259 if (fp == NULL) {
260 toCorrupt(scfile->file);
261 errent(Ct_OPEN, scfile->file, errno, __FILE__, __LINE__);
264 while (fgets(line, BUFSIZ, fp) != NULL) {
265 na = getargs(line, carray, G_MAX);
267 if (na < 6) {
268 (void) fclose(fp);
269 toCorrupt(scfile->file);
270 errent("BAD NUMBER OF ARGUMENTS", scfile->file, 0,
271 __FILE__, __LINE__);
274 /* if the type of a transfer is not a push
275 * then don't try to determine the size of
276 * the data file, because you can't.
279 if (*carray[TYPE] == 'R')
280 continue;
282 /* find the data dile that is to be transferred */
284 if ((ret = stat(carray[FILE3], &s)) != 0) {
285 if (errno == ENOENT) {
286 nodfile = TRUE;
287 ret = stat(carray[FILE1], &s);
290 else
291 Dfileused = TRUE;
294 * check to see if the return code from stat was 0
295 * if return code was not 0, write message to error
296 * log and quit. Otherwise, add size of file to job
297 * size and continue looping.
300 if (ret != 0) {
301 (void) fclose(fp);
302 errent(Ct_STAT, nodfile ?
303 carray[FILE1] : carray[FILE3], errno,
304 __FILE__, __LINE__);
307 nodfile = FALSE;
308 scfile->jsize += s.st_size;
310 (void) fclose(fp);
311 return(SUCCESS);
314 static void lcase();
317 * jsize - determines whether if a job is small enough to
318 * be placed in the appropiate queue.
320 * returns
322 * SUCCESS - if the size of the job is less than or
323 * equal to the number of bytes in the restriction
324 * of the GRADES file.
326 * FAIL - otherwise
330 jsize(scfile, climit, nlimit)
331 struct cs_struct *scfile;
332 char *climit;
333 long *nlimit;
335 #define ONE_K (1024)
336 #define ONE_MEG ((1024)*(1024))
338 char rest[SMBUF];
339 char msg[BUFSIZ], *p;
341 if (EQUALS(climit, "Any"))
342 return(SUCCESS);
344 lcase(climit, rest, SMBUF);
346 if (!(p = strchr(rest, 'k')) && (!(p = strchr(rest, 'm')))) {
348 for(p = climit; *p; ++p) {
349 if (isdigit(*p))
350 continue;
352 /* corrupt restriction field in the Grades file.
353 * report it to the uucp administrator.
356 snprintf(msg, sizeof (msg),
357 gettext("Error encountered in the"
358 " restrictions field of the Grades file."
359 " Field contents (%s)."), climit);
360 mailAdmin(msg);
361 return(SUCCESS);
364 *nlimit = atol(climit);
366 else if (*p == 'k') {
367 *p = '\0';
368 *nlimit = (long) (atof(rest) * ONE_K);
370 else {
371 *p = '\0';
372 *nlimit = (long) (atof(rest) * ONE_MEG);
375 if (scfile->jsize <= *nlimit)
376 return(SUCCESS);
377 else
378 return(FAIL);
381 static void
382 lcase(s, t, lim)
383 char s[], t[];
384 int lim;
386 char *p;
387 int i;
390 p = s;
392 for (i = 0; i < lim-1 && *p; i++)
393 if (isupper(*p))
394 t[i] = tolower(*p++);
395 else
396 t[i] = *p++;
398 t[i] = '\0';
399 return;
403 * mailAdmin - mail a message to the uucp administrator.
405 * returns:
407 * nothing
410 static void
411 mailAdmin (msg)
413 char * msg;
416 char cmd[BUFSIZ]; /* Place to build mail command. */
417 FILE * mail; /* Channel to write mail on. */
419 (void) sprintf(cmd, "%s %s %s", PATH, MAIL, "uucp");
420 if ((mail = popen(cmd, "w")) != (FILE *) NULL)
422 (void) fprintf(mail, "To: uucp\nSubject: %s\n\n%s\n",
423 gettext("Grades file problem"), msg);
424 (void) pclose(mail);
428 * Ignore popen failure. There is not much that we can do if
429 * it fails, since we are already trying to notify the administrator
430 * of a problem.
432 return;
436 * putdfiles - moves any and all of the D. to the spool directory for
437 * a C. file.
439 * returns
441 * nothing
444 void
445 putdfiles(scfile)
446 struct cs_struct scfile;
448 FILE *fp;
449 char line[BUFSIZ];
450 char *carray[G_MAX];
451 int na;
452 struct stat s;
454 fp = fopen(scfile.file, "r");
456 if (fp == NULL) {
457 toCorrupt(scfile.file);
458 errent(Ct_OPEN, scfile.file, errno, __FILE__, __LINE__);
461 while (fgets(line, BUFSIZ, fp) != NULL) {
463 na = getargs(line, carray, G_MAX);
464 if (na < 6) {
465 (void) fclose(fp);
466 toCorrupt(scfile.file);
467 errent("BAD NUMBER OF ARGUMENTS", scfile.file, 0,
468 __FILE__, __LINE__);
471 if (*carray[TYPE] == 'R')
472 continue;
474 /* move D. file to the spool area */
476 if (stat(carray[FILE3], &s) != -1)
477 wfcommit(carray[FILE3], carray[FILE3], scfile.sys);
480 (void) fclose(fp);
481 return;
485 * reads a line from a file and takes care of comment lines
486 * and continuations (\) in last column.
488 * return:
489 * the number of chars that are placed in line.
493 rdfulline(fd, line, lim)
494 FILE *fd;
495 char *line;
496 int lim;
498 register char *p, *c;
499 char buf[BUFSIZ];
500 size_t blr, btox;
502 p = line;
503 for (;fgets(buf, BUFSIZ, fd) != NULL;) {
504 /* check to see if it is a comment */
506 if (buf[0] == '#')
507 continue;
509 /* remove trailing white space */
510 c = &buf[strlen(buf)-1];
511 while (c>=buf && (*c == '\n' || *c == '\t' || *c == ' ') )
512 *c-- = NULLCHAR;
514 if (buf[0] == '\n' || buf[0] == NULLCHAR)
515 continue;
517 blr = lim - 1 - (p - line);
518 btox = blr < strlen(buf) ? blr : strlen(buf);
520 if (btox <= 0)
521 break;
523 (void) strncpy(p, buf, btox);
524 p += btox - 1;
526 if ( *(p-1) == '\\')
527 p--;
528 else
529 break;
532 *++p = '\0';
533 return(p-line-1);
536 /* upermit - checks to determine if the user has permissions
537 * to use administrator defined service grade.
539 * returns
540 * SUCCESS -> if the user can queue to this service grade.
541 * FAIL -> if the user cannot queue to this service grade.
545 upermit(carray, na)
546 char **carray;
547 int na;
549 #define G_USR "user"
550 #define G_NUSR "non-user"
551 #define G_GRP "group"
552 #define G_NGRP "non-group"
554 char actn[SMBUF];
555 char ufld[SMBUF];
556 char msg[BUFSIZ];
558 (void) strcpy(actn, carray[G_ACT]);
560 lcase(actn, ufld, SMBUF);
562 if (EQUALS(ufld, G_USR))
563 return(chkusr(carray,na));
565 if (EQUALS(ufld, G_NUSR))
566 return((chkusr(carray, na) != SUCCESS) ? SUCCESS : FAIL);
568 if (EQUALS(ufld, G_GRP))
569 return(chkgrp(carray, na));
571 if (EQUALS(ufld, G_NGRP))
572 return((chkgrp(carray, na) != SUCCESS) ? SUCCESS : FAIL);
574 (void) snprintf(msg, sizeof (msg),
575 gettext("Error encountered in action field of"
576 " the Grades file. Field contents (%s)."), carray[G_ACT]);
577 mailAdmin(msg);
578 return(FAIL);
582 * vergrd - verify if the grade name is a valid administrator
583 * defined service grade name and if the user has the
584 * appropiate permission to use this grade.
586 * returns
587 * SUCCESS -> grade is valid and user is
588 * permitted to use this grade.
589 * FAIL -> otherwise
594 vergrd(grade)
595 char *grade;
597 FILE *cfd;
598 char line[BUFSIZ];
599 char *carray[G_MAX];
600 int na;
602 /* Check for the default grade first */
604 if (EQUALS(grade, "default"))
605 return(SUCCESS);
607 /* open grades file to begin a linear for the grade requested */
609 cfd = fopen(GRADES, "r");
611 /* loop until the file is empty or we find the grade we want */
613 while (rdfulline(cfd, line, BUFSIZ) != 0) {
614 na = getargs(line, carray, G_MAX);
616 /* check to see if this is the grade we want */
618 if (!EQUALS(grade, carray[G_EXT]))
619 continue;
621 /* check for the permission on this grade */
623 if (upermit(carray, na) != FAIL) {
624 (void) fclose(cfd);
625 return(SUCCESS);
627 else {
628 (void) fclose(cfd);
629 (void) fprintf(stderr, gettext("User does not have"
630 " permission to use this service grade (%s).\n"
631 "Job has not been queued.\n"
632 "Use (uuglist) to find which service grades"
633 " you can queue to.\n"), grade);
634 return(FAIL);
638 (void) fclose(cfd);
640 (void) fprintf(stderr, gettext(
641 "Service grade (%s) does not exist on this machine."
642 " Job not queued.\n"
643 "Use (uuglist) to find which service grades are available on"
644 " this machine.\n"), grade);
645 return(FAIL);
649 * wfremove - removes a C. file from the Workspace directory and all of its
650 * D. files.
653 void
654 wfremove(file)
655 char *file;
657 FILE *fp;
658 char line[BUFSIZ];
659 char *carray[G_MAX];
660 int na;
661 struct stat s;
663 fp = fopen(file, "r");
665 if (fp == NULL) {
666 toCorrupt(file);
667 errent(Ct_OPEN, file, errno, __FILE__, __LINE__);
670 while (fgets(line, BUFSIZ, fp) != NULL) {
671 na = getargs(line, carray, G_MAX);
673 if (na < 6) {
674 (void) fclose(fp);
675 toCorrupt(file);
676 errent("BAD NUMBER OF ARGUMENTS", file, 0,
677 __FILE__, __LINE__);
680 if (*carray[TYPE] == 'R')
681 continue;
683 /* remove D. file */
685 DEBUG(4, "Removing data file (%s)\n", carray[FILE3]);
687 if ((stat(carray[FILE3], &s) != -1) && (unlink(carray[FILE3]) != 0)) {
688 (void) fclose(fp);
689 toCorrupt(file);
690 toCorrupt(carray[FILE3]);
691 errent(Ct_UNLINK, carray[FILE3], errno, __FILE__,
692 __LINE__);
696 (void) fclose(fp);
698 DEBUG(4, "Removing work file (%s)\n", file);
700 if (unlink(file) != 0) {
701 toCorrupt(file);
702 errent(Ct_UNLINK, file, errno, __FILE__, __LINE__);
704 return;
708 * findgrade - finds the highest priority job grade that is not locked
709 * and that has jobs.
711 * job grade name is null, if no job grade is found.
714 void
715 findgrade(dir, jobgrade)
716 char *dir, *jobgrade;
718 char prevgrade[MAXBASENAME+1], curgrade[MAXBASENAME+1],
719 gradedir[MAXBASENAME+1];
720 char lockname[MAXFULLNAME];
721 char Cfile[MAXBASENAME+1];
722 DIR *p, *q;
724 *prevgrade = NULLCHAR;
725 p = opendir(dir);
726 ASSERT(p != NULL, Ct_OPEN, dir, errno);
728 while (gdirf(p, gradedir, dir) == TRUE) {
729 (void) sprintf(lockname, "%s.%.*s.%s", LOCKPRE, SYSNSIZE,
730 Rmtname, gradedir);
731 if (cklock(lockname) == FAIL)
732 continue;
733 q = opendir(gradedir);
734 ASSERT(q != NULL, Ct_OPEN, gradedir, errno);
735 while (gnamef(q, Cfile) == TRUE) {
736 if (Cfile[0] == CMDPRE) {
737 if (*prevgrade == NULLCHAR) {
738 (void) strcpy(prevgrade, gradedir);
739 break;
741 (void) strcpy(curgrade, gradedir);
742 if (strcmp(curgrade, prevgrade) < 0)
743 (void) strcpy(prevgrade, curgrade);
746 closedir(q);
748 closedir(p);
749 (void) strncpy(jobgrade, prevgrade, MAXBASENAME);
750 jobgrade[MAXBASENAME] = NULLCHAR;
751 return;