Skip to content

Instantly share code, notes, and snippets.

@BHSPitMonkey
Last active January 4, 2016 13:19
Show Gist options
  • Save BHSPitMonkey/8627052 to your computer and use it in GitHub Desktop.
Save BHSPitMonkey/8627052 to your computer and use it in GitHub Desktop.
CLauncher, for iPodLinux.
/* 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;
}
}

CLauncher

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment