1 /*
2     Cmp3 works by spawning a manager process that takes care of playing the
3     songs while the regular process worries about the actual playlist.
4     This file contains the manager process.
5 */
6 
7 #include"cmp3manager.h"
8 
9 FILE *debugfile;
10 
11 
12 /* XXX - debug stuff */
startdebug()13 void startdebug()
14 {
15 	#ifdef CMP3_DEBUG
16     debugfile = fopen(CMP3_LOGFILE, "a");
17     setbuf(debugfile, NULL);
18 	#else /* CMP3_DEBUG */
19     debugfile = fopen("/dev/null", "w");
20     return;
21 	#endif /* CMP3_DEBUG */
22 }
23 
24 
25 /**************************
26 	MANAGEIT
27 	runs in a separate forked process,
28 	manages the mp3 process
29 **************************/
manageit()30 void manageit()
31 {
32 	/*     setpgrp(); */
33     shmptr = (shmdata_t*) shmat(shmid,NULL,0);
34     if (shmptr < 0) {
35         perror("can't attach shared memory");
36         dienow(1);
37     }
38     shmptr->managpid = getpid();
39     shmptr->listlen = 0;
40     shmptr->pid = 0;
41     shmptr->pltail = shmptr->plhead;
42     signal(SIGUSR1,listnext); /* why is this not Signal?? */
43     Signal(SIGCHLD,listnext);
44     Signal(SIGINT,dienow);
45     Signal(SIGTERM,dienow);
46 
47     startdebug();
48     if (debugfile)
49         fprintf(debugfile, "Initialized manager process %d\n", getpid());
50 
51     while (1)
52         /*  oh, oh, oh, oh, stayin' alive, stayin' alive */
53 		/* FIXME: what happens if there IS no stdin? i.e. tty goes away? */
54         select(0,NULL,NULL,NULL,NULL);
55     exit(0);
56 }
57 
58 /******************************************
59 	LISTNEXT
60 	plays the next file in the list.
61 *******************************************/
listnext(int signum)62 void listnext(int signum)
63 {
64     int pid;
65 
66 	/* first reap dead pid's (HACK!) */
67 	if(kill(shmptr->pid,0)){
68 		shmptr->pid = 0;
69 	}
70 
71     if (shmptr->pause)
72         return;
73 
74     if (signum==SIGCHLD) {
75         while(waitpid(-1,NULL,WNOHANG) > 0)
76             ;
77         if ((shmptr->listlen > 1)) {
78 
79             if (shmptr->repeat == 1) {
80                 pl_addentry(shmptr->plhead);
81             }
82             pl_delentry(shmptr->plhead);
83         } else {
84             if (shmptr->repeat != 1) {
85                 if (shmptr->using == 0) {
86                     dienow(1);
87                 } else {
88                     shmptr->listlen = 0;
89                     shmptr->pltail = shmptr->plhead;
90                     return;
91                 }
92             } else {
93                 /* In repeat mode, keep playing */
94             }
95         }
96         shmptr->pid=0;
97 		/* old sysv style, must reset this here */
98         Signal(SIGCHLD,listnext);
99     } else {
100 		/* FIXME: ok, this must be where it is returning cause pid full? */
101         if (shmptr->pid) {
102 			if(kill(shmptr->pid, 0) ){
103 				shmptr->pid = 0;
104 			}
105 			return;
106 		}
107 		/* old sysv style, must reset this here */
108         signal(SIGUSR1,listnext);
109     }
110     if (shmptr->listlen > 0) {
111 		/* check for file type, launch either mpg123 or ogg123 */
112 		if (Strcmp(shmptr->plhead+(strlen(shmptr->plhead)-4),".mp3") == 0){
113 			pid = fork();
114 			if (pid == -1) {
115 				perror("Cant fork");
116 				exit(0);
117 			}
118 			if (pid==0) {
119 				int returned=0;
120 
121 				sleep(1);
122 				fclose(stdin);
123 
124 				/* Route all mpg123 output from stderr to logfile */
125 				if (debugfile) {
126 					dup2(fileno(debugfile), fileno(stderr));
127 					dup2(fileno(debugfile), fileno(stdout));
128 				} else {
129 					fclose(stderr);
130 				}
131 
132 					returned = execlp(EXEC_LOC,
133 						  "mpg123",
134 						  EXEC_PARAMS
135 						  shmptr->plhead, 0);
136 
137 
138 
139 				if (returned != 0) {
140 					fprintf(debugfile, "execlp failed on %s with errno = %d\n",
141 						shmptr->plhead, errno);
142 				}
143 
144 				exit(0);
145 		   }
146 		   shmptr->pid=pid;
147 		} else if (Strcmp(shmptr->plhead+(strlen(shmptr->plhead)-4),".ogg") == 0){
148 			pid = fork();
149 			if (pid == -1) {
150 				perror("Cant fork");
151 				exit(0);
152 			}
153 			if (pid==0) {
154 				int returned=0;
155 
156 				sleep(1);
157 				fclose(stdin);
158 
159 				/* Route all mpg123 output from stderr to logfile */
160 				if (debugfile) {
161 					dup2(fileno(debugfile), fileno(stderr));
162 					dup2(fileno(debugfile), fileno(stdout));
163 				} else {
164 					fclose(stderr);
165 				}
166 
167 
168 				returned = execlp(OGG_LOC,
169 					  "ogg123",
170 					  OGG_PARAMS
171 					  shmptr->plhead, 0);
172 
173 
174 				if (returned != 0) {
175 					fprintf(debugfile, "execlp failed on %s with errno = %d\n",
176 						shmptr->plhead, errno);
177 				}
178 
179 				exit(0);
180 		   }
181 		   shmptr->pid=pid;
182 		} else {
183 			fprintf(debugfile, "listnext: %s is not an mp3 or ogg file\n",
184 				shmptr->plhead);
185 			return;
186 		}  /* end ogg/mp3 contingencies */
187 	} /* end listlen > 0 */
188 } /* END LISTNEXT */
189 
dienow(int diedude)190 void dienow(int diedude)
191 {
192     if (shmptr->pause == 1)
193         kill(shmptr->pid, SIGCONT);
194     if (shmptr->pid)
195         kill(shmptr->pid,SIGINT);
196 
197     fprintf(debugfile, "Exiting manager process %d\n", getpid());
198     fclose(debugfile);
199 
200     if (shmdt((char*)shmptr) < 0)
201         perror("can't detach shared memory");
202     if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0) < 0)
203         perror("can't remove shared memory");
204 
205   exit(1);
206 }
207 
208 /* EOF */
209