1 |
#include <stdio.h> |
2 |
#include <time.h> |
3 |
#include <unistd.h> |
4 |
#include <stdlib.h> |
5 |
#include <string.h> |
6 |
|
7 |
/* GetNextID - returns the next serial number for given file |
8 |
* |
9 |
* Uses flock on a file that contains the previous |
10 |
* ID. Locks the file, reads prev number, writes next number, removes lock. |
11 |
* returns a single line on stdout containing the incremented number. |
12 |
* Format is <fixed part>-<date>-<sequence number>. |
13 |
* |
14 |
* To call with a new file and/or new fixed-part call with 2 args, <filename> <fixed_part> |
15 |
* To simply update an existing ID number part of an existing ID file, call with just <filename> |
16 |
*/ |
17 |
|
18 |
void static getlock(FILE *fp, char *fname) |
19 |
{ |
20 |
int sleeps; |
21 |
for(sleeps=0; lockf(fileno(fp),F_TLOCK,0); sleeps++) |
22 |
{ |
23 |
if (sleeps >= 20) |
24 |
{ |
25 |
fprintf(stderr,"Lock stuck on %s, GetNextID failed.\n", fname); |
26 |
exit(1); |
27 |
} |
28 |
sleep(1); |
29 |
} |
30 |
return; |
31 |
} |
32 |
|
33 |
int main(int argc, char **argv) |
34 |
{ |
35 |
char fname[1024]; |
36 |
int NextIDsn; |
37 |
int nread; |
38 |
int old_date, new_date; |
39 |
int year, month, day; |
40 |
char fixedpart[100]; |
41 |
char NextID[100]; |
42 |
FILE *fp; |
43 |
struct tm *now; |
44 |
time_t nowtime; |
45 |
|
46 |
if (argc < 2) |
47 |
{ |
48 |
fprintf(stderr, "GetNextID failed, needs filename.\n"); |
49 |
exit(1); |
50 |
} |
51 |
strncpy(fname, argv[1], 1000); |
52 |
|
53 |
if (argc == 3) |
54 |
{ |
55 |
strcpy(fixedpart, argv[2]); |
56 |
NextIDsn = 0; |
57 |
old_date = 0; |
58 |
fp = fopen(fname, "w"); |
59 |
getlock(fp, fname); |
60 |
} |
61 |
else |
62 |
{ |
63 |
fp = fopen(fname, "r+"); |
64 |
if (!fp) |
65 |
{ |
66 |
fprintf(stderr, "GetNextID failed to open sn file, %s.\n", fname); |
67 |
exit(1); |
68 |
} |
69 |
getlock(fp, fname); |
70 |
|
71 |
nread = fscanf(fp,"%[^-]-%d-%d",fixedpart,&old_date,&NextIDsn); |
72 |
if (nread != 3) |
73 |
{ |
74 |
fprintf(stderr,"GetNextID failed. found %d instead of 3 fields in %s\n", nread, fname); |
75 |
exit(1); |
76 |
} |
77 |
} |
78 |
|
79 |
nowtime = time(0); |
80 |
now = gmtime(&nowtime); |
81 |
new_date = 10000*(now->tm_year+1900) + 100*(now->tm_mon+1) + now->tm_mday; |
82 |
if (old_date != new_date) |
83 |
{ |
84 |
FILE *history; |
85 |
strcat(fname, ".history"); |
86 |
history = fopen(fname, "a"); |
87 |
fprintf(history,"%s-%d-%05d\n", fixedpart, old_date, NextIDsn); |
88 |
fclose(history); |
89 |
NextIDsn = 1; |
90 |
} |
91 |
else |
92 |
NextIDsn += 1; |
93 |
rewind(fp); |
94 |
sprintf(NextID,"%s-%d-%05d", fixedpart, new_date, NextIDsn); |
95 |
|
96 |
fprintf(fp,"%s\n",NextID); |
97 |
rewind(fp); |
98 |
lockf(fileno(fp),F_ULOCK,0); |
99 |
fclose(fp); |
100 |
printf("%s\n",NextID); |
101 |
} |