1 /* 2 * CDDL HEADER START 3 * 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 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include "uucp.h" 34 35 static struct { 36 char sys[NAMESIZE]; 37 int job; 38 int subjob; 39 } syslst[30]; /* no more than 30 systems per job */ 40 41 static int nsys = 0; 42 static int sysseq(); 43 44 /* generate file name 45 * pre -> file prefix 46 * sys -> system name 47 * grade -> service grade 48 * file -> buffer to return filename must be of size MAXBASENAME+1 49 * return: 50 * none 51 */ 52 void 53 gename(pre, sys, grade, file) 54 char pre, *sys, grade, *file; 55 { 56 int n; 57 58 DEBUG(9, "gename(%c, ", pre); 59 DEBUG(9, "%s, ", sys); 60 DEBUG(9, "%c)\n", grade); 61 if (*sys == '\0') { 62 sys = Myname; 63 DEBUG(9, "null sys -> %s\n", sys); 64 } 65 n = sysseq(sys); 66 if (pre == CMDPRE || pre == XQTPRE) { 67 (void) sprintf(file, "%c.%.*s%c%.4x", 68 pre, SYSNSIZE, sys, grade, syslst[n].job); 69 } else 70 (void) sprintf(file, "%c.%.5s%.4x%.3x", 71 pre, sys, syslst[n].job & 0xffff, 72 ++syslst[n].subjob & 0xfff); 73 DEBUG(4, "file - %s\n", file); 74 return; 75 } 76 77 78 #define SLOCKTIME 10 79 #define SLOCKTRIES 25 80 #define SEQLEN 4 81 82 /* 83 * get next sequence number 84 * returns: 85 * number between 1 and 0xffff 86 * 87 * sequence number 0 is reserved for polling 88 */ 89 static int 90 getseq(sys) 91 char *sys; 92 { 93 register FILE *fp; 94 register int i; 95 unsigned int n; 96 time_t seed; 97 char seqlock[MAXFULLNAME], seqfile[MAXFULLNAME]; 98 99 ASSERT(nsys < sizeof (syslst)/ sizeof (syslst[0]), 100 "SYSLST OVERFLOW", "", sizeof (syslst)); 101 102 (void) time(&seed); /* crank up the sequence initializer */ 103 srand((unsigned)seed); 104 105 (void) sprintf(seqlock, "%s%s", SEQLOCK, sys); 106 BASENAME(seqlock, '/')[MAXBASENAME] = '\0'; 107 for (i = 1; i < SLOCKTRIES; i++) { 108 if ( mklock(seqlock) == SUCCESS ) 109 break; 110 sleep(5); 111 } 112 113 ASSERT(i < SLOCKTRIES, Ct_LOCK, seqlock, 0); 114 115 (void) sprintf(seqfile, "%s/%s", SEQDIR, sys); 116 if ((fp = fopen(seqfile, "r")) != NULL) { 117 /* read sequence number file */ 118 if (fscanf(fp, "%4x", &n) != 1) { 119 n = rand(); 120 clearerr(fp); 121 } 122 fp = freopen(seqfile, "w", fp); 123 ASSERT(fp != NULL, Ct_OPEN, seqfile, errno); 124 (void) chmod(seqfile, PUB_FILEMODE); 125 } else { 126 /* can not read file - create a new one */ 127 ASSERT((fp = fopen(seqfile, "w")) != NULL, 128 Ct_CREATE, seqfile, errno); 129 (void) chmod(seqfile, PUB_FILEMODE); 130 n = rand(); 131 } 132 133 n++; 134 n &= 0xffff; /* 4 byte sequence numbers */ 135 (void) fprintf(fp, "%.4x\n", n); 136 ASSERT(ferror(fp) == 0, Ct_WRITE, seqfile, errno); 137 (void) fclose(fp); 138 ASSERT(ferror(fp) == 0, Ct_CLOSE, seqfile, errno); 139 rmlock(seqlock); 140 DEBUG(6, "%s seq ", sys); DEBUG(6, "now %x\n", n); 141 (void) strcpy(syslst[nsys].sys, sys); 142 syslst[nsys].job = n; 143 syslst[nsys].subjob = rand() & 0xfff; /* random initial value */ 144 return(nsys++); 145 } 146 147 /* 148 * initSeq() exists because it is sometimes important to forget any 149 * cached work files. for example, when processing a bunch of spooled X. 150 * files, we must not re-use any C. files used to send back output. 151 */ 152 153 void 154 initSeq() 155 { 156 nsys = 0; 157 return; 158 } 159 160 /* 161 * retseq() is used to get the sequence number of a job 162 * for functions outside of this file. 163 * 164 * returns 165 * 166 * the sequence number of the job for the system. 167 */ 168 169 int 170 retseq(sys) 171 char *sys; 172 { 173 int i; 174 175 for (i = 0; i < nsys; i++) 176 if (EQUALSN(syslst[i].sys, sys, MAXBASENAME)) 177 break; 178 179 return(syslst[i].job); 180 } 181 182 static int 183 sysseq(sys) 184 char *sys; 185 { 186 int i; 187 188 for (i = 0; i < nsys; i++) 189 if (strncmp(syslst[i].sys, sys, MAXBASENAME) == SAME) 190 return(i); 191 192 return(getseq(sys)); 193 } 194