+
+
+void sighandler(int inSignal)
+{
+ unlink(LOCK_FILE);
+ exit(1);
+}
+
+
+int
+file_passwd(char *uname, char *locn)
+{
+ pid_t pid;
+ int retVal = 0;
+ int waitResult = 0;
+ int retries = 0;
+ struct stat sb;
+ FILE *lockFile;
+ struct sigaction action = {{0}};
+ struct rlimit rlim;
+
+ /* unlimit the resource limits */
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+ (void)setrlimit(RLIMIT_CPU, &rlim);
+ (void)setrlimit(RLIMIT_FSIZE, &rlim);
+ (void)setrlimit(RLIMIT_STACK, &rlim);
+ (void)setrlimit(RLIMIT_DATA, &rlim);
+ (void)setrlimit(RLIMIT_RSS, &rlim);
+ (void)setrlimit(RLIMIT_NOFILE, &rlim);
+
+ /* trap signals */
+ sigfillset( &action.sa_mask );
+ action.sa_flags = SA_RESTART;
+ action.sa_handler = sighandler;
+ sigaction(SIGHUP, &action, NULL);
+ sigaction(SIGINT, &action, NULL); // ctrl-c
+ sigaction(SIGQUIT, &action, NULL);
+ sigaction(SIGABRT, &action, NULL);
+ sigaction(SIGPIPE, &action, NULL);
+ sigaction(SIGALRM, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
+ sigaction(SIGSTOP, &action, NULL);
+ sigaction(SIGTSTP, &action, NULL);
+
+ /* Check/create lock file */
+ for (retries = 0; retries < 5; retries++)
+ {
+ retVal = lstat(LOCK_FILE, &sb);
+ if (retVal != 0)
+ break;
+ /* try in 100 milliseconds */
+ usleep(100000);
+ }
+ if (retVal == 0)
+ {
+ fprintf(stderr, "another passwd process is running.\n");
+ exit(EX_TEMPFAIL);
+ }
+
+ umask((S_IRWXG | S_IRWXO));
+ lockFile = fopen(LOCK_FILE, "w");
+ if (lockFile == NULL)
+ {
+ fprintf(stderr, "can't create lock file.\n");
+ exit(EX_CANTCREAT);
+ }
+ fprintf(lockFile, "%d\n", getpid());
+ fclose(lockFile);
+
+ pid = fork();
+ if (pid == -1)
+ {
+ fprintf(stderr, "can't fork\n");
+ exit(EX_OSERR);
+ }
+
+ /* Handle the child */
+ if (pid == 0)
+ {
+ retVal = _file_passwd_main(uname, locn);
+ exit(retVal);
+ }
+
+ /* Handle the parent */
+ waitResult = waitpid(pid, &retVal, 0);
+ retVal = (waitResult == 0) ? WEXITSTATUS(retVal) : 1;
+
+ /* delete lock file */
+ unlink(LOCK_FILE);
+
+ return retVal;
+}
+