A text-based launcher for Podzilla2, iDoom, and iBoy written for iPodLinux, and the first program I ever wrote (not counting previous TI-BASIC masterpieces). The last-modified timestamp reads Mon, Apr 10 2006 00:23:20. It required ample hand-holding from the very patient #iPodLinux IRC channel, it used hard-coded paths for everything, and I didn't really understand much of what was going on (I certainly didn't write any of the pz_exec
function). But hey, Leo Laporte himself used it on TV, so I guess some people found it useful.
Last active
January 4, 2016 13:19
-
-
Save BHSPitMonkey/8627052 to your computer and use it in GitHub Desktop.
CLauncher, for iPodLinux.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* CLauncher: CLI Program Launcher for 5G's | |
* | |
* Copyright (C) 2006 Stephen Eisenhauer (BHSPitMonkey) | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation; either version 2 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software Foundation, | |
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
*/ | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/ioctl.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sys/stat.h> | |
#include <sys/time.h> | |
/* #ifdef IPOD */ | |
#include <linux/vt.h> | |
/* #endif */ | |
#include <dirent.h> | |
#include <string.h> | |
#include <errno.h> | |
void pz_exec(char *filename); | |
int main() | |
{ | |
char selection; /* Declare variable 'selection' */ | |
char pselection; | |
menu1: | |
{ | |
/* system("clear"); */ | |
printf("\n iPod CLauncher\n\n"); /* These five lines display options */ | |
printf(" Press:\n"); | |
printf("MENU for podzilla2\n"); | |
printf("PREV for iDoom\n"); | |
printf("NEXT for iBoy\n"); | |
printf("PLAY for power options\n"); | |
while (selection = getchar()) | |
if (selection != 'l' && selection != 'r') | |
{ | |
char c; c = selection; while ((int)c!=10) c = getchar(); | |
switch (selection) /* Each response yield's a different outcome. */ | |
{ | |
case 'm': /* If MENU is pressed... */ | |
printf("\nLaunching podzilla2!\n"); | |
pz_exec("/sbin/podzilla"); | |
system("sleep 1"); | |
goto menu1; | |
break; | |
case 'w': /* If PREV is pressed... */ | |
printf("\nLaunching iDoom!\n"); | |
chdir("/mnt/iDoom"); pz_exec("./iDoom"); | |
goto menu1; | |
break; | |
case 'f': /* If NEXT is pressed... */ | |
printf("\nLaunching iBoy!\n"); | |
chdir("/mnt/iBoy"); pz_exec("./iBoy"); | |
goto menu1; | |
break; | |
/* Here's where I got lazy and decided the Power functions were unimportant... */ | |
case 'd': /* If PLAY is pressed... */ | |
/* system("clear"); */ | |
printf("\n\n Press:\n"); | |
printf("PREV for reboot\n"); | |
printf("NEXT for power off\n"); | |
while (pselection = getchar()) | |
if (pselection != 'l' && pselection != 'r') | |
{ | |
char d; d = selection; while ((int)d!=10) d = getchar(); | |
switch (pselection) | |
{ | |
case 'w': /* If PREV is pressed... */ | |
printf("Rebooting...\n"); | |
system("reboot"); | |
break; | |
case 'f': /* If NEXT is pressed... */ | |
printf("Shutting down...\n"); | |
system("poweroff"); | |
break; | |
} | |
} | |
break; | |
default: | |
printf("\nSorry, I didn't understand that option.\n"); | |
break; | |
} | |
} | |
return 0; | |
} | |
} | |
void pz_exec(char *filename) | |
{ | |
#define _ | |
static const char *const tty0[] = {"/dev/tty0", "/dev/vc/0", 0}; | |
static const char *const vcs[] = {"/dev/vc/%d", "/dev/tty%d", 0}; | |
int i, tty0_fd, ttyfd, curvt, fd, status, oldvt = 0; | |
pid_t pid; | |
/* query for a free VT */ | |
ttyfd = -1; | |
tty0_fd = -1; | |
for (i = 0; tty0[i] && (tty0_fd < 0); ++i) { | |
tty0_fd = open(tty0[i], O_WRONLY, 0); | |
} | |
if (tty0_fd < 0) { | |
tty0_fd = dup(0); /* STDIN is a VT? */ | |
} | |
ioctl(tty0_fd, VT_OPENQRY, &curvt); | |
close(tty0_fd); | |
if ((geteuid() == 0) && (curvt > 0)) { | |
for (i = 0; vcs[i] && (ttyfd < 0); ++i) { | |
char vtpath[12]; | |
sprintf(vtpath, vcs[i], curvt); | |
ttyfd = open(vtpath, O_RDWR); | |
} | |
} | |
if (ttyfd < 0) { | |
fprintf(stderr, "No available TTYs.\n"); | |
return; | |
} | |
if (ttyfd >= 0) { | |
/* switch to the correct vt */ | |
if (curvt > 0) { | |
struct vt_stat vtstate; | |
if (ioctl(ttyfd, VT_GETSTATE, &vtstate) == 0) { | |
oldvt = vtstate.v_active; | |
} | |
if (ioctl(ttyfd, VT_ACTIVATE, curvt)) { | |
perror("child VT_ACTIVATE"); | |
return; | |
} | |
if (ioctl(ttyfd, VT_WAITACTIVE, curvt)) { | |
perror("child VT_WAITACTIVE"); | |
return; | |
} | |
} | |
} | |
switch(pid = vfork()) { | |
case -1: /* error */ | |
perror("vfork"); | |
break; | |
case 0: /* child */ | |
close(ttyfd); | |
if(setsid() < 0) { | |
perror("setsid"); | |
_exit(1); | |
} | |
close(0); | |
if((fd = open("/dev/console", O_RDWR)) == -1) { | |
perror("/dev/console"); | |
_exit(1); | |
} | |
if(dup(fd) == -1) { | |
perror("stdin dup"); | |
_exit(1); | |
} | |
close(1); | |
if(dup(fd) == -1) { | |
perror("stdout dup"); | |
_exit(1); | |
} | |
close(2); | |
if(dup(fd) == -1) { | |
perror("stderr dup"); | |
_exit(1); | |
} | |
execl(filename, filename, NULL); | |
fprintf(stderr, _("Exec failed! (Check Permissions)\n")); | |
_exit(1); | |
break; | |
default: /* parent */ | |
waitpid(pid, &status, 0); | |
sleep(5); | |
if (oldvt > 0) { | |
if (ioctl(ttyfd, VT_ACTIVATE, oldvt)) { | |
perror("parent VT_ACTIVATE"); | |
return; | |
} | |
if(ioctl(ttyfd, VT_WAITACTIVE, oldvt)) { | |
perror("parent VT_WAITACTIVE"); | |
return; | |
} | |
} | |
if (ttyfd > 0) | |
close(ttyfd); | |
if (curvt > 0) { | |
int oldfd; | |
if ((oldfd = open("/dev/vc/1", O_RDWR)) < 0) | |
oldfd = open("/dev/tty1", O_RDWR); | |
if (oldfd >= 0) { | |
if (ioctl(oldfd, VT_DISALLOCATE, curvt)) { | |
perror("VT_DISALLOCATE"); | |
return; | |
} | |
close(oldfd); | |
} | |
} | |
break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment